This commit is contained in:
rootdarkarchon
2023-05-01 01:33:35 +02:00
parent dc1e1c044a
commit 7495470dd5
14 changed files with 208 additions and 105 deletions

View File

@@ -169,7 +169,7 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
private void DalamudUtil_FrameworkUpdate()
{
_cachedFrameAddresses = _playerRelatedPointers.Select(c => c.CurrentAddress).ToHashSet();
_cachedFrameAddresses = _playerRelatedPointers.Select(c => c.CurrentAddress().GetAwaiter().GetResult()).ToHashSet();
_cachedHandledPaths.Clear();
foreach (var item in TransientResources.Where(item => !_dalamudUtil.IsGameObjectPresent(item.Key)).Select(i => i.Key).ToList())
{

View File

@@ -12,7 +12,6 @@ using Microsoft.Extensions.Logging;
using MareSynchronos.PlayerData.Handlers;
using MareSynchronos.Services.Mediator;
using MareSynchronos.Services;
using System;
namespace MareSynchronos.Interop;

View File

@@ -9,6 +9,7 @@ using MareSynchronos.PlayerData.Handlers;
using MareSynchronos.Interop;
using MareSynchronos.Services;
using MareSynchronos.Utils;
using MareSynchronos.PlayerData.Factories;
namespace MareSynchronos.PlayerData.Export;
@@ -17,13 +18,13 @@ public class MareCharaFileManager
private readonly MareConfigService _configService;
private readonly DalamudUtilService _dalamudUtil;
private readonly MareCharaFileDataFactory _factory;
private readonly Func<ObjectKind, Func<IntPtr>, bool, GameObjectHandler> _gameObjectHandlerFactory;
private readonly GameObjectHandlerFactory _gameObjectHandlerFactory;
private readonly IpcManager _ipcManager;
private readonly ILogger<MareCharaFileManager> _logger;
private readonly FileCacheManager _manager;
private int _globalFileCounter = 0;
public MareCharaFileManager(ILogger<MareCharaFileManager> logger, Func<ObjectKind, Func<IntPtr>, bool, GameObjectHandler> gameObjectHandlerFactory,
public MareCharaFileManager(ILogger<MareCharaFileManager> logger, GameObjectHandlerFactory gameObjectHandlerFactory,
FileCacheManager manager, IpcManager ipcManager, MareConfigService configService, DalamudUtilService dalamudUtil)
{
_factory = new(manager);
@@ -68,7 +69,7 @@ public class MareCharaFileManager
await _ipcManager.PenumbraSetTemporaryMods(_logger, applicationId, charaTarget.Name.TextValue, charaTarget.ObjectTableIndex(),
extractedFiles.Union(fileSwaps).ToDictionary(d => d.Key, d => d.Value, StringComparer.Ordinal),
LoadedCharaFile.CharaFileData.ManipulationData).ConfigureAwait(false);
using GameObjectHandler tempHandler = _gameObjectHandlerFactory(ObjectKind.Player, () => charaTarget.Address, false);
using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.Player, () => charaTarget.Address, false).ConfigureAwait(false);
await _ipcManager.GlamourerApplyAll(_logger, tempHandler, LoadedCharaFile.CharaFileData.GlamourerData, applicationId, disposeCts.Token).ConfigureAwait(false);
_dalamudUtil.WaitWhileGposeCharacterIsDrawing(charaTarget.Address, 30000);
await _ipcManager.PenumbraRemoveTemporaryCollection(_logger, applicationId, charaTarget.Name.TextValue).ConfigureAwait(false);

View File

@@ -0,0 +1,46 @@
using MareSynchronos.API.Dto.User;
using MareSynchronos.FileCache;
using MareSynchronos.Interop;
using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.PlayerData.Factories;
public class CachedPlayerFactory
{
private readonly DalamudUtilService _dalamudUtilService;
private readonly FileCacheManager _fileCacheManager;
private readonly FileDownloadManagerFactory _fileDownloadManagerFactory;
private readonly GameObjectHandlerFactory _gameObjectHandlerFactory;
private readonly IHostApplicationLifetime _hostApplicationLifetime;
private readonly IpcManager _ipcManager;
private readonly ILoggerFactory _loggerFactory;
private readonly MareConfigService _mareConfigService;
private readonly MareMediator _mareMediator;
public CachedPlayerFactory(ILoggerFactory loggerFactory, GameObjectHandlerFactory gameObjectHandlerFactory, IpcManager ipcManager,
FileDownloadManagerFactory fileDownloadManagerFactory, MareConfigService mareConfigService, DalamudUtilService dalamudUtilService,
IHostApplicationLifetime hostApplicationLifetime, FileCacheManager fileCacheManager, MareMediator mareMediator)
{
_loggerFactory = loggerFactory;
_gameObjectHandlerFactory = gameObjectHandlerFactory;
_ipcManager = ipcManager;
_fileDownloadManagerFactory = fileDownloadManagerFactory;
_mareConfigService = mareConfigService;
_dalamudUtilService = dalamudUtilService;
_hostApplicationLifetime = hostApplicationLifetime;
_fileCacheManager = fileCacheManager;
_mareMediator = mareMediator;
}
public CachedPlayer Create(OnlineUserIdentDto onlineUserIdentDto)
{
return new CachedPlayer(_loggerFactory.CreateLogger<CachedPlayer>(), onlineUserIdentDto, _gameObjectHandlerFactory,
_ipcManager, _fileDownloadManagerFactory.Create(), _mareConfigService, _dalamudUtilService, _hostApplicationLifetime,
_fileCacheManager, _mareMediator);
}
}

View File

@@ -0,0 +1,28 @@
using MareSynchronos.FileCache;
using MareSynchronos.Services.Mediator;
using MareSynchronos.WebAPI.Files;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.PlayerData.Factories;
public class FileDownloadManagerFactory
{
private readonly FileCacheManager _fileCacheManager;
private readonly FileTransferOrchestrator _fileTransferOrchestrator;
private readonly ILoggerFactory _loggerFactory;
private readonly MareMediator _mareMediator;
public FileDownloadManagerFactory(ILoggerFactory loggerFactory, MareMediator mareMediator, FileTransferOrchestrator fileTransferOrchestrator,
FileCacheManager fileCacheManager)
{
_loggerFactory = loggerFactory;
_mareMediator = mareMediator;
_fileTransferOrchestrator = fileTransferOrchestrator;
_fileCacheManager = fileCacheManager;
}
public FileDownloadManager Create()
{
return new FileDownloadManager(_loggerFactory.CreateLogger<FileDownloadManager>(), _mareMediator, _fileTransferOrchestrator, _fileCacheManager);
}
}

View File

@@ -0,0 +1,30 @@
using MareSynchronos.API.Data.Enum;
using MareSynchronos.PlayerData.Handlers;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.PlayerData.Factories;
public class GameObjectHandlerFactory
{
private readonly DalamudUtilService _dalamudUtilService;
private readonly ILoggerFactory _loggerFactory;
private readonly MareMediator _mareMediator;
private readonly PerformanceCollectorService _performanceCollectorService;
public GameObjectHandlerFactory(ILoggerFactory loggerFactory, PerformanceCollectorService performanceCollectorService, MareMediator mareMediator,
DalamudUtilService dalamudUtilService)
{
_loggerFactory = loggerFactory;
_performanceCollectorService = performanceCollectorService;
_mareMediator = mareMediator;
_dalamudUtilService = dalamudUtilService;
}
public async Task<GameObjectHandler> Create(ObjectKind objectKind, Func<nint> getAddressFunc, bool isWatched = false)
{
return await _dalamudUtilService.RunOnFrameworkThread(() => new GameObjectHandler(_loggerFactory.CreateLogger<GameObjectHandler>(),
_performanceCollectorService, _mareMediator, _dalamudUtilService, objectKind, getAddressFunc, isWatched)).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,28 @@
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services.Mediator;
using MareSynchronos.Services.ServerConfiguration;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.PlayerData.Factories;
public class PairFactory
{
private readonly CachedPlayerFactory _cachedPlayerFactory;
private readonly ILoggerFactory _loggerFactory;
private readonly MareMediator _mareMediator;
private readonly ServerConfigurationManager _serverConfigurationManager;
public PairFactory(ILoggerFactory loggerFactory, CachedPlayerFactory cachedPlayerFactory,
MareMediator mareMediator, ServerConfigurationManager serverConfigurationManager)
{
_loggerFactory = loggerFactory;
_cachedPlayerFactory = cachedPlayerFactory;
_mareMediator = mareMediator;
_serverConfigurationManager = serverConfigurationManager;
}
public Pair Create()
{
return new Pair(_loggerFactory.CreateLogger<Pair>(), _cachedPlayerFactory, _mareMediator, _serverConfigurationManager);
}
}

View File

@@ -84,14 +84,23 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
public IntPtr Address { get; set; }
public unsafe Character* Character => (Character*)Address;
public IntPtr CurrentAddress => _getAddress.Invoke();
public Lazy<Dalamud.Game.ClientState.Objects.Types.GameObject?> GameObjectLazy { get; private set; }
public string Name { get; private set; }
public ObjectKind ObjectKind { get; }
private byte[] CustomizeData { get; set; } = new byte[26];
private IntPtr DrawObjectAddress { get; set; }
private byte[] EquipSlotData { get; set; } = new byte[40];
public async Task<IntPtr> CurrentAddress()
{
return await _dalamudUtil.RunOnFrameworkThread(_getAddress.Invoke).ConfigureAwait(true);
}
public async Task<bool> IsBeingDrawnRunOnFramework()
{
return await _dalamudUtil.RunOnFrameworkThread(() =>
@@ -99,7 +108,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
nint curPtr = IntPtr.Zero;
try
{
curPtr = CurrentAddress;
curPtr = CurrentAddress().GetAwaiter().GetResult();
if (curPtr == IntPtr.Zero) return true;
@@ -136,7 +145,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
{
if (_haltProcessing) return;
var curPtr = CurrentAddress;
var curPtr = CurrentAddress().GetAwaiter().GetResult();
bool drawObjDiff = false;
try
{

View File

@@ -6,6 +6,7 @@ using MareSynchronos.API.Dto.User;
using MareSynchronos.FileCache;
using MareSynchronos.Interop;
using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Factories;
using MareSynchronos.PlayerData.Handlers;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
@@ -24,7 +25,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
private readonly DalamudUtilService _dalamudUtil;
private readonly FileDownloadManager _downloadManager;
private readonly FileCacheManager _fileDbManager;
private readonly Func<ObjectKind, Func<nint>, bool, GameObjectHandler> _gameObjectHandlerFactory;
private readonly GameObjectHandlerFactory _gameObjectHandlerFactory;
private readonly IpcManager _ipcManager;
private readonly IHostApplicationLifetime _lifetime;
private readonly OptionalPluginWarning _pluginWarnings;
@@ -40,7 +41,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
private CancellationTokenSource _redrawCts = new();
public CachedPlayer(ILogger<CachedPlayer> logger, OnlineUserIdentDto onlineUser,
Func<ObjectKind, Func<nint>, bool, GameObjectHandler> gameObjectHandlerFactory,
GameObjectHandlerFactory gameObjectHandlerFactory,
IpcManager ipcManager, FileDownloadManager transferManager, MareConfigService mareConfigService,
DalamudUtilService dalamudUtil, IHostApplicationLifetime lifetime, FileCacheManager fileDbManager, MareMediator mediator) : base(logger, mediator)
{
@@ -119,18 +120,6 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
_cachedData = characterData;
}
public bool CheckExistence()
{
if (PlayerName == null || _charaHandler == null
|| !string.Equals(PlayerName, _charaHandler.Name, StringComparison.Ordinal)
|| _charaHandler.CurrentAddress == IntPtr.Zero)
{
return false;
}
return true;
}
public override string ToString()
{
return OnlineUser == null
@@ -200,6 +189,14 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
}
}
private static void CheckForNameAndThrow(GameObjectHandler handler, string name)
{
if (!string.Equals(handler.Name, name, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("Player name not equal to requested name, pointer invalid");
}
}
private async Task ApplyBaseData(Guid applicationId, Dictionary<string, string> moddedPaths, string manipulationData, CancellationToken token)
{
await _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, PlayerName!).ConfigureAwait(false);
@@ -217,9 +214,9 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
var handler = changes.Key switch
{
ObjectKind.Player => _charaHandler!,
ObjectKind.Companion => _gameObjectHandlerFactory(changes.Key, () => _dalamudUtil.GetCompanion(ptr).GetAwaiter().GetResult(), false),
ObjectKind.MinionOrMount => _gameObjectHandlerFactory(changes.Key, () => _dalamudUtil.GetMinionOrMount(ptr), false),
ObjectKind.Pet => _gameObjectHandlerFactory(changes.Key, () => _dalamudUtil.GetPet(ptr).GetAwaiter().GetResult(), false),
ObjectKind.Companion => await _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetCompanion(ptr).GetAwaiter().GetResult(), false).ConfigureAwait(false),
ObjectKind.MinionOrMount => await _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetMinionOrMount(ptr).GetAwaiter().GetResult(), false).ConfigureAwait(false),
ObjectKind.Pet => await _gameObjectHandlerFactory.Create(changes.Key, () => _dalamudUtil.GetPet(ptr).GetAwaiter().GetResult(), false).ConfigureAwait(false),
_ => throw new NotSupportedException("ObjectKind not supported: " + changes.Key)
};
@@ -274,14 +271,6 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
}
}
private void CheckForNameAndThrow(GameObjectHandler handler, string name)
{
if (!string.Equals(handler.Name, name, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("Player name not equal to requested name, pointer invalid");
}
}
private Dictionary<ObjectKind, HashSet<PlayerChanges>> CheckUpdatedData(CharacterData oldData, CharacterData newData, bool forced)
{
var charaDataToUpdate = new Dictionary<ObjectKind, HashSet<PlayerChanges>>();
@@ -520,7 +509,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
private void Initialize(string name)
{
PlayerName = name;
_charaHandler = _gameObjectHandlerFactory(ObjectKind.Player, () => _dalamudUtil.GetPlayerCharacterFromObjectTableByIdent(OnlineUser.Ident), false);
_charaHandler = _gameObjectHandlerFactory.Create(ObjectKind.Player, () => _dalamudUtil.GetPlayerCharacterFromObjectTableByIdent(OnlineUser.Ident), false).GetAwaiter().GetResult();
_originalGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter).ConfigureAwait(false).GetAwaiter().GetResult();
_lastGlamourerData = _originalGlamourerData;
@@ -602,7 +591,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
if (objectKind == ObjectKind.Player)
{
using GameObjectHandler tempHandler = _gameObjectHandlerFactory(ObjectKind.Player, () => address, false);
using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.Player, () => address, false).ConfigureAwait(false);
CheckForNameAndThrow(tempHandler, name);
Logger.LogDebug("[{applicationId}] Restoring Customization and Equipment for {alias}/{name}: {data}", applicationId, OnlineUser.User.AliasOrUID, name, _originalGlamourerData);
await _ipcManager.GlamourerApplyCustomizationAndEquipment(Logger, tempHandler, _originalGlamourerData, _lastGlamourerData, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false);
@@ -621,10 +610,10 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
}
else if (objectKind == ObjectKind.MinionOrMount)
{
var minionOrMount = _dalamudUtil.GetMinionOrMount(address);
var minionOrMount = await _dalamudUtil.GetMinionOrMount(address).ConfigureAwait(false);
if (minionOrMount != IntPtr.Zero)
{
using GameObjectHandler tempHandler = _gameObjectHandlerFactory(ObjectKind.MinionOrMount, () => minionOrMount, false);
using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.MinionOrMount, () => minionOrMount, false).ConfigureAwait(false);
await _ipcManager.PenumbraRedraw(Logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false);
}
}
@@ -633,7 +622,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
var pet = await _dalamudUtil.GetPet(address).ConfigureAwait(false);
if (pet != IntPtr.Zero)
{
using GameObjectHandler tempHandler = _gameObjectHandlerFactory(ObjectKind.Pet, () => pet, false);
using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.Pet, () => pet, false).ConfigureAwait(false);
await _ipcManager.PenumbraRedraw(Logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false);
}
}
@@ -642,7 +631,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
var companion = await _dalamudUtil.GetCompanion(address).ConfigureAwait(false);
if (companion != IntPtr.Zero)
{
using GameObjectHandler tempHandler = _gameObjectHandlerFactory(ObjectKind.Pet, () => companion, false);
using GameObjectHandler tempHandler = await _gameObjectHandlerFactory.Create(ObjectKind.Pet, () => companion, false).ConfigureAwait(false);
await _ipcManager.PenumbraRedraw(Logger, tempHandler, applicationId, cancelToken.Token, fireAndForget: false).ConfigureAwait(false);
}
}
@@ -653,7 +642,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
Stopwatch st = Stopwatch.StartNew();
List<FileReplacementData> missingFiles = new();
moddedDictionary = new Dictionary<string, string>(StringComparer.Ordinal);
ConcurrentDictionary<string, string> outputDict = new ConcurrentDictionary<string, string>(StringComparer.Ordinal);
ConcurrentDictionary<string, string> outputDict = new(StringComparer.Ordinal);
try
{
var replacementList = charaData.FileReplacements.SelectMany(k => k.Value.Where(v => string.IsNullOrEmpty(v.FileSwapPath))).ToList();

View File

@@ -4,6 +4,7 @@ using MareSynchronos.API.Data.Comparer;
using MareSynchronos.API.Data.Extensions;
using MareSynchronos.API.Dto.Group;
using MareSynchronos.API.Dto.User;
using MareSynchronos.PlayerData.Factories;
using MareSynchronos.Services.Mediator;
using MareSynchronos.Services.ServerConfiguration;
using MareSynchronos.Utils;
@@ -13,14 +14,14 @@ namespace MareSynchronos.PlayerData.Pairs;
public class Pair
{
private readonly Func<OnlineUserIdentDto, CachedPlayer> _cachedPlayerFactory;
private readonly CachedPlayerFactory _cachedPlayerFactory;
private readonly SemaphoreSlim _creationSemaphore = new(1);
private readonly ILogger<Pair> _logger;
private readonly MareMediator _mediator;
private readonly ServerConfigurationManager _serverConfigurationManager;
private OnlineUserIdentDto? _onlineUserIdentDto = null;
public Pair(ILogger<Pair> logger, Func<OnlineUserIdentDto, CachedPlayer> cachedPlayerFactory,
public Pair(ILogger<Pair> logger, CachedPlayerFactory cachedPlayerFactory,
MareMediator mediator, ServerConfigurationManager serverConfigurationManager)
{
_logger = logger;
@@ -29,7 +30,6 @@ public class Pair
_serverConfigurationManager = serverConfigurationManager;
}
public bool CachedPlayerExists => CachedPlayer?.CheckExistence() ?? false;
public Dictionary<GroupFullInfoDto, GroupPairFullInfoDto> GroupPair { get; set; } = new(GroupDtoComparer.Instance);
public bool HasCachedPlayer => CachedPlayer != null && !string.IsNullOrEmpty(CachedPlayer.PlayerName) && _onlineUserIdentDto != null;
public bool IsOnline => CachedPlayer != null;
@@ -108,7 +108,7 @@ public class Pair
}
CachedPlayer?.Dispose();
CachedPlayer = _cachedPlayerFactory(_onlineUserIdentDto!);
CachedPlayer = _cachedPlayerFactory.Create(_onlineUserIdentDto!);
}
finally
{

View File

@@ -6,6 +6,7 @@ using MareSynchronos.API.Data.Extensions;
using MareSynchronos.API.Dto.Group;
using MareSynchronos.API.Dto.User;
using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Factories;
using MareSynchronos.Services.Mediator;
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
@@ -18,11 +19,11 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
private readonly ConcurrentDictionary<GroupData, GroupFullInfoDto> _allGroups = new(GroupDataComparer.Instance);
private readonly MareConfigService _configurationService;
private readonly DalamudContextMenu _dalamudContextMenu;
private readonly Func<Pair> _pairFactory;
private readonly PairFactory _pairFactory;
private Lazy<List<Pair>> _directPairsInternal;
private Lazy<Dictionary<GroupFullInfoDto, List<Pair>>> _groupPairsInternal;
public PairManager(ILogger<PairManager> logger, Func<Pair> pairFactory,
public PairManager(ILogger<PairManager> logger, PairFactory pairFactory,
MareConfigService configurationService, MareMediator mediator,
DalamudContextMenu dalamudContextMenu) : base(logger, mediator)
{
@@ -51,7 +52,7 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
public void AddGroupPair(GroupPairFullInfoDto dto)
{
if (!_allClientPairs.ContainsKey(dto.User)) _allClientPairs[dto.User] = _pairFactory.Invoke();
if (!_allClientPairs.ContainsKey(dto.User)) _allClientPairs[dto.User] = _pairFactory.Create();
var group = _allGroups[dto.Group];
_allClientPairs[dto.User].GroupPair[group] = dto;
@@ -62,7 +63,7 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
{
if (!_allClientPairs.ContainsKey(dto.User))
{
_allClientPairs[dto.User] = _pairFactory.Invoke();
_allClientPairs[dto.User] = _pairFactory.Create();
}
else
{

View File

@@ -20,7 +20,7 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
private CancellationTokenSource _honorificCts = new();
private CancellationTokenSource _palettePlusCts = new();
public CacheCreationService(ILogger<CacheCreationService> logger, MareMediator mediator, Func<ObjectKind, Func<IntPtr>, bool, GameObjectHandler> gameObjectHandlerFactory,
public CacheCreationService(ILogger<CacheCreationService> logger, MareMediator mediator, GameObjectHandlerFactory gameObjectHandlerFactory,
PlayerDataFactory characterDataFactory, DalamudUtilService dalamudUtil) : base(logger, mediator)
{
_characterDataFactory = characterDataFactory;
@@ -76,14 +76,14 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
await AddPlayerCacheToCreate().ConfigureAwait(false);
});
_playerRelatedObjects[ObjectKind.Player] =
gameObjectHandlerFactory(ObjectKind.Player, () => dalamudUtil.PlayerPointer, true);
_playerRelatedObjects[ObjectKind.MinionOrMount] =
gameObjectHandlerFactory(ObjectKind.MinionOrMount, () => dalamudUtil.GetMinionOrMount(), true);
_playerRelatedObjects[ObjectKind.Pet] =
gameObjectHandlerFactory(ObjectKind.Pet, () => dalamudUtil.GetPet().GetAwaiter().GetResult(), true);
_playerRelatedObjects[ObjectKind.Companion] =
gameObjectHandlerFactory(ObjectKind.Companion, () => dalamudUtil.GetCompanion().GetAwaiter().GetResult(), true);
_playerRelatedObjects[ObjectKind.Player] = gameObjectHandlerFactory.Create(ObjectKind.Player, () => dalamudUtil.PlayerPointer, true)
.GetAwaiter().GetResult();
_playerRelatedObjects[ObjectKind.MinionOrMount] = gameObjectHandlerFactory.Create(ObjectKind.MinionOrMount, () => dalamudUtil.GetMinionOrMount().GetAwaiter().GetResult(), true)
.GetAwaiter().GetResult();
_playerRelatedObjects[ObjectKind.Pet] = gameObjectHandlerFactory.Create(ObjectKind.Pet, () => dalamudUtil.GetPet().GetAwaiter().GetResult(), true)
.GetAwaiter().GetResult();
_playerRelatedObjects[ObjectKind.Companion] = gameObjectHandlerFactory.Create(ObjectKind.Companion, () => dalamudUtil.GetCompanion().GetAwaiter().GetResult(), true)
.GetAwaiter().GetResult();
}
protected override void Dispose(bool disposing)

View File

@@ -9,14 +9,11 @@ using Dalamud.Game.Gui;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
using MareSynchronos.API.Data.Enum;
using MareSynchronos.API.Dto.User;
using MareSynchronos.FileCache;
using MareSynchronos.Interop;
using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Export;
using MareSynchronos.PlayerData.Factories;
using MareSynchronos.PlayerData.Handlers;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.PlayerData.Services;
using MareSynchronos.Services;
@@ -70,6 +67,10 @@ public sealed class Plugin : IDalamudPlugin
collection.AddSingleton<MarePlugin>();
collection.AddSingleton<MareProfileManager>();
collection.AddSingleton<UidDisplayHandler>();
collection.AddSingleton<GameObjectHandlerFactory>();
collection.AddSingleton<FileDownloadManagerFactory>();
collection.AddSingleton<CachedPlayerFactory>();
collection.AddSingleton<PairFactory>();
collection.AddSingleton((s) => new DalamudUtilService(s.GetRequiredService<ILogger<DalamudUtilService>>(),
clientState, objectTable, framework, gameGui, condition, gameData,
s.GetRequiredService<MareMediator>(), s.GetRequiredService<PerformanceCollectorService>()));
@@ -84,37 +85,6 @@ public sealed class Plugin : IDalamudPlugin
collection.AddSingleton((s) => new ConfigurationMigrator(s.GetRequiredService<ILogger<ConfigurationMigrator>>(), pluginInterface));
// func factory method singletons
collection.AddSingleton(s =>
new Func<ObjectKind, Func<nint>, bool, GameObjectHandler>((o, f, b)
=> new GameObjectHandler(s.GetRequiredService<ILogger<GameObjectHandler>>(),
s.GetRequiredService<PerformanceCollectorService>(),
s.GetRequiredService<MareMediator>(),
s.GetRequiredService<DalamudUtilService>(),
o, f, b)));
collection.AddSingleton(s =>
new Func<OnlineUserIdentDto, CachedPlayer>((o)
=> new CachedPlayer(s.GetRequiredService<ILogger<CachedPlayer>>(),
o,
s.GetRequiredService<Func<ObjectKind, Func<nint>, bool, GameObjectHandler>>(),
s.GetRequiredService<IpcManager>(),
s.GetRequiredService<Func<FileDownloadManager>>().Invoke(),
s.GetRequiredService<MareConfigService>(),
s.GetRequiredService<DalamudUtilService>(),
s.GetRequiredService<IHostApplicationLifetime>(),
s.GetRequiredService<FileCacheManager>(),
s.GetRequiredService<MareMediator>())));
collection.AddSingleton(s =>
new Func<Pair>(()
=> new Pair(s.GetRequiredService<ILogger<Pair>>(),
s.GetRequiredService<Func<OnlineUserIdentDto, CachedPlayer>>(),
s.GetRequiredService<MareMediator>(),
s.GetRequiredService<ServerConfigurationManager>())));
collection.AddSingleton(s =>
new Func<FileDownloadManager>(()
=> new FileDownloadManager(s.GetRequiredService<ILogger<FileDownloadManager>>(),
s.GetRequiredService<MareMediator>(),
s.GetRequiredService<FileTransferOrchestrator>(),
s.GetRequiredService<FileCacheManager>())));
collection.AddSingleton(s =>
new Func<Pair, StandaloneProfileUi>((pair) =>
new StandaloneProfileUi(s.GetRequiredService<ILogger<StandaloneProfileUi>>(),

View File

@@ -12,13 +12,13 @@ using MareSynchronos.Utils;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Numerics;
using System.Runtime.CompilerServices;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
namespace MareSynchronos.Services;
public class DalamudUtilService : IHostedService
{
private readonly List<uint> _classJobIdsIgnoredForPets = new() { 30 };
private readonly ClientState _clientState;
private readonly Condition _condition;
private readonly Framework _framework;
@@ -27,7 +27,6 @@ public class DalamudUtilService : IHostedService
private readonly MareMediator _mediator;
private readonly ObjectTable _objectTable;
private readonly PerformanceCollectorService _performanceCollector;
private readonly List<uint> ClassJobIdsIgnoredForPets = new() { 30 };
private uint? _classJobId = 0;
private DateTime _delayedFrameworkUpdateCheck = DateTime.Now;
private Dictionary<string, (string Name, nint Address)> _playerCharas = new(StringComparer.Ordinal);
@@ -94,11 +93,9 @@ public class DalamudUtilService : IHostedService
return await RunOnFrameworkThread(() => GetCompanionInternal(playerPointer)).ConfigureAwait(false);
}
public unsafe IntPtr GetMinionOrMount(IntPtr? playerPointer = null)
public async Task<IntPtr> GetMinionOrMount(IntPtr? playerPointer = null)
{
playerPointer ??= PlayerPointer;
if (playerPointer == IntPtr.Zero) return IntPtr.Zero;
return _objectTable.GetObjectAddress(((GameObject*)playerPointer)->ObjectIndex + 1);
return await RunOnFrameworkThread(() => GetMinionOrMountInternal(playerPointer)).ConfigureAwait(false);
}
public async Task<IntPtr> GetPet(IntPtr? playerPointer = null)
@@ -117,8 +114,7 @@ public class DalamudUtilService : IHostedService
return _objectTable.Any(f => f.Address == key);
}
public async Task RunOnFrameworkThread(Action act, [CallerMemberName] string callerMember = "",
[CallerFilePath] string callerFilePath = "", [CallerLineNumber] int lineNumber = 0)
public async Task RunOnFrameworkThread(Action act)
{
if (!_framework.IsInFrameworkUpdateThread)
{
@@ -133,8 +129,7 @@ public class DalamudUtilService : IHostedService
act();
}
public async Task<T> RunOnFrameworkThread<T>(Func<T> func, [CallerMemberName] string callerMember = "",
[CallerFilePath] string callerFilePath = "", [CallerLineNumber] int lineNumber = 0)
public async Task<T> RunOnFrameworkThread<T>(Func<T> func)
{
if (!_framework.IsInFrameworkUpdateThread)
{
@@ -146,8 +141,8 @@ public class DalamudUtilService : IHostedService
}
return result;
}
else
return func.Invoke();
return func.Invoke();
}
public Task StartAsync(CancellationToken cancellationToken)
@@ -171,7 +166,7 @@ public class DalamudUtilService : IHostedService
public async Task WaitWhileCharacterIsDrawing(ILogger logger, GameObjectHandler handler, Guid redrawId, int timeOut = 5000, CancellationToken? ct = null)
{
if (!_clientState.IsLoggedIn || handler.CurrentAddress == IntPtr.Zero) return;
if (!_clientState.IsLoggedIn || handler.Address == IntPtr.Zero) return;
logger.LogTrace("[{redrawId}] Starting wait for {handler} to draw", redrawId, handler);
@@ -337,9 +332,16 @@ public class DalamudUtilService : IHostedService
return (IntPtr)mgr->LookupBuddyByOwnerObject((BattleChara*)playerPointer);
}
private unsafe IntPtr GetMinionOrMountInternal(IntPtr? playerPointer = null)
{
playerPointer ??= PlayerPointer;
if (playerPointer == IntPtr.Zero) return IntPtr.Zero;
return _objectTable.GetObjectAddress(((GameObject*)playerPointer)->ObjectIndex + 1);
}
private unsafe IntPtr GetPetInternal(IntPtr? playerPointer = null)
{
if (ClassJobIdsIgnoredForPets.Contains(_classJobId ?? 0)) return IntPtr.Zero;
if (_classJobIdsIgnoredForPets.Contains(_classJobId ?? 0)) return IntPtr.Zero;
var mgr = CharacterManager.Instance();
playerPointer ??= PlayerPointer;
if (playerPointer == IntPtr.Zero || (IntPtr)mgr == IntPtr.Zero) return IntPtr.Zero;