ParameterDictionarySerializer.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System.Collections.Concurrent;
  2. using Newtonsoft.Json.Linq;
  3. namespace WingServerCommon.Config.Parameters
  4. {
  5. public class ParameterDictionarySerializer
  6. {
  7. /// <summary>
  8. /// Deserialize json file to parameter
  9. /// </summary>
  10. /// <param name="str">File path or json string that will be deserialize</param>
  11. /// <param name="type">str type, 0-file Path, 1-json string</param>
  12. /// <returns>Parameter list.</returns>
  13. public static ConcurrentDictionary<string, IParameter> Deserialize(string str, int type = 0)
  14. {
  15. var content = "";
  16. if (type == 0)
  17. {
  18. content = File.ReadAllText(str);
  19. }
  20. else
  21. {
  22. content = str;
  23. }
  24. //Decrypt text
  25. var configCrypter = new ConfigCrypter();
  26. content = configCrypter.DecryptDES(content);
  27. var childrenList = JToken.Parse(content).Children();
  28. var parameters = new ConcurrentDictionary<string, IParameter>();
  29. foreach (var child in childrenList)
  30. {
  31. ParseTokenSetions(child, ref parameters);
  32. }
  33. return parameters;
  34. }
  35. private static void ParseTokenSetions(JToken children, ref ConcurrentDictionary<string, IParameter> dic)
  36. {
  37. var item = (JProperty)children;
  38. ParseToken(item.Name, item.Value.Children(), ref dic);
  39. }
  40. private static void ParseToken(string sectionName, JEnumerable<JToken> childrenList, ref ConcurrentDictionary<string, IParameter> parameters)
  41. {
  42. foreach (var jToken in childrenList)
  43. {
  44. var item = (JProperty)jToken;
  45. if (item.Value is JArray jArray)
  46. {
  47. //TODO Do we have array parameter?
  48. continue;
  49. }
  50. if (item.Value is JObject jObject)
  51. {
  52. if (IsRangeParameter(jObject))
  53. {
  54. var parameter = ParseRangeParameter(jObject, item.Name);
  55. parameter.Section = sectionName;
  56. var rangeKey = parameter.Section + "_" + parameter.Name;
  57. parameters.TryAdd(rangeKey, parameter);
  58. continue;
  59. }
  60. if (IsEnumParameter(jObject))
  61. {
  62. var parameter = ParseEnumParameter(item.Name, jObject);
  63. parameter.Section = sectionName;
  64. var enumKey = parameter.Section + "_" + parameter.Name;
  65. parameters.TryAdd(enumKey, parameter);
  66. continue;
  67. }
  68. ParseToken(sectionName, jObject.Children(), ref parameters);
  69. }
  70. if (item.Value is JValue jValue)
  71. {
  72. var parameter = ParseBasicParameter(jValue, item.Name);
  73. parameter.Section = sectionName;
  74. var valueKey = parameter.Section + "_" + parameter.Name;
  75. parameters.TryAdd(valueKey, parameter);
  76. }
  77. }
  78. }
  79. private static bool IsEnumParameter(JObject jObject)
  80. {
  81. return jObject.Children().Any(m => ((JProperty)m).Name == "Source");
  82. }
  83. private static bool IsRangeParameter(JObject jObject)
  84. {
  85. return jObject.Children().Any(m => ((JProperty)m).Name == "MaxValue");
  86. }
  87. private static IParameter ParseEnumParameter(string name, JObject jObject)
  88. {
  89. var defaultValue = jObject["DefaultValue"]?.Value<JValue>();
  90. switch (defaultValue?.Type)
  91. {
  92. case JTokenType.String:
  93. return new EnumStringParameter
  94. {
  95. Name = name,
  96. Source = jObject["Source"].Values<string>().ToList(),
  97. Value = defaultValue.Value<string>()
  98. };
  99. //TODO other types
  100. }
  101. throw new ArgumentException($"Invalid enum parameter {name}.");
  102. }
  103. private static IParameter ParseRangeParameter(JObject jObject, string key)
  104. {
  105. var max = jObject["MaxValue"].Value<JValue>();
  106. switch (max.Type)
  107. {
  108. case JTokenType.Integer:
  109. {
  110. if (max.Value<long>() > int.MaxValue)
  111. {
  112. var defaultValue = jObject["DefaultValue"].Value<long>();
  113. var minValue = jObject["MinValue"].Value<long>();
  114. var maxValue = max.Value<long>();
  115. var longRangeValue = new RangeLongParameter
  116. {
  117. Name = key,
  118. Value = defaultValue,
  119. MaxValue = maxValue,
  120. MinValue = minValue
  121. };
  122. }
  123. else
  124. {
  125. var defaultValue = jObject["DefaultValue"].Value<int>();
  126. var minValue = jObject["MinValue"].Value<int>();
  127. var maxValue = max.Value<int>();
  128. var intRangeValue = new RangeIntParameter
  129. {
  130. Name = key,
  131. Value = defaultValue,
  132. MaxValue = maxValue,
  133. MinValue = minValue
  134. };
  135. }
  136. break;
  137. }
  138. }
  139. throw new ArgumentException($"Invalid range parameter with name {key}.");
  140. }
  141. private static IParameter ParseBasicParameter(JValue jValue, string key)
  142. {
  143. if (jValue.Type == JTokenType.Integer)
  144. {
  145. return new IntParameter { Name = key, Value = jValue.Value<int>() };
  146. }
  147. if (jValue.Type == JTokenType.Boolean)
  148. {
  149. return new BoolParameter { Name = key, Value = jValue.Value<bool>() };
  150. }
  151. if (jValue.Type == JTokenType.String)
  152. {
  153. return new StringParameter { Name = key, Value = jValue.Value<string>() };
  154. }
  155. //TODO Implement FloatParameter
  156. //if (jValue.Type == JTokenType.Float)
  157. //{
  158. // return new FloatParameter { Name = key, Value = jValue.Value<double>() };
  159. //}
  160. throw new ArgumentException($"Invalid jValue type {jValue.Type}");
  161. }
  162. }
  163. }