Check for unexpected party members when entering instanced duties

This commit is contained in:
Liza 2025-02-22 23:08:58 +01:00
parent ed797143b3
commit 224825b071
Signed by: liza
GPG Key ID: 2C41B84815CF6445
3 changed files with 175 additions and 0 deletions

View File

@ -0,0 +1,167 @@
using System;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Group;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
namespace Questionable.Controller.Utils;
internal sealed class PartyWatchDog : IDisposable
{
private readonly QuestController _questController;
private readonly IClientState _clientState;
private readonly IChatGui _chatGui;
private readonly ILogger<PartyWatchDog> _logger;
private ushort? _uncheckedTeritoryId;
public PartyWatchDog(QuestController questController, IClientState clientState, IChatGui chatGui,
ILogger<PartyWatchDog> logger)
{
_questController = questController;
_clientState = clientState;
_chatGui = chatGui;
_logger = logger;
_clientState.TerritoryChanged += TerritoryChanged;
}
private unsafe void TerritoryChanged(ushort newTerritoryId)
{
var intendedUse = (ETerritoryIntendedUseEnum)GameMain.Instance()->CurrentTerritoryIntendedUseId;
switch (intendedUse)
{
case ETerritoryIntendedUseEnum.Gaol:
case ETerritoryIntendedUseEnum.Frontline:
case ETerritoryIntendedUseEnum.LordOfVerminion:
case ETerritoryIntendedUseEnum.Diadem:
case ETerritoryIntendedUseEnum.CrystallineConflict:
case ETerritoryIntendedUseEnum.Battlehall:
case ETerritoryIntendedUseEnum.CrystallineConflict2:
case ETerritoryIntendedUseEnum.DeepDungeon:
case ETerritoryIntendedUseEnum.TreasureMapDuty:
case ETerritoryIntendedUseEnum.Diadem2:
case ETerritoryIntendedUseEnum.RivalWings:
case ETerritoryIntendedUseEnum.Eureka:
case ETerritoryIntendedUseEnum.LeapOfFaith:
case ETerritoryIntendedUseEnum.OceanFishing:
case ETerritoryIntendedUseEnum.Diadem3:
case ETerritoryIntendedUseEnum.Bozja:
case ETerritoryIntendedUseEnum.Battlehall2:
case ETerritoryIntendedUseEnum.Battlehall3:
case ETerritoryIntendedUseEnum.LargeScaleRaid:
case ETerritoryIntendedUseEnum.LargeScaleSavageRaid:
case ETerritoryIntendedUseEnum.Blunderville:
StopIfRunning($"Unsupported Area entered ({newTerritoryId})");
break;
case ETerritoryIntendedUseEnum.Dungeon:
case ETerritoryIntendedUseEnum.VariantDungeon:
case ETerritoryIntendedUseEnum.AllianceRaid:
case ETerritoryIntendedUseEnum.Trial:
case ETerritoryIntendedUseEnum.Raid:
case ETerritoryIntendedUseEnum.Raid2:
case ETerritoryIntendedUseEnum.SeasonalEvent:
case ETerritoryIntendedUseEnum.SeasonalEvent2:
case ETerritoryIntendedUseEnum.CriterionDuty:
case ETerritoryIntendedUseEnum.CriterionSavageDuty:
_uncheckedTeritoryId = newTerritoryId;
_logger.LogInformation("Will check territory {TerritoryId} after loading", newTerritoryId);
break;
}
}
public unsafe void Update()
{
if (_uncheckedTeritoryId == _clientState.TerritoryType && GameMain.Instance()->TerritoryLoadState == 2)
{
var groupManager = GroupManager.Instance();
if (groupManager == null)
return;
byte memberCount = groupManager->MainGroup.MemberCount;
_logger.LogDebug("Terrritory {TerritoryId} with {MemberCount} members", _uncheckedTeritoryId, memberCount);
if (memberCount > 1)
StopIfRunning("Other party members present");
_uncheckedTeritoryId = null;
}
}
private void StopIfRunning(string reason)
{
if (_questController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual)
{
_chatGui.PrintError(
$"Stopping Questionable: {reason}. If you believe this to be correct, please restart Questionable manually.",
CommandHandler.MessageTag, CommandHandler.TagColor);
_questController.Stop(reason);
}
}
public void Dispose()
{
_clientState.TerritoryChanged -= TerritoryChanged;
}
// from https://github.com/NightmareXIV/ECommons/blob/f69e460e95134c72592654059843b138b4c01a9e/ECommons/ExcelServices/TerritoryIntendedUseEnum.cs#L5
[UsedImplicitly(ImplicitUseTargetFlags.Members, Reason = "game data")]
private enum ETerritoryIntendedUseEnum : byte
{
CityArea = 0,
OpenWorld = 1,
Inn = 2,
Dungeon = 3,
VariantDungeon = 4,
Gaol = 5,
StartingArea = 6,
QuestArea = 7,
AllianceRaid = 8,
QuestBattle = 9,
Trial = 10,
QuestArea2 = 12,
ResidentialArea = 13,
HousingInstances = 14,
QuestArea3 = 15,
Raid = 16,
Raid2 = 17,
Frontline = 18,
ChocoboSquare = 20,
RestorationEvent = 21,
Sanctum = 22,
GoldSaucer = 23,
LordOfVerminion = 25,
Diadem = 26,
HallOfTheNovice = 27,
CrystallineConflict = 28,
QuestBattle2 = 29,
Barracks = 30,
DeepDungeon = 31,
SeasonalEvent = 32,
TreasureMapDuty = 33,
SeasonalEventDuty = 34,
Battlehall = 35,
CrystallineConflict2 = 37,
Diadem2 = 38,
RivalWings = 39,
Unknown1 = 40,
Eureka = 41,
SeasonalEvent2 = 43,
LeapOfFaith = 44,
MaskedCarnivale = 45,
OceanFishing = 46,
Diadem3 = 47,
Bozja = 48,
IslandSanctuary = 49,
Battlehall2 = 50,
Battlehall3 = 51,
LargeScaleRaid = 52,
LargeScaleSavageRaid = 53,
QuestArea4 = 54,
TribalInstance = 56,
CriterionDuty = 57,
CriterionSavageDuty = 58,
Blunderville = 59,
}
}

View File

@ -7,6 +7,7 @@ using Dalamud.Plugin.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Questionable.Controller; using Questionable.Controller;
using Questionable.Controller.GameUi; using Questionable.Controller.GameUi;
using Questionable.Controller.Utils;
using Questionable.Windows; using Questionable.Windows;
namespace Questionable; namespace Questionable;
@ -23,6 +24,7 @@ internal sealed class DalamudInitializer : IDisposable
private readonly ConfigWindow _configWindow; private readonly ConfigWindow _configWindow;
private readonly IToastGui _toastGui; private readonly IToastGui _toastGui;
private readonly Configuration _configuration; private readonly Configuration _configuration;
private readonly PartyWatchDog _partyWatchDog;
private readonly ILogger<DalamudInitializer> _logger; private readonly ILogger<DalamudInitializer> _logger;
public DalamudInitializer( public DalamudInitializer(
@ -42,6 +44,7 @@ internal sealed class DalamudInitializer : IDisposable
PriorityWindow priorityWindow, PriorityWindow priorityWindow,
IToastGui toastGui, IToastGui toastGui,
Configuration configuration, Configuration configuration,
PartyWatchDog partyWatchDog,
ILogger<DalamudInitializer> logger) ILogger<DalamudInitializer> logger)
{ {
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
@ -54,6 +57,7 @@ internal sealed class DalamudInitializer : IDisposable
_configWindow = configWindow; _configWindow = configWindow;
_toastGui = toastGui; _toastGui = toastGui;
_configuration = configuration; _configuration = configuration;
_partyWatchDog = partyWatchDog;
_logger = logger; _logger = logger;
_windowSystem.AddWindow(oneTimeSetupWindow); _windowSystem.AddWindow(oneTimeSetupWindow);
@ -77,6 +81,7 @@ internal sealed class DalamudInitializer : IDisposable
private void FrameworkUpdate(IFramework framework) private void FrameworkUpdate(IFramework framework)
{ {
_partyWatchDog.Update();
_questController.Update(); _questController.Update();
try try

View File

@ -20,6 +20,7 @@ using Questionable.Controller.Steps.Common;
using Questionable.Controller.Steps.Gathering; using Questionable.Controller.Steps.Gathering;
using Questionable.Controller.Steps.Interactions; using Questionable.Controller.Steps.Interactions;
using Questionable.Controller.Steps.Leves; using Questionable.Controller.Steps.Leves;
using Questionable.Controller.Utils;
using Questionable.Data; using Questionable.Data;
using Questionable.External; using Questionable.External;
using Questionable.Functions; using Questionable.Functions;
@ -260,6 +261,8 @@ public sealed class QuestionablePlugin : IDalamudPlugin
serviceCollection.AddSingleton<ShopController>(); serviceCollection.AddSingleton<ShopController>();
serviceCollection.AddSingleton<InterruptHandler>(); serviceCollection.AddSingleton<InterruptHandler>();
serviceCollection.AddSingleton<PartyWatchDog>();
serviceCollection.AddSingleton<CraftworksSupplyController>(); serviceCollection.AddSingleton<CraftworksSupplyController>();
serviceCollection.AddSingleton<CreditsController>(); serviceCollection.AddSingleton<CreditsController>();
serviceCollection.AddSingleton<HelpUiController>(); serviceCollection.AddSingleton<HelpUiController>();