using System.Collections.Generic; using System.Linq; using Newtonsoft.Json.Linq; namespace WingServerCommon.Config.Parameters { public class ParameterSerializer { /// /// Deserialize json file to parameter /// /// File path that will be deserialize /// Parameter list. public static IEnumerable Deserialize(string filePath) { var content = File.ReadAllText(filePath); var configCrypter = new ConfigCrypter(); content = configCrypter.DecryptDES(content); var childrenList = JToken.Parse(content).Children(); var parameters = new List(); foreach (var child in childrenList) { var setionParameters = ParseTokenSetions(child); parameters.AddRange(setionParameters); } return parameters; } private static IEnumerable ParseTokenSetions(JToken children) { var item = (JProperty)children; var parsedParameters = ParseToken(item.Name, item.Value.Children()).ToList(); return parsedParameters; } private static IEnumerable ParseToken(string sectionName, JEnumerable childrenList) { var parameters = new List(); foreach (var jToken in childrenList) { var item = (JProperty)jToken; if (item.Value is JArray jArray) { //TODO Do we have array parameter? continue; } if (item.Value is JObject jObject) { if (IsRangeParameter(jObject)) { var parameter = ParseRangeParameter(jObject, item.Name); parameter.Section = sectionName; parameters.Add(parameter); continue; } if (IsEnumParameter(jObject)) { var parameter = ParseEnumParameter(item.Name, jObject); parameter.Section = sectionName; parameters.Add(parameter); continue; } var parsedParameters = ParseToken(sectionName, jObject.Children()).ToList(); parameters.AddRange(parsedParameters); } if (item.Value is JValue jValue) { var parameter = ParseBasicParameter(jValue, item.Name); parameter.Section = sectionName; parameters.Add(parameter); } } return parameters; } private static bool IsEnumParameter(JObject jObject) { return jObject.Children().Any(m => ((JProperty)m).Name == "Source"); } private static bool IsRangeParameter(JObject jObject) { return jObject.Children().Any(m => ((JProperty)m).Name == "MaxValue"); } private static IParameter ParseEnumParameter(string name, JObject jObject) { var defaultValue = jObject["DefaultValue"]?.Value(); switch (defaultValue?.Type) { case JTokenType.String: return new EnumStringParameter { Name = name, Source = jObject["Source"].Values().ToList(), Value = defaultValue.Value() }; //TODO other types } throw new ArgumentException($"Invalid enum parameter {name}."); } private static IParameter ParseRangeParameter(JObject jObject, string key) { var max = jObject["MaxValue"].Value(); switch (max.Type) { case JTokenType.Integer: { if (max.Value() > int.MaxValue) { var defaultValue = jObject["DefaultValue"].Value(); var minValue = jObject["MinValue"].Value(); var maxValue = max.Value(); var longRangeValue = new RangeLongParameter { Name = key, Value = defaultValue, MaxValue = maxValue, MinValue = minValue }; } else { var defaultValue = jObject["DefaultValue"].Value(); var minValue = jObject["MinValue"].Value(); var maxValue = max.Value(); var intRangeValue = new RangeIntParameter { Name = key, Value = defaultValue, MaxValue = maxValue, MinValue = minValue }; } break; } } throw new ArgumentException($"Invalid range parameter with name {key}."); } private static IParameter ParseBasicParameter(JValue jValue, string key) { if (jValue.Type == JTokenType.Integer) { return new IntParameter { Name = key, Value = jValue.Value() }; } if (jValue.Type == JTokenType.Boolean) { return new BoolParameter { Name = key, Value = jValue.Value() }; } if (jValue.Type == JTokenType.String) { return new StringParameter { Name = key, Value = jValue.Value() }; } //TODO Implement FloatParameter //if (jValue.Type == JTokenType.Float) //{ // return new FloatParameter { Name = key, Value = jValue.Value() }; //} throw new ArgumentException($"Invalid jValue type {jValue.Type}"); } } }