fully switch to mediator from events

This commit is contained in:
rootdarkarchon
2023-01-31 01:35:11 +01:00
parent 5e7beb8518
commit 41465c2d49
24 changed files with 166 additions and 239 deletions

View File

@@ -1,3 +0,0 @@
namespace MareSynchronos.Delegates;
public delegate void CharacterDataDelegate(API.Data.CharacterData characterCache);

View File

@@ -1,3 +0,0 @@
namespace MareSynchronos.Delegates;
public delegate void DrawObjectDelegate(IntPtr address, int objTblIdx);

View File

@@ -1,3 +0,0 @@
namespace MareSynchronos.Delegates;
public delegate void FloatDelegate(float change);

View File

@@ -1,3 +0,0 @@
namespace MareSynchronos.Delegates;
public delegate void PenumbraFileResourceDelegate(IntPtr drawObject, string gamePath, string filePath);

View File

@@ -1,3 +0,0 @@
namespace MareSynchronos.Delegates;
public delegate void StringDelegate(string str);

View File

@@ -1,3 +0,0 @@
namespace MareSynchronos.Delegates;
public delegate void VoidDelegate();

View File

@@ -1,6 +1,7 @@
using MareSynchronos.API.Dto.User; using MareSynchronos.API.Dto.User;
using MareSynchronos.FileCache; using MareSynchronos.FileCache;
using MareSynchronos.Managers; using MareSynchronos.Managers;
using MareSynchronos.Mediator;
using MareSynchronos.Utils; using MareSynchronos.Utils;
using MareSynchronos.WebAPI; using MareSynchronos.WebAPI;
@@ -11,16 +12,18 @@ public class CachedPlayerFactory
private readonly IpcManager _ipcManager; private readonly IpcManager _ipcManager;
private readonly DalamudUtil _dalamudUtil; private readonly DalamudUtil _dalamudUtil;
private readonly FileCacheManager _fileCacheManager; private readonly FileCacheManager _fileCacheManager;
private readonly MareMediator _mediator;
public CachedPlayerFactory(IpcManager ipcManager, DalamudUtil dalamudUtil, FileCacheManager fileCacheManager) public CachedPlayerFactory(IpcManager ipcManager, DalamudUtil dalamudUtil, FileCacheManager fileCacheManager, MareMediator mediator)
{ {
_ipcManager = ipcManager; _ipcManager = ipcManager;
_dalamudUtil = dalamudUtil; _dalamudUtil = dalamudUtil;
_fileCacheManager = fileCacheManager; _fileCacheManager = fileCacheManager;
_mediator = mediator;
} }
public CachedPlayer Create(OnlineUserIdentDto dto, ApiController apiController) public CachedPlayer Create(OnlineUserIdentDto dto, ApiController apiController)
{ {
return new CachedPlayer(dto, _ipcManager, apiController, _dalamudUtil, _fileCacheManager); return new CachedPlayer(dto, _ipcManager, apiController, _dalamudUtil, _fileCacheManager, _mediator);
} }
} }

View File

@@ -3,7 +3,6 @@ using MareSynchronos.Managers;
using MareSynchronos.MareConfiguration; using MareSynchronos.MareConfiguration;
using MareSynchronos.Mediator; using MareSynchronos.Mediator;
using MareSynchronos.Utils; using MareSynchronos.Utils;
using MareSynchronos.WebAPI;
namespace MareSynchronos.FileCache; namespace MareSynchronos.FileCache;
@@ -12,51 +11,26 @@ public class PeriodicFileScanner : IDisposable
private readonly IpcManager _ipcManager; private readonly IpcManager _ipcManager;
private readonly ConfigurationService _configService; private readonly ConfigurationService _configService;
private readonly FileCacheManager _fileDbManager; private readonly FileCacheManager _fileDbManager;
private readonly ApiController _apiController;
private readonly DalamudUtil _dalamudUtil;
private readonly MareMediator _mediator; private readonly MareMediator _mediator;
private CancellationTokenSource? _scanCancellationTokenSource; private CancellationTokenSource? _scanCancellationTokenSource;
private Task? _fileScannerTask = null; private Task? _fileScannerTask = null;
public ConcurrentDictionary<string, int> haltScanLocks = new(StringComparer.Ordinal); public ConcurrentDictionary<string, int> haltScanLocks = new(StringComparer.Ordinal);
public PeriodicFileScanner(IpcManager ipcManager, ConfigurationService configService, FileCacheManager fileDbManager, ApiController apiController, DalamudUtil dalamudUtil, MareMediator mediator)
public PeriodicFileScanner(IpcManager ipcManager, ConfigurationService configService, FileCacheManager fileDbManager, MareMediator mediator)
{ {
Logger.Verbose("Creating " + nameof(PeriodicFileScanner)); Logger.Verbose("Creating " + nameof(PeriodicFileScanner));
_ipcManager = ipcManager; _ipcManager = ipcManager;
_configService = configService; _configService = configService;
_fileDbManager = fileDbManager; _fileDbManager = fileDbManager;
_apiController = apiController;
_dalamudUtil = dalamudUtil;
_mediator = mediator; _mediator = mediator;
_ipcManager.PenumbraInitialized += StartScan;
_apiController.DownloadStarted += ApiHaltScan;
_apiController.DownloadFinished += ApiResumeScan;
_mediator.Subscribe<ZoneSwitchStartMessage>(this, (_) => ZoneSwitchHaltScan()); _mediator.Subscribe<PenumbraInitializedMessage>(this, (_) => StartScan());
_mediator.Subscribe<ZoneSwitchEndMessage>(this, (_) => ZoneSwitchResumeScan()); _mediator.Subscribe<HaltScanMessage>(this, (msg) => HaltScan(((HaltScanMessage)msg).Source));
_mediator.Subscribe<ResumeScanMessage>(this, (msg) => ResumeScan(((ResumeScanMessage)msg).Source));
_mediator.Subscribe<SwitchToMainUiMessage>(this, (_) => StartScan()); _mediator.Subscribe<SwitchToMainUiMessage>(this, (_) => StartScan());
} }
private void ApiHaltScan()
{
HaltScan("Download");
}
private void ApiResumeScan()
{
ResumeScan("Download");
}
private void ZoneSwitchHaltScan()
{
HaltScan("Zoning/Gpose");
}
private void ZoneSwitchResumeScan()
{
ResumeScan("Zoning/Gpose");
}
public void ResetLocks() public void ResetLocks()
{ {
haltScanLocks.Clear(); haltScanLocks.Clear();
@@ -106,9 +80,6 @@ public class PeriodicFileScanner : IDisposable
{ {
Logger.Verbose("Disposing " + nameof(PeriodicFileScanner)); Logger.Verbose("Disposing " + nameof(PeriodicFileScanner));
_ipcManager.PenumbraInitialized -= StartScan;
_apiController.DownloadStarted -= ApiHaltScan;
_apiController.DownloadFinished -= ApiResumeScan;
_scanCancellationTokenSource?.Cancel(); _scanCancellationTokenSource?.Cancel();
} }

View File

@@ -4,6 +4,7 @@ using MareSynchronos.API.Data;
using MareSynchronos.API.Data.Enum; using MareSynchronos.API.Data.Enum;
using MareSynchronos.API.Dto.User; using MareSynchronos.API.Dto.User;
using MareSynchronos.FileCache; using MareSynchronos.FileCache;
using MareSynchronos.Mediator;
using MareSynchronos.Models; using MareSynchronos.Models;
using MareSynchronos.Utils; using MareSynchronos.Utils;
using MareSynchronos.WebAPI; using MareSynchronos.WebAPI;
@@ -16,6 +17,7 @@ public class CachedPlayer : IDisposable
private readonly DalamudUtil _dalamudUtil; private readonly DalamudUtil _dalamudUtil;
private readonly IpcManager _ipcManager; private readonly IpcManager _ipcManager;
private readonly FileCacheManager _fileDbManager; private readonly FileCacheManager _fileDbManager;
private readonly MareMediator _mediator;
private API.Data.CharacterData _cachedData = new(); private API.Data.CharacterData _cachedData = new();
private PlayerRelatedObject? _currentCharacterEquipment; private PlayerRelatedObject? _currentCharacterEquipment;
private CancellationTokenSource? _downloadCancellationTokenSource = new(); private CancellationTokenSource? _downloadCancellationTokenSource = new();
@@ -27,13 +29,14 @@ public class CachedPlayer : IDisposable
private Task? _penumbraRedrawEventTask; private Task? _penumbraRedrawEventTask;
public CachedPlayer(OnlineUserIdentDto onlineUser, IpcManager ipcManager, ApiController apiController, DalamudUtil dalamudUtil, FileCacheManager fileDbManager) public CachedPlayer(OnlineUserIdentDto onlineUser, IpcManager ipcManager, ApiController apiController, DalamudUtil dalamudUtil, FileCacheManager fileDbManager, MareMediator mediator)
{ {
OnlineUser = onlineUser; OnlineUser = onlineUser;
_ipcManager = ipcManager; _ipcManager = ipcManager;
_apiController = apiController; _apiController = apiController;
_dalamudUtil = dalamudUtil; _dalamudUtil = dalamudUtil;
_fileDbManager = fileDbManager; _fileDbManager = fileDbManager;
_mediator = mediator;
} }
public bool IsVisible public bool IsVisible
@@ -197,7 +200,6 @@ public class CachedPlayer : IDisposable
try try
{ {
Logger.Verbose("Restoring state for " + PlayerName); Logger.Verbose("Restoring state for " + PlayerName);
_ipcManager.PenumbraRedrawEvent -= IpcManagerOnPenumbraRedrawEvent;
_ipcManager.PenumbraRemoveTemporaryCollection(PlayerName); _ipcManager.PenumbraRemoveTemporaryCollection(PlayerName);
_downloadCancellationTokenSource?.Cancel(); _downloadCancellationTokenSource?.Cancel();
_downloadCancellationTokenSource?.Dispose(); _downloadCancellationTokenSource?.Dispose();
@@ -216,6 +218,7 @@ public class CachedPlayer : IDisposable
} }
finally finally
{ {
_mediator.UnsubscribeAll(this);
_cachedData = new(); _cachedData = new();
var tempPlayerName = PlayerName; var tempPlayerName = PlayerName;
PlayerName = string.Empty; PlayerName = string.Empty;
@@ -232,7 +235,7 @@ public class CachedPlayer : IDisposable
PlayerCharacter = character; PlayerCharacter = character;
Logger.Debug("Initializing Player " + this); Logger.Debug("Initializing Player " + this);
_ipcManager.PenumbraRedrawEvent += IpcManagerOnPenumbraRedrawEvent; _mediator.Subscribe<PenumbraRedrawMessage>(this, (msg) => IpcManagerOnPenumbraRedrawEvent(((PenumbraRedrawMessage)msg)));
_originalGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter); _originalGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter);
_currentCharacterEquipment = new PlayerRelatedObject(ObjectKind.Player, IntPtr.Zero, IntPtr.Zero, _currentCharacterEquipment = new PlayerRelatedObject(ObjectKind.Player, IntPtr.Zero, IntPtr.Zero,
() => _dalamudUtil.GetPlayerCharacterFromObjectTableByName(PlayerName)?.Address ?? IntPtr.Zero); () => _dalamudUtil.GetPlayerCharacterFromObjectTableByName(PlayerName)?.Address ?? IntPtr.Zero);
@@ -414,15 +417,15 @@ public class CachedPlayer : IDisposable
}); });
} }
private void IpcManagerOnPenumbraRedrawEvent(IntPtr address, int idx) private void IpcManagerOnPenumbraRedrawEvent(PenumbraRedrawMessage msg)
{ {
var player = _dalamudUtil.GetCharacterFromObjectTableByIndex(idx); var player = _dalamudUtil.GetCharacterFromObjectTableByIndex(msg.ObjTblIdx);
if (player == null || !string.Equals(player.Name.ToString(), PlayerName, StringComparison.OrdinalIgnoreCase)) return; if (player == null || !string.Equals(player.Name.ToString(), PlayerName, StringComparison.OrdinalIgnoreCase)) return;
if (!_penumbraRedrawEventTask?.IsCompleted ?? false) return; if (!_penumbraRedrawEventTask?.IsCompleted ?? false) return;
_penumbraRedrawEventTask = Task.Run(() => _penumbraRedrawEventTask = Task.Run(() =>
{ {
PlayerCharacter = address; PlayerCharacter = msg.Address;
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(5)); cts.CancelAfter(TimeSpan.FromSeconds(5));
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerName!, PlayerCharacter, 10000, cts.Token); _dalamudUtil.WaitWhileCharacterIsDrawing(PlayerName!, PlayerCharacter, 10000, cts.Token);

View File

@@ -7,7 +7,6 @@ using System.Collections.Concurrent;
using System.Text; using System.Text;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Api.Helpers; using Penumbra.Api.Helpers;
using MareSynchronos.Delegates;
using MareSynchronos.Mediator; using MareSynchronos.Mediator;
namespace MareSynchronos.Managers; namespace MareSynchronos.Managers;
@@ -68,6 +67,8 @@ public class IpcManager : IDisposable
{ {
Logger.Verbose("Creating " + nameof(IpcManager)); Logger.Verbose("Creating " + nameof(IpcManager));
_mediator = mediator;
_penumbraInit = Penumbra.Api.Ipc.Initialized.Subscriber(pi, () => PenumbraInit()); _penumbraInit = Penumbra.Api.Ipc.Initialized.Subscriber(pi, () => PenumbraInit());
_penumbraDispose = Penumbra.Api.Ipc.Disposed.Subscriber(pi, () => PenumbraDispose()); _penumbraDispose = Penumbra.Api.Ipc.Disposed.Subscriber(pi, () => PenumbraDispose());
_penumbraResolvePlayer = Penumbra.Api.Ipc.ResolvePlayerPath.Subscriber(pi); _penumbraResolvePlayer = Penumbra.Api.Ipc.ResolvePlayerPath.Subscriber(pi);
@@ -120,11 +121,10 @@ public class IpcManager : IDisposable
if (Initialized) if (Initialized)
{ {
PenumbraInitialized?.Invoke(); _mediator.Publish(new PenumbraInitializedMessage());
} }
_dalamudUtil = dalamudUtil; _dalamudUtil = dalamudUtil;
_mediator = mediator;
_mediator.Subscribe<FrameworkUpdateMessage>(this, (_) => HandleActionQueue()); _mediator.Subscribe<FrameworkUpdateMessage>(this, (_) => HandleActionQueue());
_mediator.Subscribe<GposeFrameworkUpdateMessage>(this, (_) => HandleGposeActionQueue()); _mediator.Subscribe<GposeFrameworkUpdateMessage>(this, (_) => HandleGposeActionQueue());
_mediator.Subscribe<ZoneSwitchEndMessage>(this, (_) => ClearActionQueue()); _mediator.Subscribe<ZoneSwitchEndMessage>(this, (_) => ClearActionQueue());
@@ -147,7 +147,7 @@ public class IpcManager : IDisposable
private void PenumbraModSettingChangedHandler() private void PenumbraModSettingChangedHandler()
{ {
PenumbraModSettingChanged?.Invoke(); _mediator.Publish(new PenumbraModSettingChangedMessage());
} }
private void ClearActionQueue() private void ClearActionQueue()
@@ -162,7 +162,7 @@ public class IpcManager : IDisposable
{ {
if (ptr != IntPtr.Zero && string.Compare(arg1, arg2, ignoreCase: true, System.Globalization.CultureInfo.InvariantCulture) != 0) if (ptr != IntPtr.Zero && string.Compare(arg1, arg2, ignoreCase: true, System.Globalization.CultureInfo.InvariantCulture) != 0)
{ {
PenumbraResourceLoadEvent?.Invoke(ptr, arg1, arg2); _mediator.Publish(new PenumbraResourceLoadMessage(ptr, arg1, arg2));
} }
}); });
} }
@@ -177,15 +177,6 @@ public class IpcManager : IDisposable
} }
} }
public event VoidDelegate? PenumbraModSettingChanged;
public event VoidDelegate? PenumbraInitialized;
public event VoidDelegate? PenumbraDisposed;
public event DrawObjectDelegate? PenumbraRedrawEvent;
public event FloatDelegate? HeelsOffsetChangeEvent;
public event PenumbraFileResourceDelegate? PenumbraResourceLoadEvent;
public event StringDelegate? CustomizePlusScaleChange;
public event StringDelegate? PalettePlusPaletteChange;
public bool Initialized => CheckPenumbraApi(); public bool Initialized => CheckPenumbraApi();
public bool CheckGlamourerApi() public bool CheckGlamourerApi()
{ {
@@ -509,31 +500,31 @@ public class IpcManager : IDisposable
private void RedrawEvent(IntPtr objectAddress, int objectTableIndex) private void RedrawEvent(IntPtr objectAddress, int objectTableIndex)
{ {
PenumbraRedrawEvent?.Invoke(objectAddress, objectTableIndex); _mediator.Publish(new PenumbraRedrawMessage(objectAddress, objectTableIndex));
} }
private void PenumbraInit() private void PenumbraInit()
{ {
PenumbraInitialized?.Invoke(); _mediator.Publish(new PenumbraInitializedMessage());
_penumbraRedraw!.Invoke("self", RedrawType.Redraw); _penumbraRedraw!.Invoke("self", RedrawType.Redraw);
} }
private void HeelsOffsetChange(float offset) private void HeelsOffsetChange(float offset)
{ {
HeelsOffsetChangeEvent?.Invoke(offset); _mediator.Publish(new HeelsOffsetMessage(offset));
} }
private void OnCustomizePlusScaleChange(string? scale) private void OnCustomizePlusScaleChange(string? scale)
{ {
if (scale != null) scale = Convert.ToBase64String(Encoding.UTF8.GetBytes(scale)); if (scale != null) scale = Convert.ToBase64String(Encoding.UTF8.GetBytes(scale));
CustomizePlusScaleChange?.Invoke(scale); _mediator.Publish(new CustomizePlusMessage(scale));
} }
private void OnPalettePlusPaletteChange(Character character, string palette) private void OnPalettePlusPaletteChange(Character character, string palette)
{ {
if (character.Address == 0 || character.Address != _dalamudUtil.PlayerPointer) return; if (character.Address == 0 || character.Address != _dalamudUtil.PlayerPointer) return;
if (palette != null) palette = Convert.ToBase64String(Encoding.UTF8.GetBytes(palette)); if (palette != null) palette = Convert.ToBase64String(Encoding.UTF8.GetBytes(palette));
PalettePlusPaletteChange?.Invoke(palette); _mediator.Publish(new PalettePlusMessage(palette));
} }
public void PalettePlusSetPalette(IntPtr character, string palette) public void PalettePlusSetPalette(IntPtr character, string palette)
@@ -584,7 +575,7 @@ public class IpcManager : IDisposable
private void PenumbraDispose() private void PenumbraDispose()
{ {
PenumbraDisposed?.Invoke(); _mediator.Publish(new PenumbraDisposedMessage());
ActionQueue.Clear(); ActionQueue.Clear();
} }
} }

View File

@@ -7,16 +7,15 @@ using MareSynchronos.WebAPI;
namespace MareSynchronos.Managers; namespace MareSynchronos.Managers;
public class OnlinePlayerManager : IDisposable public class OnlinePlayerManager : MediatorSubscriberBase, IDisposable
{ {
private readonly ApiController _apiController; private readonly ApiController _apiController;
private readonly DalamudUtil _dalamudUtil; private readonly DalamudUtil _dalamudUtil;
private readonly PlayerManager _playerManager; private readonly PlayerManager _playerManager;
private readonly FileCacheManager _fileDbManager; private readonly FileCacheManager _fileDbManager;
private readonly PairManager _pairManager; private readonly PairManager _pairManager;
private readonly MareMediator _mediator;
public OnlinePlayerManager(ApiController apiController, DalamudUtil dalamudUtil, PlayerManager playerManager, FileCacheManager fileDbManager, PairManager pairManager, MareMediator mediator) public OnlinePlayerManager(ApiController apiController, DalamudUtil dalamudUtil, PlayerManager playerManager, FileCacheManager fileDbManager, PairManager pairManager, MareMediator mediator) : base(mediator)
{ {
Logger.Verbose("Creating " + nameof(OnlinePlayerManager)); Logger.Verbose("Creating " + nameof(OnlinePlayerManager));
@@ -25,41 +24,32 @@ public class OnlinePlayerManager : IDisposable
_playerManager = playerManager; _playerManager = playerManager;
_fileDbManager = fileDbManager; _fileDbManager = fileDbManager;
_pairManager = pairManager; _pairManager = pairManager;
_mediator = mediator;
_playerManager.PlayerHasChanged += PlayerManagerOnPlayerHasChanged;
_mediator.Subscribe<DalamudLoginMessage>(this, (_) => DalamudUtilOnLogIn()); Mediator.Subscribe<PlayerChangedMessage>(this, (msg) => PlayerManagerOnPlayerHasChanged((PlayerChangedMessage)msg));
_mediator.Subscribe<DalamudLogoutMessage>(this, (_) => DalamudUtilOnLogOut()); Mediator.Subscribe<DalamudLoginMessage>(this, (_) => DalamudUtilOnLogIn());
Mediator.Subscribe<DalamudLogoutMessage>(this, (_) => DalamudUtilOnLogOut());
if (_dalamudUtil.IsLoggedIn) Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) => FrameworkOnUpdate());
{
DalamudUtilOnLogIn();
}
} }
private void PlayerManagerOnPlayerHasChanged(CharacterData characterCache) private void PlayerManagerOnPlayerHasChanged(PlayerChangedMessage msg)
{ {
PushCharacterData(_pairManager.VisibleUsers); PushCharacterData(_pairManager.VisibleUsers);
} }
private void DalamudUtilOnLogIn() private void DalamudUtilOnLogIn()
{ {
_mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) => FrameworkOnUpdate()); Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) => FrameworkOnUpdate());
} }
private void DalamudUtilOnLogOut() private void DalamudUtilOnLogOut()
{ {
_mediator.Unsubscribe<DelayedFrameworkUpdateMessage>(this); Mediator.Unsubscribe<DelayedFrameworkUpdateMessage>(this);
} }
public void Dispose() public override void Dispose()
{ {
Logger.Verbose("Disposing " + nameof(OnlinePlayerManager)); Logger.Verbose("Disposing " + nameof(OnlinePlayerManager));
base.Dispose();
_playerManager.PlayerHasChanged -= PlayerManagerOnPlayerHasChanged;
_mediator.Unsubscribe<DalamudLoginMessage>(this);
_mediator.Unsubscribe<DalamudLogoutMessage>(this);
_mediator.Unsubscribe<DelayedFrameworkUpdateMessage>(this);
} }
private void FrameworkOnUpdate() private void FrameworkOnUpdate()

View File

@@ -3,10 +3,8 @@ using MareSynchronos.Utils;
using MareSynchronos.WebAPI; using MareSynchronos.WebAPI;
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using MareSynchronos.Models; using MareSynchronos.Models;
using MareSynchronos.FileCache;
using MareSynchronos.UI; using MareSynchronos.UI;
using MareSynchronos.API.Data.Enum; using MareSynchronos.API.Data.Enum;
using MareSynchronos.Delegates;
using MareSynchronos.Mediator; using MareSynchronos.Mediator;
#if DEBUG #if DEBUG
#endif #endif
@@ -14,17 +12,12 @@ using MareSynchronos.Mediator;
namespace MareSynchronos.Managers; namespace MareSynchronos.Managers;
public class PlayerManager : IDisposable public class PlayerManager : MediatorSubscriberBase, IDisposable
{ {
private readonly ApiController _apiController; private readonly ApiController _apiController;
private readonly CharacterDataFactory _characterDataFactory; private readonly CharacterDataFactory _characterDataFactory;
private readonly DalamudUtil _dalamudUtil; private readonly DalamudUtil _dalamudUtil;
private readonly TransientResourceManager _transientResourceManager;
private readonly PeriodicFileScanner _periodicFileScanner;
private readonly SettingsUi _settingsUi;
private readonly MareMediator _mediator;
private readonly IpcManager _ipcManager; private readonly IpcManager _ipcManager;
public event CharacterDataDelegate? PlayerHasChanged;
public API.Data.CharacterData? LastCreatedCharacterData { get; private set; } public API.Data.CharacterData? LastCreatedCharacterData { get; private set; }
public Models.CharacterData PermanentDataCache { get; private set; } = new(); public Models.CharacterData PermanentDataCache { get; private set; } = new();
private readonly Dictionary<ObjectKind, Func<bool>> _objectKindsToUpdate = new(); private readonly Dictionary<ObjectKind, Func<bool>> _objectKindsToUpdate = new();
@@ -35,8 +28,8 @@ public class PlayerManager : IDisposable
private readonly List<PlayerRelatedObject> _playerRelatedObjects = new(); private readonly List<PlayerRelatedObject> _playerRelatedObjects = new();
public unsafe PlayerManager(ApiController apiController, IpcManager ipcManager, public unsafe PlayerManager(ApiController apiController, IpcManager ipcManager,
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil, TransientResourceManager transientResourceManager, CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil,
PeriodicFileScanner periodicFileScanner, SettingsUi settingsUi, MareMediator mediator) MareMediator mediator) : base(mediator)
{ {
Logger.Verbose("Creating " + nameof(PlayerManager)); Logger.Verbose("Creating " + nameof(PlayerManager));
@@ -44,19 +37,15 @@ public class PlayerManager : IDisposable
_ipcManager = ipcManager; _ipcManager = ipcManager;
_characterDataFactory = characterDataFactory; _characterDataFactory = characterDataFactory;
_dalamudUtil = dalamudUtil; _dalamudUtil = dalamudUtil;
_transientResourceManager = transientResourceManager;
_periodicFileScanner = periodicFileScanner; Mediator.Subscribe<CustomizePlusMessage>(this, (msg) => CustomizePlusChanged((CustomizePlusMessage)msg));
_settingsUi = settingsUi; Mediator.Subscribe<HeelsOffsetMessage>(this, (msg) => HeelsOffsetChanged((HeelsOffsetMessage)msg));
_mediator = mediator; Mediator.Subscribe<HeelsOffsetMessage>(this, (msg) => PalettePlusChanged((PalettePlusMessage)msg));
_apiController.Connected += ApiControllerOnConnected; Mediator.Subscribe<ConnectedMessage>(this, (_) => ApiControllerOnConnected());
_apiController.Disconnected += ApiController_Disconnected; Mediator.Subscribe<DisconnectedMessage>(this, (_) => ApiController_Disconnected());
_transientResourceManager.TransientResourceLoaded += HandleTransientResourceLoad; Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) => DalamudUtilOnDelayedFrameworkUpdate());
_ipcManager.HeelsOffsetChangeEvent += HeelsOffsetChanged; Mediator.Subscribe<FrameworkUpdateMessage>(this, (_) => DalamudUtilOnFrameworkUpdate());
_ipcManager.CustomizePlusScaleChange += CustomizePlusChanged; Mediator.Subscribe<TransientResourceChangedMessage>(this, (msg) => HandleTransientResourceLoad((TransientResourceChangedMessage)msg));
_ipcManager.PalettePlusPaletteChange += PalettePlusChanged;
_mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) => DalamudUtilOnDelayedFrameworkUpdate());
_mediator.Subscribe<FrameworkUpdateMessage>(this, (_) => DalamudUtilOnFrameworkUpdate());
Logger.Debug("Watching Player, ApiController is Connected: " + _apiController.IsConnected); Logger.Debug("Watching Player, ApiController is Connected: " + _apiController.IsConnected);
if (_apiController.IsConnected) if (_apiController.IsConnected)
@@ -75,14 +64,14 @@ public class PlayerManager : IDisposable
private void DalamudUtilOnFrameworkUpdate() private void DalamudUtilOnFrameworkUpdate()
{ {
_transientResourceManager.PlayerRelatedPointers = _playerRelatedObjects.Select(f => f.CurrentAddress).ToArray(); Mediator.Publish(new PlayerRelatedObjectPointerUpdateMessage(_playerRelatedObjects.Select(f => f.CurrentAddress).ToArray()));
} }
public void HandleTransientResourceLoad(IntPtr gameObj, int idx) public void HandleTransientResourceLoad(TransientResourceChangedMessage msg)
{ {
foreach (var obj in _playerRelatedObjects) foreach (var obj in _playerRelatedObjects)
{ {
if (obj.Address == gameObj && !obj.HasUnprocessedUpdate) if (obj.Address == msg.Address && !obj.HasUnprocessedUpdate)
{ {
_transientUpdateCts.Cancel(); _transientUpdateCts.Cancel();
_transientUpdateCts = new CancellationTokenSource(); _transientUpdateCts = new CancellationTokenSource();
@@ -101,19 +90,19 @@ public class PlayerManager : IDisposable
} }
} }
private void HeelsOffsetChanged(float change) private void HeelsOffsetChanged(HeelsOffsetMessage change)
{ {
var player = _playerRelatedObjects.First(f => f.ObjectKind == ObjectKind.Player); var player = _playerRelatedObjects.First(f => f.ObjectKind == ObjectKind.Player);
if (LastCreatedCharacterData != null && LastCreatedCharacterData.HeelsOffset != change && !player.IsProcessing) if (LastCreatedCharacterData != null && LastCreatedCharacterData.HeelsOffset != change.Offset && !player.IsProcessing)
{ {
Logger.Debug("Heels offset changed to " + change); Logger.Debug("Heels offset changed to " + change.Offset);
player.HasTransientsUpdate = true; player.HasTransientsUpdate = true;
} }
} }
private void CustomizePlusChanged(string? change) private void CustomizePlusChanged(CustomizePlusMessage msg)
{ {
change ??= string.Empty; var change = msg.Data ?? string.Empty;
var player = _playerRelatedObjects.First(f => f.ObjectKind == ObjectKind.Player); var player = _playerRelatedObjects.First(f => f.ObjectKind == ObjectKind.Player);
if (LastCreatedCharacterData != null && !string.Equals(LastCreatedCharacterData.CustomizePlusData, change, StringComparison.Ordinal) && !player.IsProcessing) if (LastCreatedCharacterData != null && !string.Equals(LastCreatedCharacterData.CustomizePlusData, change, StringComparison.Ordinal) && !player.IsProcessing)
{ {
@@ -122,9 +111,9 @@ public class PlayerManager : IDisposable
} }
} }
private void PalettePlusChanged(string? change) private void PalettePlusChanged(PalettePlusMessage msg)
{ {
change ??= string.Empty; var change = msg.Data ?? string.Empty;
var player = _playerRelatedObjects.First(f => f.ObjectKind == ObjectKind.Player); var player = _playerRelatedObjects.First(f => f.ObjectKind == ObjectKind.Player);
if (LastCreatedCharacterData != null && !string.Equals(LastCreatedCharacterData.PalettePlusData, change, StringComparison.Ordinal) && !player.IsProcessing) if (LastCreatedCharacterData != null && !string.Equals(LastCreatedCharacterData.PalettePlusData, change, StringComparison.Ordinal) && !player.IsProcessing)
{ {
@@ -133,24 +122,13 @@ public class PlayerManager : IDisposable
} }
} }
public void Dispose() public override void Dispose()
{ {
Logger.Verbose("Disposing " + nameof(PlayerManager)); Logger.Verbose("Disposing " + nameof(PlayerManager));
_mediator.Unsubscribe<DelayedFrameworkUpdateMessage>(this); base.Dispose();
_mediator.Unsubscribe<FrameworkUpdateMessage>(this);
_apiController.Connected -= ApiControllerOnConnected;
_apiController.Disconnected -= ApiController_Disconnected;
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent;
_transientResourceManager.TransientResourceLoaded -= HandleTransientResourceLoad;
_playerChangedCts?.Cancel(); _playerChangedCts?.Cancel();
_ipcManager.HeelsOffsetChangeEvent -= HeelsOffsetChanged;
_ipcManager.CustomizePlusScaleChange -= CustomizePlusChanged;
_ipcManager.PalettePlusPaletteChange -= PalettePlusChanged;
} }
private unsafe void DalamudUtilOnDelayedFrameworkUpdate() private unsafe void DalamudUtilOnDelayedFrameworkUpdate()
@@ -168,14 +146,14 @@ public class PlayerManager : IDisposable
{ {
Logger.Debug("ApiController Connected"); Logger.Debug("ApiController Connected");
_ipcManager.PenumbraRedrawEvent += IpcManager_PenumbraRedrawEvent; Mediator.Subscribe<PenumbraRedrawMessage>(this, (msg) => IpcManager_PenumbraRedrawEvent((PenumbraRedrawMessage)msg));
} }
private void ApiController_Disconnected() private void ApiController_Disconnected()
{ {
Logger.Debug(nameof(ApiController_Disconnected)); Logger.Debug(nameof(ApiController_Disconnected));
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent; Mediator.Unsubscribe<PenumbraRedrawMessage>(this);
} }
private async Task<API.Data.CharacterData?> CreateFullCharacterCacheDto(CancellationToken token) private async Task<API.Data.CharacterData?> CreateFullCharacterCacheDto(CancellationToken token)
@@ -210,13 +188,13 @@ public class PlayerManager : IDisposable
return cache; return cache;
} }
private void IpcManager_PenumbraRedrawEvent(IntPtr address, int idx) private void IpcManager_PenumbraRedrawEvent(PenumbraRedrawMessage msg)
{ {
Logger.Verbose("RedrawEvent for addr " + address); Logger.Verbose("RedrawEvent for addr " + msg.Address);
foreach (var item in _playerRelatedObjects) foreach (var item in _playerRelatedObjects)
{ {
if (address == item.Address) if (msg.Address == item.Address)
{ {
Logger.Debug("Penumbra redraw Event for " + item.ObjectKind); Logger.Debug("Penumbra redraw Event for " + item.ObjectKind);
item.HasUnprocessedUpdate = true; item.HasUnprocessedUpdate = true;
@@ -264,43 +242,41 @@ public class PlayerManager : IDisposable
Task.Run(async () => Task.Run(async () =>
{ {
API.Data.CharacterData? cacheDto = null; API.Data.CharacterData? cacheData = null;
try try
{ {
_periodicFileScanner.HaltScan("Character creation"); Mediator.Publish(new HaltScanMessage("Character creation"));
foreach (var item in unprocessedObjects) foreach (var item in unprocessedObjects)
{ {
_dalamudUtil.WaitWhileCharacterIsDrawing("self " + item.ObjectKind.ToString(), item.Address, item.ObjectKind == ObjectKind.MinionOrMount ? 1000 : 10000, token); _dalamudUtil.WaitWhileCharacterIsDrawing("self " + item.ObjectKind.ToString(), item.Address, item.ObjectKind == ObjectKind.MinionOrMount ? 1000 : 10000, token);
} }
cacheDto = (await CreateFullCharacterCacheDto(token).ConfigureAwait(false)); cacheData = (await CreateFullCharacterCacheDto(token).ConfigureAwait(false));
} }
catch { } catch { }
finally finally
{ {
_periodicFileScanner.ResumeScan("Character creation"); Mediator.Publish(new ResumeScanMessage("Character creation"));
} }
if (cacheDto == null || token.IsCancellationRequested) return; if (cacheData == null || token.IsCancellationRequested) return;
_settingsUi.LastCreatedCharacterData = cacheDto;
#if DEBUG #if DEBUG
//var json = JsonConvert.SerializeObject(cacheDto, Formatting.Indented); //var json = JsonConvert.SerializeObject(cacheDto, Formatting.Indented);
//Logger.Verbose(json); //Logger.Verbose(json);
#endif #endif
if (string.Equals(LastCreatedCharacterData?.DataHash.Value ?? string.Empty, cacheDto.DataHash.Value, StringComparison.Ordinal)) if (string.Equals(LastCreatedCharacterData?.DataHash.Value ?? string.Empty, cacheData.DataHash.Value, StringComparison.Ordinal))
{ {
Logger.Debug("Not sending data, already sent"); Logger.Debug("Not sending data, already sent");
return; return;
} }
LastCreatedCharacterData = cacheDto; LastCreatedCharacterData = cacheData;
if (_apiController.IsConnected && !token.IsCancellationRequested && !doNotSendUpdate) if (_apiController.IsConnected && !token.IsCancellationRequested && !doNotSendUpdate)
{ {
Logger.Verbose("Invoking PlayerHasChanged"); Logger.Verbose("Invoking PlayerHasChanged");
PlayerHasChanged?.Invoke(cacheDto); Mediator.Publish(new PlayerChangedMessage(cacheData));
} }
}, token); }, token);
} }

View File

@@ -1,5 +1,4 @@
using MareSynchronos.API.Data.Enum; using MareSynchronos.API.Data.Enum;
using MareSynchronos.Delegates;
using MareSynchronos.Factories; using MareSynchronos.Factories;
using MareSynchronos.MareConfiguration; using MareSynchronos.MareConfiguration;
using MareSynchronos.Mediator; using MareSynchronos.Mediator;
@@ -10,14 +9,11 @@ using System.Collections.Concurrent;
namespace MareSynchronos.Managers; namespace MareSynchronos.Managers;
public class TransientResourceManager : IDisposable public class TransientResourceManager : MediatorSubscriberBase, IDisposable
{ {
private readonly IpcManager _ipcManager;
private readonly ConfigurationService _configurationService; private readonly ConfigurationService _configurationService;
private readonly DalamudUtil _dalamudUtil; private readonly DalamudUtil _dalamudUtil;
private readonly MareMediator _mediator;
public event DrawObjectDelegate? TransientResourceLoaded;
public IntPtr[] PlayerRelatedPointers = Array.Empty<IntPtr>(); public IntPtr[] PlayerRelatedPointers = Array.Empty<IntPtr>();
private readonly string[] _fileTypesToHandle = new[] { "tmb", "pap", "avfx", "atex", "sklb", "eid", "phyb", "scd", "skp", "shpk" }; private readonly string[] _fileTypesToHandle = new[] { "tmb", "pap", "avfx", "atex", "sklb", "eid", "phyb", "scd", "skp", "shpk" };
[Obsolete] [Obsolete]
@@ -26,16 +22,16 @@ public class TransientResourceManager : IDisposable
private ConcurrentDictionary<IntPtr, HashSet<string>> TransientResources { get; } = new(); private ConcurrentDictionary<IntPtr, HashSet<string>> TransientResources { get; } = new();
private ConcurrentDictionary<ObjectKind, HashSet<FileReplacement>> SemiTransientResources { get; } = new(); private ConcurrentDictionary<ObjectKind, HashSet<FileReplacement>> SemiTransientResources { get; } = new();
public TransientResourceManager(IpcManager manager, ConfigurationService configurationService, DalamudUtil dalamudUtil, FileReplacementFactory fileReplacementFactory, MareMediator mediator) public TransientResourceManager(ConfigurationService configurationService, DalamudUtil dalamudUtil, FileReplacementFactory fileReplacementFactory, MareMediator mediator) : base(mediator)
{ {
manager.PenumbraResourceLoadEvent += Manager_PenumbraResourceLoadEvent;
manager.PenumbraModSettingChanged += Manager_PenumbraModSettingChanged;
_ipcManager = manager;
_configurationService = configurationService; _configurationService = configurationService;
_dalamudUtil = dalamudUtil; _dalamudUtil = dalamudUtil;
_mediator = mediator;
_mediator.Subscribe<FrameworkUpdateMessage>(this, (_) => DalamudUtil_FrameworkUpdate()); mediator.Subscribe<PenumbraResourceLoadMessage>(this, (msg) => Manager_PenumbraResourceLoadEvent((PenumbraResourceLoadMessage)msg));
_mediator.Subscribe<ClassJobChangedMessage>(this, (_) => DalamudUtil_ClassJobChanged()); Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, (_) => Manager_PenumbraModSettingChanged());
Mediator.Subscribe<FrameworkUpdateMessage>(this, (_) => DalamudUtil_FrameworkUpdate());
Mediator.Subscribe<ClassJobChangedMessage>(this, (_) => DalamudUtil_ClassJobChanged());
Mediator.Subscribe<PlayerRelatedObjectPointerUpdateMessage>(this, (msg) => PlayerRelatedPointers = ((PlayerRelatedObjectPointerUpdateMessage)msg).RelatedObjects);
// migrate obsolete data to new format // migrate obsolete data to new format
if (File.Exists(PersistentDataCache)) if (File.Exists(PersistentDataCache))
{ {
@@ -87,7 +83,7 @@ public class TransientResourceManager : IDisposable
return !verified; return !verified;
}); });
if (!successfulValidation) if (!successfulValidation)
TransientResourceLoaded?.Invoke(_dalamudUtil.PlayerPointer, -1); Mediator.Publish(new TransientResourceChangedMessage(_dalamudUtil.PlayerPointer));
} }
}); });
} }
@@ -140,8 +136,11 @@ public class TransientResourceManager : IDisposable
return new List<FileReplacement>(); return new List<FileReplacement>();
} }
private void Manager_PenumbraResourceLoadEvent(IntPtr gameObject, string gamePath, string filePath) private void Manager_PenumbraResourceLoadEvent(PenumbraResourceLoadMessage msg)
{ {
var gamePath = msg.GamePath;
var gameObject = msg.GameObject;
var filePath = msg.FilePath;
if (!_fileTypesToHandle.Any(type => gamePath.EndsWith(type, StringComparison.OrdinalIgnoreCase))) if (!_fileTypesToHandle.Any(type => gamePath.EndsWith(type, StringComparison.OrdinalIgnoreCase)))
{ {
return; return;
@@ -180,7 +179,7 @@ public class TransientResourceManager : IDisposable
{ {
TransientResources[gameObject].Add(replacedGamePath); TransientResources[gameObject].Add(replacedGamePath);
Logger.Debug($"Adding {replacedGamePath} for {gameObject} ({filePath})"); Logger.Debug($"Adding {replacedGamePath} for {gameObject} ({filePath})");
TransientResourceLoaded?.Invoke(gameObject, -1); Mediator.Publish(new TransientResourceChangedMessage(gameObject));
} }
} }
@@ -250,12 +249,9 @@ public class TransientResourceManager : IDisposable
TransientResources[gameObject].Clear(); TransientResources[gameObject].Clear();
} }
public void Dispose() public override void Dispose()
{ {
_mediator.Unsubscribe<FrameworkUpdateMessage>(this); base.Dispose();
_mediator.Unsubscribe<ClassJobChangedMessage>(this);
_ipcManager.PenumbraResourceLoadEvent -= Manager_PenumbraResourceLoadEvent;
_ipcManager.PenumbraModSettingChanged -= Manager_PenumbraModSettingChanged;
TransientResources.Clear(); TransientResources.Clear();
SemiTransientResources.Clear(); SemiTransientResources.Clear();
if (SemiTransientResources.ContainsKey(ObjectKind.Player)) if (SemiTransientResources.ContainsKey(ObjectKind.Player))

View File

@@ -44,6 +44,14 @@ public class MareMediator : IDisposable
} }
} }
internal void UnsubscribeAll(object subscriber)
{
foreach (var kvp in _subscriberDict)
{
kvp.Value.RemoveWhere(p => p.Subscriber == subscriber);
}
}
public void Dispose() public void Dispose()
{ {
_subscriberDict.Clear(); _subscriberDict.Clear();

View File

@@ -20,4 +20,23 @@ public record ZoneSwitchEndMessage : IMessage;
public record GposeStartMessage : IMessage; public record GposeStartMessage : IMessage;
public record GposeEndMessage : IMessage; public record GposeEndMessage : IMessage;
public record GposeFrameworkUpdateMessage : IMessage; public record GposeFrameworkUpdateMessage : IMessage;
public record ConnectedMessage : IMessage;
public record DisconnectedMessage : IMessage;
public record DownloadStartedMessage : IMessage;
public record DownloadFinishedMessage : IMessage;
public record PenumbraModSettingChangedMessage : IMessage;
public record PenumbraInitializedMessage : IMessage;
public record PenumbraDisposedMessage : IMessage;
public record PenumbraRedrawMessage(IntPtr Address, int ObjTblIdx) : IMessage;
public record HeelsOffsetMessage(float Offset) : IMessage;
public record PenumbraResourceLoadMessage(IntPtr GameObject, string GamePath, string FilePath) : IMessage;
public record CustomizePlusMessage(string? Data) : IMessage;
public record PalettePlusMessage(string? Data) : IMessage;
public record PlayerChangedMessage(API.Data.CharacterData Data) : IMessage;
public record TransientResourceChangedMessage(IntPtr Address) : IMessage;
public record PlayerRelatedObjectPointerUpdateMessage(IntPtr[] RelatedObjects) : IMessage;
public record HaltScanMessage(string Source) : IMessage;
public record ResumeScanMessage(string Source) : IMessage;
#pragma warning restore MA0048 // File name must match type name #pragma warning restore MA0048 // File name must match type name

View File

@@ -24,10 +24,9 @@ namespace MareSynchronos;
public sealed class Plugin : IDalamudPlugin public sealed class Plugin : IDalamudPlugin
{ {
private const string _commandName = "/mare"; private const string _commandName = "/mare";
private IServiceScope? _runtimeServiceServiceScope; private IServiceScope? _runtimeServiceScope;
private readonly ServiceProvider _serviceProvider; private readonly ServiceProvider _serviceProvider;
public Plugin(DalamudPluginInterface pluginInterface, CommandManager commandManager, DataManager gameData, public Plugin(DalamudPluginInterface pluginInterface, CommandManager commandManager, DataManager gameData,
Framework framework, ObjectTable objectTable, ClientState clientState, Condition condition, ChatGui chatGui) Framework framework, ObjectTable objectTable, ClientState clientState, Condition condition, ChatGui chatGui)
{ {
@@ -78,13 +77,11 @@ public sealed class Plugin : IDalamudPlugin
_serviceProvider = collection.BuildServiceProvider(new ServiceProviderOptions() { ValidateOnBuild = true, ValidateScopes = true }); _serviceProvider = collection.BuildServiceProvider(new ServiceProviderOptions() { ValidateOnBuild = true, ValidateScopes = true });
// those can be initialized outside of game login
_serviceProvider.GetRequiredService<Dalamud.Localization>().SetupWithLangCode("en"); _serviceProvider.GetRequiredService<Dalamud.Localization>().SetupWithLangCode("en");
_serviceProvider.GetRequiredService<DalamudPluginInterface>().UiBuilder.DisableGposeUiHide = true; _serviceProvider.GetRequiredService<DalamudPluginInterface>().UiBuilder.DisableGposeUiHide = true;
var mediator = _serviceProvider.GetRequiredService<MareMediator>(); var mediator = _serviceProvider.GetRequiredService<MareMediator>();
mediator.Subscribe<SwitchToMainUiMessage>(this, (_) => ReLaunchCharacterManager()); mediator.Subscribe<SwitchToMainUiMessage>(this, (_) => Task.Run(WaitForPlayerAndLaunchCharacterManager));
mediator.Subscribe<DalamudLoginMessage>(this, (_) => DalamudUtilOnLogIn()); mediator.Subscribe<DalamudLoginMessage>(this, (_) => DalamudUtilOnLogIn());
mediator.Subscribe<DalamudLogoutMessage>(this, (_) => DalamudUtilOnLogOut()); mediator.Subscribe<DalamudLogoutMessage>(this, (_) => DalamudUtilOnLogOut());
@@ -103,13 +100,12 @@ public sealed class Plugin : IDalamudPlugin
_serviceProvider.GetRequiredService<CommandManager>().RemoveHandler(_commandName); _serviceProvider.GetRequiredService<CommandManager>().RemoveHandler(_commandName);
_runtimeServiceServiceScope?.Dispose(); _runtimeServiceScope?.Dispose();
_serviceProvider.Dispose(); _serviceProvider.Dispose();
Logger.Debug("Shut down"); Logger.Debug("Shut down");
} }
private void DalamudUtilOnLogIn() private void DalamudUtilOnLogIn()
{ {
Logger.Debug("Client login"); Logger.Debug("Client login");
@@ -136,7 +132,7 @@ public sealed class Plugin : IDalamudPlugin
private void DalamudUtilOnLogOut() private void DalamudUtilOnLogOut()
{ {
Logger.Debug("Client logout"); Logger.Debug("Client logout");
_runtimeServiceServiceScope?.Dispose(); _runtimeServiceScope?.Dispose();
var pi = _serviceProvider.GetRequiredService<DalamudPluginInterface>(); var pi = _serviceProvider.GetRequiredService<DalamudPluginInterface>();
pi.UiBuilder.Draw -= Draw; pi.UiBuilder.Draw -= Draw;
pi.UiBuilder.OpenConfigUi -= OpenUi; pi.UiBuilder.OpenConfigUi -= OpenUi;
@@ -145,9 +141,7 @@ public sealed class Plugin : IDalamudPlugin
public void ReLaunchCharacterManager() public void ReLaunchCharacterManager()
{ {
_runtimeServiceServiceScope?.Dispose();
Task.Run(WaitForPlayerAndLaunchCharacterManager);
} }
private async Task WaitForPlayerAndLaunchCharacterManager() private async Task WaitForPlayerAndLaunchCharacterManager()
@@ -162,10 +156,11 @@ public sealed class Plugin : IDalamudPlugin
{ {
Logger.Debug("Launching Managers"); Logger.Debug("Launching Managers");
_runtimeServiceServiceScope = _serviceProvider.CreateScope(); _runtimeServiceScope?.Dispose();
_runtimeServiceServiceScope.ServiceProvider.GetRequiredService<TransientResourceManager>(); _runtimeServiceScope = _serviceProvider.CreateScope();
_runtimeServiceServiceScope.ServiceProvider.GetRequiredService<PlayerManager>(); _runtimeServiceScope.ServiceProvider.GetRequiredService<TransientResourceManager>();
_runtimeServiceServiceScope.ServiceProvider.GetRequiredService<OnlinePlayerManager>(); _runtimeServiceScope.ServiceProvider.GetRequiredService<PlayerManager>();
_runtimeServiceScope.ServiceProvider.GetRequiredService<OnlinePlayerManager>();
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -10,7 +10,6 @@ using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;
using MareSynchronos.API.Data.Extensions; using MareSynchronos.API.Data.Extensions;
using MareSynchronos.API.Dto.User; using MareSynchronos.API.Dto.User;
using MareSynchronos.Delegates;
using MareSynchronos.Managers; using MareSynchronos.Managers;
using MareSynchronos.MareConfiguration; using MareSynchronos.MareConfiguration;
using MareSynchronos.Mediator; using MareSynchronos.Mediator;
@@ -100,9 +99,8 @@ public class CompactUi : Window, IDisposable
_mediator.Subscribe<SwitchToMainUiMessage>(this, (_) => IsOpen = true); _mediator.Subscribe<SwitchToMainUiMessage>(this, (_) => IsOpen = true);
_mediator.Subscribe<SwitchToIntroUiMessage>(this, (_) => IsOpen = false); _mediator.Subscribe<SwitchToIntroUiMessage>(this, (_) => IsOpen = false);
_mediator.Subscribe<GposeStartMessage>(this, (_) => UiShared_GposeStart());
_uiShared.GposeStart += UiShared_GposeStart; _mediator.Subscribe<GposeEndMessage>(this, (_) => UiShared_GposeEnd());
_uiShared.GposeEnd += UiShared_GposeEnd;
SizeConstraints = new WindowSizeConstraints() SizeConstraints = new WindowSizeConstraints()
{ {
@@ -127,8 +125,6 @@ public class CompactUi : Window, IDisposable
public void Dispose() public void Dispose()
{ {
Logger.Verbose("Disposing " + nameof(CompactUi)); Logger.Verbose("Disposing " + nameof(CompactUi));
_uiShared.GposeStart -= UiShared_GposeStart;
_uiShared.GposeEnd -= UiShared_GposeEnd;
_windowSystem.RemoveWindow(this); _windowSystem.RemoveWindow(this);
} }

View File

@@ -58,8 +58,9 @@ public class SettingsUi : Window, IDisposable
_mediator.Subscribe<OpenSettingsUiMessage>(this, (_) => Toggle()); _mediator.Subscribe<OpenSettingsUiMessage>(this, (_) => Toggle());
_mediator.Subscribe<SwitchToIntroUiMessage>(this, (_) => IsOpen = false); _mediator.Subscribe<SwitchToIntroUiMessage>(this, (_) => IsOpen = false);
_uiShared.GposeStart += UiShared_GposeStart; _mediator.Subscribe<GposeStartMessage>(this, (_) => UiShared_GposeStart());
_uiShared.GposeEnd += UiShared_GposeEnd; _mediator.Subscribe<GposeEndMessage>(this, (_) => UiShared_GposeEnd());
_mediator.Subscribe<PlayerChangedMessage>(this, (msg) => LastCreatedCharacterData = ((PlayerChangedMessage)msg).Data);
windowSystem.AddWindow(this); windowSystem.AddWindow(this);
} }
@@ -79,9 +80,6 @@ public class SettingsUi : Window, IDisposable
{ {
Logger.Verbose("Disposing " + nameof(SettingsUi)); Logger.Verbose("Disposing " + nameof(SettingsUi));
_uiShared.GposeStart -= UiShared_GposeStart;
_uiShared.GposeEnd -= UiShared_GposeEnd;
_windowSystem.RemoveWindow(this); _windowSystem.RemoveWindow(this);
} }

View File

@@ -9,7 +9,6 @@ using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;
using MareSynchronos.Delegates;
using MareSynchronos.FileCache; using MareSynchronos.FileCache;
using MareSynchronos.Localization; using MareSynchronos.Localization;
using MareSynchronos.Managers; using MareSynchronos.Managers;
@@ -35,7 +34,6 @@ public partial class UiShared : IDisposable
private readonly DalamudPluginInterface _pluginInterface; private readonly DalamudPluginInterface _pluginInterface;
private readonly Dalamud.Localization _localization; private readonly Dalamud.Localization _localization;
private readonly ServerConfigurationManager _serverConfigurationManager; private readonly ServerConfigurationManager _serverConfigurationManager;
private readonly MareMediator _mediator;
public long FileCacheSize => _cacheScanner.FileCacheSize; public long FileCacheSize => _cacheScanner.FileCacheSize;
public string PlayerName => _dalamudUtil.PlayerName; public string PlayerName => _dalamudUtil.PlayerName;
@@ -46,8 +44,6 @@ public partial class UiShared : IDisposable
public ImFontPtr UidFont { get; private set; } public ImFontPtr UidFont { get; private set; }
public bool UidFontBuilt { get; private set; } public bool UidFontBuilt { get; private set; }
public bool IsInGpose => _dalamudUtil.IsInGpose; public bool IsInGpose => _dalamudUtil.IsInGpose;
public event VoidDelegate? GposeStart;
public event VoidDelegate? GposeEnd;
public static bool CtrlPressed() => (GetKeyState(0xA2) & 0x8000) != 0 || (GetKeyState(0xA3) & 0x8000) != 0; public static bool CtrlPressed() => (GetKeyState(0xA2) & 0x8000) != 0 || (GetKeyState(0xA3) & 0x8000) != 0;
public static bool ShiftPressed() => (GetKeyState(0xA1) & 0x8000) != 0 || (GetKeyState(0xA0) & 0x8000) != 0; public static bool ShiftPressed() => (GetKeyState(0xA1) & 0x8000) != 0 || (GetKeyState(0xA0) & 0x8000) != 0;
@@ -59,7 +55,7 @@ public partial class UiShared : IDisposable
public UiShared(IpcManager ipcManager, ApiController apiController, PeriodicFileScanner cacheScanner, FileDialogManager fileDialogManager, public UiShared(IpcManager ipcManager, ApiController apiController, PeriodicFileScanner cacheScanner, FileDialogManager fileDialogManager,
ConfigurationService configService, DalamudUtil dalamudUtil, DalamudPluginInterface pluginInterface, Dalamud.Localization localization, ConfigurationService configService, DalamudUtil dalamudUtil, DalamudPluginInterface pluginInterface, Dalamud.Localization localization,
ServerConfigurationManager serverManager, MareMediator mediator) ServerConfigurationManager serverManager)
{ {
_ipcManager = ipcManager; _ipcManager = ipcManager;
_apiController = apiController; _apiController = apiController;
@@ -70,24 +66,10 @@ public partial class UiShared : IDisposable
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_localization = localization; _localization = localization;
_serverConfigurationManager = serverManager; _serverConfigurationManager = serverManager;
_mediator = mediator;
_isDirectoryWritable = IsDirectoryWritable(_configService.Current.CacheFolder); _isDirectoryWritable = IsDirectoryWritable(_configService.Current.CacheFolder);
_pluginInterface.UiBuilder.BuildFonts += BuildFont; _pluginInterface.UiBuilder.BuildFonts += BuildFont;
_pluginInterface.UiBuilder.RebuildFonts(); _pluginInterface.UiBuilder.RebuildFonts();
_mediator.Subscribe<GposeStartMessage>(this, (_) => DalamudUtil_GposeStart());
_mediator.Subscribe<GposeEndMessage>(this, (_) => DalamudUtil_GposeEnd());
}
private void DalamudUtil_GposeEnd()
{
GposeEnd?.Invoke();
}
private void DalamudUtil_GposeStart()
{
GposeStart?.Invoke();
} }
public static float GetWindowContentRegionWidth() public static float GetWindowContentRegionWidth()

View File

@@ -6,6 +6,7 @@ namespace MareSynchronos.Utils;
public static class Crypto public static class Crypto
{ {
#pragma warning disable SYSLIB0021 // Type or member is obsolete
public static string GetFileHash(this string filePath) public static string GetFileHash(this string filePath)
{ {
using SHA1CryptoServiceProvider cryptoProvider = new(); using SHA1CryptoServiceProvider cryptoProvider = new();
@@ -29,4 +30,5 @@ public static class Crypto
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); return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(character.Name + character.HomeWorld.Id.ToString()))).Replace("-", "", StringComparison.Ordinal);
} }
#pragma warning restore SYSLIB0021 // Type or member is obsolete
} }

View File

@@ -107,6 +107,7 @@ public class DalamudUtil : IDisposable
Logger.Debug("Zone switch/Gpose start"); Logger.Debug("Zone switch/Gpose start");
_sentBetweenAreas = true; _sentBetweenAreas = true;
_mediator.Publish(new ZoneSwitchStartMessage()); _mediator.Publish(new ZoneSwitchStartMessage());
_mediator.Publish(new HaltScanMessage("Zone switch"));
} }
if (IsInGpose) _mediator.Publish(new GposeFrameworkUpdateMessage()); if (IsInGpose) _mediator.Publish(new GposeFrameworkUpdateMessage());
@@ -119,6 +120,7 @@ public class DalamudUtil : IDisposable
Logger.Debug("Zone switch/Gpose end"); Logger.Debug("Zone switch/Gpose end");
_sentBetweenAreas = false; _sentBetweenAreas = false;
_mediator.Publish(new ZoneSwitchEndMessage()); _mediator.Publish(new ZoneSwitchEndMessage());
_mediator.Publish(new ResumeScanMessage("Zone switch"));
} }
_mediator.Publish(new FrameworkUpdateMessage()); _mediator.Publish(new FrameworkUpdateMessage());

View File

@@ -0,0 +1,18 @@
using MareSynchronos.Mediator;
namespace MareSynchronos.Utils;
public abstract class MediatorSubscriberBase : IDisposable
{
protected MediatorSubscriberBase(MareMediator mediator)
{
Mediator = mediator;
}
protected MareMediator Mediator;
public virtual void Dispose()
{
Mediator.UnsubscribeAll(this);
}
}

View File

@@ -9,6 +9,7 @@ using LZ4;
using MareSynchronos.API.Data; using MareSynchronos.API.Data;
using MareSynchronos.API.Dto.Files; using MareSynchronos.API.Dto.Files;
using MareSynchronos.API.Routes; using MareSynchronos.API.Routes;
using MareSynchronos.Mediator;
using MareSynchronos.Utils; using MareSynchronos.Utils;
using MareSynchronos.WebAPI.Utils; using MareSynchronos.WebAPI.Utils;
using Microsoft.AspNetCore.SignalR.Client; using Microsoft.AspNetCore.SignalR.Client;
@@ -185,7 +186,7 @@ public partial class ApiController
public async Task DownloadFiles(int currentDownloadId, List<FileReplacementData> fileReplacementDto, CancellationToken ct) public async Task DownloadFiles(int currentDownloadId, List<FileReplacementData> fileReplacementDto, CancellationToken ct)
{ {
DownloadStarted?.Invoke(); _mediator.Publish(new HaltScanMessage("Download"));
try try
{ {
await DownloadFilesInternal(currentDownloadId, fileReplacementDto, ct).ConfigureAwait(false); await DownloadFilesInternal(currentDownloadId, fileReplacementDto, ct).ConfigureAwait(false);
@@ -196,7 +197,7 @@ public partial class ApiController
} }
finally finally
{ {
DownloadFinished?.Invoke(); _mediator.Publish(new ResumeScanMessage("Download"));
} }
} }

View File

@@ -11,7 +11,6 @@ using MareSynchronos.API.SignalR;
using MareSynchronos.Managers; using MareSynchronos.Managers;
using Dalamud.Utility; using Dalamud.Utility;
using MareSynchronos.MareConfiguration; using MareSynchronos.MareConfiguration;
using MareSynchronos.Delegates;
using MareSynchronos.Mediator; using MareSynchronos.Mediator;
namespace MareSynchronos.WebAPI; namespace MareSynchronos.WebAPI;
@@ -80,11 +79,6 @@ public partial class ApiController : IDisposable, IMareHubClient
Task.Run(() => CreateConnections(forceGetToken: true)); Task.Run(() => CreateConnections(forceGetToken: true));
} }
public event VoidDelegate? Connected;
public event VoidDelegate? Disconnected;
public event VoidDelegate? DownloadStarted;
public event VoidDelegate? DownloadFinished;
public ConcurrentDictionary<int, List<DownloadFileTransfer>> CurrentDownloads { get; } = new(); public ConcurrentDictionary<int, List<DownloadFileTransfer>> CurrentDownloads { get; } = new();
public List<FileTransfer> CurrentUploads { get; } = new(); public List<FileTransfer> CurrentUploads { get; } = new();
@@ -309,7 +303,7 @@ public partial class ApiController : IDisposable, IMareHubClient
_ = ClientHealthCheck(_healthCheckTokenSource.Token); _ = ClientHealthCheck(_healthCheckTokenSource.Token);
_initialized = true; _initialized = true;
Connected?.Invoke(); _mediator.Publish(new ConnectedMessage());
} }
public void Dispose() public void Dispose()
@@ -346,7 +340,7 @@ public partial class ApiController : IDisposable, IMareHubClient
CurrentDownloads.Clear(); CurrentDownloads.Clear();
_uploadCancellationTokenSource?.Cancel(); _uploadCancellationTokenSource?.Cancel();
_healthCheckTokenSource?.Cancel(); _healthCheckTokenSource?.Cancel();
Disconnected?.Invoke(); _mediator.Publish(new DisconnectedMessage());
_pairManager.ClearPairs(); _pairManager.ClearPairs();
ServerState = ServerState.Offline; ServerState = ServerState.Offline;
Logger.Info("Connection closed"); Logger.Info("Connection closed");
@@ -361,7 +355,7 @@ public partial class ApiController : IDisposable, IMareHubClient
Logger.Warn("Connection closed... Reconnecting"); Logger.Warn("Connection closed... Reconnecting");
Logger.Warn(arg?.Message ?? string.Empty); Logger.Warn(arg?.Message ?? string.Empty);
Logger.Warn(arg?.StackTrace ?? string.Empty); Logger.Warn(arg?.StackTrace ?? string.Empty);
Disconnected?.Invoke(); _mediator.Publish(new DisconnectedMessage());
_pairManager.ClearPairs(); _pairManager.ClearPairs();
return Task.CompletedTask; return Task.CompletedTask;
} }
@@ -391,7 +385,7 @@ public partial class ApiController : IDisposable, IMareHubClient
await _mareHub.DisposeAsync().ConfigureAwait(false); await _mareHub.DisposeAsync().ConfigureAwait(false);
CurrentUploads.Clear(); CurrentUploads.Clear();
CurrentDownloads.Clear(); CurrentDownloads.Clear();
Disconnected?.Invoke(); _mediator.Publish(new DisconnectedMessage());
_pairManager.ClearPairs(); _pairManager.ClearPairs();
_mareHub = null; _mareHub = null;
} }