forked from aly/qstbak
qstcompanion v1.0.1
This commit is contained in:
parent
3e10cbbbf2
commit
44c67ab71b
79 changed files with 21148 additions and 0 deletions
|
|
@ -0,0 +1,479 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
|
||||
namespace QuestionableCompanion.Data;
|
||||
|
||||
public static class MSQExpansionData
|
||||
{
|
||||
public enum Expansion
|
||||
{
|
||||
ARealmReborn,
|
||||
Heavensward,
|
||||
Stormblood,
|
||||
Shadowbringers,
|
||||
Endwalker,
|
||||
Dawntrail
|
||||
}
|
||||
|
||||
private static readonly Dictionary<Expansion, HashSet<uint>> ExpansionQuests = new Dictionary<Expansion, HashSet<uint>>
|
||||
{
|
||||
{
|
||||
Expansion.ARealmReborn,
|
||||
new HashSet<uint>()
|
||||
},
|
||||
{
|
||||
Expansion.Heavensward,
|
||||
new HashSet<uint>()
|
||||
},
|
||||
{
|
||||
Expansion.Stormblood,
|
||||
new HashSet<uint>()
|
||||
},
|
||||
{
|
||||
Expansion.Shadowbringers,
|
||||
new HashSet<uint>()
|
||||
},
|
||||
{
|
||||
Expansion.Endwalker,
|
||||
new HashSet<uint>()
|
||||
},
|
||||
{
|
||||
Expansion.Dawntrail,
|
||||
new HashSet<uint>()
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly Dictionary<Expansion, int> ExpectedQuestCounts = new Dictionary<Expansion, int>
|
||||
{
|
||||
{
|
||||
Expansion.ARealmReborn,
|
||||
200
|
||||
},
|
||||
{
|
||||
Expansion.Heavensward,
|
||||
100
|
||||
},
|
||||
{
|
||||
Expansion.Stormblood,
|
||||
100
|
||||
},
|
||||
{
|
||||
Expansion.Shadowbringers,
|
||||
100
|
||||
},
|
||||
{
|
||||
Expansion.Endwalker,
|
||||
100
|
||||
},
|
||||
{
|
||||
Expansion.Dawntrail,
|
||||
100
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly Dictionary<Expansion, string> ExpansionNames = new Dictionary<Expansion, string>
|
||||
{
|
||||
{
|
||||
Expansion.ARealmReborn,
|
||||
"A Realm Reborn"
|
||||
},
|
||||
{
|
||||
Expansion.Heavensward,
|
||||
"Heavensward"
|
||||
},
|
||||
{
|
||||
Expansion.Stormblood,
|
||||
"Stormblood"
|
||||
},
|
||||
{
|
||||
Expansion.Shadowbringers,
|
||||
"Shadowbringers"
|
||||
},
|
||||
{
|
||||
Expansion.Endwalker,
|
||||
"Endwalker"
|
||||
},
|
||||
{
|
||||
Expansion.Dawntrail,
|
||||
"Dawntrail"
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly Dictionary<Expansion, string> ExpansionShortNames = new Dictionary<Expansion, string>
|
||||
{
|
||||
{
|
||||
Expansion.ARealmReborn,
|
||||
"ARR"
|
||||
},
|
||||
{
|
||||
Expansion.Heavensward,
|
||||
"HW"
|
||||
},
|
||||
{
|
||||
Expansion.Stormblood,
|
||||
"SB"
|
||||
},
|
||||
{
|
||||
Expansion.Shadowbringers,
|
||||
"ShB"
|
||||
},
|
||||
{
|
||||
Expansion.Endwalker,
|
||||
"EW"
|
||||
},
|
||||
{
|
||||
Expansion.Dawntrail,
|
||||
"DT"
|
||||
}
|
||||
};
|
||||
|
||||
public static void RegisterQuest(uint questId, Expansion expansion)
|
||||
{
|
||||
if (ExpansionQuests.TryGetValue(expansion, out HashSet<uint> quests))
|
||||
{
|
||||
quests.Add(questId);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearQuests()
|
||||
{
|
||||
foreach (HashSet<uint> value in ExpansionQuests.Values)
|
||||
{
|
||||
value.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static Expansion GetExpansionForQuest(uint questId)
|
||||
{
|
||||
foreach (var (expansion2, hashSet2) in ExpansionQuests)
|
||||
{
|
||||
if (hashSet2.Contains(questId))
|
||||
{
|
||||
return expansion2;
|
||||
}
|
||||
}
|
||||
return Expansion.ARealmReborn;
|
||||
}
|
||||
|
||||
public static IReadOnlySet<uint> GetQuestsForExpansion(Expansion expansion)
|
||||
{
|
||||
if (!ExpansionQuests.TryGetValue(expansion, out HashSet<uint> quests))
|
||||
{
|
||||
return new HashSet<uint>();
|
||||
}
|
||||
return quests;
|
||||
}
|
||||
|
||||
public static int GetExpectedQuestCount(Expansion expansion)
|
||||
{
|
||||
if (!ExpectedQuestCounts.TryGetValue(expansion, out var count))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static string GetExpansionName(Expansion expansion)
|
||||
{
|
||||
if (!ExpansionNames.TryGetValue(expansion, out string name))
|
||||
{
|
||||
return "Unknown";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static string GetExpansionShortName(Expansion expansion)
|
||||
{
|
||||
if (!ExpansionShortNames.TryGetValue(expansion, out string name))
|
||||
{
|
||||
return "???";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static IEnumerable<Expansion> GetAllExpansions()
|
||||
{
|
||||
return from e in Enum.GetValues<Expansion>()
|
||||
orderby (int)e
|
||||
select e;
|
||||
}
|
||||
|
||||
public static int GetCompletedQuestCountForExpansion(IEnumerable<uint> completedQuestIds, Expansion expansion)
|
||||
{
|
||||
IReadOnlySet<uint> expansionQuests = GetQuestsForExpansion(expansion);
|
||||
return completedQuestIds.Count((uint qId) => expansionQuests.Contains(qId));
|
||||
}
|
||||
|
||||
public unsafe static (Expansion expansion, string debugInfo) GetCurrentExpansionFromGameWithDebug()
|
||||
{
|
||||
StringBuilder debug = new StringBuilder();
|
||||
debug.AppendLine("=== AGENT SCENARIO TREE DEBUG ===");
|
||||
try
|
||||
{
|
||||
AgentScenarioTree* agentScenarioTree = AgentScenarioTree.Instance();
|
||||
StringBuilder stringBuilder = debug;
|
||||
StringBuilder stringBuilder2 = stringBuilder;
|
||||
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(30, 1, stringBuilder);
|
||||
handler.AppendLiteral("AgentScenarioTree.Instance(): ");
|
||||
handler.AppendFormatted((agentScenarioTree != null) ? "OK" : "NULL");
|
||||
stringBuilder2.AppendLine(ref handler);
|
||||
if (agentScenarioTree == null)
|
||||
{
|
||||
debug.AppendLine("ERROR: AgentScenarioTree is NULL!");
|
||||
return (expansion: Expansion.ARealmReborn, debugInfo: debug.ToString());
|
||||
}
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder3 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(25, 1, stringBuilder);
|
||||
handler.AppendLiteral("AgentScenarioTree->Data: ");
|
||||
handler.AppendFormatted((agentScenarioTree->Data != null) ? "OK" : "NULL");
|
||||
stringBuilder3.AppendLine(ref handler);
|
||||
if (agentScenarioTree->Data == null)
|
||||
{
|
||||
debug.AppendLine("ERROR: AgentScenarioTree->Data is NULL!");
|
||||
return (expansion: Expansion.ARealmReborn, debugInfo: debug.ToString());
|
||||
}
|
||||
ushort currentQuest = agentScenarioTree->Data->CurrentScenarioQuest;
|
||||
ushort completedQuest = agentScenarioTree->Data->CompleteScenarioQuest;
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder4 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(33, 2, stringBuilder);
|
||||
handler.AppendLiteral("CurrentScenarioQuest (raw): ");
|
||||
handler.AppendFormatted(currentQuest);
|
||||
handler.AppendLiteral(" (0x");
|
||||
handler.AppendFormatted(currentQuest, "X4");
|
||||
handler.AppendLiteral(")");
|
||||
stringBuilder4.AppendLine(ref handler);
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder5 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(34, 2, stringBuilder);
|
||||
handler.AppendLiteral("CompleteScenarioQuest (raw): ");
|
||||
handler.AppendFormatted(completedQuest);
|
||||
handler.AppendLiteral(" (0x");
|
||||
handler.AppendFormatted(completedQuest, "X4");
|
||||
handler.AppendLiteral(")");
|
||||
stringBuilder5.AppendLine(ref handler);
|
||||
ushort questToCheck = ((currentQuest != 0) ? currentQuest : completedQuest);
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder6 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(25, 2, stringBuilder);
|
||||
handler.AppendLiteral("Quest to check: ");
|
||||
handler.AppendFormatted(questToCheck);
|
||||
handler.AppendLiteral(" (using ");
|
||||
handler.AppendFormatted((currentQuest != 0) ? "Current" : "Completed");
|
||||
handler.AppendLiteral(")");
|
||||
stringBuilder6.AppendLine(ref handler);
|
||||
if (questToCheck == 0)
|
||||
{
|
||||
debug.AppendLine("WARNING: Both CurrentScenarioQuest and CompleteScenarioQuest are 0!");
|
||||
return (expansion: Expansion.ARealmReborn, debugInfo: debug.ToString());
|
||||
}
|
||||
uint questId = (uint)(questToCheck | 0x10000);
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder7 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(25, 2, stringBuilder);
|
||||
handler.AppendLiteral("Converted Quest ID: ");
|
||||
handler.AppendFormatted(questId);
|
||||
handler.AppendLiteral(" (0x");
|
||||
handler.AppendFormatted(questId, "X8");
|
||||
handler.AppendLiteral(")");
|
||||
stringBuilder7.AppendLine(ref handler);
|
||||
Expansion expansion = GetExpansionForQuest(questId);
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder8 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(22, 2, stringBuilder);
|
||||
handler.AppendLiteral("Expansion for Quest ");
|
||||
handler.AppendFormatted(questId);
|
||||
handler.AppendLiteral(": ");
|
||||
handler.AppendFormatted(GetExpansionName(expansion));
|
||||
stringBuilder8.AppendLine(ref handler);
|
||||
IReadOnlySet<uint> expansionQuests = GetQuestsForExpansion(expansion);
|
||||
bool isRegistered = expansionQuests.Contains(questId);
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder9 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(23, 3, stringBuilder);
|
||||
handler.AppendLiteral("Quest ");
|
||||
handler.AppendFormatted(questId);
|
||||
handler.AppendLiteral(" registered in ");
|
||||
handler.AppendFormatted(expansion);
|
||||
handler.AppendLiteral(": ");
|
||||
handler.AppendFormatted(isRegistered);
|
||||
stringBuilder9.AppendLine(ref handler);
|
||||
if (!isRegistered)
|
||||
{
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder10 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(48, 1, stringBuilder);
|
||||
handler.AppendLiteral("WARNING: Quest ");
|
||||
handler.AppendFormatted(questId);
|
||||
handler.AppendLiteral(" is NOT in our registered quests!");
|
||||
stringBuilder10.AppendLine(ref handler);
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder11 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(30, 2, stringBuilder);
|
||||
handler.AppendLiteral("Total registered quests for ");
|
||||
handler.AppendFormatted(expansion);
|
||||
handler.AppendLiteral(": ");
|
||||
handler.AppendFormatted(expansionQuests.Count);
|
||||
stringBuilder11.AppendLine(ref handler);
|
||||
foreach (Expansion exp in GetAllExpansions())
|
||||
{
|
||||
if (GetQuestsForExpansion(exp).Contains(questId))
|
||||
{
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder12 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(10, 1, stringBuilder);
|
||||
handler.AppendLiteral("FOUND in ");
|
||||
handler.AppendFormatted(exp);
|
||||
handler.AppendLiteral("!");
|
||||
stringBuilder12.AppendLine(ref handler);
|
||||
expansion = exp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder13 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(25, 1, stringBuilder);
|
||||
handler.AppendLiteral(">>> FINAL EXPANSION: ");
|
||||
handler.AppendFormatted(GetExpansionName(expansion));
|
||||
handler.AppendLiteral(" <<<");
|
||||
stringBuilder13.AppendLine(ref handler);
|
||||
return (expansion: expansion, debugInfo: debug.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StringBuilder stringBuilder = debug;
|
||||
StringBuilder stringBuilder14 = stringBuilder;
|
||||
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(11, 1, stringBuilder);
|
||||
handler.AppendLiteral("EXCEPTION: ");
|
||||
handler.AppendFormatted(ex.Message);
|
||||
stringBuilder14.AppendLine(ref handler);
|
||||
stringBuilder = debug;
|
||||
StringBuilder stringBuilder15 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(7, 1, stringBuilder);
|
||||
handler.AppendLiteral("Stack: ");
|
||||
handler.AppendFormatted(ex.StackTrace);
|
||||
stringBuilder15.AppendLine(ref handler);
|
||||
return (expansion: Expansion.ARealmReborn, debugInfo: debug.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static Expansion GetCurrentExpansionFromGame()
|
||||
{
|
||||
return GetCurrentExpansionFromGameWithDebug().expansion;
|
||||
}
|
||||
|
||||
public static Expansion GetCurrentExpansion(IEnumerable<uint> completedQuestIds)
|
||||
{
|
||||
List<uint> questList = completedQuestIds.ToList();
|
||||
if (questList.Count == 0)
|
||||
{
|
||||
return Expansion.ARealmReborn;
|
||||
}
|
||||
foreach (Expansion expansion in GetAllExpansions().Reverse().ToList())
|
||||
{
|
||||
IReadOnlySet<uint> expansionQuests = GetQuestsForExpansion(expansion);
|
||||
if (questList.Where((uint qId) => expansionQuests.Contains(qId)).ToList().Count > 0)
|
||||
{
|
||||
return expansion;
|
||||
}
|
||||
}
|
||||
return Expansion.ARealmReborn;
|
||||
}
|
||||
|
||||
public static string GetExpansionDetectionDebugInfo(IEnumerable<uint> completedQuestIds)
|
||||
{
|
||||
List<uint> questList = completedQuestIds.ToList();
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.AppendLine("=== EXPANSION DETECTION DEBUG ===");
|
||||
StringBuilder stringBuilder = result;
|
||||
StringBuilder stringBuilder2 = stringBuilder;
|
||||
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(24, 1, stringBuilder);
|
||||
handler.AppendLiteral("Total completed quests: ");
|
||||
handler.AppendFormatted(questList.Count);
|
||||
stringBuilder2.AppendLine(ref handler);
|
||||
result.AppendLine("");
|
||||
result.AppendLine("Checking expansions from highest to lowest:");
|
||||
result.AppendLine("");
|
||||
foreach (Expansion expansion in GetAllExpansions().Reverse())
|
||||
{
|
||||
IReadOnlySet<uint> expansionQuests = GetQuestsForExpansion(expansion);
|
||||
List<uint> completedInExpansion = questList.Where((uint qId) => expansionQuests.Contains(qId)).ToList();
|
||||
float percentage = ((expansionQuests.Count > 0) ? ((float)completedInExpansion.Count / (float)expansionQuests.Count * 100f) : 0f);
|
||||
stringBuilder = result;
|
||||
StringBuilder stringBuilder3 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(4, 2, stringBuilder);
|
||||
handler.AppendFormatted(GetExpansionName(expansion));
|
||||
handler.AppendLiteral(" (");
|
||||
handler.AppendFormatted(GetExpansionShortName(expansion));
|
||||
handler.AppendLiteral("):");
|
||||
stringBuilder3.AppendLine(ref handler);
|
||||
stringBuilder = result;
|
||||
StringBuilder stringBuilder4 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(28, 1, stringBuilder);
|
||||
handler.AppendLiteral(" - Total MSQ in expansion: ");
|
||||
handler.AppendFormatted(expansionQuests.Count);
|
||||
stringBuilder4.AppendLine(ref handler);
|
||||
stringBuilder = result;
|
||||
StringBuilder stringBuilder5 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(32, 2, stringBuilder);
|
||||
handler.AppendLiteral(" - Completed by character: ");
|
||||
handler.AppendFormatted(completedInExpansion.Count);
|
||||
handler.AppendLiteral(" (");
|
||||
handler.AppendFormatted(percentage, "F1");
|
||||
handler.AppendLiteral("%)");
|
||||
stringBuilder5.AppendLine(ref handler);
|
||||
if (completedInExpansion.Count > 0)
|
||||
{
|
||||
string samples = string.Join(", ", completedInExpansion.OrderByDescending((uint x) => x).Take(5));
|
||||
stringBuilder = result;
|
||||
StringBuilder stringBuilder6 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(22, 1, stringBuilder);
|
||||
handler.AppendLiteral(" - Sample Quest IDs: ");
|
||||
handler.AppendFormatted(samples);
|
||||
stringBuilder6.AppendLine(ref handler);
|
||||
result.AppendLine(" >>> HAS COMPLETED QUESTS - WOULD SELECT THIS EXPANSION <<<");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendLine(" - No quests completed in this expansion");
|
||||
}
|
||||
result.AppendLine("");
|
||||
}
|
||||
Expansion currentExpansion = GetCurrentExpansion(questList);
|
||||
result.AppendLine("===========================================");
|
||||
stringBuilder = result;
|
||||
StringBuilder stringBuilder7 = stringBuilder;
|
||||
handler = new StringBuilder.AppendInterpolatedStringHandler(34, 1, stringBuilder);
|
||||
handler.AppendLiteral(">>> FINAL DETECTED EXPANSION: ");
|
||||
handler.AppendFormatted(GetExpansionName(currentExpansion));
|
||||
handler.AppendLiteral(" <<<");
|
||||
stringBuilder7.AppendLine(ref handler);
|
||||
result.AppendLine("===========================================");
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
public static ExpansionProgress GetExpansionProgress(IEnumerable<uint> completedQuestIds, Expansion expansion)
|
||||
{
|
||||
int completed = GetCompletedQuestCountForExpansion(completedQuestIds, expansion);
|
||||
int expected = GetExpectedQuestCount(expansion);
|
||||
return new ExpansionProgress
|
||||
{
|
||||
Expansion = expansion,
|
||||
CompletedCount = completed,
|
||||
ExpectedCount = expected,
|
||||
Percentage = ((expected > 0) ? ((float)completed / (float)expected * 100f) : 0f),
|
||||
IsComplete = (completed >= expected)
|
||||
};
|
||||
}
|
||||
|
||||
public static List<ExpansionProgress> GetAllExpansionProgress(IEnumerable<uint> completedQuestIds)
|
||||
{
|
||||
return (from exp in GetAllExpansions()
|
||||
select GetExpansionProgress(completedQuestIds, exp)).ToList();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue