Fix IpcProvider

This commit is contained in:
Loporrit
2025-08-12 11:18:35 +00:00
parent 81238b1a20
commit 9556605200
3 changed files with 28 additions and 12 deletions

View File

@@ -5,6 +5,7 @@ using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Handlers; using MareSynchronos.PlayerData.Handlers;
using MareSynchronos.Services; using MareSynchronos.Services;
using MareSynchronos.Services.Mediator; using MareSynchronos.Services.Mediator;
using MareSynchronos.Utils;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -27,7 +28,8 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
private bool _marePluginEnabled = false; private bool _marePluginEnabled = false;
private bool _impersonating = false; private bool _impersonating = false;
private readonly CancellationTokenSource _registerDelayCts = new(); private DateTime _unregisterTime = DateTime.UtcNow;
private CancellationTokenSource _registerDelayCts = new();
public bool MarePluginEnabled => _marePluginEnabled; public bool MarePluginEnabled => _marePluginEnabled;
public bool ImpersonationActive => _impersonating; public bool ImpersonationActive => _impersonating;
@@ -57,7 +59,7 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
_marePluginEnabled = PluginWatcherService.GetInitialPluginState(pi, "MareSynchronos")?.IsLoaded ?? false; _marePluginEnabled = PluginWatcherService.GetInitialPluginState(pi, "MareSynchronos")?.IsLoaded ?? false;
Mediator.SubscribeKeyed<PluginChangeMessage>(this, "MareSynchronos", p => { Mediator.SubscribeKeyed<PluginChangeMessage>(this, "MareSynchronos", p => {
_marePluginEnabled = p.IsLoaded; _marePluginEnabled = p.IsLoaded;
HandleMareImpersonation(); HandleMareImpersonation(automatic: true);
}); });
} }
@@ -74,22 +76,24 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
_loadFileProviderMare = _pi.GetIpcProvider<string, IGameObject, bool>("MareSynchronos.LoadMcdf"); _loadFileProviderMare = _pi.GetIpcProvider<string, IGameObject, bool>("MareSynchronos.LoadMcdf");
_loadFileAsyncProviderMare = _pi.GetIpcProvider<string, IGameObject, Task<bool>>("MareSynchronos.LoadMcdfAsync"); _loadFileAsyncProviderMare = _pi.GetIpcProvider<string, IGameObject, Task<bool>>("MareSynchronos.LoadMcdfAsync");
_handledGameAddressesMare = _pi.GetIpcProvider<List<nint>>("MareSynchronos.GetHandledAddresses"); _handledGameAddressesMare = _pi.GetIpcProvider<List<nint>>("MareSynchronos.GetHandledAddresses");
HandleMareImpersonation(); HandleMareImpersonation(automatic: true);
_logger.LogInformation("Started IpcProviderService"); _logger.LogInformation("Started IpcProviderService");
return Task.CompletedTask; return Task.CompletedTask;
} }
public void HandleMareImpersonation() public void HandleMareImpersonation(bool automatic = false)
{ {
if (_marePluginEnabled) if (_marePluginEnabled)
{ {
if (_impersonating) if (_impersonating)
{ {
// Do not attempt to unregister the functions at this point, otherwise we risk unregistering Mare's _loadFileProviderMare?.UnregisterFunc();
// This may leave the APIs hanging if Mare did not initialize to the point of registering its API though _loadFileAsyncProviderMare?.UnregisterFunc();
_handledGameAddressesMare?.UnregisterFunc();
_impersonating = false; _impersonating = false;
_logger.LogDebug("Releasing MareSynchronos API"); _unregisterTime = DateTime.UtcNow;
_logger.LogDebug("Unregistered MareSynchronos API");
} }
} }
else else
@@ -100,7 +104,8 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
Task.Run(async () => Task.Run(async () =>
{ {
// Wait before registering to reduce the chance of a race condition // Wait before registering to reduce the chance of a race condition
await Task.Delay(500); if (automatic)
await Task.Delay(5000);
if (cancelToken.IsCancellationRequested) if (cancelToken.IsCancellationRequested)
return; return;
@@ -120,13 +125,14 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
} }
else else
{ {
_registerDelayCts.Cancel(); _registerDelayCts = _registerDelayCts.CancelRecreate();
if (_impersonating) if (_impersonating)
{ {
_loadFileProviderMare?.UnregisterFunc(); _loadFileProviderMare?.UnregisterFunc();
_loadFileAsyncProviderMare?.UnregisterFunc(); _loadFileAsyncProviderMare?.UnregisterFunc();
_handledGameAddressesMare?.UnregisterFunc(); _handledGameAddressesMare?.UnregisterFunc();
_impersonating = false; _impersonating = false;
_unregisterTime = DateTime.UtcNow;
_logger.LogDebug("Unregistered MareSynchronos API"); _logger.LogDebug("Unregistered MareSynchronos API");
} }
} }
@@ -175,6 +181,16 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
private List<nint> GetHandledAddresses() private List<nint> GetHandledAddresses()
{ {
if (!_impersonating)
{
if ((DateTime.UtcNow - _unregisterTime).TotalSeconds >= 1.0)
{
_logger.LogWarning("GetHandledAddresses called when it should not be registered");
_handledGameAddressesMare?.UnregisterFunc();
}
return [];
}
return _activeGameObjectHandlers.Where(g => g.Address != nint.Zero).Select(g => g.Address).Distinct().ToList(); return _activeGameObjectHandlers.Where(g => g.Address != nint.Zero).Select(g => g.Address).Distinct().ToList();
} }
} }

View File

@@ -594,7 +594,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
using (_ = ImRaii.PushIndent()) using (_ = ImRaii.PushIndent())
{ {
ImGui.SameLine(300.0f); ImGui.SameLine(300.0f * ImGuiHelpers.GlobalScale);
if (_ipcProvider.ImpersonationActive) if (_ipcProvider.ImpersonationActive)
{ {
UiSharedService.ColorTextWrapped("Mare API active!", ImGuiColors.HealerGreen); UiSharedService.ColorTextWrapped("Mare API active!", ImGuiColors.HealerGreen);
@@ -617,7 +617,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
_configService.Save(); _configService.Save();
} }
ImGui.SameLine(300.0f); ImGui.SameLine(300.0f * ImGuiHelpers.GlobalScale);
if (_uiShared.IconTextButton(FontAwesomeIcon.NotesMedical, "Open Event Viewer")) if (_uiShared.IconTextButton(FontAwesomeIcon.NotesMedical, "Open Event Viewer"))
{ {
Mediator.Publish(new UiToggleMessage(typeof(EventViewerUI))); Mediator.Publish(new UiToggleMessage(typeof(EventViewerUI)));