7.1
This commit is contained in:
parent
8f7b0a6ffd
commit
7a3acf9da6
@ -1,7 +1,7 @@
|
|||||||
using Lumina.Excel.GeneratedSheets;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace QuestMap
|
namespace QuestMap
|
||||||
{
|
{
|
||||||
|
28
QuestMap/IQuestInfo.cs
Normal file
28
QuestMap/IQuestInfo.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
|
namespace QuestMap;
|
||||||
|
|
||||||
|
public interface IQuestInfo
|
||||||
|
{
|
||||||
|
public Quest Quest { get; }
|
||||||
|
public uint RowId { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public IEnumerable<Quest> PreviousQuests();
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class SheetQuestInfo(Quest quest) : IQuestInfo
|
||||||
|
{
|
||||||
|
public Quest Quest => quest;
|
||||||
|
public uint RowId => quest.RowId;
|
||||||
|
public string Name => quest.Name.ToString();
|
||||||
|
public IEnumerable<Quest> PreviousQuests() => quest.PreviousQuests();
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ConsolidatedQuestInfo(IQuestInfo baseQuest, string name) : IQuestInfo
|
||||||
|
{
|
||||||
|
public Quest Quest => baseQuest.Quest;
|
||||||
|
public uint RowId => baseQuest.RowId;
|
||||||
|
public string Name => name;
|
||||||
|
public IEnumerable<Quest> PreviousQuests() => baseQuest.PreviousQuests();
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace QuestMap {
|
namespace QuestMap {
|
||||||
internal class Node<T> {
|
internal class Node<T> where T : IQuestInfo {
|
||||||
internal uint Id { get; }
|
internal uint Id { get; }
|
||||||
internal List<Node<T>> Parents { get; set; }
|
internal List<Node<T>> Parents { get; set; }
|
||||||
internal T Value { get; set; }
|
internal T Value { get; set; }
|
||||||
@ -101,16 +101,16 @@ namespace QuestMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static (List<Node<Quest>>, Dictionary<uint, Node<Quest>>) BuildTree(Dictionary<uint, Quest> layouts) {
|
internal static (List<Node<IQuestInfo>>, Dictionary<uint, Node<IQuestInfo>>) BuildTree(Dictionary<uint, IQuestInfo> layouts) {
|
||||||
var lookup = new Dictionary<uint, Node<Quest>>();
|
var lookup = new Dictionary<uint, Node<IQuestInfo>>();
|
||||||
var rootNodes = new List<Node<Quest>>();
|
var rootNodes = new List<Node<IQuestInfo>>();
|
||||||
var allNodes = new Dictionary<uint, Node<Quest>>();
|
var allNodes = new Dictionary<uint, Node<IQuestInfo>>();
|
||||||
|
|
||||||
foreach (var item in layouts) {
|
foreach (var item in layouts) {
|
||||||
if (lookup.TryGetValue(item.Key, out var ourNode)) {
|
if (lookup.TryGetValue(item.Key, out var ourNode)) {
|
||||||
ourNode.Value = item.Value;
|
ourNode.Value = item.Value;
|
||||||
} else {
|
} else {
|
||||||
ourNode = new Node<Quest>([], item.Key, item.Value);
|
ourNode = new Node<IQuestInfo>([], item.Key, item.Value);
|
||||||
lookup[item.Key] = ourNode;
|
lookup[item.Key] = ourNode;
|
||||||
allNodes[item.Key] = ourNode;
|
allNodes[item.Key] = ourNode;
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ namespace QuestMap {
|
|||||||
foreach (var prev in previous) {
|
foreach (var prev in previous) {
|
||||||
if (!lookup.TryGetValue(prev.RowId, out var parentNode)) {
|
if (!lookup.TryGetValue(prev.RowId, out var parentNode)) {
|
||||||
// create preliminary parent
|
// create preliminary parent
|
||||||
parentNode = new Node<Quest>(prev.RowId);
|
parentNode = new Node<IQuestInfo>(prev.RowId);
|
||||||
lookup[prev.RowId] = parentNode;
|
lookup[prev.RowId] = parentNode;
|
||||||
allNodes[prev.RowId] = parentNode;
|
allNodes[prev.RowId] = parentNode;
|
||||||
}
|
}
|
||||||
@ -138,7 +138,8 @@ namespace QuestMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal static class NodeExt {
|
internal static class NodeExt {
|
||||||
internal static Node<T>? Find<T>(this IEnumerable<Node<T>> nodes, uint id) {
|
internal static Node<T>? Find<T>(this IEnumerable<Node<T>> nodes, uint id)
|
||||||
|
where T : IQuestInfo {
|
||||||
foreach (var node in nodes) {
|
foreach (var node in nodes) {
|
||||||
var found = node.Find(id);
|
var found = node.Find(id);
|
||||||
|
|
||||||
@ -152,7 +153,7 @@ namespace QuestMap {
|
|||||||
|
|
||||||
internal static IEnumerable<Quest> PreviousQuests(this Quest quest) {
|
internal static IEnumerable<Quest> PreviousQuests(this Quest quest) {
|
||||||
foreach (var previous in quest.PreviousQuest) {
|
foreach (var previous in quest.PreviousQuest) {
|
||||||
if (previous != null && previous.Row != 0) {
|
if (previous.RowId != 0) {
|
||||||
yield return previous.Value!;
|
yield return previous.Value!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,14 @@ using Dalamud.Game.Text.SeStringHandling.Payloads;
|
|||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Textures;
|
using Dalamud.Interface.Textures;
|
||||||
using Dalamud.Interface.Textures.TextureWraps;
|
using Dalamud.Interface.Textures.TextureWraps;
|
||||||
|
using Dalamud.Utility;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Data;
|
using Lumina.Data;
|
||||||
using Lumina.Excel;
|
using Lumina.Excel;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
using Lumina.Text.ReadOnly;
|
||||||
using Microsoft.Msagl.Core.Geometry;
|
using Microsoft.Msagl.Core.Geometry;
|
||||||
using Microsoft.Msagl.Core.Geometry.Curves;
|
using Microsoft.Msagl.Core.Geometry.Curves;
|
||||||
using Microsoft.Msagl.Core.Layout;
|
using Microsoft.Msagl.Core.Layout;
|
||||||
@ -88,7 +90,7 @@ namespace QuestMap {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.Plugin.Config.ShowSeasonal && quest.Festival.Row != 0) {
|
if (!this.Plugin.Config.ShowSeasonal && quest.Festival.RowId != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +115,7 @@ namespace QuestMap {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.All(item => item.ItemUICategory.Row != 81)) {
|
if (items.All(item => item.ItemUICategory.RowId != 81)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,7 +156,7 @@ namespace QuestMap {
|
|||||||
var allItems = this.Plugin.Config.ItemVis != Visibility.Hidden;
|
var allItems = this.Plugin.Config.ItemVis != Visibility.Hidden;
|
||||||
var anyItemVisible = allItems || this.Plugin.Config.MinionVis != Visibility.Hidden;
|
var anyItemVisible = allItems || this.Plugin.Config.MinionVis != Visibility.Hidden;
|
||||||
if (anyItemVisible && this.Plugin.Quests.ItemRewards.TryGetValue(quest.RowId, out var items)) {
|
if (anyItemVisible && this.Plugin.Quests.ItemRewards.TryGetValue(quest.RowId, out var items)) {
|
||||||
var toShow = items.Where(item => allItems || item.ItemUICategory.Row == 81);
|
var toShow = items.Where(item => allItems || item.ItemUICategory.RowId == 81);
|
||||||
drawItems.AddRange(toShow.Select(item => (quest, true, $"{this.Convert(item.Name)}##item-{quest.RowId}-{item.RowId}")));
|
drawItems.AddRange(toShow.Select(item => (quest, true, $"{this.Convert(item.Name)}##item-{quest.RowId}-{item.RowId}")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +302,7 @@ namespace QuestMap {
|
|||||||
ImGui.PushStyleColor(ImGuiCol.Text, disabled);
|
ImGui.PushStyleColor(ImGuiCol.Text, disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = ImGui.Selectable(name, this.Quest == quest);
|
var ret = ImGui.Selectable(name, this.Quest?.RowId == quest.RowId);
|
||||||
|
|
||||||
if (completed) {
|
if (completed) {
|
||||||
ImGui.PopStyleColor();
|
ImGui.PopStyleColor();
|
||||||
@ -352,7 +354,7 @@ namespace QuestMap {
|
|||||||
if (this._relayout && this.Quest != null) {
|
if (this._relayout && this.Quest != null) {
|
||||||
this.Graph = null;
|
this.Graph = null;
|
||||||
this.CancellationTokenSource?.Cancel();
|
this.CancellationTokenSource?.Cancel();
|
||||||
this.CancellationTokenSource = this.Plugin.Quests.StartGraphRecalculation(this.Quest);
|
this.CancellationTokenSource = this.Plugin.Quests.StartGraphRecalculation(this.Quest.Value);
|
||||||
this._relayout = false;
|
this._relayout = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,14 +365,14 @@ namespace QuestMap {
|
|||||||
var remove = 0u;
|
var remove = 0u;
|
||||||
|
|
||||||
foreach (var id in this.InfoWindows) {
|
foreach (var id in this.InfoWindows) {
|
||||||
var quest = this.Plugin.DataManager.GetExcelSheet<Quest>()!.GetRow(id);
|
var quest = this.Plugin.DataManager.GetExcelSheet<Quest>()!.GetRowOrDefault(id);
|
||||||
if (quest == null)
|
if (quest == null)
|
||||||
{
|
{
|
||||||
remove = id;
|
remove = id;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.DrawInfoWindow(quest)) {
|
if (this.DrawInfoWindow(quest.Value)) {
|
||||||
remove = id;
|
remove = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -390,7 +392,7 @@ namespace QuestMap {
|
|||||||
|
|
||||||
var completed = QuestManager.IsQuestComplete(quest.RowId);
|
var completed = QuestManager.IsQuestComplete(quest.RowId);
|
||||||
|
|
||||||
ImGui.TextUnformatted($"Level: {quest.ClassJobLevel0}");
|
ImGui.TextUnformatted($"Level: {quest.ClassJobLevel[0]}");
|
||||||
|
|
||||||
if (completed) {
|
if (completed) {
|
||||||
ImGui.PushFont(UiBuilder.IconFont);
|
ImGui.PushFont(UiBuilder.IconFont);
|
||||||
@ -416,10 +418,10 @@ namespace QuestMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var rewards = new List<string>();
|
var rewards = new List<string>();
|
||||||
var paramGrow = this.Plugin.DataManager.GetExcelSheet<ParamGrow>()!.GetRow(quest.ClassJobLevel0);
|
var paramGrow = this.Plugin.DataManager.GetExcelSheet<ParamGrow>()!.GetRowOrDefault(quest.ClassJobLevel[0]);
|
||||||
var xp = 0;
|
var xp = 0;
|
||||||
if (paramGrow != null) {
|
if (paramGrow != null) {
|
||||||
xp = quest.ExpFactor * paramGrow.ScaledQuestXP * paramGrow.QuestExpModifier / 100;
|
xp = quest.ExpFactor * paramGrow.Value.ScaledQuestXP * paramGrow.Value.QuestExpModifier / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xp > 0) {
|
if (xp > 0) {
|
||||||
@ -486,16 +488,16 @@ namespace QuestMap {
|
|||||||
additionalRewards.Add((this.Convert(job.Name).ToString(), 62000 + job.RowId, 1));
|
additionalRewards.Add((this.Convert(job.Name).ToString(), 62000 + job.RowId, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < quest.ItemCatalyst.Length; i++) {
|
for (var i = 0; i < quest.ItemCatalyst.Count; i++) {
|
||||||
var catalyst = quest.ItemCatalyst[i];
|
var catalyst = quest.ItemCatalyst[i];
|
||||||
var amount = quest.ItemCountCatalyst[i];
|
var amount = quest.ItemCountCatalyst[i];
|
||||||
|
|
||||||
if (catalyst.Row != 0) {
|
if (catalyst.RowId != 0) {
|
||||||
additionalRewards.Add((this.Convert(catalyst.Value!.Name), catalyst.Value.Icon, amount));
|
additionalRewards.Add((this.Convert(catalyst.Value!.Name), catalyst.Value.Icon, amount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var generalAction in quest.GeneralActionReward.Where(row => row.Row != 0)) {
|
foreach (var generalAction in quest.GeneralActionReward.Where(row => row.RowId != 0)) {
|
||||||
additionalRewards.Add((this.Convert(generalAction.Value!.Name), (uint) generalAction.Value.Icon, 1));
|
additionalRewards.Add((this.Convert(generalAction.Value!.Name), (uint) generalAction.Value.Icon, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,34 +509,34 @@ namespace QuestMap {
|
|||||||
additionalRewards.Add((this.Convert(emote.Name), emote.Icon, 1));
|
additionalRewards.Add((this.Convert(emote.Name), emote.Icon, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quest.OtherReward.Row != 0) {
|
if (quest.OtherReward.RowId != 0) {
|
||||||
additionalRewards.Add((this.Convert(quest.OtherReward.Value!.Name), quest.OtherReward.Value.Icon, 1));
|
additionalRewards.Add((this.Convert(quest.OtherReward.Value!.Name), quest.OtherReward.Value.Icon, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quest.ReputationReward > 0) {
|
if (quest.ReputationReward > 0) {
|
||||||
var beastTribe = quest.BeastTribe.Value;
|
var beastTribe = quest.BeastTribe.ValueNullable;
|
||||||
if (beastTribe != null) {
|
if (beastTribe != null) {
|
||||||
additionalRewards.Add((this.Convert(beastTribe.NameRelation), beastTribe.Icon, quest.ReputationReward));
|
additionalRewards.Add((this.Convert(beastTribe.Value.NameRelation), beastTribe.Value.Icon, quest.ReputationReward));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quest.TomestoneReward > 0) {
|
if (quest.TomestoneReward > 0) {
|
||||||
var tomestone = this.Plugin.DataManager.GetExcelSheet<TomestonesItem>()!.FirstOrDefault(row => row.Tomestones.Row == quest.TomestoneReward);
|
var tomestone = this.Plugin.DataManager.GetExcelSheet<TomestonesItem>().Cast<TomestonesItem?>().FirstOrDefault(row => row.Value.Tomestones.RowId == quest.TomestoneReward);
|
||||||
var item = tomestone?.Item?.Value;
|
var item = tomestone?.Item.ValueNullable;
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
additionalRewards.Add((this.Convert(item.Name), item.Icon, quest.TomestoneCountReward));
|
additionalRewards.Add((this.Convert(item.Value.Name), item.Value.Icon, quest.TomestoneCountReward));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quest.ItemRewardType is 0 or 1 or 3 or 5) {
|
if (quest.ItemRewardType is 0 or 1 or 3 or 5) {
|
||||||
DrawItemRewards(
|
DrawItemRewards(
|
||||||
"Rewards",
|
"Rewards",
|
||||||
quest.ItemReward
|
quest.Reward
|
||||||
.Zip(quest.ItemCountReward, (id, qty) => (id, qty))
|
.Zip(quest.ItemCountReward, (id, qty) => (id: id.RowId, qty))
|
||||||
.Where(entry => entry.id != 0)
|
.Where(entry => entry.id != 0)
|
||||||
.Select(entry => (item: this.Plugin.DataManager.GetExcelSheet<Item>()!.GetRow(entry.id), entry.qty))
|
.Select(entry => (item: this.Plugin.DataManager.GetExcelSheet<Item>()!.GetRowOrDefault(entry.id), entry.qty))
|
||||||
.Where(entry => entry.item != null)
|
.Where(entry => entry.item != null)
|
||||||
.Select(entry => (this.Convert(entry.item!.Name), (uint) entry.item.Icon, entry.qty))
|
.Select(entry => (this.Convert(entry.item.Value.Name), (uint) entry.item.Value.Icon, entry.qty))
|
||||||
.Concat(additionalRewards)
|
.Concat(additionalRewards)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -542,10 +544,10 @@ namespace QuestMap {
|
|||||||
"Optional rewards",
|
"Optional rewards",
|
||||||
quest.OptionalItemReward
|
quest.OptionalItemReward
|
||||||
.Zip(quest.OptionalItemCountReward, (row, qty) => (row, qty))
|
.Zip(quest.OptionalItemCountReward, (row, qty) => (row, qty))
|
||||||
.Where(entry => entry.row.Row != 0)
|
.Where(entry => entry.row.RowId != 0)
|
||||||
.Select(entry => (item: entry.row.Value, entry.qty))
|
.Select(entry => (item: entry.row.ValueNullable, entry.qty))
|
||||||
.Where(entry => entry.item != null)
|
.Where(entry => entry.item != null)
|
||||||
.Select(entry => (this.Convert(entry.item!.Name), (uint) entry.item.Icon, entry.qty))
|
.Select(entry => (this.Convert(entry.item.Value.Name), (uint) entry.item.Value.Icon, entry.qty))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,7 +555,7 @@ namespace QuestMap {
|
|||||||
ImGui.TextUnformatted("Instances");
|
ImGui.TextUnformatted("Instances");
|
||||||
|
|
||||||
foreach (var instance in instances) {
|
foreach (var instance in instances) {
|
||||||
var icon = instance.ContentType.Value?.Icon ?? 0;
|
var icon = instance.ContentType.ValueNullable?.Icon ?? 0;
|
||||||
if (icon > 0) {
|
if (icon > 0) {
|
||||||
var image = GetIcon(icon);
|
var image = GetIcon(icon);
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
@ -592,9 +594,9 @@ namespace QuestMap {
|
|||||||
ClientLanguage.French => Language.French,
|
ClientLanguage.French => Language.French,
|
||||||
_ => Language.English,
|
_ => Language.English,
|
||||||
};
|
};
|
||||||
var path = $"quest/{id.ToString("00000")[..3]}/{quest.Id.RawString.ToLowerInvariant()}";
|
var path = $"quest/{id.ToString("00000")[..3]}/{quest.Id.ToString().ToLowerInvariant()}";
|
||||||
// FIXME: this is gross, but lumina caches incorrectly
|
// FIXME: this is gross, but lumina caches incorrectly
|
||||||
this.Plugin.DataManager.Excel.RemoveSheetFromCache<QuestData>();
|
// this.Plugin.DataManager.Excel.RemoveSheetFromCache<QuestData>();
|
||||||
var sheet = this.Plugin.DataManager.Excel.GetType()
|
var sheet = this.Plugin.DataManager.Excel.GetType()
|
||||||
.GetMethod("GetSheet", BindingFlags.Instance | BindingFlags.NonPublic)?
|
.GetMethod("GetSheet", BindingFlags.Instance | BindingFlags.NonPublic)?
|
||||||
// ReSharper disable once ConstantConditionalAccessQualifier
|
// ReSharper disable once ConstantConditionalAccessQualifier
|
||||||
@ -606,11 +608,11 @@ namespace QuestMap {
|
|||||||
null,
|
null,
|
||||||
]) as ExcelSheet<QuestData>;
|
]) as ExcelSheet<QuestData>;
|
||||||
// default to english if reflection failed
|
// default to english if reflection failed
|
||||||
sheet ??= this.Plugin.DataManager.Excel.GetSheet<QuestData>(path);
|
sheet ??= this.Plugin.DataManager.Excel.GetSheet<QuestData>(name: path);
|
||||||
var firstData = sheet?.GetRow(0);
|
var firstData = sheet?.GetRow(0);
|
||||||
if (firstData != null) {
|
if (firstData != null) {
|
||||||
ImGui.PushTextWrapPos(textWrap);
|
ImGui.PushTextWrapPos(textWrap);
|
||||||
ImGui.TextUnformatted(this.Convert(firstData.Text).ToString());
|
ImGui.TextUnformatted(this.Convert(firstData.Value.Text).ToString());
|
||||||
ImGui.PopTextWrapPos();
|
ImGui.PopTextWrapPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,24 +624,24 @@ namespace QuestMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var mapLink = new MapLinkPayload(
|
var mapLink = new MapLinkPayload(
|
||||||
level.Territory.Row,
|
level.Value.Territory.RowId,
|
||||||
level.Map.Row,
|
level.Value.Map.RowId,
|
||||||
(int) (level.X * 1_000f),
|
(int) (level.Value.X * 1_000f),
|
||||||
(int) (level.Z * 1_000f)
|
(int) (level.Value.Z * 1_000f)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.Plugin.GameGui.OpenMapWithMapLink(mapLink);
|
this.Plugin.GameGui.OpenMapWithMapLink(mapLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
var issuer = this.Plugin.DataManager.GetExcelSheet<ENpcResident>()!.GetRow(quest.IssuerStart)?.Singular ?? "Unknown";
|
var issuer = this.Plugin.DataManager.GetExcelSheet<ENpcResident>()!.GetRowOrDefault(quest.IssuerStart.RowId)?.Singular ?? "Unknown";
|
||||||
var target = this.Plugin.DataManager.GetExcelSheet<ENpcResident>()!.GetRow(quest.TargetEnd)?.Singular ?? "Unknown";
|
var target = this.Plugin.DataManager.GetExcelSheet<ENpcResident>()!.GetRowOrDefault(quest.TargetEnd.RowId)?.Singular ?? "Unknown";
|
||||||
ImGui.TextUnformatted(issuer);
|
ImGui.TextUnformatted(issuer.ToString());
|
||||||
ImGui.PushFont(UiBuilder.IconFont);
|
ImGui.PushFont(UiBuilder.IconFont);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextUnformatted(FontAwesomeIcon.ArrowRight.ToIconString());
|
ImGui.TextUnformatted(FontAwesomeIcon.ArrowRight.ToIconString());
|
||||||
ImGui.PopFont();
|
ImGui.PopFont();
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextUnformatted(target);
|
ImGui.TextUnformatted(target.ToString());
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
@ -822,9 +824,10 @@ namespace QuestMap {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var quest = (Quest) node.UserData;
|
var questInfo = (IQuestInfo)node.UserData;
|
||||||
|
var quest = questInfo.Quest;
|
||||||
|
|
||||||
var colour = quest.EventIconType.Row switch {
|
var colour = quest.EventIconType.RowId switch {
|
||||||
1 => Colours.NormalQuest, // normal
|
1 => Colours.NormalQuest, // normal
|
||||||
3 => Colours.MsqQuest, // msq
|
3 => Colours.MsqQuest, // msq
|
||||||
8 => Colours.BlueQuest, // blue
|
8 => Colours.BlueQuest, // blue
|
||||||
@ -846,12 +849,12 @@ namespace QuestMap {
|
|||||||
|
|
||||||
drawn.Add((start, end, quest.RowId));
|
drawn.Add((start, end, quest.RowId));
|
||||||
|
|
||||||
if (quest == this.Quest) {
|
if (quest.RowId == this.Quest?.RowId) {
|
||||||
drawList.AddRect(start - Vector2.One, end + Vector2.One, Colours.Line, 5, ImDrawFlags.RoundCornersAll);
|
drawList.AddRect(start - Vector2.One, end + Vector2.One, Colours.Line, 5, ImDrawFlags.RoundCornersAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawList.AddRectFilled(start, end, ImGui.GetColorU32(colour), 5, ImDrawFlags.RoundCornersAll);
|
drawList.AddRectFilled(start, end, ImGui.GetColorU32(colour), 5, ImDrawFlags.RoundCornersAll);
|
||||||
drawList.AddText(start + TextOffset, textColour, this.Convert(quest.Name).ToString());
|
drawList.AddText(start + TextOffset, textColour, questInfo.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HOW ABOUT DRAGGING THE VIEW?
|
// HOW ABOUT DRAGGING THE VIEW?
|
||||||
@ -905,8 +908,8 @@ namespace QuestMap {
|
|||||||
|
|
||||||
private static readonly byte[] NewLinePayload = [0x02, 0x10, 0x01, 0x03];
|
private static readonly byte[] NewLinePayload = [0x02, 0x10, 0x01, 0x03];
|
||||||
|
|
||||||
private SeString Convert(Lumina.Text.SeString lumina) {
|
private SeString Convert(ReadOnlySeString lumina) {
|
||||||
var se = (SeString) lumina;
|
var se = lumina.ToDalamudString();
|
||||||
for (var i = 0; i < se.Payloads.Count; i++) {
|
for (var i = 0; i < se.Payloads.Count; i++) {
|
||||||
switch (se.Payloads[i].Type) {
|
switch (se.Payloads[i].Type) {
|
||||||
case PayloadType.Unknown:
|
case PayloadType.Unknown:
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Lumina;
|
|
||||||
using Lumina.Data;
|
|
||||||
using Lumina.Excel;
|
using Lumina.Excel;
|
||||||
using Lumina.Text;
|
using Lumina.Text.ReadOnly;
|
||||||
|
|
||||||
namespace QuestMap {
|
namespace QuestMap {
|
||||||
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
|
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
|
||||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||||
internal class QuestData : ExcelRow {
|
[Sheet("")]
|
||||||
#pragma warning disable 8618
|
public readonly struct QuestData(ExcelPage page, uint offset, uint row) : IExcelRow<QuestData>
|
||||||
public string Id { get; set; }
|
{
|
||||||
public SeString Text { get; set; }
|
public uint RowId => row;
|
||||||
#pragma warning restore 8618
|
|
||||||
|
|
||||||
public override void PopulateData(RowParser parser, GameData gameData, Language language) {
|
public ReadOnlySeString Id => page.ReadString(offset, offset);
|
||||||
base.PopulateData(parser, gameData, language);
|
public ReadOnlySeString Text => page.ReadString(offset + 4, offset);
|
||||||
|
|
||||||
this.Id = parser.ReadColumn<string>(0)!;
|
static QuestData IExcelRow<QuestData>.Create(ExcelPage page, uint offset, uint row) =>
|
||||||
this.Text = parser.ReadColumn<SeString>(1)!;
|
new(page, offset, row);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutomaticGraphLayout" Version="1.1.12"/>
|
<PackageReference Include="AutomaticGraphLayout" Version="1.1.12"/>
|
||||||
<PackageReference Include="DalamudPackager" Version="2.1.13" />
|
<PackageReference Include="DalamudPackager" Version="11.0.0" />
|
||||||
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
|
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -4,21 +4,21 @@ using System.Numerics;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Channels;
|
using System.Threading.Channels;
|
||||||
|
using FFXIVClientStructs.FFXIV.Component.Excel;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Excel;
|
using Lumina.Excel.Sheets;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
|
||||||
using Microsoft.Msagl.Core.Geometry;
|
using Microsoft.Msagl.Core.Geometry;
|
||||||
using Microsoft.Msagl.Core.Geometry.Curves;
|
using Microsoft.Msagl.Core.Geometry.Curves;
|
||||||
using Microsoft.Msagl.Core.Layout;
|
using Microsoft.Msagl.Core.Layout;
|
||||||
using Microsoft.Msagl.Layout.Layered;
|
using Microsoft.Msagl.Layout.Layered;
|
||||||
using Microsoft.Msagl.Miscellaneous;
|
using Microsoft.Msagl.Miscellaneous;
|
||||||
using Action = Lumina.Excel.GeneratedSheets.Action;
|
using Action = Lumina.Excel.Sheets.Action;
|
||||||
|
|
||||||
namespace QuestMap {
|
namespace QuestMap {
|
||||||
internal class Quests {
|
internal class Quests {
|
||||||
private Plugin Plugin { get; }
|
private Plugin Plugin { get; }
|
||||||
|
|
||||||
private Dictionary<uint, Node<Quest>> AllNodes { get; }
|
private Dictionary<uint, Node<IQuestInfo>> AllNodes { get; }
|
||||||
internal IReadOnlyDictionary<uint, List<Item>> ItemRewards { get; }
|
internal IReadOnlyDictionary<uint, List<Item>> ItemRewards { get; }
|
||||||
internal IReadOnlyDictionary<uint, Emote> EmoteRewards { get; }
|
internal IReadOnlyDictionary<uint, Emote> EmoteRewards { get; }
|
||||||
internal IReadOnlyDictionary<uint, Action> ActionRewards { get; }
|
internal IReadOnlyDictionary<uint, Action> ActionRewards { get; }
|
||||||
@ -40,20 +40,20 @@ namespace QuestMap {
|
|||||||
var jobRewards = new Dictionary<uint, ClassJob>();
|
var jobRewards = new Dictionary<uint, ClassJob>();
|
||||||
var linkedInstances = new HashSet<ContentFinderCondition>();
|
var linkedInstances = new HashSet<ContentFinderCondition>();
|
||||||
|
|
||||||
var allQuests = new Dictionary<uint, Quest>();
|
var allQuests = new Dictionary<uint, IQuestInfo>();
|
||||||
foreach (var quest in this.Plugin.DataManager.GetExcelSheet<Quest>()!) {
|
foreach (var quest in this.Plugin.DataManager.GetExcelSheet<Quest>()!) {
|
||||||
if (quest.Name.RawString.Length == 0 || quest.RowId == 65536) {
|
if (quest.Name.ToString().Length == 0 || quest.RowId == 65536) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
allQuests[quest.RowId] = quest;
|
allQuests[quest.RowId] = new SheetQuestInfo(quest);
|
||||||
|
|
||||||
if (quest.EmoteReward.Row != 0) {
|
if (quest.EmoteReward.RowId != 0) {
|
||||||
emoteRewards[quest.RowId] = quest.EmoteReward.Value!;
|
emoteRewards[quest.RowId] = quest.EmoteReward.Value!;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var row in quest.ItemReward.Where(item => item != 0)) {
|
foreach (var row in quest.Reward.Where(item => item.RowId != 0)) {
|
||||||
var item = this.Plugin.DataManager.GetExcelSheet<Item>()!.GetRow(row);
|
var item = row.GetValueOrDefault<Item>();
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -66,10 +66,10 @@ namespace QuestMap {
|
|||||||
itemRewards[quest.RowId] = rewards;
|
itemRewards[quest.RowId] = rewards;
|
||||||
}
|
}
|
||||||
|
|
||||||
rewards.Add(item);
|
rewards.Add(item.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var row in quest.OptionalItemReward.Where(item => item.Row != 0)) {
|
foreach (var row in quest.OptionalItemReward.Where(item => item.RowId != 0)) {
|
||||||
var item = row.Value;
|
var item = row.Value;
|
||||||
|
|
||||||
List<Item> rewards;
|
List<Item> rewards;
|
||||||
@ -83,7 +83,7 @@ namespace QuestMap {
|
|||||||
rewards.Add(item!);
|
rewards.Add(item!);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quest.ActionReward.Row != 0) {
|
if (quest.ActionReward.RowId != 0) {
|
||||||
actionRewards[quest.RowId] = quest.ActionReward.Value!;
|
actionRewards[quest.RowId] = quest.ActionReward.Value!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,13 +95,13 @@ namespace QuestMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quest.BeastTribe.Row != 0 && !quest.IsRepeatable && quest.BeastReputationRank.Row == 0) {
|
if (quest.BeastTribe.RowId != 0 && !quest.IsRepeatable && quest.BeastReputationRank.RowId == 0) {
|
||||||
beastRewards[quest.RowId] = quest.BeastTribe.Value!;
|
beastRewards[quest.RowId] = quest.BeastTribe.Value!;
|
||||||
}
|
}
|
||||||
|
|
||||||
var jobReward = this.JobUnlocks(quest);
|
var jobReward = this.JobUnlocks(quest);
|
||||||
if (jobReward != null) {
|
if (jobReward != null) {
|
||||||
jobRewards[quest.RowId] = jobReward;
|
jobRewards[quest.RowId] = jobReward.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,13 +112,13 @@ namespace QuestMap {
|
|||||||
this.BeastRewards = beastRewards;
|
this.BeastRewards = beastRewards;
|
||||||
this.JobRewards = jobRewards;
|
this.JobRewards = jobRewards;
|
||||||
|
|
||||||
var (_, nodes) = Node<Quest>.BuildTree(allQuests);
|
var (_, nodes) = Node<IQuestInfo>.BuildTree(allQuests);
|
||||||
this.AllNodes = nodes;
|
this.AllNodes = nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Vector2 TextOffset = new(5, 2);
|
private static readonly Vector2 TextOffset = new(5, 2);
|
||||||
|
|
||||||
internal CancellationTokenSource StartGraphRecalculation(ExcelRow quest) {
|
internal CancellationTokenSource StartGraphRecalculation(Quest quest) {
|
||||||
var cts = new CancellationTokenSource();
|
var cts = new CancellationTokenSource();
|
||||||
new Thread(async () => {
|
new Thread(async () => {
|
||||||
var info = this.GetGraphInfo(quest, cts.Token);
|
var info = this.GetGraphInfo(quest, cts.Token);
|
||||||
@ -130,7 +130,7 @@ namespace QuestMap {
|
|||||||
return cts;
|
return cts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GraphInfo? GetGraphInfo(ExcelRow quest, CancellationToken cancel) {
|
private GraphInfo? GetGraphInfo(Quest quest, CancellationToken cancel) {
|
||||||
if (!this.AllNodes.TryGetValue(quest.RowId, out var first)) {
|
if (!this.AllNodes.TryGetValue(quest.RowId, out var first)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ namespace QuestMap {
|
|||||||
var links = new List<(uint, uint)>();
|
var links = new List<(uint, uint)>();
|
||||||
var g = new GeometryGraph();
|
var g = new GeometryGraph();
|
||||||
|
|
||||||
void AddNode(Node<Quest> node) {
|
void AddNode(Node<IQuestInfo> node) {
|
||||||
if (msaglNodes.ContainsKey(node.Id)) {
|
if (msaglNodes.ContainsKey(node.Id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ namespace QuestMap {
|
|||||||
g.Nodes.Add(graphNode);
|
g.Nodes.Add(graphNode);
|
||||||
msaglNodes[node.Id] = graphNode;
|
msaglNodes[node.Id] = graphNode;
|
||||||
|
|
||||||
IEnumerable<Node<Quest>> parents;
|
IEnumerable<Node<IQuestInfo>> parents;
|
||||||
if (this.Plugin.Config.ShowRedundantArrows) {
|
if (this.Plugin.Config.ShowRedundantArrows) {
|
||||||
parents = node.Parents;
|
parents = node.Parents;
|
||||||
} else {
|
} else {
|
||||||
@ -214,7 +214,7 @@ namespace QuestMap {
|
|||||||
: new GraphInfo(g, centre);
|
: new GraphInfo(g, centre);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Quest? ConsolidateMsq(Quest quest) {
|
private IQuestInfo? ConsolidateMsq(IQuestInfo quest) {
|
||||||
if (!this.Plugin.Config.CondenseMsq) {
|
if (!this.Plugin.Config.CondenseMsq) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -256,6 +256,7 @@ namespace QuestMap {
|
|||||||
70286 => "Growing Light (6.5)",
|
70286 => "Growing Light (6.5)",
|
||||||
70289 => "The Coming Dawn (6.55)",
|
70289 => "The Coming Dawn (6.55)",
|
||||||
70495 => "Dawntrail (7.0)",
|
70495 => "Dawntrail (7.0)",
|
||||||
|
70786 => "Crossroads (7.1)",
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -263,13 +264,7 @@ namespace QuestMap {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newQuest = new Quest();
|
return new ConsolidatedQuestInfo(quest, $"{name} MSQ");
|
||||||
foreach (var property in newQuest.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) {
|
|
||||||
property.SetValue(newQuest, property.GetValue(quest));
|
|
||||||
}
|
|
||||||
|
|
||||||
newQuest.Name = new Lumina.Text.SeString($"{name} MSQ");
|
|
||||||
return newQuest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashSet<ContentFinderCondition> InstanceUnlocks(Quest quest, ICollection<ContentFinderCondition> others) {
|
private HashSet<ContentFinderCondition> InstanceUnlocks(Quest quest, ICollection<ContentFinderCondition> others) {
|
||||||
@ -279,52 +274,50 @@ namespace QuestMap {
|
|||||||
|
|
||||||
var unlocks = new HashSet<ContentFinderCondition>();
|
var unlocks = new HashSet<ContentFinderCondition>();
|
||||||
|
|
||||||
if (quest.InstanceContentUnlock.Row != 0) {
|
if (quest.InstanceContentUnlock.RowId != 0) {
|
||||||
var cfc = this.Plugin.DataManager.GetExcelSheet<ContentFinderCondition>()!.FirstOrDefault(cfc => cfc.Content == quest.InstanceContentUnlock.Row && cfc.ContentLinkType == 1);
|
var cfc = this.Plugin.DataManager.GetExcelSheet<ContentFinderCondition>().Cast<ContentFinderCondition?>().FirstOrDefault(cfc => cfc.Value.Content.RowId == quest.InstanceContentUnlock.RowId && cfc.Value.ContentLinkType == 1);
|
||||||
if (cfc != null && cfc.UnlockQuest.Row == 0) {
|
if (cfc != null && cfc.Value.UnlockQuest.RowId == 0) {
|
||||||
unlocks.Add(cfc);
|
unlocks.Add(cfc.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var instanceRefs = quest.ScriptInstruction
|
var instanceRefs = quest.QuestParams
|
||||||
.Zip(quest.ScriptArg, (ins, arg) => (ins, arg))
|
.Where(x => x.ScriptInstruction.ToString().StartsWith("INSTANCEDUNGEON"));
|
||||||
.Where(x => x.ins.RawString.StartsWith("INSTANCEDUNGEON"));
|
|
||||||
|
|
||||||
foreach (var reference in instanceRefs) {
|
foreach (var reference in instanceRefs) {
|
||||||
var key = reference.arg;
|
var key = reference.ScriptArg;
|
||||||
|
|
||||||
// var content = this.Plugin.Interface.Data.GetExcelSheet<InstanceContent>().GetRow(key);
|
// var content = this.Plugin.Interface.Data.GetExcelSheet<InstanceContent>().GetRow(key);
|
||||||
|
|
||||||
var cfc = this.Plugin.DataManager.GetExcelSheet<ContentFinderCondition>()!.FirstOrDefault(cfc => cfc.Content == key && cfc.ContentLinkType == 1);
|
var cfc = this.Plugin.DataManager.GetExcelSheet<ContentFinderCondition>().Cast<ContentFinderCondition?>().FirstOrDefault(cfc => cfc.Value.Content.RowId == key && cfc.Value.ContentLinkType == 1);
|
||||||
if (cfc == null || cfc.UnlockQuest.Row != 0 || others.Contains(cfc)) {
|
if (cfc == null || cfc.Value.UnlockQuest.RowId != 0 || others.Contains(cfc.Value)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quest.ScriptInstruction.Any(i => i.RawString == "UNLOCK_ADD_NEW_CONTENT_TO_CF" || i.RawString.StartsWith("UNLOCK_DUNGEON"))) {
|
if (!quest.QuestParams.Any(i => i.ScriptInstruction.ToString() == "UNLOCK_ADD_NEW_CONTENT_TO_CF" || i.ScriptInstruction.ToString().StartsWith("UNLOCK_DUNGEON"))) {
|
||||||
if (quest.ScriptInstruction.Any(i => i.RawString.StartsWith("LOC_ITEM"))) {
|
if (quest.QuestParams.Any(i => i.ScriptInstruction.ToString().StartsWith("LOC_ITEM"))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlocks.Add(cfc);
|
unlocks.Add(cfc.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return unlocks;
|
return unlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassJob? JobUnlocks(Quest quest) {
|
private ClassJob? JobUnlocks(Quest quest) {
|
||||||
if (quest.ClassJobUnlock.Row > 0) {
|
if (quest.ClassJobUnlock.RowId > 0) {
|
||||||
return quest.ClassJobUnlock.Value;
|
return quest.ClassJobUnlock.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quest.ScriptInstruction.All(ins => ins.RawString.StartsWith("UNLOCK_IMAGE_CLASS"))) {
|
if (quest.QuestParams.All(ins => ins.ScriptInstruction.ToString().StartsWith("UNLOCK_IMAGE_CLASS"))) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var jobId = quest.ScriptInstruction
|
var jobId = quest.QuestParams.Cast<Quest.QuestParamsStruct?>()
|
||||||
.Zip(quest.ScriptArg, (ins, arg) => (ins, arg))
|
.FirstOrDefault(entry => entry.Value.ScriptInstruction.ToString().StartsWith("CLASSJOB"))
|
||||||
.FirstOrDefault(entry => entry.ins.RawString.StartsWith("CLASSJOB"))
|
?.ScriptArg ?? 0;
|
||||||
.arg;
|
|
||||||
return jobId == 0
|
return jobId == 0
|
||||||
? null
|
? null
|
||||||
: this.Plugin.DataManager.GetExcelSheet<ClassJob>()!.GetRow(jobId);
|
: this.Plugin.DataManager.GetExcelSheet<ClassJob>()!.GetRow(jobId);
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
},
|
},
|
||||||
"DalamudPackager": {
|
"DalamudPackager": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[2.1.13, )",
|
"requested": "[11.0.0, )",
|
||||||
"resolved": "2.1.13",
|
"resolved": "11.0.0",
|
||||||
"contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ=="
|
"contentHash": "bjT7XUlhIJSmsE/O76b7weUX+evvGQctbQB8aKXt94o+oPWxHpCepxAGMs7Thow3AzCyqWs7cOpp9/2wcgRRQA=="
|
||||||
},
|
},
|
||||||
"System.Threading.Channels": {
|
"System.Threading.Channels": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
|
Loading…
Reference in New Issue
Block a user