Add MareSynchronos API impersonation
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Plugin.Ipc;
|
using Dalamud.Plugin.Ipc;
|
||||||
|
using MareSynchronos.MareConfiguration;
|
||||||
using MareSynchronos.PlayerData.Export;
|
using MareSynchronos.PlayerData.Export;
|
||||||
using MareSynchronos.PlayerData.Handlers;
|
using MareSynchronos.PlayerData.Handlers;
|
||||||
using MareSynchronos.Services;
|
using MareSynchronos.Services;
|
||||||
@@ -14,6 +15,7 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
|
|||||||
{
|
{
|
||||||
private readonly ILogger<IpcProvider> _logger;
|
private readonly ILogger<IpcProvider> _logger;
|
||||||
private readonly IDalamudPluginInterface _pi;
|
private readonly IDalamudPluginInterface _pi;
|
||||||
|
private readonly MareConfigService _mareConfig;
|
||||||
private readonly MareCharaFileManager _mareCharaFileManager;
|
private readonly MareCharaFileManager _mareCharaFileManager;
|
||||||
private readonly DalamudUtilService _dalamudUtil;
|
private readonly DalamudUtilService _dalamudUtil;
|
||||||
private ICallGateProvider<string, IGameObject, bool>? _loadFileProvider;
|
private ICallGateProvider<string, IGameObject, bool>? _loadFileProvider;
|
||||||
@@ -21,14 +23,25 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
|
|||||||
private ICallGateProvider<List<nint>>? _handledGameAddresses;
|
private ICallGateProvider<List<nint>>? _handledGameAddresses;
|
||||||
private readonly List<GameObjectHandler> _activeGameObjectHandlers = [];
|
private readonly List<GameObjectHandler> _activeGameObjectHandlers = [];
|
||||||
|
|
||||||
|
private ICallGateProvider<string, IGameObject, bool>? _loadFileProviderMare;
|
||||||
|
private ICallGateProvider<string, IGameObject, Task<bool>>? _loadFileAsyncProviderMare;
|
||||||
|
private ICallGateProvider<List<nint>>? _handledGameAddressesMare;
|
||||||
|
|
||||||
|
private bool _marePluginEnabled = false;
|
||||||
|
private bool _impersonating = false;
|
||||||
|
|
||||||
|
public bool MarePluginEnabled => _marePluginEnabled;
|
||||||
|
public bool ImpersonationActive => _impersonating;
|
||||||
|
|
||||||
public MareMediator Mediator { get; init; }
|
public MareMediator Mediator { get; init; }
|
||||||
|
|
||||||
public IpcProvider(ILogger<IpcProvider> logger, IDalamudPluginInterface pi,
|
public IpcProvider(ILogger<IpcProvider> logger, IDalamudPluginInterface pi, MareConfigService mareConfig,
|
||||||
MareCharaFileManager mareCharaFileManager, DalamudUtilService dalamudUtil,
|
MareCharaFileManager mareCharaFileManager, DalamudUtilService dalamudUtil,
|
||||||
MareMediator mareMediator)
|
MareMediator mareMediator)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_pi = pi;
|
_pi = pi;
|
||||||
|
_mareConfig = mareConfig;
|
||||||
_mareCharaFileManager = mareCharaFileManager;
|
_mareCharaFileManager = mareCharaFileManager;
|
||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
Mediator = mareMediator;
|
Mediator = mareMediator;
|
||||||
@@ -43,6 +56,13 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
|
|||||||
if (msg.OwnedObject) return;
|
if (msg.OwnedObject) return;
|
||||||
_activeGameObjectHandlers.Remove(msg.GameObjectHandler);
|
_activeGameObjectHandlers.Remove(msg.GameObjectHandler);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_marePluginEnabled = pi.InstalledPlugins.Any(p => p.InternalName == "MareSynchronos" && p.IsLoaded);
|
||||||
|
Mediator.Subscribe<PluginChangeMessage>(this, p => {
|
||||||
|
if (p.InternalName == "MareSynchronos")
|
||||||
|
_marePluginEnabled = p.IsLoaded;
|
||||||
|
HandleMareImpersonation();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
@@ -54,16 +74,63 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
|
|||||||
_loadFileAsyncProvider.RegisterFunc(LoadMcdfAsync);
|
_loadFileAsyncProvider.RegisterFunc(LoadMcdfAsync);
|
||||||
_handledGameAddresses = _pi.GetIpcProvider<List<nint>>("LoporritSync.GetHandledAddresses");
|
_handledGameAddresses = _pi.GetIpcProvider<List<nint>>("LoporritSync.GetHandledAddresses");
|
||||||
_handledGameAddresses.RegisterFunc(GetHandledAddresses);
|
_handledGameAddresses.RegisterFunc(GetHandledAddresses);
|
||||||
|
|
||||||
|
_loadFileProviderMare = _pi.GetIpcProvider<string, IGameObject, bool>("MareSynchronos.LoadMcdf");
|
||||||
|
_loadFileAsyncProviderMare = _pi.GetIpcProvider<string, IGameObject, Task<bool>>("MareSynchronos.LoadMcdfAsync");
|
||||||
|
_handledGameAddressesMare = _pi.GetIpcProvider<List<nint>>("MareSynchronos.GetHandledAddresses");
|
||||||
|
HandleMareImpersonation();
|
||||||
|
|
||||||
_logger.LogInformation("Started IpcProviderService");
|
_logger.LogInformation("Started IpcProviderService");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HandleMareImpersonation()
|
||||||
|
{
|
||||||
|
if (_marePluginEnabled)
|
||||||
|
{
|
||||||
|
if (_impersonating)
|
||||||
|
{
|
||||||
|
// Do not attempt to unregister the functions at this point, otherwise we risk unregistering Mare's
|
||||||
|
// This may leave the APIs hanging if Mare did not initialize to the point of registering its API though
|
||||||
|
_impersonating = false;
|
||||||
|
_logger.LogDebug("Releasing MareSynchronos API");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_mareConfig.Current.MareAPI)
|
||||||
|
{
|
||||||
|
_loadFileProviderMare?.RegisterFunc(LoadMcdf);
|
||||||
|
_loadFileAsyncProviderMare?.RegisterFunc(LoadMcdfAsync);
|
||||||
|
_handledGameAddressesMare?.RegisterFunc(GetHandledAddresses);
|
||||||
|
_impersonating = true;
|
||||||
|
_logger.LogDebug("Registered MareSynchronos API");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_loadFileProviderMare?.UnregisterFunc();
|
||||||
|
_loadFileAsyncProviderMare?.UnregisterFunc();
|
||||||
|
_handledGameAddressesMare?.UnregisterFunc();
|
||||||
|
_impersonating = false;
|
||||||
|
_logger.LogDebug("Unregistered MareSynchronos API");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Task StopAsync(CancellationToken cancellationToken)
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.LogDebug("Stopping IpcProvider Service");
|
_logger.LogDebug("Stopping IpcProvider Service");
|
||||||
_loadFileProvider?.UnregisterFunc();
|
_loadFileProvider?.UnregisterFunc();
|
||||||
_loadFileAsyncProvider?.UnregisterFunc();
|
_loadFileAsyncProvider?.UnregisterFunc();
|
||||||
_handledGameAddresses?.UnregisterFunc();
|
_handledGameAddresses?.UnregisterFunc();
|
||||||
|
|
||||||
|
if (_impersonating)
|
||||||
|
{
|
||||||
|
_loadFileProviderMare?.UnregisterFunc();
|
||||||
|
_loadFileAsyncProviderMare?.UnregisterFunc();
|
||||||
|
_handledGameAddressesMare?.UnregisterFunc();
|
||||||
|
}
|
||||||
|
|
||||||
Mediator.UnsubscribeAll(this);
|
Mediator.UnsubscribeAll(this);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,4 +69,6 @@ public class MareConfig : IMareConfiguration
|
|||||||
public int ChatLogKind { get; set; } = 1; // XivChatType.Debug
|
public int ChatLogKind { get; set; } = 1; // XivChatType.Debug
|
||||||
public bool ExtraChatAPI { get; set; } = false;
|
public bool ExtraChatAPI { get; set; } = false;
|
||||||
public bool ExtraChatTags { get; set; } = false;
|
public bool ExtraChatTags { get; set; } = false;
|
||||||
|
|
||||||
|
public bool MareAPI { get; set; } = true;
|
||||||
}
|
}
|
||||||
@@ -38,6 +38,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
private readonly ApiController _apiController;
|
private readonly ApiController _apiController;
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
|
private readonly IpcProvider _ipcProvider;
|
||||||
private readonly CacheMonitor _cacheMonitor;
|
private readonly CacheMonitor _cacheMonitor;
|
||||||
private readonly DalamudUtilService _dalamudUtilService;
|
private readonly DalamudUtilService _dalamudUtilService;
|
||||||
private readonly MareConfigService _configService;
|
private readonly MareConfigService _configService;
|
||||||
@@ -84,7 +85,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
FileTransferOrchestrator fileTransferOrchestrator,
|
FileTransferOrchestrator fileTransferOrchestrator,
|
||||||
FileCacheManager fileCacheManager,
|
FileCacheManager fileCacheManager,
|
||||||
FileCompactor fileCompactor, ApiController apiController,
|
FileCompactor fileCompactor, ApiController apiController,
|
||||||
IpcManager ipcManager, CacheMonitor cacheMonitor,
|
IpcManager ipcManager, IpcProvider ipcProvider, CacheMonitor cacheMonitor,
|
||||||
DalamudUtilService dalamudUtilService) : base(logger, mediator, "Loporrit Settings", performanceCollector)
|
DalamudUtilService dalamudUtilService) : base(logger, mediator, "Loporrit Settings", performanceCollector)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
@@ -101,6 +102,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
_fileCacheManager = fileCacheManager;
|
_fileCacheManager = fileCacheManager;
|
||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
_ipcManager = ipcManager;
|
_ipcManager = ipcManager;
|
||||||
|
_ipcProvider = ipcProvider;
|
||||||
_cacheMonitor = cacheMonitor;
|
_cacheMonitor = cacheMonitor;
|
||||||
_dalamudUtilService = dalamudUtilService;
|
_dalamudUtilService = dalamudUtilService;
|
||||||
_fileCompactor = fileCompactor;
|
_fileCompactor = fileCompactor;
|
||||||
@@ -616,10 +618,50 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawDebug()
|
private void DrawAdvanced()
|
||||||
{
|
{
|
||||||
_lastTab = "Debug";
|
_lastTab = "Advanced";
|
||||||
|
|
||||||
|
_uiShared.BigText("Advanced");
|
||||||
|
|
||||||
|
bool mareApi = _configService.Current.MareAPI;
|
||||||
|
if (ImGui.Checkbox("Enable Mare Synchronos API", ref mareApi))
|
||||||
|
{
|
||||||
|
_configService.Current.MareAPI = mareApi;
|
||||||
|
_configService.Save();
|
||||||
|
_ipcProvider.HandleMareImpersonation();
|
||||||
|
}
|
||||||
|
_uiShared.DrawHelpText("Enables handling of the Mare Synchronos API. This currently includes:\n\n" +
|
||||||
|
" - MCDF loading support for other plugins\n" +
|
||||||
|
" - Blocking Moodles applications to paired users\n\n" +
|
||||||
|
"If the Mare Synchronos plugin is loaded while this option is enabled, control of its API will be relinquished.");
|
||||||
|
|
||||||
|
using (_ = ImRaii.PushIndent())
|
||||||
|
{
|
||||||
|
ImGui.SameLine(300.0f);
|
||||||
|
if (_ipcProvider.ImpersonationActive)
|
||||||
|
{
|
||||||
|
UiSharedService.ColorTextWrapped("Mare API active!", ImGuiColors.HealerGreen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!mareApi)
|
||||||
|
UiSharedService.ColorTextWrapped("Mare API inactive: Option is disabled", ImGuiColors.DalamudYellow);
|
||||||
|
else if (_ipcProvider.MarePluginEnabled)
|
||||||
|
UiSharedService.ColorTextWrapped("Mare API inactive: Mare plugin is loaded", ImGuiColors.DalamudYellow);
|
||||||
|
else
|
||||||
|
UiSharedService.ColorTextWrapped("Mare API inactive: Unknown reason", ImGuiColors.DalamudRed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool logEvents = _configService.Current.LogEvents;
|
||||||
|
if (ImGui.Checkbox("Log Event Viewer Data", ref logEvents))
|
||||||
|
{
|
||||||
|
_configService.Current.LogEvents = logEvents;
|
||||||
|
_configService.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
_uiShared.BigText("Debug");
|
_uiShared.BigText("Debug");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (LastCreatedCharacterData != null && ImGui.TreeNode("Last created character data"))
|
if (LastCreatedCharacterData != null && ImGui.TreeNode("Last created character data"))
|
||||||
@@ -672,22 +714,17 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool logEvents = _configService.Current.LogEvents;
|
if (ImGui.TreeNode("Active Character Blocks"))
|
||||||
if (ImGui.Checkbox("Log Event Viewer Data", ref logEvents))
|
|
||||||
{
|
{
|
||||||
_configService.Current.LogEvents = logEvents;
|
var onlinePairs = _pairManager.GetOnlineUserPairs();
|
||||||
_configService.Save();
|
foreach (var pair in onlinePairs)
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
_uiShared.BigText("Active Character Blocks");
|
|
||||||
foreach (var pair in _pairManager.GetOnlineUserPairs())
|
|
||||||
{
|
|
||||||
if (pair.IsApplicationBlocked)
|
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted(pair.PlayerName);
|
if (pair.IsApplicationBlocked)
|
||||||
ImGui.SameLine();
|
{
|
||||||
ImGui.TextUnformatted(string.Join(", ", pair.HoldApplicationReasons));
|
ImGui.TextUnformatted(pair.PlayerName);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(string.Join(", ", pair.HoldApplicationReasons));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1932,9 +1969,9 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
ImGui.EndTabItem();
|
ImGui.EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.BeginTabItem("Debug"))
|
if (ImGui.BeginTabItem("Advanced"))
|
||||||
{
|
{
|
||||||
DrawDebug();
|
DrawAdvanced();
|
||||||
ImGui.EndTabItem();
|
ImGui.EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user