qstbak/Questionable.Model/Questionable.Model.Questing/QuestRootSerializer.cs
2026-08-17 20:29:32 +10:00

103 lines
3.2 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
namespace Questionable.Model.Questing;
public static class QuestRootSerializer
{
public const string SchemaUrl = "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/QuestPaths/quest-v1.json";
public static JsonSerializerOptions CreateOptions()
{
return new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
WriteIndented = true,
IncludeFields = false,
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers =
{
(Action<JsonTypeInfo>)NoEmptyCollectionModifier,
(Action<JsonTypeInfo>)DialogueChoiceSerializationModifier,
(Action<JsonTypeInfo>)NonDefaultBoolModifier
}
}
};
}
public static QuestRoot Clone(QuestRoot source, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<QuestRoot>(JsonSerializer.Serialize(source, options), options);
}
public static byte[] SerializeToUtf8(QuestRoot questRoot, JsonSerializerOptions options)
{
JsonObject obj = (JsonObject)JsonSerializer.SerializeToNode(questRoot, options);
JsonObject jsonObject = new JsonObject { { "$schema", "https://github.com/WigglyMuffin/Questionable/raw/refs/heads/main/QuestPaths/quest-v1.json" } };
foreach (var (propertyName, jsonNode2) in obj)
{
jsonObject.Add(propertyName, jsonNode2?.DeepClone());
}
using MemoryStream memoryStream = new MemoryStream();
using (Utf8JsonWriter writer = new Utf8JsonWriter(memoryStream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Indented = true,
IndentSize = 2,
IndentCharacter = ' ',
NewLine = "\n"
}))
{
jsonObject.WriteTo(writer, options);
}
memoryStream.WriteByte(10);
return memoryStream.ToArray();
}
private static void NoEmptyCollectionModifier(JsonTypeInfo typeInfo)
{
foreach (JsonPropertyInfo property in typeInfo.Properties)
{
if (typeof(ICollection).IsAssignableFrom(property.PropertyType))
{
property.ShouldSerialize = (object _, object? val) => val is ICollection collection && collection.Count > 0;
}
}
}
private static void DialogueChoiceSerializationModifier(JsonTypeInfo typeInfo)
{
if (typeInfo.Type != typeof(DialogueChoice))
{
return;
}
JsonPropertyInfo jsonPropertyInfo = typeInfo.Properties.FirstOrDefault((JsonPropertyInfo x) => x.Name == "Yes");
if (jsonPropertyInfo != null)
{
jsonPropertyInfo.ShouldSerialize = (object obj, object? _) => obj is DialogueChoice dialogueChoice && dialogueChoice.Type == EDialogChoiceType.YesNo;
}
}
private static void NonDefaultBoolModifier(JsonTypeInfo typeInfo)
{
if (typeInfo.Type != typeof(QuestRoot))
{
return;
}
JsonPropertyInfo jsonPropertyInfo = typeInfo.Properties.FirstOrDefault((JsonPropertyInfo x) => x.Name == "Interruptible");
if (jsonPropertyInfo != null)
{
jsonPropertyInfo.ShouldSerialize = (object obj, object? _) => obj is QuestRoot questRoot && !questRoot.Interruptible;
}
}
}