MongoHelper.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Reflection;
  5. using MongoDB.Bson;
  6. using MongoDB.Bson.IO;
  7. using MongoDB.Bson.Serialization;
  8. using MongoDB.Bson.Serialization.Conventions;
  9. using MongoDB.Bson.Serialization.Serializers;
  10. using Unity.Mathematics;
  11. namespace ET
  12. {
  13. public static class MongoHelper
  14. {
  15. private class StructBsonSerialize<TValue>: StructSerializerBase<TValue> where TValue : struct
  16. {
  17. public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value)
  18. {
  19. Type nominalType = args.NominalType;
  20. IBsonWriter bsonWriter = context.Writer;
  21. bsonWriter.WriteStartDocument();
  22. FieldInfo[] fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  23. foreach (FieldInfo field in fields)
  24. {
  25. bsonWriter.WriteName(field.Name);
  26. BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value));
  27. }
  28. bsonWriter.WriteEndDocument();
  29. }
  30. public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
  31. {
  32. //boxing is required for SetValue to work
  33. object obj = new TValue();
  34. Type actualType = args.NominalType;
  35. IBsonReader bsonReader = context.Reader;
  36. bsonReader.ReadStartDocument();
  37. while (bsonReader.State != BsonReaderState.EndOfDocument)
  38. {
  39. switch (bsonReader.State)
  40. {
  41. case BsonReaderState.Name:
  42. {
  43. string name = bsonReader.ReadName(Utf8NameDecoder.Instance);
  44. FieldInfo field = actualType.GetField(name);
  45. if (field != null)
  46. {
  47. object value = BsonSerializer.Deserialize(bsonReader, field.FieldType);
  48. field.SetValue(obj, value);
  49. }
  50. break;
  51. }
  52. case BsonReaderState.Type:
  53. {
  54. bsonReader.ReadBsonType();
  55. break;
  56. }
  57. case BsonReaderState.Value:
  58. {
  59. bsonReader.SkipValue();
  60. break;
  61. }
  62. }
  63. }
  64. bsonReader.ReadEndDocument();
  65. return (TValue)obj;
  66. }
  67. }
  68. [StaticField]
  69. private static readonly JsonWriterSettings defaultSettings = new() { OutputMode = JsonOutputMode.RelaxedExtendedJson };
  70. static MongoHelper()
  71. {
  72. // 自动注册IgnoreExtraElements
  73. ConventionPack conventionPack = new ConventionPack { new IgnoreExtraElementsConvention(true) };
  74. ConventionRegistry.Register("IgnoreExtraElements", conventionPack, type => true);
  75. RegisterStruct<float2>();
  76. RegisterStruct<float3>();
  77. RegisterStruct<float4>();
  78. RegisterStruct<quaternion>();
  79. Dictionary<string, Type> types = EventSystem.Instance.GetTypes();
  80. foreach (Type type in types.Values)
  81. {
  82. if (!type.IsSubclassOf(typeof (Object)))
  83. {
  84. continue;
  85. }
  86. if (type.IsGenericType)
  87. {
  88. continue;
  89. }
  90. BsonClassMap.LookupClassMap(type);
  91. }
  92. }
  93. public static void Init()
  94. {
  95. ObjectSerializer objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) || type.FullName.StartsWith("ET"));
  96. BsonSerializer.RegisterSerializer(objectSerializer);
  97. }
  98. public static void RegisterStruct<T>() where T : struct
  99. {
  100. BsonSerializer.RegisterSerializer(typeof (T), new StructBsonSerialize<T>());
  101. }
  102. public static string ToJson(object obj)
  103. {
  104. return obj.ToJson(defaultSettings);
  105. }
  106. public static string ToJson(object obj, JsonWriterSettings settings)
  107. {
  108. return obj.ToJson(settings);
  109. }
  110. public static T FromJson<T>(string str)
  111. {
  112. try
  113. {
  114. return BsonSerializer.Deserialize<T>(str);
  115. }
  116. catch (Exception e)
  117. {
  118. throw new Exception($"{str}\n{e}");
  119. }
  120. }
  121. public static object FromJson(Type type, string str)
  122. {
  123. return BsonSerializer.Deserialize(str, type);
  124. }
  125. public static byte[] Serialize(object obj)
  126. {
  127. return obj.ToBson();
  128. }
  129. public static void Serialize(object message, MemoryStream stream)
  130. {
  131. using (BsonBinaryWriter bsonWriter = new BsonBinaryWriter(stream, BsonBinaryWriterSettings.Defaults))
  132. {
  133. BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter);
  134. BsonSerializationArgs args = default;
  135. args.NominalType = typeof (object);
  136. IBsonSerializer serializer = BsonSerializer.LookupSerializer(args.NominalType);
  137. serializer.Serialize(context, args, message);
  138. }
  139. }
  140. public static object Deserialize(Type type, byte[] bytes)
  141. {
  142. try
  143. {
  144. return BsonSerializer.Deserialize(bytes, type);
  145. }
  146. catch (Exception e)
  147. {
  148. throw new Exception($"from bson error: {type.Name}", e);
  149. }
  150. }
  151. public static object Deserialize(Type type, byte[] bytes, int index, int count)
  152. {
  153. try
  154. {
  155. using (MemoryStream memoryStream = new MemoryStream(bytes, index, count))
  156. {
  157. return BsonSerializer.Deserialize(memoryStream, type);
  158. }
  159. }
  160. catch (Exception e)
  161. {
  162. throw new Exception($"from bson error: {type.Name}", e);
  163. }
  164. }
  165. public static object Deserialize(Type type, Stream stream)
  166. {
  167. try
  168. {
  169. return BsonSerializer.Deserialize(stream, type);
  170. }
  171. catch (Exception e)
  172. {
  173. throw new Exception($"from bson error: {type.Name}", e);
  174. }
  175. }
  176. public static T Deserialize<T>(byte[] bytes)
  177. {
  178. try
  179. {
  180. using (MemoryStream memoryStream = new MemoryStream(bytes))
  181. {
  182. return (T)BsonSerializer.Deserialize(memoryStream, typeof (T));
  183. }
  184. }
  185. catch (Exception e)
  186. {
  187. throw new Exception($"from bson error: {typeof (T).Name}", e);
  188. }
  189. }
  190. public static T Deserialize<T>(byte[] bytes, int index, int count)
  191. {
  192. return (T)Deserialize(typeof (T), bytes, index, count);
  193. }
  194. public static T Clone<T>(T t)
  195. {
  196. return Deserialize<T>(Serialize(t));
  197. }
  198. }
  199. }