MongoHelper.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. }
  96. public static void RegisterStruct<T>() where T : struct
  97. {
  98. BsonSerializer.RegisterSerializer(typeof (T), new StructBsonSerialize<T>());
  99. }
  100. public static string ToJson(object obj)
  101. {
  102. return obj.ToJson(defaultSettings);
  103. }
  104. public static string ToJson(object obj, JsonWriterSettings settings)
  105. {
  106. return obj.ToJson(settings);
  107. }
  108. public static T FromJson<T>(string str)
  109. {
  110. try
  111. {
  112. return BsonSerializer.Deserialize<T>(str);
  113. }
  114. catch (Exception e)
  115. {
  116. throw new Exception($"{str}\n{e}");
  117. }
  118. }
  119. public static object FromJson(Type type, string str)
  120. {
  121. return BsonSerializer.Deserialize(str, type);
  122. }
  123. public static byte[] Serialize(object obj)
  124. {
  125. return obj.ToBson();
  126. }
  127. public static void Serialize(object message, MemoryStream stream)
  128. {
  129. using (BsonBinaryWriter bsonWriter = new BsonBinaryWriter(stream, BsonBinaryWriterSettings.Defaults))
  130. {
  131. BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter);
  132. BsonSerializationArgs args = default;
  133. args.NominalType = typeof (object);
  134. IBsonSerializer serializer = BsonSerializer.LookupSerializer(args.NominalType);
  135. serializer.Serialize(context, args, message);
  136. }
  137. }
  138. public static object Deserialize(Type type, byte[] bytes)
  139. {
  140. try
  141. {
  142. return BsonSerializer.Deserialize(bytes, type);
  143. }
  144. catch (Exception e)
  145. {
  146. throw new Exception($"from bson error: {type.Name}", e);
  147. }
  148. }
  149. public static object Deserialize(Type type, byte[] bytes, int index, int count)
  150. {
  151. try
  152. {
  153. using (MemoryStream memoryStream = new MemoryStream(bytes, index, count))
  154. {
  155. return BsonSerializer.Deserialize(memoryStream, type);
  156. }
  157. }
  158. catch (Exception e)
  159. {
  160. throw new Exception($"from bson error: {type.Name}", e);
  161. }
  162. }
  163. public static object Deserialize(Type type, Stream stream)
  164. {
  165. try
  166. {
  167. return BsonSerializer.Deserialize(stream, type);
  168. }
  169. catch (Exception e)
  170. {
  171. throw new Exception($"from bson error: {type.Name}", e);
  172. }
  173. }
  174. public static T Deserialize<T>(byte[] bytes)
  175. {
  176. try
  177. {
  178. using (MemoryStream memoryStream = new MemoryStream(bytes))
  179. {
  180. return (T)BsonSerializer.Deserialize(memoryStream, typeof (T));
  181. }
  182. }
  183. catch (Exception e)
  184. {
  185. throw new Exception($"from bson error: {typeof (T).Name}", e);
  186. }
  187. }
  188. public static T Deserialize<T>(byte[] bytes, int index, int count)
  189. {
  190. return (T)Deserialize(typeof (T), bytes, index, count);
  191. }
  192. public static T Clone<T>(T t)
  193. {
  194. return Deserialize<T>(Serialize(t));
  195. }
  196. }
  197. }