100 lines
2.7 KiB
C#
100 lines
2.7 KiB
C#
using System;
|
|
using System.Linq;
|
|
using Dalamud.Plugin;
|
|
using Dalamud.Plugin.Services;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Questionable.External;
|
|
|
|
internal sealed class WigglyNavAvailability : IDisposable
|
|
{
|
|
private const int SupportedMajorVersion = 1;
|
|
|
|
private const string WigglyNavInternalName = "WigglyNav";
|
|
|
|
private const long ReprobeIntervalMs = 5000L;
|
|
|
|
private readonly IDalamudPluginInterface _pluginInterface;
|
|
|
|
private readonly WigglyNavIpc _wigglyNavIpc;
|
|
|
|
private readonly IFramework _framework;
|
|
|
|
private readonly ILogger<WigglyNavAvailability> _logger;
|
|
|
|
private readonly object _verdictLock = new object();
|
|
|
|
private volatile bool _isCompatible;
|
|
|
|
private long _lastProbeTicks;
|
|
|
|
public bool IsCompatible => _isCompatible;
|
|
|
|
public event Action? CompatibilityChanged;
|
|
|
|
public WigglyNavAvailability(IDalamudPluginInterface pluginInterface, WigglyNavIpc wigglyNavIpc, IFramework framework, ILogger<WigglyNavAvailability> logger)
|
|
{
|
|
_pluginInterface = pluginInterface;
|
|
_wigglyNavIpc = wigglyNavIpc;
|
|
_framework = framework;
|
|
_logger = logger;
|
|
TryRefreshVerdict(respectThrottle: false);
|
|
_logger.LogInformation("WigglyNav native surface is {State} at startup", DescribeVerdict(_isCompatible));
|
|
_pluginInterface.ActivePluginsChanged += OnActivePluginsChanged;
|
|
_framework.Update += OnFrameworkUpdate;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_framework.Update -= OnFrameworkUpdate;
|
|
_pluginInterface.ActivePluginsChanged -= OnActivePluginsChanged;
|
|
}
|
|
|
|
private void OnActivePluginsChanged(IActivePluginsChangedEventArgs args)
|
|
{
|
|
if (args.AffectedInternalNames.Contains("WigglyNav") && TryRefreshVerdict(respectThrottle: false))
|
|
{
|
|
_logger.LogInformation("WigglyNav native surface is now {State} (plugin list change: {Kind})", DescribeVerdict(_isCompatible), args.Kind);
|
|
this.CompatibilityChanged?.Invoke();
|
|
}
|
|
}
|
|
|
|
private void OnFrameworkUpdate(IFramework framework)
|
|
{
|
|
if (!_isCompatible && TryRefreshVerdict(respectThrottle: true))
|
|
{
|
|
_logger.LogInformation("WigglyNav native surface is now {State} (periodic re-probe)", DescribeVerdict(_isCompatible));
|
|
this.CompatibilityChanged?.Invoke();
|
|
}
|
|
}
|
|
|
|
private bool TryRefreshVerdict(bool respectThrottle)
|
|
{
|
|
lock (_verdictLock)
|
|
{
|
|
long tickCount = Environment.TickCount64;
|
|
if (respectThrottle && tickCount - _lastProbeTicks < 5000)
|
|
{
|
|
return false;
|
|
}
|
|
_lastProbeTicks = tickCount;
|
|
(int, int)? tuple = _wigglyNavIpc.TryGetApiVersion();
|
|
bool flag = tuple.HasValue && tuple.GetValueOrDefault().Item1 == 1;
|
|
if (flag == _isCompatible)
|
|
{
|
|
return false;
|
|
}
|
|
_isCompatible = flag;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private static string DescribeVerdict(bool isCompatible)
|
|
{
|
|
if (!isCompatible)
|
|
{
|
|
return "unavailable or incompatible";
|
|
}
|
|
return "compatible";
|
|
}
|
|
}
|