959 lines
28 KiB
C#
959 lines
28 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Dalamud.Plugin;
|
|
using Dalamud.Plugin.Ipc;
|
|
using Dalamud.Plugin.Services;
|
|
|
|
namespace QuestionableCompanion.Services;
|
|
|
|
public class QuestionableIPC : IDisposable
|
|
{
|
|
private readonly IDalamudPluginInterface pluginInterface;
|
|
|
|
private readonly IPluginLog log;
|
|
|
|
private ICallGateSubscriber<string, bool>? importQuestPrioritySubscriber;
|
|
|
|
private ICallGateSubscriber<string?>? getCurrentQuestIdSubscriber;
|
|
|
|
private ICallGateSubscriber<StepData?>? getCurrentStepDataSubscriber;
|
|
|
|
private ICallGateSubscriber<bool>? isRunningSubscriber;
|
|
|
|
private ICallGateSubscriber<object?>? getCurrentTaskSubscriber;
|
|
|
|
private ICallGateSubscriber<string, bool>? isQuestCompleteSubscriber;
|
|
|
|
private ICallGateSubscriber<string, bool>? isReadyToAcceptQuestSubscriber;
|
|
|
|
private ICallGateSubscriber<string, bool>? addQuestPrioritySubscriber;
|
|
|
|
private ICallGateSubscriber<bool>? clearQuestPrioritySubscriber;
|
|
|
|
private ICallGateSubscriber<List<string>>? getCurrentlyActiveEventQuestsSubscriber;
|
|
|
|
private ICallGateSubscriber<int>? getAlliedSocietyRemainingAllowancesSubscriber;
|
|
|
|
private ICallGateSubscriber<byte, List<string>>? getAlliedSocietyAvailableQuestIdsSubscriber;
|
|
|
|
private ICallGateSubscriber<Dictionary<byte, int>>? getAlliedSocietyAllAvailableQuestCountsSubscriber;
|
|
|
|
private ICallGateSubscriber<byte, bool>? getAlliedSocietyIsMaxRankSubscriber;
|
|
|
|
private ICallGateSubscriber<byte, int>? getAlliedSocietyCurrentRankSubscriber;
|
|
|
|
private ICallGateSubscriber<List<byte>>? getAlliedSocietiesWithAvailableQuestsSubscriber;
|
|
|
|
private ICallGateSubscriber<byte, int>? addAlliedSocietyOptimalQuestsSubscriber;
|
|
|
|
private ICallGateSubscriber<byte, List<string>>? getAlliedSocietyOptimalQuestsSubscriber;
|
|
|
|
private ICallGateSubscriber<long>? getAlliedSocietyTimeUntilResetSubscriber;
|
|
|
|
private ICallGateSubscriber<bool>? getStopConditionsEnabledSubscriber;
|
|
|
|
private ICallGateSubscriber<List<string>>? getStopQuestListSubscriber;
|
|
|
|
private ICallGateSubscriber<StopConditionData>? getLevelStopConditionSubscriber;
|
|
|
|
private ICallGateSubscriber<StopConditionData>? getSequenceStopConditionSubscriber;
|
|
|
|
private ICallGateSubscriber<string, uint, int, object?>? getQuestSequenceStopConditionSubscriber;
|
|
|
|
private ICallGateSubscriber<string, bool>? removeQuestSequenceStopConditionSubscriber;
|
|
|
|
private ICallGateSubscriber<Dictionary<string, object>>? getAllQuestSequenceStopConditionsSubscriber;
|
|
|
|
private ICallGateSubscriber<int>? getDefaultDutyModeSubscriber;
|
|
|
|
private ICallGateSubscriber<int, bool>? setDefaultDutyModeSubscriber;
|
|
|
|
private bool subscribersInitialized;
|
|
|
|
private DateTime lastAvailabilityCheck = DateTime.MinValue;
|
|
|
|
private const int AvailabilityCheckCooldownSeconds = 5;
|
|
|
|
public bool IsAvailable { get; private set; }
|
|
|
|
public QuestionableIPC(IDalamudPluginInterface pluginInterface, IPluginLog log)
|
|
{
|
|
this.pluginInterface = pluginInterface;
|
|
this.log = log;
|
|
InitializeIPC();
|
|
}
|
|
|
|
private void InitializeIPC()
|
|
{
|
|
try
|
|
{
|
|
getCurrentQuestIdSubscriber = pluginInterface.GetIpcSubscriber<string>("Questionable.GetCurrentQuestId");
|
|
getCurrentStepDataSubscriber = pluginInterface.GetIpcSubscriber<StepData>("Questionable.GetCurrentStepData");
|
|
isRunningSubscriber = pluginInterface.GetIpcSubscriber<bool>("Questionable.IsRunning");
|
|
importQuestPrioritySubscriber = pluginInterface.GetIpcSubscriber<string, bool>("Questionable.ImportQuestPriority");
|
|
getCurrentTaskSubscriber = pluginInterface.GetIpcSubscriber<object>("Questionable.GetCurrentTask");
|
|
isQuestCompleteSubscriber = pluginInterface.GetIpcSubscriber<string, bool>("Questionable.IsQuestComplete");
|
|
isReadyToAcceptQuestSubscriber = pluginInterface.GetIpcSubscriber<string, bool>("Questionable.IsReadyToAcceptQuest");
|
|
addQuestPrioritySubscriber = pluginInterface.GetIpcSubscriber<string, bool>("Questionable.AddQuestPriority");
|
|
clearQuestPrioritySubscriber = pluginInterface.GetIpcSubscriber<bool>("Questionable.ClearQuestPriority");
|
|
getCurrentlyActiveEventQuestsSubscriber = pluginInterface.GetIpcSubscriber<List<string>>("Questionable.GetCurrentlyActiveEventQuests");
|
|
getAlliedSocietyRemainingAllowancesSubscriber = pluginInterface.GetIpcSubscriber<int>("Questionable.AlliedSociety.GetRemainingAllowances");
|
|
getAlliedSocietyAvailableQuestIdsSubscriber = pluginInterface.GetIpcSubscriber<byte, List<string>>("Questionable.AlliedSociety.GetAvailableQuestIds");
|
|
getAlliedSocietyAllAvailableQuestCountsSubscriber = pluginInterface.GetIpcSubscriber<Dictionary<byte, int>>("Questionable.AlliedSociety.GetAllAvailableQuestCounts");
|
|
getAlliedSocietyIsMaxRankSubscriber = pluginInterface.GetIpcSubscriber<byte, bool>("Questionable.AlliedSociety.IsMaxRank");
|
|
getAlliedSocietyCurrentRankSubscriber = pluginInterface.GetIpcSubscriber<byte, int>("Questionable.AlliedSociety.GetCurrentRank");
|
|
getAlliedSocietiesWithAvailableQuestsSubscriber = pluginInterface.GetIpcSubscriber<List<byte>>("Questionable.AlliedSociety.GetSocietiesWithAvailableQuests");
|
|
addAlliedSocietyOptimalQuestsSubscriber = pluginInterface.GetIpcSubscriber<byte, int>("Questionable.AlliedSociety.AddOptimalQuests");
|
|
getAlliedSocietyOptimalQuestsSubscriber = pluginInterface.GetIpcSubscriber<byte, List<string>>("Questionable.AlliedSociety.GetOptimalQuests");
|
|
getAlliedSocietyTimeUntilResetSubscriber = pluginInterface.GetIpcSubscriber<long>("Questionable.AlliedSociety.GetTimeUntilReset");
|
|
getStopConditionsEnabledSubscriber = pluginInterface.GetIpcSubscriber<bool>("Questionable.GetStopConditionsEnabled");
|
|
getStopQuestListSubscriber = pluginInterface.GetIpcSubscriber<List<string>>("Questionable.GetStopQuestList");
|
|
getLevelStopConditionSubscriber = pluginInterface.GetIpcSubscriber<StopConditionData>("Questionable.GetLevelStopCondition");
|
|
getSequenceStopConditionSubscriber = pluginInterface.GetIpcSubscriber<StopConditionData>("Questionable.GetSequenceStopCondition");
|
|
getQuestSequenceStopConditionSubscriber = pluginInterface.GetIpcSubscriber<string, uint, int, object>("Questionable.GetQuestSequenceStopCondition");
|
|
removeQuestSequenceStopConditionSubscriber = pluginInterface.GetIpcSubscriber<string, bool>("Questionable.RemoveQuestSequenceStopCondition");
|
|
getAllQuestSequenceStopConditionsSubscriber = pluginInterface.GetIpcSubscriber<Dictionary<string, object>>("Questionable.GetAllQuestSequenceStopConditions");
|
|
getDefaultDutyModeSubscriber = pluginInterface.GetIpcSubscriber<int>("Questionable.GetDefaultDutyMode");
|
|
setDefaultDutyModeSubscriber = pluginInterface.GetIpcSubscriber<int, bool>("Questionable.SetDefaultDutyMode");
|
|
subscribersInitialized = true;
|
|
log.Debug("[QuestionableIPC] IPC subscribers initialized (lazy-loading enabled)");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
IsAvailable = false;
|
|
subscribersInitialized = false;
|
|
log.Error("[QuestionableIPC] Failed to initialize subscribers: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private bool TryEnsureAvailable()
|
|
{
|
|
if (IsAvailable)
|
|
{
|
|
return true;
|
|
}
|
|
if (!subscribersInitialized)
|
|
{
|
|
log.Warning("[QuestionableIPC] Subscribers not initialized!");
|
|
return false;
|
|
}
|
|
DateTime now = DateTime.Now;
|
|
if ((now - lastAvailabilityCheck).TotalSeconds < 5.0)
|
|
{
|
|
return false;
|
|
}
|
|
lastAvailabilityCheck = now;
|
|
try
|
|
{
|
|
if (isRunningSubscriber == null)
|
|
{
|
|
log.Error("[QuestionableIPC] isRunningSubscriber is NULL!");
|
|
return false;
|
|
}
|
|
isRunningSubscriber.InvokeFunc();
|
|
if (!IsAvailable)
|
|
{
|
|
IsAvailable = true;
|
|
}
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] Failed to connect to Questionable:");
|
|
log.Error("[QuestionableIPC] Exception Type: " + ex.GetType().Name);
|
|
log.Error("[QuestionableIPC] Message: " + ex.Message);
|
|
log.Error("[QuestionableIPC] Stack Trace: " + ex.StackTrace);
|
|
IsAvailable = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool ForceCheckAvailability()
|
|
{
|
|
try
|
|
{
|
|
if (!subscribersInitialized)
|
|
{
|
|
log.Error("[QuestionableIPC] Subscribers not initialized!");
|
|
return false;
|
|
}
|
|
if (isRunningSubscriber == null)
|
|
{
|
|
log.Error("[QuestionableIPC] isRunningSubscriber is NULL!");
|
|
return false;
|
|
}
|
|
log.Information("[QuestionableIPC] Force checking Questionable availability...");
|
|
log.Information("[QuestionableIPC] Attempting to call Questionable.IsRunning...");
|
|
bool testRunning = isRunningSubscriber.InvokeFunc();
|
|
log.Information($"[QuestionableIPC] SUCCESS! Questionable.IsRunning returned: {testRunning}");
|
|
IsAvailable = true;
|
|
lastAvailabilityCheck = DateTime.Now;
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] Failed to connect to Questionable:");
|
|
log.Error("[QuestionableIPC] Exception Type: " + ex.GetType().Name);
|
|
log.Error("[QuestionableIPC] Message: " + ex.Message);
|
|
log.Error("[QuestionableIPC] Stack Trace: " + ex.StackTrace);
|
|
IsAvailable = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool TryEnsureAvailableSilent()
|
|
{
|
|
if (IsAvailable)
|
|
{
|
|
return true;
|
|
}
|
|
if (!subscribersInitialized)
|
|
{
|
|
return false;
|
|
}
|
|
lastAvailabilityCheck = DateTime.MinValue;
|
|
try
|
|
{
|
|
if (isRunningSubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
isRunningSubscriber.InvokeFunc();
|
|
if (!IsAvailable)
|
|
{
|
|
IsAvailable = true;
|
|
}
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
IsAvailable = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public string? GetCurrentQuestId()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getCurrentQuestIdSubscriber == null)
|
|
{
|
|
return null;
|
|
}
|
|
try
|
|
{
|
|
return getCurrentQuestIdSubscriber.InvokeFunc();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Debug("[QuestionableIPC] GetCurrentQuestId failed: " + ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public StepData? GetCurrentStepData()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getCurrentStepDataSubscriber == null)
|
|
{
|
|
return null;
|
|
}
|
|
try
|
|
{
|
|
return getCurrentStepDataSubscriber.InvokeFunc();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Debug("[QuestionableIPC] GetCurrentStepData failed: " + ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public byte? GetCurrentSequence()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getCurrentStepDataSubscriber == null)
|
|
{
|
|
return null;
|
|
}
|
|
try
|
|
{
|
|
return getCurrentStepDataSubscriber.InvokeFunc()?.Sequence;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Debug("[QuestionableIPC] GetCurrentSequence failed: " + ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public bool IsRunning()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (isRunningSubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = isRunningSubscriber.InvokeFunc();
|
|
if (!IsAvailable)
|
|
{
|
|
IsAvailable = true;
|
|
log.Information("[QuestionableIPC] Questionable is now available");
|
|
}
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (IsAvailable)
|
|
{
|
|
IsAvailable = false;
|
|
log.Warning("[QuestionableIPC] Questionable is no longer available: " + ex.Message);
|
|
}
|
|
log.Debug("[QuestionableIPC] IsRunning failed: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public object? GetCurrentTask()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (getCurrentTaskSubscriber == null)
|
|
{
|
|
return null;
|
|
}
|
|
try
|
|
{
|
|
object? result = getCurrentTaskSubscriber.InvokeFunc();
|
|
if (!IsAvailable)
|
|
{
|
|
IsAvailable = true;
|
|
log.Information("[QuestionableIPC] Questionable is now available");
|
|
}
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (IsAvailable)
|
|
{
|
|
IsAvailable = false;
|
|
log.Warning("[QuestionableIPC] Questionable is no longer available: " + ex.Message);
|
|
}
|
|
log.Debug("[QuestionableIPC] GetCurrentTask failed: " + ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public bool Start()
|
|
{
|
|
log.Warning("[QuestionableIPC] Start() called - NOT AVAILABLE VIA IPC!");
|
|
log.Warning("[QuestionableIPC] Use /qst start command instead");
|
|
return false;
|
|
}
|
|
|
|
public bool Stop()
|
|
{
|
|
log.Warning("[QuestionableIPC] Stop() called - NOT AVAILABLE VIA IPC!");
|
|
log.Warning("[QuestionableIPC] Use /qst stop command instead");
|
|
return false;
|
|
}
|
|
|
|
public bool ImportQuestPriority(string base64QuestData)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || importQuestPrioritySubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = importQuestPrioritySubscriber.InvokeFunc(base64QuestData);
|
|
log.Information($"[QuestionableIPC] Imported priority quest: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] ImportQuestPriority failed: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool AddQuestPriority(string questId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || addQuestPrioritySubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = addQuestPrioritySubscriber.InvokeFunc(questId);
|
|
log.Debug($"[QuestionableIPC] Added quest {questId} to priority: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] AddQuestPriority failed: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool ClearQuestPriority()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || clearQuestPrioritySubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = clearQuestPrioritySubscriber.InvokeFunc();
|
|
log.Debug($"[QuestionableIPC] Cleared quest priority: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] ClearQuestPriority failed: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool IsQuestComplete(string questId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || isQuestCompleteSubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = isQuestCompleteSubscriber.InvokeFunc(questId);
|
|
log.Debug($"[QuestionableIPC] Quest {questId} complete: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] IsQuestComplete failed: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool IsReadyToAcceptQuest(string questId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || isReadyToAcceptQuestSubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = isReadyToAcceptQuestSubscriber.InvokeFunc(questId);
|
|
log.Debug($"[QuestionableIPC] Quest {questId} ready to accept: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] IsReadyToAcceptQuest failed: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool AddQuestsToQueue(List<string> questIds)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable)
|
|
{
|
|
log.Warning("[QuestionableIPC] Cannot add quests to queue - Questionable not available");
|
|
return false;
|
|
}
|
|
if (questIds == null || questIds.Count == 0)
|
|
{
|
|
return true;
|
|
}
|
|
try
|
|
{
|
|
log.Information($"[QuestionableIPC] Adding {questIds.Count} quests to priority queue");
|
|
foreach (string questId in questIds)
|
|
{
|
|
if (!string.IsNullOrEmpty(questId))
|
|
{
|
|
try
|
|
{
|
|
bool? result = addQuestPrioritySubscriber?.InvokeFunc(questId);
|
|
log.Debug($"[QuestionableIPC] Added quest {questId} to queue: {result}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Warning("[QuestionableIPC] Failed to add quest " + questId + " to queue: " + ex.Message);
|
|
}
|
|
}
|
|
}
|
|
log.Information("[QuestionableIPC] All quests added to priority queue");
|
|
return true;
|
|
}
|
|
catch (Exception ex2)
|
|
{
|
|
log.Error("[QuestionableIPC] Error adding quests to queue: " + ex2.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public List<string> GetCurrentlyActiveEventQuests()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getCurrentlyActiveEventQuestsSubscriber == null)
|
|
{
|
|
log.Warning("[QuestionableIPC] Cannot get active event quests - Questionable not available");
|
|
return new List<string>();
|
|
}
|
|
try
|
|
{
|
|
List<string> eventQuests = getCurrentlyActiveEventQuestsSubscriber.InvokeFunc();
|
|
log.Debug($"[QuestionableIPC] Retrieved {eventQuests?.Count ?? 0} active event quests");
|
|
return eventQuests ?? new List<string>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] Error getting active event quests: " + ex.Message);
|
|
return new List<string>();
|
|
}
|
|
}
|
|
|
|
public int GetAlliedSocietyRemainingAllowances()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAlliedSocietyRemainingAllowancesSubscriber == null)
|
|
{
|
|
log.Debug("[AlliedSociety] Cannot get remaining allowances - Questionable not available");
|
|
return 12;
|
|
}
|
|
try
|
|
{
|
|
int result = getAlliedSocietyRemainingAllowancesSubscriber.InvokeFunc();
|
|
log.Debug($"[AlliedSociety] Remaining allowances: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[AlliedSociety] Error getting remaining allowances: " + ex.Message);
|
|
return 12;
|
|
}
|
|
}
|
|
|
|
public List<string> GetAlliedSocietyAvailableQuestIds(byte societyId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAlliedSocietyAvailableQuestIdsSubscriber == null)
|
|
{
|
|
log.Debug($"[AlliedSociety] Cannot get quest IDs for society {societyId} - Questionable not available");
|
|
return new List<string>();
|
|
}
|
|
try
|
|
{
|
|
List<string> result = getAlliedSocietyAvailableQuestIdsSubscriber.InvokeFunc(societyId);
|
|
log.Debug($"[AlliedSociety] Society {societyId} has {result?.Count ?? 0} available quests");
|
|
return result ?? new List<string>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"[AlliedSociety] Error getting quest IDs for society {societyId}: {ex.Message}");
|
|
return new List<string>();
|
|
}
|
|
}
|
|
|
|
public Dictionary<byte, int> GetAlliedSocietyAllAvailableQuestCounts()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAlliedSocietyAllAvailableQuestCountsSubscriber == null)
|
|
{
|
|
log.Debug("[AlliedSociety] Cannot get quest counts - Questionable not available");
|
|
return new Dictionary<byte, int>();
|
|
}
|
|
try
|
|
{
|
|
Dictionary<byte, int> result = getAlliedSocietyAllAvailableQuestCountsSubscriber.InvokeFunc();
|
|
log.Debug($"[AlliedSociety] Found {result?.Count ?? 0} societies with available quests");
|
|
return result ?? new Dictionary<byte, int>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[AlliedSociety] Error getting quest counts: " + ex.Message);
|
|
return new Dictionary<byte, int>();
|
|
}
|
|
}
|
|
|
|
public bool GetAlliedSocietyIsMaxRank(byte societyId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAlliedSocietyIsMaxRankSubscriber == null)
|
|
{
|
|
log.Debug($"[AlliedSociety] Cannot check max rank for society {societyId} - Questionable not available");
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = getAlliedSocietyIsMaxRankSubscriber.InvokeFunc(societyId);
|
|
log.Debug($"[AlliedSociety] Society {societyId} max rank: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"[AlliedSociety] Error checking max rank for society {societyId}: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public int GetAlliedSocietyCurrentRank(byte societyId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAlliedSocietyCurrentRankSubscriber == null)
|
|
{
|
|
log.Debug($"[AlliedSociety] Cannot get rank for society {societyId} - Questionable not available");
|
|
return -1;
|
|
}
|
|
try
|
|
{
|
|
int result = getAlliedSocietyCurrentRankSubscriber.InvokeFunc(societyId);
|
|
log.Debug($"[AlliedSociety] Society {societyId} current rank: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"[AlliedSociety] Error getting rank for society {societyId}: {ex.Message}");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public List<byte> GetAlliedSocietiesWithAvailableQuests()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAlliedSocietiesWithAvailableQuestsSubscriber == null)
|
|
{
|
|
log.Debug("[AlliedSociety] Cannot get societies with quests - Questionable not available");
|
|
return new List<byte>();
|
|
}
|
|
try
|
|
{
|
|
List<byte> result = getAlliedSocietiesWithAvailableQuestsSubscriber.InvokeFunc();
|
|
log.Debug($"[AlliedSociety] Found {result?.Count ?? 0} societies with available quests");
|
|
return result ?? new List<byte>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[AlliedSociety] Error getting societies with quests: " + ex.Message);
|
|
return new List<byte>();
|
|
}
|
|
}
|
|
|
|
public int AddAlliedSocietyOptimalQuests(byte societyId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || addAlliedSocietyOptimalQuestsSubscriber == null)
|
|
{
|
|
log.Debug($"[AlliedSociety] Cannot add optimal quests for society {societyId} - Questionable not available");
|
|
return 0;
|
|
}
|
|
try
|
|
{
|
|
int result = addAlliedSocietyOptimalQuestsSubscriber.InvokeFunc(societyId);
|
|
log.Information($"[AlliedSociety] Added {result} optimal quests for society {societyId}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"[AlliedSociety] Error adding optimal quests for society {societyId}: {ex.Message}");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public List<string> GetAlliedSocietyOptimalQuests(byte societyId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAlliedSocietyOptimalQuestsSubscriber == null)
|
|
{
|
|
log.Debug($"[AlliedSociety] Cannot get optimal quests for society {societyId} - Questionable not available");
|
|
return new List<string>();
|
|
}
|
|
try
|
|
{
|
|
List<string> result = getAlliedSocietyOptimalQuestsSubscriber.InvokeFunc(societyId);
|
|
log.Debug($"[AlliedSociety] Found {result?.Count ?? 0} optimal quests for society {societyId}");
|
|
return result ?? new List<string>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error($"[AlliedSociety] Error getting optimal quests for society {societyId}: {ex.Message}");
|
|
return new List<string>();
|
|
}
|
|
}
|
|
|
|
public TimeSpan GetAlliedSocietyTimeUntilReset()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAlliedSocietyTimeUntilResetSubscriber == null)
|
|
{
|
|
log.Debug("[AlliedSociety] Cannot get time until reset - Questionable not available");
|
|
return TimeSpan.Zero;
|
|
}
|
|
try
|
|
{
|
|
TimeSpan timeSpan = TimeSpan.FromTicks(getAlliedSocietyTimeUntilResetSubscriber.InvokeFunc());
|
|
log.Debug($"[AlliedSociety] Time until reset: {timeSpan}");
|
|
return timeSpan;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[AlliedSociety] Error getting time until reset: " + ex.Message);
|
|
return TimeSpan.Zero;
|
|
}
|
|
}
|
|
|
|
public bool GetStopConditionsEnabled()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getStopConditionsEnabledSubscriber == null)
|
|
{
|
|
log.Debug("[StopCondition] Cannot get stop conditions enabled - Questionable not available");
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = getStopConditionsEnabledSubscriber.InvokeFunc();
|
|
log.Debug($"[StopCondition] Stop conditions enabled: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[StopCondition] Error getting stop conditions enabled: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public List<string> GetStopQuestList()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getStopQuestListSubscriber == null)
|
|
{
|
|
return new List<string>();
|
|
}
|
|
try
|
|
{
|
|
List<string> result = getStopQuestListSubscriber.InvokeFunc();
|
|
log.Debug($"[StopCondition] Found {result?.Count ?? 0} stop quests");
|
|
return result ?? new List<string>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[StopCondition] Error getting stop quest list: " + ex.Message);
|
|
return new List<string>();
|
|
}
|
|
}
|
|
|
|
public StopConditionData? GetLevelStopCondition()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getLevelStopConditionSubscriber == null)
|
|
{
|
|
log.Debug("[StopCondition] Cannot get level stop condition - Questionable not available");
|
|
return null;
|
|
}
|
|
try
|
|
{
|
|
return getLevelStopConditionSubscriber.InvokeFunc();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[StopCondition] Error getting level stop condition: " + ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public StopConditionData? GetSequenceStopCondition()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getSequenceStopConditionSubscriber == null)
|
|
{
|
|
log.Debug("[StopCondition] Cannot get sequence stop condition - Questionable not available");
|
|
return null;
|
|
}
|
|
try
|
|
{
|
|
StopConditionData result = getSequenceStopConditionSubscriber.InvokeFunc();
|
|
log.Debug($"[StopCondition] Sequence stop condition - Enabled: {result?.Enabled}, Target: {result?.TargetValue}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[StopCondition] Error getting sequence stop condition: " + ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public object? GetQuestSequenceStopCondition(string questId, uint sequence, int step)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getQuestSequenceStopConditionSubscriber == null)
|
|
{
|
|
log.Warning("[StopCondition] Cannot get quest sequence stop condition - Questionable not available");
|
|
return null;
|
|
}
|
|
try
|
|
{
|
|
object result = getQuestSequenceStopConditionSubscriber.InvokeFunc(questId, sequence, step);
|
|
if (result == null)
|
|
{
|
|
log.Information($"[StopCondition] No quest sequence stop condition found for {questId} at {sequence}-{step}");
|
|
}
|
|
else
|
|
{
|
|
log.Information($"[StopCondition] Quest sequence stop condition for {questId} at {sequence}-{step}: {result}");
|
|
}
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[StopCondition] Error getting quest sequence stop condition: " + ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public bool RemoveQuestSequenceStopCondition(string questId)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || removeQuestSequenceStopConditionSubscriber == null)
|
|
{
|
|
log.Warning("[StopCondition] Cannot remove quest sequence stop condition - Questionable not available");
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool num = removeQuestSequenceStopConditionSubscriber.InvokeFunc(questId);
|
|
if (num)
|
|
{
|
|
log.Information("[StopCondition] ✓ Removed quest sequence stop condition for " + questId);
|
|
}
|
|
else
|
|
{
|
|
log.Warning("[StopCondition] ✗ No quest sequence stop condition to remove for " + questId + " (or removal failed)");
|
|
}
|
|
return num;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[StopCondition] Error removing quest sequence stop condition: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public Dictionary<string, object> GetAllQuestSequenceStopConditions()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getAllQuestSequenceStopConditionsSubscriber == null)
|
|
{
|
|
return new Dictionary<string, object>();
|
|
}
|
|
try
|
|
{
|
|
Dictionary<string, object> result = getAllQuestSequenceStopConditionsSubscriber.InvokeFunc();
|
|
if (result == null || result.Count == 0)
|
|
{
|
|
log.Information("[StopCondition] No quest sequence stop conditions configured (empty or null result)");
|
|
return new Dictionary<string, object>();
|
|
}
|
|
log.Information($"[StopCondition] Found {result.Count} quest sequence stop condition(s)");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[StopCondition] Error getting all quest sequence stop conditions: " + ex.Message);
|
|
return new Dictionary<string, object>();
|
|
}
|
|
}
|
|
|
|
public int GetDefaultDutyMode()
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || getDefaultDutyModeSubscriber == null)
|
|
{
|
|
log.Debug("[QuestionableIPC] Cannot get default duty mode - Questionable not available");
|
|
return 0;
|
|
}
|
|
try
|
|
{
|
|
int result = getDefaultDutyModeSubscriber.InvokeFunc();
|
|
log.Debug($"[QuestionableIPC] Default Duty Mode: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] GetDefaultDutyMode failed: " + ex.Message);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public bool SetDefaultDutyMode(int dutyMode)
|
|
{
|
|
TryEnsureAvailable();
|
|
if (!IsAvailable || setDefaultDutyModeSubscriber == null)
|
|
{
|
|
log.Debug("[QuestionableIPC] Cannot set default duty mode - Questionable not available");
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
bool result = setDefaultDutyModeSubscriber.InvokeFunc(dutyMode);
|
|
log.Information($"[QuestionableIPC] Set Default Duty Mode to {dutyMode}: {result}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("[QuestionableIPC] SetDefaultDutyMode failed: " + ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool ValidateFeatureCompatibility()
|
|
{
|
|
if (!IsAvailable)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
if (getAllQuestSequenceStopConditionsSubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (getLevelStopConditionSubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (getAlliedSocietyOptimalQuestsSubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (getDefaultDutyModeSubscriber == null)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
getAllQuestSequenceStopConditionsSubscriber.InvokeFunc();
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
IsAvailable = false;
|
|
}
|
|
}
|