# Conflicts:
#	Core/Models/Eft/Common/Tables/Achievement.cs
This commit is contained in:
CWX
2025-01-08 23:33:42 +00:00
10 changed files with 221 additions and 9 deletions
@@ -49,3 +49,21 @@ public class Achievement
[JsonPropertyName("index")]
public int? Index { get; set; }
}
public class AchievementQuestConditionTypes
{
[JsonPropertyName("started")]
public List<QuestCondition>? Started { get; set; }
[JsonPropertyName("availableForFinish")]
public List<QuestCondition>? AvailableForFinish { get; set; }
[JsonPropertyName("availableForStart")]
public List<QuestCondition>? AvailableForStart { get; set; }
[JsonPropertyName("success")]
public List<QuestCondition>? Success { get; set; }
[JsonPropertyName("fail")]
public List<QuestCondition>? Fail { get; set; }
}
+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;
@@ -12,6 +13,7 @@ public class BotBase
public string? Id { get; set; }
[JsonPropertyName("aid")]
[JsonConverter(typeof(StringToNumberFactoryConverter))]
public double? Aid { get; set; }
/** SPT property - use to store player id - TODO - move to AID ( account id as guid of choice) */
@@ -293,6 +295,9 @@ public class BotBaseInventory
[JsonPropertyName("favoriteItems")]
public List<string>? FavoriteItems { get; set; }
[JsonPropertyName("hideoutCustomizationStashId")]
public string? HideoutCustomizationStashId { get; set; }
}
public class BaseJsonSkills
@@ -304,8 +309,7 @@ public class BaseJsonSkills
public class Skills
{
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
public Dictionary<SkillTypes, Common>? Common { get; set; }
public DictionaryOrList<string, 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; }
}
@@ -61,6 +61,12 @@ public class TemplateSide
[JsonPropertyName("trader")]
public ProfileTraderTemplate? Trader { get; set; }
[JsonPropertyName("equipmentBuilds")]
public object? EquipmentBuilds { get; set; }
[JsonPropertyName("weaponbuilds")]
public object? WeaponBuilds { get; set; }
}
public class ProfileTraderTemplate
@@ -69,7 +75,7 @@ public class ProfileTraderTemplate
public Dictionary<string, int>? InitialLoyaltyLevel { get; set; }
[JsonPropertyName("initialStanding")]
public Dictionary<string, int>? InitialStanding { get; set; }
public Dictionary<string, double>? InitialStanding { get; set; }
[JsonPropertyName("setQuestsAvailableForStart")]
public bool? SetQuestsAvailableForStart { get; set; }
@@ -94,4 +100,4 @@ public class ProfileTraderTemplate
/** What traders should have their clothing unlocked/purchased on creation */
[JsonPropertyName("purchaseAllClothingByDefaultForTrader")]
public List<string>? PurchaseAllClothingByDefaultForTrader { get; set; }
}
}
+3 -1
View File
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;
using Core.Models.Eft.Health;
using Core.Models.Enums;
@@ -166,6 +167,7 @@ public class SkillRequirement : QteRequirement
public RequirementType? Type { get; set; } = Models.Enums.Hideout.RequirementType.Skill;
[JsonPropertyName("skillName")]
[JsonConverter(typeof(JsonStringEnumConverter))]
public SkillTypes? SkillName { get; set; }
[JsonPropertyName("skillLevel")]
@@ -254,4 +256,4 @@ public class BodyPartBuffRequirement : QteRequirement
[JsonPropertyName("excluded")]
public bool? Excluded { 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(), new DictionaryOrListConverter() }
};
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 DictionaryOrListConverter: JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(DictionaryOrList<,>);
}
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return (JsonConverter)Activator.CreateInstance(typeof(DictionaryOrListConverter<,>).MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1]));
}
}
public class DictionaryOrListConverter<K,V> : JsonConverter<DictionaryOrList<K,V>?>
{
public override DictionaryOrList<K,V>? 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<V>>(jsonText, options);
return new DictionaryOrList<K,V>(null, list);
}
case JsonTokenType.StartObject:
using (var jsonDocument = JsonDocument.ParseValue(ref reader))
{
var jsonText = jsonDocument.RootElement.GetRawText();
var dictionary = JsonSerializer.Deserialize<Dictionary<K,V>>(jsonText, options);
return new DictionaryOrList<K,V>(dictionary, null);
}
default:
throw new Exception($"Unable to translate object type {reader.TokenType} to ListOrT<T>.");
}
}
public override void Write(Utf8JsonWriter writer, DictionaryOrList<K,V> value, JsonSerializerOptions options)
{
if (value.IsList)
{
JsonSerializer.Serialize(writer, value.List, options);
}
else
{
JsonSerializer.Serialize(writer, value.Dictionary, 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 DictionaryOrList<K, V>(Dictionary<K, V>? dictionary, List<V>? list)
{
public Dictionary<K, V>? Dictionary { get; } = dictionary;
public List<V>? List { get; } = list;
public bool IsList => List != null;
public bool IsDictionary => Dictionary != null;
}
+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;
}