using System; using System.Collections.Generic; using System.Globalization; using System.Text.Json.Nodes; using Json.Schema; using Questionable.Model; using Questionable.Model.Questing; using Questionable.QuestPaths; namespace Questionable.Validation.Validators; internal sealed class JsonSchemaValidator : IQuestValidator { private readonly Dictionary _questNodes = new Dictionary(); private JsonSchema? _questSchema; public JsonSchemaValidator() { SchemaRegistry.Global.Register(new Uri("https://qstxiv.github.io/schema/common-aethernetshard.json"), JsonSchema.FromStream(AssemblyModelLoader.CommonAethernetShard).AsTask().Result); SchemaRegistry.Global.Register(new Uri("https://qstxiv.github.io/schema/common-aetheryte.json"), JsonSchema.FromStream(AssemblyModelLoader.CommonAetheryte).AsTask().Result); SchemaRegistry.Global.Register(new Uri("https://qstxiv.github.io/schema/common-classjob.json"), JsonSchema.FromStream(AssemblyModelLoader.CommonClassJob).AsTask().Result); SchemaRegistry.Global.Register(new Uri("https://qstxiv.github.io/schema/common-completionflags.json"), JsonSchema.FromStream(AssemblyModelLoader.CommonCompletionFlags).AsTask().Result); SchemaRegistry.Global.Register(new Uri("https://qstxiv.github.io/schema/common-vector3.json"), JsonSchema.FromStream(AssemblyModelLoader.CommonVector3).AsTask().Result); } public IEnumerable Validate(Quest quest) { if (_questSchema == null) { _questSchema = JsonSchema.FromStream(AssemblyQuestLoader.QuestSchema).AsTask().Result; } if (_questNodes.TryGetValue(quest.Id, out JsonNode value) && !_questSchema.Evaluate(value, new EvaluationOptions { Culture = CultureInfo.InvariantCulture, OutputFormat = OutputFormat.List }).IsValid) { yield return new ValidationIssue { ElementId = quest.Id, Sequence = null, Step = null, Type = EIssueType.InvalidJsonSchema, Severity = EIssueSeverity.Error, Description = "JSON Validation failed" }; } } public void Enqueue(ElementId elementId, JsonNode questNode) { _questNodes[elementId] = questNode; } public void Reset() { _questNodes.Clear(); } }