more serialization and other fixes

This commit is contained in:
Alex
2025-01-08 22:37:10 +00:00
parent 251b328208
commit 708b2ec361
5 changed files with 127 additions and 6 deletions
+7 -3
View File
@@ -2,6 +2,7 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Ragfair;
using Core.Models.Enums;
using Core.Utils.Json;
using Core.Utils.Json.Converters;
namespace Core.Models.Eft.Common.Tables;
@@ -293,6 +294,9 @@ public class BotBaseInventory
[JsonPropertyName("favoriteItems")]
public List<string>? FavoriteItems { get; set; }
[JsonPropertyName("hideoutCustomizationStashId")]
public string? HideoutCustomizationStashId { get; set; }
}
public class BaseJsonSkills
@@ -304,8 +308,8 @@ public class BaseJsonSkills
public class Skills
{
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<SkillTypes, Common>? Common { get; set; }
[JsonConverter(typeof(DictionaryOfListOrTConverter))]
public Dictionary<SkillTypes, ListOrT<Common>>? Common { get; set; }
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<string, Mastering>? Mastering { get; set; }
@@ -681,7 +685,7 @@ public class LastCompleted
public class Notes
{
[JsonPropertyName("notes")]
[JsonPropertyName("Notes")]
public List<Note>? DataNotes { get; set; }
}
+12 -3
View File
@@ -2,6 +2,7 @@ using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Core.Annotations;
using Core.Utils.Json.Converters;
namespace Core.Utils;
@@ -12,6 +13,11 @@ public class ImporterUtil
private readonly HashSet<string> filesToIgnore = ["bearsuits.json", "usecsuits.json", "archivedquests.json"];
private readonly JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions
{
UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow, Converters = { new ListOrTConverterFactory() }
};
public ImporterUtil(FileUtil fileUtil)
{
_fileUtil = fileUtil;
@@ -58,8 +64,7 @@ public class ImporterUtil
);
try
{
var fileDeserialized = JsonSerializer.Deserialize(fileData, propertyType,
new JsonSerializerOptions { UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow });
var fileDeserialized = JsonSerializer.Deserialize(fileData, propertyType, jsonSerializerOptions);
if (onObjectDeserialized != null)
onObjectDeserialized(file, fileDeserialized);
@@ -77,13 +82,17 @@ public class ImporterUtil
// deep tree search
foreach (var directory in directories)
{
var dictionaryLock = new object();
tasks.Add(
Task.Factory.StartNew(() =>
{
var setMethod = GetSetMethod(directory.Split("/").Last().Replace("_", ""), loadedType, out var matchedProperty, out var isDictionary);
var loadTask = LoadRecursiveAsync($"{directory}/", matchedProperty);
loadTask.Wait();
setMethod.Invoke(result, isDictionary ? [directory, loadTask.Result] : [loadTask.Result]);
lock (dictionaryLock)
{
setMethod.Invoke(result, isDictionary ? [directory, loadTask.Result] : [loadTask.Result]);
}
})
);
}
@@ -0,0 +1,43 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Core.Utils.Json.Converters;
public class DictionaryOfListOrTConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(Dictionary<,>) &&
typeToConvert.GenericTypeArguments[1].IsGenericType && typeToConvert.GenericTypeArguments[1].GetGenericTypeDefinition() == typeof(ListOrT<>);
}
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return (JsonConverter)Activator.CreateInstance(typeof(DictionaryOfListOrTConverter<,>).MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1].GenericTypeArguments[0]));
}
}
public class DictionaryOfListOrTConverter<T, K> : JsonConverter<Dictionary<T, ListOrT<K>>?>
{
public override Dictionary<T, ListOrT<K>>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.StartArray)
{
reader.Read();
return default;
}
else
{
using (var jsonDocument = JsonDocument.ParseValue(ref reader))
{
var jsonText = jsonDocument.RootElement.GetRawText();
return JsonSerializer.Deserialize<Dictionary<T, ListOrT<K>>>(jsonText, options);
}
}
}
public override void Write(Utf8JsonWriter writer, Dictionary<T, ListOrT<K>> value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, options);
}
}
@@ -0,0 +1,55 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Core.Utils.Json.Converters;
public class ListOrTConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(ListOrT<>);
}
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return (JsonConverter)Activator.CreateInstance(typeof(ListOrTConverter<>).MakeGenericType(typeToConvert.GenericTypeArguments[0]));
}
}
public class ListOrTConverter<T> : JsonConverter<ListOrT<T>?>
{
public override ListOrT<T>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.StartArray:
using (var jsonDocument = JsonDocument.ParseValue(ref reader))
{
var jsonText = jsonDocument.RootElement.GetRawText();
var list = JsonSerializer.Deserialize<List<T>>(jsonText, options);
return new ListOrT<T>(list, default);
}
case JsonTokenType.StartObject:
using (var jsonDocument = JsonDocument.ParseValue(ref reader))
{
var jsonText = jsonDocument.RootElement.GetRawText();
var obj = JsonSerializer.Deserialize<T>(jsonText, options);
return new ListOrT<T?>(null, obj);
}
default:
throw new Exception($"Unable to translate object type {reader.TokenType} to ListOrT<T>.");
}
}
public override void Write(Utf8JsonWriter writer, ListOrT<T> value, JsonSerializerOptions options)
{
if (value.IsItem)
{
JsonSerializer.Serialize(writer, value.Item, options);
}
else
{
JsonSerializer.Serialize(writer, value.List, options);
}
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace Core.Utils.Json;
public class ListOrT<T>(List<T>? list, T? item)
{
public List<T>? List { get; } = list;
public T? Item { get; } = item;
public bool IsItem => Item != null;
public bool IsList => List != null;
}