255 lines
6.6 KiB
C#
255 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Numerics;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.Colors;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
using Dalamud.Plugin;
|
|
using Questionable.Data;
|
|
using Questionable.Validation;
|
|
|
|
namespace Questionable.Windows.QuestComponents;
|
|
|
|
internal sealed class QuestValidationComponent
|
|
{
|
|
private readonly QuestValidator _questValidator;
|
|
|
|
private readonly QuestData _questData;
|
|
|
|
private readonly IDalamudPluginInterface _pluginInterface;
|
|
|
|
private readonly ValidationDetailsRenderer _detailsRenderer;
|
|
|
|
public bool ShouldDraw => _questValidator.Issues.Count > 0;
|
|
|
|
public QuestValidationComponent(QuestValidator questValidator, QuestData questData, IDalamudPluginInterface pluginInterface)
|
|
{
|
|
_questValidator = questValidator;
|
|
_questData = questData;
|
|
_pluginInterface = pluginInterface;
|
|
_detailsRenderer = new ValidationDetailsRenderer(questData, pluginInterface);
|
|
}
|
|
|
|
public void Draw()
|
|
{
|
|
DrawSummaryHeader();
|
|
ImGui.Separator();
|
|
DrawValidationTable();
|
|
_detailsRenderer.DrawDetailWindows();
|
|
}
|
|
|
|
private void DrawSummaryHeader()
|
|
{
|
|
int issueCount = _questValidator.IssueCount;
|
|
int errorCount = _questValidator.ErrorCount;
|
|
int num = issueCount - errorCount;
|
|
ImU8String text = new ImU8String(33, 1);
|
|
text.AppendLiteral("Validation Results: ");
|
|
text.AppendFormatted(issueCount);
|
|
text.AppendLiteral(" total issues");
|
|
ImGui.Text(text);
|
|
if (errorCount > 0)
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.Text("(");
|
|
ImGui.SameLine();
|
|
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed))
|
|
{
|
|
text = new ImU8String(7, 1);
|
|
text.AppendFormatted(errorCount);
|
|
text.AppendLiteral(" errors");
|
|
ImGui.Text(text);
|
|
}
|
|
}
|
|
if (num > 0)
|
|
{
|
|
if (errorCount > 0)
|
|
{
|
|
ImGui.SameLine();
|
|
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudOrange))
|
|
{
|
|
text = new ImU8String(12, 1);
|
|
text.AppendLiteral(", ");
|
|
text.AppendFormatted(num);
|
|
text.AppendLiteral(" warnings)");
|
|
ImGui.Text(text);
|
|
return;
|
|
}
|
|
}
|
|
ImGui.SameLine();
|
|
ImGui.Text("(");
|
|
ImGui.SameLine();
|
|
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudOrange))
|
|
{
|
|
text = new ImU8String(10, 1);
|
|
text.AppendFormatted(num);
|
|
text.AppendLiteral(" warnings)");
|
|
ImGui.Text(text);
|
|
return;
|
|
}
|
|
}
|
|
if (errorCount > 0)
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.Text(")");
|
|
}
|
|
}
|
|
|
|
private void DrawValidationTable()
|
|
{
|
|
using ImRaii.IEndObject endObject = ImRaii.Table("ValidationIssues", 6, ImGuiTableFlags.Borders | ImGuiTableFlags.Sortable | ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY);
|
|
if (!(!endObject))
|
|
{
|
|
ImGui.TableSetupColumn("ID", ImGuiTableColumnFlags.WidthFixed, 60f);
|
|
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.WidthFixed, 250f);
|
|
ImGui.TableSetupColumn("Seq", ImGuiTableColumnFlags.WidthFixed, 40f);
|
|
ImGui.TableSetupColumn("Step", ImGuiTableColumnFlags.WidthFixed, 40f);
|
|
ImGui.TableSetupColumn("Issue", ImGuiTableColumnFlags.WidthStretch);
|
|
ImGui.TableSetupColumn("Actions", ImGuiTableColumnFlags.WidthFixed, 60f);
|
|
ImGui.TableHeadersRow();
|
|
IReadOnlyList<ValidationIssue> issues = _questValidator.Issues;
|
|
for (int i = 0; i < issues.Count; i++)
|
|
{
|
|
DrawValidationRow(issues[i], i);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawValidationRow(ValidationIssue issue, int index)
|
|
{
|
|
ImGui.TableNextRow();
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
ImGui.TextUnformatted(issue.ElementId?.ToString() ?? string.Empty);
|
|
}
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
ImGui.TextUnformatted((issue.ElementId != null) ? _questData.GetQuestInfo(issue.ElementId).Name : issue.AlliedSociety.ToString());
|
|
}
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
if (issue.Sequence.HasValue)
|
|
{
|
|
ImGui.TextUnformatted(issue.Sequence.Value.ToString(CultureInfo.InvariantCulture));
|
|
}
|
|
else
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudGrey2))
|
|
{
|
|
ImGui.TextUnformatted("\ufffd");
|
|
}
|
|
}
|
|
}
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
if (issue.Step.HasValue)
|
|
{
|
|
ImGui.TextUnformatted(issue.Step.Value.ToString(CultureInfo.InvariantCulture));
|
|
}
|
|
else
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudGrey2))
|
|
{
|
|
ImGui.TextUnformatted("\ufffd");
|
|
}
|
|
}
|
|
}
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
DrawIssueCell(issue, index);
|
|
}
|
|
if (ImGui.TableNextColumn())
|
|
{
|
|
DrawActionsCell(issue, index);
|
|
}
|
|
}
|
|
|
|
private void DrawIssueCell(ValidationIssue issue, int index)
|
|
{
|
|
Vector4 color = ((issue.Severity == EIssueSeverity.Error) ? ImGuiColors.DalamudRed : ImGuiColors.DalamudOrange);
|
|
FontAwesomeIcon icon = ((issue.Severity == EIssueSeverity.Error) ? FontAwesomeIcon.ExclamationTriangle : FontAwesomeIcon.InfoCircle);
|
|
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.Text, color))
|
|
{
|
|
ImGui.TextUnformatted(icon.ToIconString());
|
|
}
|
|
}
|
|
ImGui.SameLine();
|
|
string issueSummary = GetIssueSummary(issue);
|
|
using (ImRaii.PushColor(ImGuiCol.Text, color))
|
|
{
|
|
ImGui.TextWrapped(issueSummary);
|
|
}
|
|
}
|
|
|
|
private void DrawActionsCell(ValidationIssue issue, int index)
|
|
{
|
|
if (HasDetailedDescription(issue) && ImGui.SmallButton($"Details##{index}"))
|
|
{
|
|
_detailsRenderer.OpenDetails(issue, index);
|
|
}
|
|
}
|
|
|
|
private static string GetIssueSummary(ValidationIssue issue)
|
|
{
|
|
string text = ValidationDetailsRenderer.CleanJsonText(issue.Description ?? string.Empty);
|
|
if (issue.Type == EIssueType.QuestDisabled && issue.ElementId == null)
|
|
{
|
|
string[] array = text.Split(':', 2);
|
|
if (array.Length == 0)
|
|
{
|
|
return text;
|
|
}
|
|
return array[0];
|
|
}
|
|
if (issue.Type == EIssueType.InvalidJsonSchema)
|
|
{
|
|
string[] array2 = text.Split('\n', 2, StringSplitOptions.RemoveEmptyEntries);
|
|
if (array2.Length == 0)
|
|
{
|
|
return text;
|
|
}
|
|
return array2[0];
|
|
}
|
|
if (issue.Type == EIssueType.InvalidJsonSyntax)
|
|
{
|
|
string[] array3 = text.Split('\n', 2, StringSplitOptions.RemoveEmptyEntries);
|
|
if (array3.Length == 0)
|
|
{
|
|
return text;
|
|
}
|
|
return array3[0];
|
|
}
|
|
string[] array4 = text.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
|
if (array4.Length <= 2)
|
|
{
|
|
return text;
|
|
}
|
|
return array4[0] + ((array4.Length > 1) ? "..." : "");
|
|
}
|
|
|
|
private static bool HasDetailedDescription(ValidationIssue issue)
|
|
{
|
|
string text = issue.Description ?? string.Empty;
|
|
if (issue.Type == EIssueType.QuestDisabled && issue.ElementId == null)
|
|
{
|
|
return true;
|
|
}
|
|
if (issue.Type == EIssueType.InvalidJsonSchema)
|
|
{
|
|
return true;
|
|
}
|
|
if (issue.Type == EIssueType.InvalidJsonSyntax)
|
|
{
|
|
return true;
|
|
}
|
|
if (!text.Contains('\n', StringComparison.Ordinal))
|
|
{
|
|
return text.Length > 100;
|
|
}
|
|
return true;
|
|
}
|
|
}
|