77 lines
3.2 KiB
C#
77 lines
3.2 KiB
C#
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Linq;
|
|
using System;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using CFUtils.Serialization.Modpack;
|
|
|
|
namespace CFUtils.Serialization
|
|
{
|
|
internal class ManifestConverter : JsonConverter<Manifest>
|
|
{
|
|
PropertyInfo[] manifestProperties;
|
|
Type manifestType;
|
|
|
|
public ManifestConverter()
|
|
{
|
|
manifestType = typeof(Manifest);
|
|
manifestProperties = manifestType.GetProperties();
|
|
}
|
|
public override Manifest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
{
|
|
string[] propertyNames = new string[manifestProperties.Length];
|
|
for (int i = 0; i < propertyNames.Length; i++) propertyNames[i] = manifestProperties[i].Name;
|
|
Manifest result = new Manifest();
|
|
HashSet<string> pendingProperties = new HashSet<string>(propertyNames);
|
|
while (reader.Read())
|
|
{
|
|
if (reader.TokenType == JsonTokenType.EndObject)
|
|
{
|
|
if (pendingProperties.Count != 0)
|
|
{
|
|
throw new JsonException("Manifest is missing data. Will not proceed.");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
if (reader.TokenType == JsonTokenType.PropertyName)
|
|
{
|
|
string propertyName = reader.GetString() ?? throw new JsonException();
|
|
if (propertyNames.Contains(propertyName))
|
|
{
|
|
PropertyInfo property = manifestProperties[Array.IndexOf(propertyNames, propertyName)];
|
|
pendingProperties.Remove(propertyName);
|
|
property.SetValue(result, JsonSerializer.Deserialize(ref reader, property.PropertyType, options));
|
|
}
|
|
else if (Enum.GetNames(typeof(ManifestGames)).Contains(propertyName, StringComparer.CurrentCultureIgnoreCase))
|
|
{
|
|
Game game = JsonSerializer.Deserialize<Game>(ref reader);
|
|
game.gameType = Enum.Parse<ManifestGames>(propertyName, true);
|
|
result.game = game;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new JsonException();
|
|
}
|
|
}
|
|
throw new JsonException(); // Reached end of stream and did not find ending token.
|
|
}
|
|
|
|
public override void Write(Utf8JsonWriter writer, Manifest value, JsonSerializerOptions options)
|
|
{
|
|
writer.WriteStartObject();
|
|
writer.WritePropertyName(value.game.gameType.ToString().ToLower());
|
|
JsonSerializer.Serialize(writer, value.game, typeof(Game), options);
|
|
for (int i = 0; i < manifestProperties.Length; i++)
|
|
{
|
|
PropertyInfo property = manifestProperties[i];
|
|
writer.WritePropertyName(property.Name);
|
|
JsonSerializer.Serialize(writer, property.GetValue(value), property.PropertyType, options);
|
|
}
|
|
|
|
writer.WriteEndObject();
|
|
}
|
|
}
|
|
} |