minor adjustments for potential concurrency issues

This commit is contained in:
Stanley Dimant
2022-09-07 02:41:25 +02:00
parent 1e9161aed5
commit 23abae4c20
3 changed files with 39 additions and 29 deletions

View File

@@ -292,16 +292,6 @@ public class CharacterDataFactory
{
transientResourceManager.PersistTransientResources(charaPointer, objectKind, CreateFileReplacement);
/*foreach (var item in transientResourceManager.GetTransientResources(charaPointer))
{
if (!previousData.FileReplacements[objectKind].Any(f => f.GamePaths.Any(p => p.ToLowerInvariant() == item.ToLowerInvariant())))
{
Logger.Verbose("Found transient resource: " + item);
AddReplacement(item, objectKind, previousData, 1, true);
}
}*/
foreach (var item in transientResourceManager.GetSemiTransientResources(objectKind))
{
if (!previousData.FileReplacements.ContainsKey(objectKind))

View File

@@ -40,7 +40,7 @@ public class CachedPlayer
}
}
private bool _isDisposed = false;
private bool _isDisposed = true;
private CancellationTokenSource? _downloadCancellationTokenSource = new();
private string _lastGlamourerData = string.Empty;
@@ -206,6 +206,7 @@ public class CachedPlayer
}
else
{
Logger.Verbose("Missing file: " + item.Hash);
missingFiles.Add(item);
}
}
@@ -397,6 +398,7 @@ public class CachedPlayer
public void InitializePlayer(PlayerCharacter character, CharacterCacheDto? cache)
{
if (!_isDisposed) return;
Logger.Debug("Initializing Player " + this + " has cache: " + (cache != null));
IsVisible = true;
PlayerName = character.Name.ToString();

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -8,7 +9,6 @@ using MareSynchronos.API;
using MareSynchronos.Utils;
using MareSynchronos.WebAPI;
using MareSynchronos.WebAPI.Utils;
using Newtonsoft.Json;
namespace MareSynchronos.Managers;
@@ -19,12 +19,12 @@ public class OnlinePlayerManager : IDisposable
private readonly Framework _framework;
private readonly IpcManager _ipcManager;
private readonly PlayerManager _playerManager;
private readonly List<CachedPlayer> _onlineCachedPlayers = new();
private readonly ConcurrentDictionary<string, CachedPlayer> _onlineCachedPlayers = new();
private readonly Dictionary<string, CharacterCacheDto> _temporaryStoredCharacterCache = new();
private readonly Dictionary<CachedPlayer, CancellationTokenSource> _playerTokenDisposal = new();
private List<string> OnlineVisiblePlayerHashes => _onlineCachedPlayers.Where(p => p.PlayerCharacter != null)
.Select(p => p.PlayerNameHash).ToList();
private List<string> OnlineVisiblePlayerHashes => _onlineCachedPlayers.Where(p => p.Value.PlayerCharacter != null)
.Select(p => p.Value.PlayerNameHash).ToList();
private DateTime _lastPlayerObjectCheck = DateTime.Now;
public OnlinePlayerManager(Framework framework, ApiController apiController, DalamudUtil dalamudUtil, IpcManager ipcManager, PlayerManager playerManager)
@@ -58,7 +58,7 @@ public class OnlinePlayerManager : IDisposable
private void ApiControllerOnCharacterReceived(object? sender, CharacterReceivedEventArgs e)
{
var visiblePlayer = _onlineCachedPlayers.SingleOrDefault(c => c.IsVisible && c.PlayerNameHash == e.CharacterNameHash);
var visiblePlayer = _onlineCachedPlayers.Select(v => v.Value).SingleOrDefault(c => c.IsVisible && c.PlayerNameHash == e.CharacterNameHash);
if (visiblePlayer != null)
{
Logger.Debug("Received data and applying to " + e.CharacterNameHash);
@@ -99,7 +99,15 @@ public class OnlinePlayerManager : IDisposable
private void IpcManagerOnPenumbraDisposed()
{
_onlineCachedPlayers.ForEach(p => p.DisposePlayer());
DisposeAllPlayers();
}
private void DisposeAllPlayers()
{
foreach (var entry in _onlineCachedPlayers)
{
entry.Value.DisposePlayer();
}
}
private void ApiControllerOnDisconnected()
@@ -111,7 +119,10 @@ public class OnlinePlayerManager : IDisposable
public void AddInitialPairs(List<string> apiTaskResult)
{
_onlineCachedPlayers.Clear();
_onlineCachedPlayers.AddRange(apiTaskResult.Select(CreateCachedPlayer));
foreach (var result in apiTaskResult)
{
_onlineCachedPlayers.TryAdd(result, CreateCachedPlayer(result));
}
Logger.Verbose("Online and paired users: " + string.Join(Environment.NewLine, _onlineCachedPlayers));
}
@@ -138,7 +149,7 @@ public class OnlinePlayerManager : IDisposable
private void RestoreAllCharacters()
{
_onlineCachedPlayers.ForEach(p => p.DisposePlayer());
DisposeAllPlayers();
_onlineCachedPlayers.Clear();
}
@@ -171,19 +182,23 @@ public class OnlinePlayerManager : IDisposable
private void AddPlayer(string characterNameHash)
{
if (_onlineCachedPlayers.Any(p => p.PlayerNameHash == characterNameHash))
if (_onlineCachedPlayers.ContainsKey(characterNameHash))
{
PushCharacterData(new List<string>() { characterNameHash });
_playerTokenDisposal.TryGetValue(_onlineCachedPlayers.Single(p => p.PlayerNameHash == characterNameHash), out var cancellationTokenSource);
_playerTokenDisposal.TryGetValue(_onlineCachedPlayers[characterNameHash], out var cancellationTokenSource);
cancellationTokenSource?.Cancel();
return;
}
_onlineCachedPlayers.Add(CreateCachedPlayer(characterNameHash));
_onlineCachedPlayers.TryAdd(characterNameHash, CreateCachedPlayer(characterNameHash));
}
private void RemovePlayer(string characterHash)
{
var cachedPlayer = _onlineCachedPlayers.First(p => p.PlayerNameHash == characterHash);
if (!_onlineCachedPlayers.TryGetValue(characterHash, out var cachedPlayer))
{
return;
}
if (_dalamudUtil.IsInGpose)
{
_playerTokenDisposal.TryGetValue(cachedPlayer, out var cancellationTokenSource);
@@ -202,14 +217,14 @@ public class OnlinePlayerManager : IDisposable
}
cachedPlayer.DisposePlayer();
_onlineCachedPlayers.RemoveAll(c => c.PlayerNameHash == cachedPlayer.PlayerNameHash);
_onlineCachedPlayers.TryRemove(cachedPlayer.PlayerNameHash, out _);
}, token);
return;
}
cachedPlayer.DisposePlayer();
_onlineCachedPlayers.RemoveAll(c => c.PlayerNameHash == cachedPlayer.PlayerNameHash);
_onlineCachedPlayers.TryRemove(characterHash, out _);
}
private void FrameworkOnUpdate(Framework framework)
@@ -222,8 +237,7 @@ public class OnlinePlayerManager : IDisposable
foreach (var pChar in playerCharacters)
{
var hashedName = Crypto.GetHash256(pChar);
var existingCachedPlayer = _onlineCachedPlayers.SingleOrDefault(p => p.PlayerNameHash == hashedName && !string.IsNullOrEmpty(p.PlayerName));
if (existingCachedPlayer != null)
if (_onlineCachedPlayers.TryGetValue(hashedName, out var existingCachedPlayer) && !string.IsNullOrEmpty(existingCachedPlayer.PlayerName))
{
existingCachedPlayer.IsVisible = true;
continue;
@@ -233,10 +247,14 @@ public class OnlinePlayerManager : IDisposable
{
_temporaryStoredCharacterCache.Remove(hashedName);
}
_onlineCachedPlayers.SingleOrDefault(p => p.PlayerNameHash == hashedName)?.InitializePlayer(pChar, cache);
if (_onlineCachedPlayers.TryGetValue(hashedName, out var playerToInit))
{
playerToInit.InitializePlayer(pChar, cache);
}
}
var newlyVisiblePlayers = _onlineCachedPlayers
var newlyVisiblePlayers = _onlineCachedPlayers.Values
.Where(p => p.PlayerCharacter != null && p.IsVisible && !p.WasVisible).Select(p => p.PlayerNameHash)
.ToList();
if (newlyVisiblePlayers.Any())