Merge branch 'main' of https://github.com/sp-tarkov/server-csharp
# Conflicts: # Core/Models/Eft/Common/Tables/Achievement.cs
This commit is contained in:
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user