forked from aly/qstbak
103 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|