questStates done
This commit is contained in:
parent
445ae1387c
commit
568df4c7fe
17 changed files with 1012 additions and 40 deletions
|
|
@ -20,6 +20,9 @@ public sealed class UIElements : RemoteObject
|
|||
|
||||
private readonly MsvcStringReader _strings;
|
||||
|
||||
/// <summary>Optional lookup for resolving quest state IDs to human-readable text.</summary>
|
||||
public QuestStateLookup? QuestStateLookup { get; set; }
|
||||
|
||||
public UIElements(MemoryContext ctx, MsvcStringReader strings) : base(ctx)
|
||||
{
|
||||
_strings = strings;
|
||||
|
|
@ -382,7 +385,11 @@ public sealed class UIElements : RemoteObject
|
|||
displayName = _strings.ReadNullTermWString(namePtr);
|
||||
}
|
||||
|
||||
var isTracked = trackedMap.TryGetValue(questPtr, out var objectiveText);
|
||||
var isTracked = trackedMap.ContainsKey(questPtr);
|
||||
|
||||
string? stateText = null;
|
||||
if (QuestStateLookup is not null && questPtr != 0 && stateId > 0)
|
||||
QuestStateLookup.TryGetStateText(questPtr, stateId, out stateText);
|
||||
|
||||
result.Add(new QuestLinkedEntry
|
||||
{
|
||||
|
|
@ -390,8 +397,8 @@ public sealed class UIElements : RemoteObject
|
|||
DisplayName = displayName,
|
||||
Act = act,
|
||||
StateId = stateId,
|
||||
StateText = stateText,
|
||||
IsTracked = isTracked,
|
||||
ObjectiveText = objectiveText,
|
||||
QuestDatPtr = questPtr,
|
||||
});
|
||||
|
||||
|
|
@ -402,8 +409,9 @@ public sealed class UIElements : RemoteObject
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Walks the tracked-quests linked list. Builds a dict of QuestDatPtr → ObjectiveText.
|
||||
/// Node+0x20 is a pointer to a runtime state object; text is at stateObj+QuestStateObjTextOffset (std::wstring).
|
||||
/// Walks the tracked-quests linked list. Builds a dict of QuestDatPtr → null.
|
||||
/// Tracked status is used; objective text is not available from runtime memory
|
||||
/// (stateObj contains quest flag arrays, not display text).
|
||||
/// </summary>
|
||||
private void TraverseTrackedQuests(nint headPtr, Dictionary<nint, string?> trackedMap)
|
||||
{
|
||||
|
|
@ -434,35 +442,15 @@ public sealed class UIElements : RemoteObject
|
|||
}
|
||||
|
||||
var questPtr = (nint)BitConverter.ToInt64(nodeData, offsets.QuestNodeQuestPtrOffset);
|
||||
string? objectiveText = null;
|
||||
|
||||
// +0x20 in tracked list is a pointer to the quest state runtime object
|
||||
var stateObjPtr = (nint)BitConverter.ToInt64(nodeData, 0x20);
|
||||
if (stateObjPtr != 0 && ((ulong)stateObjPtr >> 32) is > 0 and < 0x7FFF)
|
||||
{
|
||||
// Read std::wstring at stateObj + QuestStateObjTextOffset
|
||||
objectiveText = ParseWStringFromMemory(stateObjPtr + offsets.QuestStateObjTextOffset);
|
||||
}
|
||||
|
||||
if (questPtr != 0)
|
||||
trackedMap[questPtr] = objectiveText;
|
||||
trackedMap[questPtr] = null;
|
||||
|
||||
count++;
|
||||
walk = next;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an inline MSVC std::wstring from a process memory address.
|
||||
/// Same layout as UIElement strings: Buffer(8) + Reserved(8) + Length(4) + pad(4) + Capacity(4) + pad(4).
|
||||
/// </summary>
|
||||
private string? ParseWStringFromMemory(nint addr)
|
||||
{
|
||||
var strData = Ctx.Memory.ReadBytes(addr, 32);
|
||||
if (strData is null || strData.Length < 28) return null;
|
||||
return ParseWStringFromBuffer(strData, 0);
|
||||
}
|
||||
|
||||
private void EnqueueChildren(Queue<nint> queue, HashSet<nint> visited, nint parentAddr)
|
||||
{
|
||||
var mem = Ctx.Memory;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue