1
0
Fork 0
forked from aly/qstbak
qstbak/Questionable/Questionable.Controller.GameUi/QteController.cs
2026-01-19 08:31:23 +10:00

113 lines
2.6 KiB
C#

using System;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Component.GUI;
using FFXIVClientStructs.Interop;
using LLib.GameUI;
using Microsoft.Extensions.Logging;
using Questionable.Controller.Utils;
namespace Questionable.Controller.GameUi;
internal sealed class QteController : IDisposable
{
private readonly Configuration _configuration;
private readonly IGameGui _gameGui;
private readonly IGameConfig _gameConfig;
private readonly IFramework _framework;
private readonly ILogger<QteController> _logger;
private long _throttler = Environment.TickCount64;
private readonly Random _random = new Random();
private bool _hasDirectChat;
private bool _directChatWasEnabled;
public QteController(Configuration configuration, IGameGui gameGui, IGameConfig gameConfig, IFramework framework, ILogger<QteController> logger)
{
_configuration = configuration;
_gameGui = gameGui;
_gameConfig = gameConfig;
_framework = framework;
_logger = logger;
_framework.Update += OnUpdate;
}
private unsafe void OnUpdate(IFramework framework)
{
AtkUnitBase* addonPtr;
if (!_configuration.General.AutoSolveQte)
{
EnableDirectChatIfNeeded();
}
else if (_gameGui.TryGetAddonByName<AtkUnitBase>("QTE", out addonPtr) && LAddon.IsAddonReady(addonPtr) && addonPtr->IsVisible)
{
DisableDirectChatIfNeeded();
if (Environment.TickCount64 >= _throttler)
{
if (IsChatLogFocused())
{
WindowsKeypress.SendKeypress(WindowsKeypress.LimitedKeys.Escape);
}
WindowsKeypress.SendKeypress(WindowsKeypress.LimitedKeys.A);
_throttler = Environment.TickCount64 + _random.Next(25, 50);
}
}
else
{
EnableDirectChatIfNeeded();
}
}
private unsafe bool IsChatLogFocused()
{
AtkStage* ptr = AtkStage.Instance();
if (ptr == null)
{
return false;
}
Span<Pointer<AtkUnitBase>> entries = ptr->RaptureAtkUnitManager->AtkUnitManager.FocusedUnitsList.Entries;
for (int i = 0; i < entries.Length; i++)
{
Pointer<AtkUnitBase> pointer = entries[i];
if (pointer.Value != null && pointer.Value->NameString == "ChatLog")
{
return true;
}
}
return false;
}
private void EnableDirectChatIfNeeded()
{
if (_hasDirectChat)
{
_gameConfig.UiControl.Set("DirectChat", _directChatWasEnabled);
_hasDirectChat = false;
}
}
private void DisableDirectChatIfNeeded()
{
if (!_hasDirectChat && _gameConfig.UiControl.TryGetBool("DirectChat", out var value))
{
_directChatWasEnabled = value;
if (value)
{
_gameConfig.UiControl.Set("DirectChat", value: false);
}
_hasDirectChat = true;
}
}
public void Dispose()
{
_framework.Update -= OnUpdate;
EnableDirectChatIfNeeded();
}
}