optimize hash computation

This commit is contained in:
rootdarkarchon
2023-03-27 11:37:39 +02:00
parent 1aa0563fc0
commit 4cabc39e45
4 changed files with 57 additions and 32 deletions

View File

@@ -5,6 +5,7 @@ using MareSynchronos.Utils;
using MareSynchronos.WebAPI; using MareSynchronos.WebAPI;
using MareSynchronos.WebAPI.Files; using MareSynchronos.WebAPI.Files;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Linq;
namespace MareSynchronos.PlayerData.Pairs; namespace MareSynchronos.PlayerData.Pairs;
@@ -47,16 +48,9 @@ public class OnlinePlayerManager : DisposableMediatorSubscriberBase
var playerCharacters = _dalamudUtil.GetPlayerCharacters(); var playerCharacters = _dalamudUtil.GetPlayerCharacters();
var newVisiblePlayers = new List<UserData>(); var newVisiblePlayers = new List<UserData>();
foreach (var pChar in playerCharacters) var chars = _pairManager.FindAllPairs(playerCharacters);
{ newVisiblePlayers.AddRange(from pChar in chars.Where(p => p.Pair != null && p.Pair.InitializePair(p.Character.Name.ToString()))
var pair = _pairManager.FindPair(pChar); select pChar.Pair.UserData);
if (pair == null) continue;
if (pair.InitializePair(pChar.Name.ToString()))
{
newVisiblePlayers.Add(pair.UserData);
}
}
if (newVisiblePlayers.Any()) if (newVisiblePlayers.Any())
{ {

View File

@@ -45,22 +45,10 @@ public class Pair
public CharacterData? LastReceivedCharacterData { get; set; } public CharacterData? LastReceivedCharacterData { get; set; }
public string? PlayerName => CachedPlayer?.PlayerName ?? string.Empty; public string? PlayerName => CachedPlayer?.PlayerName ?? string.Empty;
public string GetPlayerNameHash()
{
try
{
return CachedPlayer?.PlayerNameHash ?? string.Empty;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Error accessing PlayerNameHash, recreating CachedPlayer");
RecreateCachedPlayer();
}
return string.Empty;
}
public UserData UserData => UserPair?.User ?? GroupPair.First().Value.User; public UserData UserData => UserPair?.User ?? GroupPair.First().Value.User;
public UserPairDto? UserPair { get; set; } public UserPairDto? UserPair { get; set; }
private CachedPlayer? CachedPlayer { get; set; } private CachedPlayer? CachedPlayer { get; set; }
public void AddContextMenu(GameObjectContextMenuOpenArgs args) public void AddContextMenu(GameObjectContextMenuOpenArgs args)
@@ -118,6 +106,21 @@ public class Pair
return _serverConfigurationManager.GetNoteForUid(UserData.UID); return _serverConfigurationManager.GetNoteForUid(UserData.UID);
} }
public string GetPlayerNameHash()
{
try
{
return CachedPlayer?.PlayerNameHash ?? string.Empty;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Error accessing PlayerNameHash, recreating CachedPlayer");
RecreateCachedPlayer();
}
return string.Empty;
}
public bool HasAnyConnection() public bool HasAnyConnection()
{ {
return UserPair != null || GroupPair.Any(); return UserPair != null || GroupPair.Any();
@@ -203,14 +206,14 @@ public class Pair
if (disableAnimations || disableSounds) if (disableAnimations || disableSounds)
{ {
_logger.LogTrace("Data cleaned up: Animations disabled: {disableAnimations}, Sounds disabled: {disableSounds}", disableAnimations, disableSounds); _logger.LogTrace("Data cleaned up: Animations disabled: {disableAnimations}, Sounds disabled: {disableSounds}", disableAnimations, disableSounds);
foreach (var kvp in data.FileReplacements) foreach (var objectKind in data.FileReplacements.Select(k => k.Key))
{ {
if (disableSounds) if (disableSounds)
data.FileReplacements[kvp.Key] = data.FileReplacements[kvp.Key] data.FileReplacements[objectKind] = data.FileReplacements[objectKind]
.Where(f => !f.GamePaths.Any(p => p.EndsWith("scd", StringComparison.OrdinalIgnoreCase))) .Where(f => !f.GamePaths.Any(p => p.EndsWith("scd", StringComparison.OrdinalIgnoreCase)))
.ToList(); .ToList();
if (disableAnimations) if (disableAnimations)
data.FileReplacements[kvp.Key] = data.FileReplacements[kvp.Key] data.FileReplacements[objectKind] = data.FileReplacements[objectKind]
.Where(f => !f.GamePaths.Any(p => p.EndsWith("tmb", StringComparison.OrdinalIgnoreCase) || p.EndsWith("pap", StringComparison.OrdinalIgnoreCase))) .Where(f => !f.GamePaths.Any(p => p.EndsWith("tmb", StringComparison.OrdinalIgnoreCase) || p.EndsWith("pap", StringComparison.OrdinalIgnoreCase)))
.ToList(); .ToList();
} }

View File

@@ -91,6 +91,11 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
RecreateLazy(); RecreateLazy();
} }
public List<(PlayerCharacter Character, Pair? Pair)> FindAllPairs(List<PlayerCharacter> playerCharacters)
{
return playerCharacters.Select(p => (p, _allClientPairs.Values.FirstOrDefault(f => string.Equals(p.GetHash256(), f.GetPlayerNameHash())))).ToList();
}
public Pair? FindPair(PlayerCharacter? pChar) public Pair? FindPair(PlayerCharacter? pChar)
{ {
if (pChar == null) return null; if (pChar == null) return null;

View File

@@ -6,6 +6,9 @@ namespace MareSynchronos.Utils;
public static class Crypto public static class Crypto
{ {
private static readonly Dictionary<string, string> _hashListSHA1 = new(StringComparer.Ordinal);
private static readonly Dictionary<string, string> _hashListSHA256 = new(StringComparer.Ordinal);
#pragma warning disable SYSLIB0021 // Type or member is obsolete #pragma warning disable SYSLIB0021 // Type or member is obsolete
public static string GetFileHash(this string filePath) public static string GetFileHash(this string filePath)
@@ -16,20 +19,40 @@ public static class Crypto
public static string GetHash(this string stringToHash) public static string GetHash(this string stringToHash)
{ {
using SHA1CryptoServiceProvider cryptoProvider = new(); return GetOrComputeHashSHA1(stringToHash);
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToHash))).Replace("-", "", StringComparison.Ordinal);
} }
public static string GetHash256(this string stringToHash) public static string GetHash256(this string stringToHash)
{ {
using SHA256CryptoServiceProvider cryptoProvider = new(); return GetOrComputeHashSHA256(stringToHash);
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToHash))).Replace("-", "", StringComparison.Ordinal);
} }
public static string GetHash256(this PlayerCharacter character) public static string GetHash256(this PlayerCharacter character)
{ {
var charName = character.Name + character.HomeWorld.Id.ToString();
return GetOrComputeHashSHA256(charName);
}
private static string GetOrComputeHashSHA1(string stringToCompute)
{
if (_hashListSHA1.TryGetValue(stringToCompute, out var hash))
return hash;
using SHA1CryptoServiceProvider cryptoProvider = new();
var computedHash = BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal);
_hashListSHA1[stringToCompute] = computedHash;
return computedHash;
}
private static string GetOrComputeHashSHA256(string stringToCompute)
{
if (_hashListSHA256.TryGetValue(stringToCompute, out var hash))
return hash;
using SHA256CryptoServiceProvider cryptoProvider = new(); using SHA256CryptoServiceProvider cryptoProvider = new();
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(character.Name + character.HomeWorld.Id.ToString()))).Replace("-", "", StringComparison.Ordinal); var computedHash = BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal);
_hashListSHA256[stringToCompute] = computedHash;
return computedHash;
} }
#pragma warning restore SYSLIB0021 // Type or member is obsolete #pragma warning restore SYSLIB0021 // Type or member is obsolete