using System; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Component.GUI; namespace QuestionableCompanion.Services; public class PartyInviteAutoAccept : IDisposable { private readonly IPluginLog log; private readonly IFramework framework; private readonly IGameGui gameGui; private readonly IPartyList partyList; private readonly Configuration configuration; private bool shouldAutoAccept; private DateTime autoAcceptUntil = DateTime.MinValue; private bool hasLoggedAlwaysAccept; public PartyInviteAutoAccept(IPluginLog log, IFramework framework, IGameGui gameGui, IPartyList partyList, Configuration configuration) { this.log = log; this.framework = framework; this.gameGui = gameGui; this.partyList = partyList; this.configuration = configuration; framework.Update += OnFrameworkUpdate; log.Information("[PartyInviteAutoAccept] Initialized"); } public void EnableAutoAccept() { if (!configuration.IsHighLevelHelper && !configuration.IsQuester) { log.Debug("[PartyInviteAutoAccept] Not a helper or quester, ignoring auto-accept request"); return; } shouldAutoAccept = true; autoAcceptUntil = DateTime.Now.AddSeconds(30.0); string role = (configuration.IsHighLevelHelper ? "Helper" : "Quester"); log.Information("[PartyInviteAutoAccept] Auto-accept enabled for 30 seconds (" + role + ")"); log.Information($"[PartyInviteAutoAccept] Will accept until: {autoAcceptUntil:HH:mm:ss}"); log.Information("[PartyInviteAutoAccept] Will accept ALL party invites during this time!"); } public void EnableForQuester(string questerName) { shouldAutoAccept = true; autoAcceptUntil = DateTime.Now.AddSeconds(60.0); log.Information("[PartyInviteAutoAccept] Auto-accept enabled for quester: " + questerName); log.Information("[PartyInviteAutoAccept] Will accept invites for 60 seconds"); } private unsafe void OnFrameworkUpdate(IFramework framework) { bool shouldAcceptNow = false; if (configuration.IsHighLevelHelper && configuration.AlwaysAutoAcceptInvites) { if (!hasLoggedAlwaysAccept) { log.Information("[PartyInviteAutoAccept] === ALWAYS AUTO-ACCEPT ENABLED ==="); log.Information("[PartyInviteAutoAccept] Helper will continuously accept ALL party invites"); log.Information("[PartyInviteAutoAccept] This mode is ALWAYS ON (no timeout)"); hasLoggedAlwaysAccept = true; } shouldAcceptNow = true; } else if (shouldAutoAccept) { if (hasLoggedAlwaysAccept) { log.Information("[PartyInviteAutoAccept] Always auto-accept disabled"); hasLoggedAlwaysAccept = false; } if (DateTime.Now > autoAcceptUntil) { shouldAutoAccept = false; log.Information("[PartyInviteAutoAccept] Auto-accept window expired"); return; } shouldAcceptNow = true; } else if (hasLoggedAlwaysAccept) { log.Information("[PartyInviteAutoAccept] Always auto-accept disabled"); hasLoggedAlwaysAccept = false; } if (!shouldAcceptNow) { return; } try { string[] obj = new string[6] { "SelectYesno", "SelectYesNo", "_PartyInvite", "PartyInvite", "SelectString", "_Notification" }; nint addonPtr = IntPtr.Zero; string[] array = obj; foreach (string name in array) { addonPtr = (nint)gameGui.GetAddonByName(name); if (addonPtr != IntPtr.Zero) { break; } } if (addonPtr != IntPtr.Zero) { AtkUnitBase* addon = (AtkUnitBase*)addonPtr; if (addon == null) { log.Warning("[PartyInviteAutoAccept] Addon pointer is null!"); } else if (addon->IsVisible) { AtkValue* values = stackalloc AtkValue[1]; *values = new AtkValue { Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.Int, Int = 0 }; addon->FireCallback(1u, values); AtkValue* values2 = stackalloc AtkValue[2]; *values2 = new AtkValue { Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.Int, Int = 0 }; values2[1] = new AtkValue { Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.UInt, UInt = 0u }; addon->FireCallback(2u, values2); } } } catch (Exception ex) { log.Error("[PartyInviteAutoAccept] Error: " + ex.Message); log.Error("[PartyInviteAutoAccept] Stack: " + ex.StackTrace); } } public void Dispose() { framework.Update -= OnFrameworkUpdate; } }