diff --git a/MareSynchronos/Managers/CachedPlayer.cs b/MareSynchronos/Managers/CachedPlayer.cs index 4ed5d27..e061429 100644 --- a/MareSynchronos/Managers/CachedPlayer.cs +++ b/MareSynchronos/Managers/CachedPlayer.cs @@ -130,6 +130,16 @@ public class CachedPlayer } } + if (_dalamudUtil.IsInGpose) + { + Logger.Verbose("Player is in GPose, waiting"); + while (_dalamudUtil.IsInGpose) + { + await Task.Delay(TimeSpan.FromSeconds(0.5)); + downloadToken.ThrowIfCancellationRequested(); + } + } + ApplyCharacterData(_cache[_lastAppliedEquipmentHash], moddedPaths); }, downloadToken).ContinueWith(task => { @@ -221,10 +231,10 @@ public class CachedPlayer public void InitializePlayer(PlayerCharacter character, CharacterCacheDto? cache) { + Logger.Debug("Initializing Player " + this); IsVisible = true; PlayerName = character.Name.ToString(); PlayerCharacter = character; - Logger.Debug("Initializing Player " + this); _dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate; _ipcManager.PenumbraRedrawEvent += IpcManagerOnPenumbraRedrawEvent; _originalGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter); diff --git a/MareSynchronos/Managers/OnlinePlayerManager.cs b/MareSynchronos/Managers/OnlinePlayerManager.cs index 0e578ad..f2ecb60 100644 --- a/MareSynchronos/Managers/OnlinePlayerManager.cs +++ b/MareSynchronos/Managers/OnlinePlayerManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Dalamud.Game; using MareSynchronos.API; @@ -20,6 +21,7 @@ public class OnlinePlayerManager : IDisposable private readonly PlayerManager _playerManager; private readonly List _onlineCachedPlayers = new(); private readonly Dictionary _temporaryStoredCharacterCache = new(); + private readonly Dictionary _playerTokenDisposal = new(); private List OnlineVisiblePlayerHashes => _onlineCachedPlayers.Where(p => p.PlayerCharacter != null) .Select(p => p.PlayerNameHash).ToList(); @@ -169,13 +171,43 @@ public class OnlinePlayerManager : IDisposable private void AddPlayer(string characterNameHash) { - if (_onlineCachedPlayers.Any(p => p.PlayerNameHash == characterNameHash)) return; + if (_onlineCachedPlayers.Any(p => p.PlayerNameHash == characterNameHash)) + { + PushCharacterData(new List() { characterNameHash }); + _playerTokenDisposal.TryGetValue(_onlineCachedPlayers.Single(p => p.PlayerNameHash == characterNameHash), out var cancellationTokenSource); + cancellationTokenSource?.Cancel(); + return; + } _onlineCachedPlayers.Add(CreateCachedPlayer(characterNameHash)); } private void RemovePlayer(string characterHash) { var cachedPlayer = _onlineCachedPlayers.First(p => p.PlayerNameHash == characterHash); + if (_dalamudUtil.IsInGpose) + { + _playerTokenDisposal.TryGetValue(cachedPlayer, out var cancellationTokenSource); + cancellationTokenSource?.Cancel(); + cachedPlayer.IsVisible = false; + _playerTokenDisposal[cachedPlayer] = new CancellationTokenSource(); + cancellationTokenSource = _playerTokenDisposal[cachedPlayer]; + var token = cancellationTokenSource.Token; + Task.Run(async () => + { + Logger.Verbose("Cannot dispose Player, in GPose"); + while (_dalamudUtil.IsInGpose) + { + await Task.Delay(TimeSpan.FromSeconds(0.5)); + if (token.IsCancellationRequested) return; + } + + cachedPlayer.DisposePlayer(); + _onlineCachedPlayers.RemoveAll(c => c.PlayerNameHash == cachedPlayer.PlayerNameHash); + }, token); + + return; + } + cachedPlayer.DisposePlayer(); _onlineCachedPlayers.RemoveAll(c => c.PlayerNameHash == cachedPlayer.PlayerNameHash); } @@ -207,7 +239,11 @@ public class OnlinePlayerManager : IDisposable var newlyVisiblePlayers = _onlineCachedPlayers .Where(p => p.PlayerCharacter != null && p.IsVisible && !p.WasVisible).Select(p => p.PlayerNameHash) .ToList(); - PushCharacterData(newlyVisiblePlayers); + if (newlyVisiblePlayers.Any()) + { + Logger.Verbose("Has new visible players, pushing character data"); + PushCharacterData(newlyVisiblePlayers); + } _lastPlayerObjectCheck = DateTime.Now; } diff --git a/MareSynchronos/Managers/PlayerManager.cs b/MareSynchronos/Managers/PlayerManager.cs index 33fc240..f0f0da9 100644 --- a/MareSynchronos/Managers/PlayerManager.cs +++ b/MareSynchronos/Managers/PlayerManager.cs @@ -125,6 +125,8 @@ namespace MareSynchronos.Managers private void PlayerChanged() { + if (_dalamudUtil.IsInGpose) return; + Logger.Debug("Player changed: " + _dalamudUtil.PlayerName); _playerChangedCts?.Cancel(); _playerChangedCts = new CancellationTokenSource(); diff --git a/MareSynchronos/MareSynchronos.csproj b/MareSynchronos/MareSynchronos.csproj index 8baafe6..eef00b9 100644 --- a/MareSynchronos/MareSynchronos.csproj +++ b/MareSynchronos/MareSynchronos.csproj @@ -3,7 +3,7 @@ - 0.1.16.0 + 0.1.17.0 https://github.com/Penumbra-Sync/client diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index b1cc4e5..f110654 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -68,6 +68,8 @@ namespace MareSynchronos.Utils public string PlayerNameHashed => Crypto.GetHash256(PlayerName + _clientState.LocalPlayer!.HomeWorld.Id); + public bool IsInGpose => _objectTable[201] != null; + public List GetPlayerCharacters() { return _objectTable.Where(obj =>