forked from aly/qstbak
118 lines
4.6 KiB
C#
118 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Json.Schema;
|
|
using Questionable.FatePaths;
|
|
using Questionable.GatheringPaths;
|
|
using Questionable.Model;
|
|
using Questionable.QuestPaths;
|
|
using Questionable.SeasonalDutyPaths;
|
|
|
|
namespace Questionable.Validation;
|
|
|
|
internal sealed class SchemaRegistrar
|
|
{
|
|
private const string BaseUri = "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main";
|
|
|
|
private static readonly IReadOnlyList<(string FileName, string Uri, Func<Stream> Embedded)> Catalog = new global::_003C_003Ez__ReadOnlyArray<(string, string, Func<Stream>)>(new(string, string, Func<Stream>)[10]
|
|
{
|
|
("common-aethernetshard.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/Questionable.Model/common-aethernetshard.json", () => AssemblyModelLoader.CommonAethernetShard),
|
|
("common-aetheryte.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/Questionable.Model/common-aetheryte.json", () => AssemblyModelLoader.CommonAetheryte),
|
|
("common-classjob.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/Questionable.Model/common-classjob.json", () => AssemblyModelLoader.CommonClassJob),
|
|
("common-completionflags.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/Questionable.Model/common-completionflags.json", () => AssemblyModelLoader.CommonCompletionFlags),
|
|
("common-requiredvariables.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/Questionable.Model/common-requiredvariables.json", () => AssemblyModelLoader.CommonRequiredVariables),
|
|
("common-vector3.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/Questionable.Model/common-vector3.json", () => AssemblyModelLoader.CommonVector3),
|
|
("quest-v1.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/QuestPaths/quest-v1.json", () => AssemblyQuestLoader.QuestSchema),
|
|
("fatedefinition-v1.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/FatePaths/fatedefinition-v1.json", () => AssemblyFateDefinitionLoader.FateDefinitionSchema),
|
|
("gatheringlocation-v1.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/GatheringPaths/gatheringlocation-v1.json", () => AssemblyGatheringLocationLoader.GatheringSchema),
|
|
("seasonaldutydefinition-v1.json", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/SeasonalDutyPaths/seasonaldutydefinition-v1.json", () => AssemblySeasonalDutyDefinitionLoader.SeasonalDutyDefinitionSchema)
|
|
});
|
|
|
|
private readonly SchemaRegistry _registry = new SchemaRegistry();
|
|
|
|
private readonly Dictionary<string, JsonSchema> _schemas = new Dictionary<string, JsonSchema>();
|
|
|
|
private readonly object _lock = new object();
|
|
|
|
private bool _built;
|
|
|
|
public void EnsureBuilt()
|
|
{
|
|
if (_built)
|
|
{
|
|
return;
|
|
}
|
|
lock (_lock)
|
|
{
|
|
if (_built)
|
|
{
|
|
return;
|
|
}
|
|
BuildOptions buildOptions = new BuildOptions
|
|
{
|
|
SchemaRegistry = _registry
|
|
};
|
|
DirectoryInfo projectRoot = FindProjectRoot();
|
|
foreach (var (fileName, key, embedded) in Catalog)
|
|
{
|
|
_schemas[key] = Build(fileName, embedded, projectRoot, buildOptions);
|
|
}
|
|
_built = true;
|
|
}
|
|
}
|
|
|
|
public JsonSchema Get(string uri)
|
|
{
|
|
EnsureBuilt();
|
|
if (!_schemas.TryGetValue(uri, out JsonSchema value))
|
|
{
|
|
throw new InvalidOperationException("schema not registered: " + uri);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
private static JsonSchema Build(string fileName, Func<Stream> embedded, DirectoryInfo? projectRoot, BuildOptions buildOptions)
|
|
{
|
|
if (projectRoot != null)
|
|
{
|
|
try
|
|
{
|
|
string text = Directory.EnumerateFiles(projectRoot.FullName, fileName, SearchOption.AllDirectories).FirstOrDefault();
|
|
if (text != null)
|
|
{
|
|
return JsonSchema.FromText(File.ReadAllText(text), buildOptions);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
using StreamReader streamReader = new StreamReader(embedded());
|
|
return JsonSchema.FromText(streamReader.ReadToEnd(), buildOptions);
|
|
}
|
|
|
|
private static DirectoryInfo? FindProjectRoot()
|
|
{
|
|
try
|
|
{
|
|
string location = Assembly.GetExecutingAssembly().Location;
|
|
if (string.IsNullOrEmpty(location))
|
|
{
|
|
return null;
|
|
}
|
|
for (DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(location) ?? location); directoryInfo != null; directoryInfo = directoryInfo.Parent)
|
|
{
|
|
if (directoryInfo.GetDirectories("QuestPaths", SearchOption.TopDirectoryOnly).Length != 0 || directoryInfo.GetDirectories("Questionable.Model", SearchOption.TopDirectoryOnly).Length != 0 || directoryInfo.GetDirectories("Questionable", SearchOption.TopDirectoryOnly).Length != 0)
|
|
{
|
|
return directoryInfo;
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
return null;
|
|
}
|
|
}
|