From 30c1a0ff94cce6d16c8def295d185a6e1e6e60f4 Mon Sep 17 00:00:00 2001 From: ishkong <19740260+ishkong@users.noreply.github.com> Date: Sat, 23 Nov 2024 19:35:31 +0800 Subject: [PATCH 1/4] [OneBot] Correctly handle POST urlencode content being empty (#691) --- Lagrange.OneBot/Core/Network/Service/HttpService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Lagrange.OneBot/Core/Network/Service/HttpService.cs b/Lagrange.OneBot/Core/Network/Service/HttpService.cs index 72241db1a..6018a9e92 100644 --- a/Lagrange.OneBot/Core/Network/Service/HttpService.cs +++ b/Lagrange.OneBot/Core/Network/Service/HttpService.cs @@ -150,6 +150,7 @@ private async Task HandleRequestAsync(HttpListenerContext context, CancellationT var body = await reader.ReadToEndAsync(token); Log.LogReceived(_logger, identifier, body); var @params = body.Split('&') + .Where(pair => !string.IsNullOrEmpty(pair)) .Select(pair => pair.Split('=', 2)) .ToDictionary(pair => pair[0], pair => Uri.UnescapeDataString(pair[1])); payload = JsonSerializer.Serialize(new { action, @params }); From 5e7072c641d738749c016bd5d54a8af2761ce166 Mon Sep 17 00:00:00 2001 From: ishkong <19740260+ishkong@users.noreply.github.com> Date: Sat, 23 Nov 2024 20:20:39 +0800 Subject: [PATCH 2/4] [OneBot] Adjusting HTTP code to OneBot standards (#692) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/botuniverse/onebot-11/blob/d4456ee706f9ada9c2dfde56a2bcfc69752600e4/communication/http.md?plain=1#L41 所有的POST content-type不支持都应该返回406,所以哪怕遇到lgr无法处理的,也应该返回406 --- Lagrange.OneBot/Core/Network/Service/HttpService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lagrange.OneBot/Core/Network/Service/HttpService.cs b/Lagrange.OneBot/Core/Network/Service/HttpService.cs index 6018a9e92..690f0a17c 100644 --- a/Lagrange.OneBot/Core/Network/Service/HttpService.cs +++ b/Lagrange.OneBot/Core/Network/Service/HttpService.cs @@ -128,7 +128,7 @@ private async Task HandleRequestAsync(HttpListenerContext context, CancellationT if (!MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaType)) { Log.LogCannotParseMediaType(_logger, request.ContentType ?? string.Empty); - response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType; + response.StatusCode = (int)HttpStatusCode.NotAcceptable; response.Close(); return; } From c79f814b14943fa9ef95ab4fefb54b7dd69e58a0 Mon Sep 17 00:00:00 2001 From: DarkRRb <177549718+DarkRRb@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:22:48 +0800 Subject: [PATCH 3/4] [OneBot] fix check sequence (#696) --- .../Core/Operation/Message/SendGroupAiRecordOperation.cs | 5 ++++- .../Core/Operation/Message/SendGroupForwardOperation.cs | 4 ++++ .../Core/Operation/Message/SendGroupMessageOperation.cs | 8 ++++++-- .../Core/Operation/Message/SendMessageOperation.cs | 1 + .../Operation/Message/SendPrivateForwardOperation.cs | 1 + .../Operation/Message/SendPrivateMessageOperation.cs | 1 + Lagrange.OneBot/LagrangeAppBuilder.cs | 2 +- Lagrange.OneBot/Utility/QrCodeHelper.cs | 9 ++++++--- 8 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Lagrange.OneBot/Core/Operation/Message/SendGroupAiRecordOperation.cs b/Lagrange.OneBot/Core/Operation/Message/SendGroupAiRecordOperation.cs index 626e45074..858734ced 100644 --- a/Lagrange.OneBot/Core/Operation/Message/SendGroupAiRecordOperation.cs +++ b/Lagrange.OneBot/Core/Operation/Message/SendGroupAiRecordOperation.cs @@ -26,9 +26,12 @@ public async Task HandleOperation(BotContext context, JsonNode? pa ); if (code != 0 || recordEntity == null) return new OneBotResult(null, code, "failed"); - var chain = MessageBuilder.Group(message.GroupId).Add(recordEntity).Build(); var result = await context.SendMessage(chain); + + if (result.Result != 0) return new OneBotResult(null, (int)result.Result, "failed"); + if (result.Sequence == null || result.Sequence == 0) return new OneBotResult(null, 9000, "failed"); + int hash = MessageRecord.CalcMessageHash(chain.MessageId, result.Sequence ?? 0); return new OneBotResult(new OneBotMessageResponse(hash), (int)result.Result, "ok"); diff --git a/Lagrange.OneBot/Core/Operation/Message/SendGroupForwardOperation.cs b/Lagrange.OneBot/Core/Operation/Message/SendGroupForwardOperation.cs index 8e9f1272f..8714e0bf3 100644 --- a/Lagrange.OneBot/Core/Operation/Message/SendGroupForwardOperation.cs +++ b/Lagrange.OneBot/Core/Operation/Message/SendGroupForwardOperation.cs @@ -23,6 +23,10 @@ public async Task HandleOperation(BotContext context, JsonNode? pa var multi = new MultiMsgEntity(chains); var chain = MessageBuilder.Group(forward.GroupId).Add(multi).Build(); var ret = await context.SendMessage(chain); + + if (ret.Result != 0) return new OneBotResult(null, (int)ret.Result, "failed"); + if (ret.Sequence == null || ret.Sequence == 0) return new OneBotResult(null, 9000, "failed"); + int hash = MessageRecord.CalcMessageHash(chain.MessageId, ret.Sequence ?? 0); return new OneBotResult(new OneBotForwardResponse(hash, multi.ResId ?? ""), (int)ret.Result, "ok"); diff --git a/Lagrange.OneBot/Core/Operation/Message/SendGroupMessageOperation.cs b/Lagrange.OneBot/Core/Operation/Message/SendGroupMessageOperation.cs index 79703df7a..fd77191a8 100644 --- a/Lagrange.OneBot/Core/Operation/Message/SendGroupMessageOperation.cs +++ b/Lagrange.OneBot/Core/Operation/Message/SendGroupMessageOperation.cs @@ -21,10 +21,14 @@ public async Task HandleOperation(BotContext context, JsonNode? pa OneBotGroupMessageText messageText => common.ParseChain(messageText).Build(), _ => throw new Exception() }; - + var result = await context.SendMessage(chain); + + if (result.Result != 0) return new OneBotResult(null, (int)result.Result, "failed"); + if (result.Sequence == null || result.Sequence == 0) return new OneBotResult(null, 9000, "failed"); + int hash = MessageRecord.CalcMessageHash(chain.MessageId, result.Sequence ?? 0); - + return new OneBotResult(new OneBotMessageResponse(hash), (int)result.Result, "ok"); } } diff --git a/Lagrange.OneBot/Core/Operation/Message/SendMessageOperation.cs b/Lagrange.OneBot/Core/Operation/Message/SendMessageOperation.cs index 422bff57f..7d69f5f59 100644 --- a/Lagrange.OneBot/Core/Operation/Message/SendMessageOperation.cs +++ b/Lagrange.OneBot/Core/Operation/Message/SendMessageOperation.cs @@ -26,6 +26,7 @@ public async Task HandleOperation(BotContext context, JsonNode? pa var result = await context.SendMessage(chain); if (result.Result != 0) return new OneBotResult(null, (int)result.Result, "failed"); + if (result.Sequence == null || result.Sequence == 0) return new OneBotResult(null, 9000, "failed"); int hash = MessageRecord.CalcMessageHash(result.MessageId, result.Sequence ?? 0); diff --git a/Lagrange.OneBot/Core/Operation/Message/SendPrivateForwardOperation.cs b/Lagrange.OneBot/Core/Operation/Message/SendPrivateForwardOperation.cs index 16e18d0ce..f1bef6041 100644 --- a/Lagrange.OneBot/Core/Operation/Message/SendPrivateForwardOperation.cs +++ b/Lagrange.OneBot/Core/Operation/Message/SendPrivateForwardOperation.cs @@ -27,6 +27,7 @@ public async Task HandleOperation(BotContext context, JsonNode? pa var result = await context.SendMessage(chain); if (result.Result != 0) return new OneBotResult(null, (int)result.Result, "failed"); + if (result.Sequence == null || result.Sequence == 0) return new OneBotResult(null, 9000, "failed"); int hash = MessageRecord.CalcMessageHash(result.MessageId, result.Sequence ?? 0); diff --git a/Lagrange.OneBot/Core/Operation/Message/SendPrivateMessageOperation.cs b/Lagrange.OneBot/Core/Operation/Message/SendPrivateMessageOperation.cs index 88bc27197..e0f83828b 100644 --- a/Lagrange.OneBot/Core/Operation/Message/SendPrivateMessageOperation.cs +++ b/Lagrange.OneBot/Core/Operation/Message/SendPrivateMessageOperation.cs @@ -26,6 +26,7 @@ public async Task HandleOperation(BotContext context, JsonNode? pa var result = await context.SendMessage(chain); if (result.Result != 0) return new OneBotResult(null, (int)result.Result, "failed"); + if (result.Sequence == null || result.Sequence == 0) return new OneBotResult(null, 9000, "failed"); int hash = MessageRecord.CalcMessageHash(result.MessageId, result.Sequence ?? 0); diff --git a/Lagrange.OneBot/LagrangeAppBuilder.cs b/Lagrange.OneBot/LagrangeAppBuilder.cs index ed357287f..a7ca0d1fa 100644 --- a/Lagrange.OneBot/LagrangeAppBuilder.cs +++ b/Lagrange.OneBot/LagrangeAppBuilder.cs @@ -103,7 +103,7 @@ public LagrangeAppBuilder ConfigureBots() { appInfo = JsonSerializer.Deserialize(File.ReadAllText(appInfoPath)) ?? BotAppInfo.ProtocolToAppInfo[config.Protocol]; } - + Services.AddSingleton(BotFactory.Create(config, deviceInfo, keystore, appInfo)); return this; diff --git a/Lagrange.OneBot/Utility/QrCodeHelper.cs b/Lagrange.OneBot/Utility/QrCodeHelper.cs index f852286d1..ba870b686 100644 --- a/Lagrange.OneBot/Utility/QrCodeHelper.cs +++ b/Lagrange.OneBot/Utility/QrCodeHelper.cs @@ -23,14 +23,17 @@ internal static void Output(string text, bool compatibilityMode) if (foregroundBlack && !backgroundBlack) { Console.Write(bottomHalfBlock); - } else if (!foregroundBlack && backgroundBlack) + } + else if (!foregroundBlack && backgroundBlack) { Console.Write(topHalfBlock); - } else if (foregroundBlack && backgroundBlack) + } + else if (foregroundBlack && backgroundBlack) { Console.Write(emptyBlock); - } else if (!foregroundBlack && !backgroundBlack) + } + else if (!foregroundBlack && !backgroundBlack) { Console.Write(fullBlock); } From 22d6b79b1e402d38ef2bc222acef207b31b9887f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=84=91=E8=A2=8B=E9=87=8C=E8=BF=9B=E8=8A=B1=E7=94=9F?= =?UTF-8?q?=E4=BA=86?= <109732988+Redmomn@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:57:29 +0800 Subject: [PATCH 4/4] [All] feat: implemented delete friend (#697) * [Core] feat: implemented delete friend * [OneBot] feat: implemented delete friend * [Core] fix possible null reference --- .../Common/Interface/Api/OperationExt.cs | 5 ++- .../Logic/Implementation/OperationLogic.cs | 8 ++++ .../Event/Action/DeleteFriendEvent.cs | 20 +++++++++ .../Oidb/Request/OidbSvcTrpcTcp0x126B_0.cs | 45 +++++++++++++++++++ .../Service/Action/DeleteFriendService.cs | 39 ++++++++++++++++ .../Core/Entity/Action/OneBotDeleteFriend.cs | 11 +++++ .../Generic/DeleteFriendOperation.cs | 24 ++++++++++ 7 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 Lagrange.Core/Internal/Event/Action/DeleteFriendEvent.cs create mode 100644 Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x126B_0.cs create mode 100644 Lagrange.Core/Internal/Service/Action/DeleteFriendService.cs create mode 100644 Lagrange.OneBot/Core/Entity/Action/OneBotDeleteFriend.cs create mode 100644 Lagrange.OneBot/Core/Operation/Generic/DeleteFriendOperation.cs diff --git a/Lagrange.Core/Common/Interface/Api/OperationExt.cs b/Lagrange.Core/Common/Interface/Api/OperationExt.cs index c1fe6c111..b5f2cffc8 100644 --- a/Lagrange.Core/Common/Interface/Api/OperationExt.cs +++ b/Lagrange.Core/Common/Interface/Api/OperationExt.cs @@ -108,7 +108,7 @@ public static Task RecallFriendMessage(this BotContext bot, MessageChain c => bot.ContextCollection.Business.OperationLogic.FetchGroupRequests(); /// - /// + /// /// /// /// @@ -137,6 +137,9 @@ public static Task SetCustomStatus(this BotContext bot, uint faceId, strin public static Task GroupTransfer(this BotContext bot, uint groupUin, uint targetUin) => bot.ContextCollection.Business.OperationLogic.GroupTransfer(groupUin, targetUin); + public static Task DeleteFriend (this BotContext bot, uint friendUin, bool block) + =>bot.ContextCollection.Business.OperationLogic.DeleteFriend(friendUin, block); + public static Task RequestFriend(this BotContext bot, uint targetUin, string question = "", string message = "") => bot.ContextCollection.Business.OperationLogic.RequestFriend(targetUin, question, message); diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs index 1eae3b5b0..55b1dbb37 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs @@ -435,6 +435,14 @@ public async Task SetCustomStatus(uint faceId, string text) return results.Count != 0 && results[0].ResultCode == 0; } + public async Task DeleteFriend(uint targetUin, bool block) + { + var uid = await Collection.Business.CachingLogic.ResolveUid(null, targetUin); + var deleteFriendEvent = DeleteFriendEvent.Create(uid, block); + var results = await Collection.Business.SendEvent(deleteFriendEvent); + return results.Count != 0 && results[0].ResultCode == 0; + } + public async Task RequestFriend(uint targetUin, string question, string message) { var requestFriendSearchEvent = RequestFriendSearchEvent.Create(targetUin); diff --git a/Lagrange.Core/Internal/Event/Action/DeleteFriendEvent.cs b/Lagrange.Core/Internal/Event/Action/DeleteFriendEvent.cs new file mode 100644 index 000000000..05e1d5bae --- /dev/null +++ b/Lagrange.Core/Internal/Event/Action/DeleteFriendEvent.cs @@ -0,0 +1,20 @@ +namespace Lagrange.Core.Internal.Event.Action; + +internal class DeleteFriendEvent : ProtocolEvent +{ + public string? TargetUid { get; set; } + + public bool Block { get; set; } + + private DeleteFriendEvent(string? targetUid, bool block) : base(true) + { + TargetUid = targetUid; + Block = block; + } + + private DeleteFriendEvent(int resultCode) : base(resultCode) { } + + public static DeleteFriendEvent Create(string? targetUid, bool block) => new (targetUid, block); + + public static DeleteFriendEvent Result(int resultCode) => new (resultCode); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x126B_0.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x126B_0.cs new file mode 100644 index 000000000..f39e753f7 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x126B_0.cs @@ -0,0 +1,45 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +// ReSharper disable InconsistentNaming +#pragma warning disable CS8618 + +[ProtoContract] +[OidbSvcTrpcTcp(0x126B, 0)] +internal class OidbSvcTrpcTcp0x126B_0 +{ + [ProtoMember(1)] public OidbSvcTrpcTcp0x126B_0_Field1 Field1 { get; set; } = new(); +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x126B_0_Field1 +{ + [ProtoMember(1)] public string? TargetUid { get; set; } + + [ProtoMember(2)] public OidbSvcTrpcTcp0x126B_0_Field1_2 Field2 { get; set; } = new(); + + [ProtoMember(3)] public bool Block { get; set; } + + [ProtoMember(4)] public bool Field4 { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x126B_0_Field1_2 +{ + [ProtoMember(1)] public uint Field1 { get; set; } = 130; + + [ProtoMember(2)] public uint Field2 { get; set; } = 109; + + [ProtoMember(3)] public OidbSvcTrpcTcp0x126B_0_Field1_2_3 Field3 { get; set; } = new(); +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x126B_0_Field1_2_3 +{ + [ProtoMember(1)] public uint Field1 { get; set; } = 8; + + [ProtoMember(2)] public uint Field2 { get; set; } = 8; + + [ProtoMember(3)] public uint Field3 { get; set; } = 50; +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Action/DeleteFriendService.cs b/Lagrange.Core/Internal/Service/Action/DeleteFriendService.cs new file mode 100644 index 000000000..bfa49e288 --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/DeleteFriendService.cs @@ -0,0 +1,39 @@ +using Lagrange.Core.Common; +using Lagrange.Core.Internal.Event; +using Lagrange.Core.Internal.Event.Action; +using Lagrange.Core.Internal.Packets.Service.Oidb; +using Lagrange.Core.Internal.Packets.Service.Oidb.Request; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(DeleteFriendEvent))] +[Service("OidbSvcTrpcTcp.0x126b_0")] +internal class DeleteFriendService : BaseService +{ + protected override bool Build(DeleteFriendEvent input, BotKeystore keystore, BotAppInfo appInfo, + BotDeviceInfo device, out Span output, + out List>? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(new OidbSvcTrpcTcp0x126B_0 + { + Field1 = new OidbSvcTrpcTcp0x126B_0_Field1 { TargetUid = input.TargetUid, Block = input.Block } + },0x126b, 0, false, false); + + output = packet.Serialize(); + extraPackets = null; + return true; + } + + protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out DeleteFriendEvent output, + out List? extraEvents) + { + var payload = Serializer.Deserialize>(input); + + output = DeleteFriendEvent.Result((int)payload.ErrorCode); + extraEvents = null; + return true; + } +} \ No newline at end of file diff --git a/Lagrange.OneBot/Core/Entity/Action/OneBotDeleteFriend.cs b/Lagrange.OneBot/Core/Entity/Action/OneBotDeleteFriend.cs new file mode 100644 index 000000000..2e757d683 --- /dev/null +++ b/Lagrange.OneBot/Core/Entity/Action/OneBotDeleteFriend.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace Lagrange.OneBot.Core.Entity.Action; + +[Serializable] +public class OneBotDeleteFriend +{ + [JsonPropertyName("user_id")] public uint UserId { get; set; } + + [JsonPropertyName("block")] public bool Block { get; set; } +} \ No newline at end of file diff --git a/Lagrange.OneBot/Core/Operation/Generic/DeleteFriendOperation.cs b/Lagrange.OneBot/Core/Operation/Generic/DeleteFriendOperation.cs new file mode 100644 index 000000000..a0309f8d2 --- /dev/null +++ b/Lagrange.OneBot/Core/Operation/Generic/DeleteFriendOperation.cs @@ -0,0 +1,24 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using Lagrange.Core; +using Lagrange.Core.Common.Interface.Api; +using Lagrange.OneBot.Core.Entity.Action; +using Lagrange.OneBot.Core.Operation.Converters; + +namespace Lagrange.OneBot.Core.Operation.Generic; + +[Operation("delete_friend")] +public class DeleteFriendOperation : IOperation +{ + public async Task HandleOperation(BotContext context, JsonNode? payload) + { + if (payload.Deserialize(SerializerOptions.DefaultOptions) is {} delete) + { + return await context.DeleteFriend(delete.UserId, delete.Block) + ? new OneBotResult(null, 0, "ok") + : new OneBotResult(null, 0, "failed"); + } + + throw new Exception(); + } +} \ No newline at end of file