Client rework for API change and paradigm shift (#39)
* most of the groups refactoring on client * register OnMethods for group stuff * start implementing client (still pretty broken) * finish implementing new api first iteration * idk rework everything for pair shit (still WIP); goal is to remove PairedClients and GroupPairClients from ApiController * move everything to PairManager, remove dictionaries from APiController * remove admin stuff from client, cleanup * adjust reconnection handling, add new settings, todo still to remove access from old stuff that's marked obsolete from config * add back adding servers, fix intro ui * fix obsolete calls * adjust config namespace * add UI for setting animation/sound permissions to syncshells * add ConfigurationService to hot reload config on change from external * move transient data cache to configuration * add deleting service to ui * fix saving of transient resources * fix group pair user assignments * halt scanner when penumbra inactive, add visible/online/offline split to individual pairs and tags * add presence to syncshell ui * move fullpause from config to server config * fixes in code style * more codestyle * show info icon on player in shells, don't show icon when no changes from default state are made, add online notifs * fixes to intro UI --------- Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
@@ -1,15 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MareSynchronos.API;
|
||||
using MareSynchronos.API.Data;
|
||||
using MareSynchronos.API.Dto.User;
|
||||
using MareSynchronos.FileCache;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.Utils;
|
||||
using MareSynchronos.WebAPI;
|
||||
using MareSynchronos.WebAPI.Utils;
|
||||
|
||||
namespace MareSynchronos.Managers;
|
||||
|
||||
@@ -17,39 +10,24 @@ public class OnlinePlayerManager : IDisposable
|
||||
{
|
||||
private readonly ApiController _apiController;
|
||||
private readonly DalamudUtil _dalamudUtil;
|
||||
private readonly IpcManager _ipcManager;
|
||||
private readonly PlayerManager _playerManager;
|
||||
private readonly FileCacheManager _fileDbManager;
|
||||
private readonly Configuration _configuration;
|
||||
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 readonly ConcurrentDictionary<string, OptionalPluginWarning> _shownWarnings = new(StringComparer.Ordinal);
|
||||
private readonly PairManager _pairManager;
|
||||
|
||||
private List<string> OnlineVisiblePlayerHashes => _onlineCachedPlayers.Select(p => p.Value).Where(p => p.PlayerCharacter != IntPtr.Zero)
|
||||
.Select(p => p.PlayerNameHash).ToList();
|
||||
|
||||
public OnlinePlayerManager(ApiController apiController, DalamudUtil dalamudUtil, IpcManager ipcManager, PlayerManager playerManager, FileCacheManager fileDbManager, Configuration configuration)
|
||||
public OnlinePlayerManager(ApiController apiController, DalamudUtil dalamudUtil, PlayerManager playerManager, FileCacheManager fileDbManager, PairManager pairManager)
|
||||
{
|
||||
Logger.Verbose("Creating " + nameof(OnlinePlayerManager));
|
||||
|
||||
_apiController = apiController;
|
||||
_dalamudUtil = dalamudUtil;
|
||||
_ipcManager = ipcManager;
|
||||
_playerManager = playerManager;
|
||||
_fileDbManager = fileDbManager;
|
||||
_configuration = configuration;
|
||||
_apiController.PairedClientOnline += ApiControllerOnPairedClientOnline;
|
||||
_apiController.PairedClientOffline += ApiControllerOnPairedClientOffline;
|
||||
_apiController.Connected += ApiControllerOnConnected;
|
||||
_apiController.Disconnected += ApiControllerOnDisconnected;
|
||||
_apiController.CharacterReceived += ApiControllerOnCharacterReceived;
|
||||
_pairManager = pairManager;
|
||||
|
||||
_ipcManager.PenumbraDisposed += IpcManagerOnPenumbraDisposed;
|
||||
_playerManager.PlayerHasChanged += PlayerManagerOnPlayerHasChanged;
|
||||
|
||||
_dalamudUtil.LogIn += DalamudUtilOnLogIn;
|
||||
_dalamudUtil.LogOut += DalamudUtilOnLogOut;
|
||||
_dalamudUtil.ZoneSwitchStart += DalamudUtilOnZoneSwitched;
|
||||
|
||||
if (_dalamudUtil.IsLoggedIn)
|
||||
{
|
||||
@@ -57,49 +35,9 @@ public class OnlinePlayerManager : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private void DalamudUtilOnZoneSwitched()
|
||||
private void PlayerManagerOnPlayerHasChanged(CharacterData characterCache)
|
||||
{
|
||||
DisposePlayers();
|
||||
}
|
||||
|
||||
private void ApiControllerOnCharacterReceived(object? sender, CharacterReceivedEventArgs e)
|
||||
{
|
||||
if (!_shownWarnings.ContainsKey(e.CharacterNameHash)) _shownWarnings[e.CharacterNameHash] = new()
|
||||
{
|
||||
ShownCustomizePlusWarning = _configuration.DisableOptionalPluginWarnings,
|
||||
ShownHeelsWarning = _configuration.DisableOptionalPluginWarnings,
|
||||
};
|
||||
if (_onlineCachedPlayers.TryGetValue(e.CharacterNameHash, out var visiblePlayer) && visiblePlayer.IsVisible)
|
||||
{
|
||||
Logger.Debug("Received data and applying to " + e.CharacterNameHash);
|
||||
visiblePlayer.ApplyCharacterData(e.CharacterData, _shownWarnings[e.CharacterNameHash]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug("Received data but no fitting character visible for " + e.CharacterNameHash);
|
||||
_temporaryStoredCharacterCache[e.CharacterNameHash] = e.CharacterData;
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayerManagerOnPlayerHasChanged(CharacterCacheDto characterCache)
|
||||
{
|
||||
PushCharacterData(OnlineVisiblePlayerHashes);
|
||||
}
|
||||
|
||||
private void ApiControllerOnConnected()
|
||||
{
|
||||
var apiTask = _apiController.UserGetOnlineCharacters();
|
||||
|
||||
Task.WaitAll(apiTask);
|
||||
|
||||
AddInitialPairs(apiTask.Result);
|
||||
|
||||
_playerManager.PlayerHasChanged += PlayerManagerOnPlayerHasChanged;
|
||||
}
|
||||
|
||||
private void DalamudUtilOnLogOut()
|
||||
{
|
||||
_dalamudUtil.DelayedFrameworkUpdate -= FrameworkOnUpdate;
|
||||
PushCharacterData(_pairManager.VisibleUsers);
|
||||
}
|
||||
|
||||
private void DalamudUtilOnLogIn()
|
||||
@@ -107,146 +45,53 @@ public class OnlinePlayerManager : IDisposable
|
||||
_dalamudUtil.DelayedFrameworkUpdate += FrameworkOnUpdate;
|
||||
}
|
||||
|
||||
private void IpcManagerOnPenumbraDisposed()
|
||||
private void DalamudUtilOnLogOut()
|
||||
{
|
||||
DisposePlayers();
|
||||
}
|
||||
|
||||
private void DisposePlayers()
|
||||
{
|
||||
foreach (var kvp in _onlineCachedPlayers)
|
||||
{
|
||||
kvp.Value.DisposePlayer();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApiControllerOnDisconnected()
|
||||
{
|
||||
RestoreAllCharacters();
|
||||
_playerManager.PlayerHasChanged -= PlayerManagerOnPlayerHasChanged;
|
||||
}
|
||||
|
||||
public void AddInitialPairs(List<string> apiTaskResult)
|
||||
{
|
||||
_onlineCachedPlayers.Clear();
|
||||
foreach (var hash in apiTaskResult)
|
||||
{
|
||||
_onlineCachedPlayers.TryAdd(hash, CreateCachedPlayer(hash));
|
||||
}
|
||||
Logger.Verbose("Online and paired users: " + string.Join(Environment.NewLine, _onlineCachedPlayers.Select(k => k.Key)));
|
||||
_dalamudUtil.DelayedFrameworkUpdate -= FrameworkOnUpdate;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Logger.Verbose("Disposing " + nameof(OnlinePlayerManager));
|
||||
|
||||
RestoreAllCharacters();
|
||||
|
||||
_apiController.PairedClientOnline -= ApiControllerOnPairedClientOnline;
|
||||
_apiController.PairedClientOffline -= ApiControllerOnPairedClientOffline;
|
||||
_apiController.Disconnected -= ApiControllerOnDisconnected;
|
||||
_apiController.Connected -= ApiControllerOnConnected;
|
||||
|
||||
_ipcManager.PenumbraDisposed -= ApiControllerOnDisconnected;
|
||||
|
||||
_playerManager.PlayerHasChanged -= PlayerManagerOnPlayerHasChanged;
|
||||
_dalamudUtil.LogIn -= DalamudUtilOnLogIn;
|
||||
_dalamudUtil.LogOut -= DalamudUtilOnLogOut;
|
||||
_dalamudUtil.ZoneSwitchStart -= DalamudUtilOnZoneSwitched;
|
||||
_dalamudUtil.DelayedFrameworkUpdate -= FrameworkOnUpdate;
|
||||
}
|
||||
|
||||
private void RestoreAllCharacters()
|
||||
{
|
||||
DisposePlayers();
|
||||
_onlineCachedPlayers.Clear();
|
||||
}
|
||||
|
||||
private void ApiControllerOnPairedClientOffline(string charHash)
|
||||
{
|
||||
Logger.Debug("Player offline: " + charHash);
|
||||
RemovePlayer(charHash);
|
||||
}
|
||||
|
||||
private void ApiControllerOnPairedClientOnline(string charHash)
|
||||
{
|
||||
Logger.Debug("Player online: " + charHash);
|
||||
AddPlayer(charHash);
|
||||
return;
|
||||
}
|
||||
|
||||
private void AddPlayer(string characterNameHash)
|
||||
{
|
||||
if (_onlineCachedPlayers.TryGetValue(characterNameHash, out var cachedPlayer))
|
||||
{
|
||||
PushCharacterData(new List<string>() { characterNameHash });
|
||||
_playerTokenDisposal.TryGetValue(cachedPlayer, out var cancellationTokenSource);
|
||||
cancellationTokenSource?.Cancel();
|
||||
return;
|
||||
}
|
||||
_onlineCachedPlayers.TryAdd(characterNameHash, CreateCachedPlayer(characterNameHash));
|
||||
}
|
||||
|
||||
private void RemovePlayer(string characterHash)
|
||||
{
|
||||
if (!_onlineCachedPlayers.TryGetValue(characterHash, out var cachedPlayer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cachedPlayer.DisposePlayer();
|
||||
_onlineCachedPlayers.TryRemove(characterHash, out _);
|
||||
}
|
||||
|
||||
private void FrameworkOnUpdate()
|
||||
{
|
||||
if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized || !_apiController.IsConnected) return;
|
||||
if (!_dalamudUtil.IsPlayerPresent || !_apiController.IsConnected) return;
|
||||
|
||||
var playerCharacters = _dalamudUtil.GetPlayerCharacters();
|
||||
var onlinePairs = _pairManager.OnlineUserPairs;
|
||||
foreach (var pChar in playerCharacters)
|
||||
{
|
||||
var hashedName = Crypto.GetHash256(pChar);
|
||||
if (_onlineCachedPlayers.TryGetValue(hashedName, out var existingPlayer) && !string.IsNullOrEmpty(existingPlayer.PlayerName))
|
||||
{
|
||||
existingPlayer.IsVisible = true;
|
||||
continue;
|
||||
}
|
||||
var pair = _pairManager.FindPair(pChar);
|
||||
if (pair == null) continue;
|
||||
|
||||
if (existingPlayer != null)
|
||||
{
|
||||
_temporaryStoredCharacterCache.TryRemove(hashedName, out var cache);
|
||||
if (!_shownWarnings.ContainsKey(hashedName)) _shownWarnings[hashedName] = new()
|
||||
{
|
||||
ShownCustomizePlusWarning = _configuration.DisableOptionalPluginWarnings,
|
||||
ShownHeelsWarning = _configuration.DisableOptionalPluginWarnings,
|
||||
};
|
||||
existingPlayer.InitializePlayer(pChar.Address, pChar.Name.ToString(), cache, _shownWarnings[hashedName]);
|
||||
}
|
||||
pair.InitializePair(pChar.Address, pChar.Name.ToString());
|
||||
}
|
||||
|
||||
var newlyVisiblePlayers = _onlineCachedPlayers.Select(v => v.Value)
|
||||
.Where(p => p.PlayerCharacter != IntPtr.Zero && p.IsVisible && !p.WasVisible).Select(p => p.PlayerNameHash)
|
||||
var newlyVisiblePlayers = onlinePairs.Select(v => v.CachedPlayer)
|
||||
.Where(p => p != null && p.PlayerCharacter != IntPtr.Zero && p.IsVisible && !p.WasVisible).Select(p => (UserDto)p!.OnlineUser)
|
||||
.ToList();
|
||||
if (newlyVisiblePlayers.Any())
|
||||
{
|
||||
Logger.Verbose("Has new visible players, pushing character data");
|
||||
PushCharacterData(newlyVisiblePlayers);
|
||||
PushCharacterData(newlyVisiblePlayers.Select(c => c.User).ToList());
|
||||
}
|
||||
}
|
||||
|
||||
private void PushCharacterData(List<string> visiblePlayers)
|
||||
private void PushCharacterData(List<UserData> visiblePlayers)
|
||||
{
|
||||
if (visiblePlayers.Any() && _playerManager.LastCreatedCharacterData != null)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await _apiController.PushCharacterData(_playerManager.LastCreatedCharacterData,
|
||||
visiblePlayers).ConfigureAwait(false);
|
||||
await _apiController.PushCharacterData(_playerManager.LastCreatedCharacterData, visiblePlayers).ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private CachedPlayer CreateCachedPlayer(string hashedName)
|
||||
{
|
||||
return new CachedPlayer(hashedName, _ipcManager, _apiController, _dalamudUtil, _fileDbManager);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user