diff --git a/Lagrange.OneBot/LagrangeAppBuilder.cs b/Lagrange.OneBot/LagrangeAppBuilder.cs index 11bb6e864..5f8ac37ea 100644 --- a/Lagrange.OneBot/LagrangeAppBuilder.cs +++ b/Lagrange.OneBot/LagrangeAppBuilder.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using Lagrange.Core.Common; using Lagrange.Core.Common.Interface; using Lagrange.Core.Utility.Sign; @@ -119,6 +118,12 @@ public LagrangeAppBuilder ConfigureOneBot() BsonMapper.Global.TrimWhitespace = false; BsonMapper.Global.EmptyStringToNull = false; + // Specify ctor for some classes + BsonMapper.Global.RegisterType( + LiteDbUtility.IMessageEntitySerialize, + LiteDbUtility.IMessageEntityDeserialize + ); + string path = Configuration["ConfigPath:Database"] ?? $"lagrange-{Configuration["Account:Uin"]}.db"; bool isFirstCreate = false; diff --git a/Lagrange.OneBot/Utility/LiteDbUtility.cs b/Lagrange.OneBot/Utility/LiteDbUtility.cs new file mode 100644 index 000000000..006e566b5 --- /dev/null +++ b/Lagrange.OneBot/Utility/LiteDbUtility.cs @@ -0,0 +1,49 @@ +using Lagrange.Core.Message; +using Lagrange.Core.Message.Entity; +using LiteDB; + +namespace Lagrange.OneBot.Utility; + +public static class LiteDbUtility +{ + public static BsonValue IMessageEntitySerialize(IMessageEntity entity) + { + var type = entity.GetType(); + var result = BsonMapper.Global.Serialize(type, entity); + result["_type"] = new BsonValue(DefaultTypeNameBinder.Instance.GetName(type)); + return result; + } + + public static IMessageEntity IMessageEntityDeserialize(BsonValue bson) + { + if (!bson.IsDocument) throw new Exception("bson not BsonDocument"); + + var doc = bson.AsDocument; + if (!doc.TryGetValue("_type", out var typeBson) || !typeBson.IsString) + { + throw new Exception("no `_type` or `_type` not string"); + } + + var type = DefaultTypeNameBinder.Instance.GetType(typeBson.AsString); + + if (type == typeof(MarkdownEntity)) return MarkdownEntityDeserialize(doc); + + return (IMessageEntity)BsonMapper.Global.Deserialize(type, bson); + } + + private static MarkdownEntity MarkdownEntityDeserialize(BsonDocument doc) + { + if (!doc.TryGetValue("Data", out var dataBson) || !dataBson.IsDocument) + { + throw new Exception("no `Data` or `Data` not document"); + } + + var dataDocument = dataBson.AsDocument; + if (!dataDocument.TryGetValue("Content", out var contentBson) || !contentBson.IsString) + { + throw new InvalidCastException("no `Data.Content` or `Data.Content` not string"); + } + + return new(new MarkdownData() { Content = contentBson.AsString }); + } +} \ No newline at end of file