MongoHelper.cs 7.2 KB

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