From ad2c4a5207d3f17214c6e83eefc45dcc17b66277 Mon Sep 17 00:00:00 2001 From: CwkDark <177549718+CwkDark@users.noreply.github.com> Date: Fri, 23 Aug 2024 20:06:04 +0800 Subject: [PATCH 01/11] add git version info (#542) --- Lagrange.OneBot/Program.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lagrange.OneBot/Program.cs b/Lagrange.OneBot/Program.cs index 5152070a9..bb47932f6 100644 --- a/Lagrange.OneBot/Program.cs +++ b/Lagrange.OneBot/Program.cs @@ -9,6 +9,11 @@ internal abstract class Program { public static void Main(string[] args) { + string version = Assembly.GetAssembly(typeof(Program))? + .GetCustomAttribute()? + .InformationalVersion ?? "Unknown Lagrange.OneBot Version"; + Console.WriteLine($"Lagrange.OneBot Version: {version}\n"); + Console.OutputEncoding = Encoding.UTF8; Console.InputEncoding = Encoding.UTF8; From 207e0197359a0d63395fd77791a25e73f535d926 Mon Sep 17 00:00:00 2001 From: dogdie233 Date: Fri, 23 Aug 2024 20:06:59 +0800 Subject: [PATCH 02/11] =?UTF-8?q?[Core]=20Group=20clock=20in=20=E7=BE=A4?= =?UTF-8?q?=E6=89=93=E5=8D=A1=20(#528)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Core] Group clock in 群打卡 * OIdb subCmd漏了,补上ww --- .../Common/Entity/BotGroupClockInResult.cs | 52 +++++++++++++++ .../Common/Interface/Api/OperationExt.cs | 9 +++ .../Logic/Implementation/OperationLogic.cs | 7 +++ .../Event/Action/GroupClockInEvent.cs | 24 +++++++ .../Oidb/Request/OidbSvcTrpcTcp0xEB7_1.cs | 27 ++++++++ .../Response/OidbSvcTrpcTcp0xEB7_1Response.cs | 27 ++++++++ .../Service/Action/GroupClockInService.cs | 63 +++++++++++++++++++ 7 files changed, 209 insertions(+) create mode 100644 Lagrange.Core/Common/Entity/BotGroupClockInResult.cs create mode 100644 Lagrange.Core/Internal/Event/Action/GroupClockInEvent.cs create mode 100644 Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0xEB7_1.cs create mode 100644 Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0xEB7_1Response.cs create mode 100644 Lagrange.Core/Internal/Service/Action/GroupClockInService.cs diff --git a/Lagrange.Core/Common/Entity/BotGroupClockInResult.cs b/Lagrange.Core/Common/Entity/BotGroupClockInResult.cs new file mode 100644 index 000000000..1520d32c1 --- /dev/null +++ b/Lagrange.Core/Common/Entity/BotGroupClockInResult.cs @@ -0,0 +1,52 @@ +namespace Lagrange.Core.Common.Entity; + +[Serializable] +public class BotGroupClockInResult +{ + public BotGroupClockInResult() { } + + public BotGroupClockInResult(bool isSuccess) + { + IsSuccess = isSuccess; + } + + /// + /// Is the clock in successful + /// + public bool IsSuccess { get; set; } = false; + + /// + /// Maybe "今日已成功打卡" + /// + public string Title { get; set; } = string.Empty; + + /// + /// Maybe "已打卡N天" + /// + public string KeepDayText { get; set; } = string.Empty; + + /// + /// Maybe "群内排名第N位" + /// + public string GroupRankText { get; set; } = string.Empty; + + /// + /// The utc time of clock in + /// + public DateTime ClockInUtcTime { get; set; } = DateTime.UnixEpoch; // 打卡时间 + + /// + /// Detail info url + /// + public string DetailUrl { get; set; } = string.Empty; // https://qun.qq.com/v2/signin/detail?... + + public static BotGroupClockInResult Fail() => new BotGroupClockInResult() + { + IsSuccess = false + }; + + public static BotGroupClockInResult Success() => new BotGroupClockInResult() + { + IsSuccess = true + }; +} diff --git a/Lagrange.Core/Common/Interface/Api/OperationExt.cs b/Lagrange.Core/Common/Interface/Api/OperationExt.cs index 4c37edb19..ef1fb80a7 100644 --- a/Lagrange.Core/Common/Interface/Api/OperationExt.cs +++ b/Lagrange.Core/Common/Interface/Api/OperationExt.cs @@ -152,6 +152,15 @@ public static Task Like(this BotContext bot, uint targetUin, uint count = return bot.ContextCollection.Business.OperationLogic.GetRoamMessage(targetChain.FriendUin, timestamp, count); } + /// + /// Do group clock in (群打卡) + /// + /// target BotContext + /// target groupUin + /// + public static Task ClockInGroup(this BotContext bot, uint groupUin) + => bot.ContextCollection.Business.OperationLogic.ClockInGroup(groupUin); + public static Task FetchUserInfo(this BotContext bot, uint uin, bool refreshCache = false) => bot.ContextCollection.Business.OperationLogic.FetchUserInfo(uin, refreshCache); diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs index 54ad40491..ff9aff75a 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs @@ -453,4 +453,11 @@ public async Task SetNeedToConfirmSwitch(bool enableNoNeed) var results = await Collection.Business.SendEvent(fetchMarketFaceKeyEvent); return results.Count != 0 ? ((FetchMarketFaceKeyEvent)results[0]).Keys : null; } + + public async Task ClockInGroup(uint groupUin) + { + var groupClockInEvent = GroupClockInEvent.Create(groupUin); + var results = await Collection.Business.SendEvent(groupClockInEvent); + return ((GroupClockInEvent)results[0]).ResultInfo ?? new BotGroupClockInResult(false); + } } \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Action/GroupClockInEvent.cs b/Lagrange.Core/Internal/Event/Action/GroupClockInEvent.cs new file mode 100644 index 000000000..e7d1c6209 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Action/GroupClockInEvent.cs @@ -0,0 +1,24 @@ +using Lagrange.Core.Common.Entity; + +namespace Lagrange.Core.Internal.Event.Action; + +internal class GroupClockInEvent : ProtocolEvent +{ + public uint GroupUin { get; set; } + public BotGroupClockInResult? ResultInfo { get; set; } + + private GroupClockInEvent(uint groupUin) : base(true) + { + GroupUin = groupUin; + ResultInfo = null; + } + + private GroupClockInEvent(int resultCode, BotGroupClockInResult result) : base(resultCode) + { + ResultInfo = result; + } + + public static GroupClockInEvent Create(uint groupUin) => new(groupUin); + + public static GroupClockInEvent Result(int resultCode, BotGroupClockInResult result) => new(resultCode, result); +} diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0xEB7_1.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0xEB7_1.cs new file mode 100644 index 000000000..007bc21c3 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0xEB7_1.cs @@ -0,0 +1,27 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +/// +/// Group Clock In +/// +[ProtoContract] +[OidbSvcTrpcTcp(0xEB7, 1)] +internal class OidbSvcTrpcTcp0xEB7_1 +{ + [ProtoMember(2)] public BodyClass Body { get; set; } + + [ProtoContract] + internal class BodyClass + { + [ProtoMember(1)] public string Uin { get; set; } + + [ProtoMember(2)] public string GroupUin { get; set; } + + // 不确定要不要加,测试过没有这个参数也是可以的 + [ProtoMember(3)] public string AppVersion { get; set; } + } +} diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0xEB7_1Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0xEB7_1Response.cs new file mode 100644 index 000000000..fe4b7648d --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0xEB7_1Response.cs @@ -0,0 +1,27 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Response; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +[ProtoContract] +internal class OidbSvcTrpcTcp0xEB7_1Response +{ + [ProtoMember(2)] public BodyClass Body { get; set; } + + [ProtoContract] + internal class BodyClass + { + [ProtoMember(2)] public ResultClass Result { get; set; } + + [ProtoContract] + internal class ResultClass + { + [ProtoMember(1)] public string Title { get; set; } // 今日已成功打卡 + [ProtoMember(2)] public string KeepDayText { get; set; } // 已打卡N天 + [ProtoMember(3)] public string[] ClockInInfo1 { get; set; } // ["群内排名第N位", "[clock in timestamp (second)]"] + [ProtoMember(4)] public string DetailUrl { get; set; } // https://qun.qq.com/v2/signin/detail?... + } + } +} diff --git a/Lagrange.Core/Internal/Service/Action/GroupClockInService.cs b/Lagrange.Core/Internal/Service/Action/GroupClockInService.cs new file mode 100644 index 000000000..fa1d6acd7 --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/GroupClockInService.cs @@ -0,0 +1,63 @@ +using Lagrange.Core.Common; +using Lagrange.Core.Common.Entity; +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.Internal.Packets.Service.Oidb.Response; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(GroupClockInEvent))] +[Service("OidbSvcTrpcTcp.0xeb7_1")] +internal class GroupClockInService : BaseService +{ + protected override bool Build(GroupClockInEvent input, BotKeystore keystore, BotAppInfo appInfo, + BotDeviceInfo device, out Span output, out List>? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(new() + { + Body = new() + { + Uin = keystore.Uin.ToString(), + GroupUin = input.GroupUin.ToString(), + AppVersion = appInfo.CurrentVersion + } + }); + + output = packet.Serialize(); + extraPackets = null; + return true; + } + + protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo appInfo, + BotDeviceInfo device, out GroupClockInEvent output, out List? extraEvents) + { + var payload = Serializer.Deserialize>(input); + extraEvents = null; + + var payloadResult = payload.Body?.Body?.Result; + if (payload.ErrorCode != 0 || payloadResult == null) + { + output = GroupClockInEvent.Result((int)payload.ErrorCode, new BotGroupClockInResult(false)); + return true; + } + + if (payloadResult.ClockInInfo1 is not { Length: > 1 } || !long.TryParse(payloadResult.ClockInInfo1[1], out var clockInTimestamp)) + clockInTimestamp = 0; + + var result = new BotGroupClockInResult(true) + { + Title = payloadResult.Title ?? string.Empty, + KeepDayText = payloadResult.KeepDayText ?? string.Empty, + GroupRankText = payloadResult.ClockInInfo1 is { Length: > 0 } ? payloadResult.ClockInInfo1[0] : string.Empty, + ClockInUtcTime = DateTime.UnixEpoch + TimeSpan.FromSeconds(clockInTimestamp), + DetailUrl = payloadResult.DetailUrl ?? string.Empty, + }; + output = GroupClockInEvent.Result((int)payload.ErrorCode, result); + + return true; + } +} From 1a8f1710ad3d205d56e22661c32449c7a2f4eefc Mon Sep 17 00:00:00 2001 From: pk5ls20 Date: Fri, 23 Aug 2024 20:14:37 +0800 Subject: [PATCH 03/11] [All] Add DeleteGroupFolderOp & adjust CreateGroupFolderOp (#540) * [All] Add `DeleteGroupFileFolderOperation` & adjust `CreateGroupFileFolderOperation` - Implemented `DeleteGroupFileFolderOperation` - Add error codes and error messages obtained from the server response for both `DeleteGroupFileFolderOperation` and `CreateGroupFileFolderOperation` - fix Oidb subCmd in `OidbSvcTrpcTcp0x6D7_0.cs` * chore: use Tuple instead of KeyValuePair, resolve https://github.com/LagrangeDev/Lagrange.Core/pull/540#discussion_r1728863261 --- .../Common/Interface/Api/GroupExt.cs | 5 ++- .../Logic/Implementation/OperationLogic.cs | 15 ++++++- .../Event/Action/GroupFSCreateFolderEvent.cs | 9 +++- .../Event/Action/GroupFSDeleteFolderEvent.cs | 25 +++++++++++ .../Oidb/Request/OidbSvcTrpcTcp0x6D7_0.cs | 8 ++-- .../Oidb/Request/OidbSvcTrpcTcp0x6D7_1.cs | 24 +++++++++++ .../Response/OidbSvcTrpcTcp0x6D7Response.cs | 14 +++++++ .../Response/OidbSvcTrpcTcp0x6D7_0Response.cs | 36 ++++++++++++++++ .../Response/OidbSvcTrpcTcp0x6D7_1Response.cs | 16 +++++++ .../Action/GroupFSCreateFolderService.cs | 7 ++-- .../Action/GroupFSDeleteFolderService.cs | 42 +++++++++++++++++++ .../Core/Entity/Action/OneBotDeleteFolder.cs | 11 +++++ .../Core/Operation/File/GroupFSOperations.cs | 19 ++++++++- 13 files changed, 217 insertions(+), 14 deletions(-) create mode 100644 Lagrange.Core/Internal/Event/Action/GroupFSDeleteFolderEvent.cs create mode 100644 Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_1.cs create mode 100644 Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7Response.cs create mode 100644 Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_0Response.cs create mode 100644 Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1Response.cs create mode 100644 Lagrange.Core/Internal/Service/Action/GroupFSDeleteFolderService.cs create mode 100644 Lagrange.OneBot/Core/Entity/Action/OneBotDeleteFolder.cs diff --git a/Lagrange.Core/Common/Interface/Api/GroupExt.cs b/Lagrange.Core/Common/Interface/Api/GroupExt.cs index a8e2545bf..91dbca303 100644 --- a/Lagrange.Core/Common/Interface/Api/GroupExt.cs +++ b/Lagrange.Core/Common/Interface/Api/GroupExt.cs @@ -107,9 +107,12 @@ public static Task GroupFSMove(this BotContext bot, uint groupUin, string public static Task GroupFSDelete(this BotContext bot, uint groupUin, string fileId) => bot.ContextCollection.Business.OperationLogic.GroupFSDelete(groupUin, fileId); - public static Task GroupFSCreateFolder(this BotContext bot, uint groupUin, string name) + public static Task<(int, string)> GroupFSCreateFolder(this BotContext bot, uint groupUin, string name) => bot.ContextCollection.Business.OperationLogic.GroupFSCreateFolder(groupUin, name); + public static Task<(int, string)> GroupFSDeleteFolder(this BotContext bot, uint groupUin, string folderId) + => bot.ContextCollection.Business.OperationLogic.GroupFSDeleteFolder(groupUin, folderId); + public static Task GroupFSUpload(this BotContext bot, uint groupUin, FileEntity fileEntity, string targetDirectory = "/") => bot.ContextCollection.Business.OperationLogic.GroupFSUpload(groupUin, fileEntity, targetDirectory); diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs index ff9aff75a..5fa9c786b 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs @@ -164,11 +164,22 @@ public async Task GroupFSDelete(uint groupUin, string fileId) return events.Count != 0 && ((GroupFSDeleteEvent)events[0]).ResultCode == 0; } - public async Task GroupFSCreateFolder(uint groupUin, string name) + public async Task<(int, string)> GroupFSCreateFolder(uint groupUin, string name) { var groupFSCreateFolderEvent = GroupFSCreateFolderEvent.Create(groupUin, name); var events = await Collection.Business.SendEvent(groupFSCreateFolderEvent); - return events.Count != 0 && ((GroupFSCreateFolderEvent)events[0]).ResultCode == 0; + var retCode = events.Count > 0 ? ((GroupFSCreateFolderEvent)events[0]).ResultCode : -1; + var retMsg = events.Count > 0 ? ((GroupFSCreateFolderEvent)events[0]).RetMsg : ""; + return new(retCode, retMsg); + } + + public async Task<(int, string)> GroupFSDeleteFolder(uint groupUin, string folderId) + { + var groupFSDeleteFolderEvent = GroupFSDeleteFolderEvent.Create(groupUin, folderId); + var events = await Collection.Business.SendEvent(groupFSDeleteFolderEvent); + var retCode = events.Count > 0 ? ((GroupFSDeleteFolderEvent)events[0]).ResultCode : -1; + var retMsg = events.Count > 0 ? ((GroupFSDeleteFolderEvent)events[0]).RetMsg : ""; + return new(retCode, retMsg); } public Task GroupFSUpload(uint groupUin, FileEntity fileEntity, string targetDirectory) diff --git a/Lagrange.Core/Internal/Event/Action/GroupFSCreateFolderEvent.cs b/Lagrange.Core/Internal/Event/Action/GroupFSCreateFolderEvent.cs index d0d99bb2a..bda99c710 100644 --- a/Lagrange.Core/Internal/Event/Action/GroupFSCreateFolderEvent.cs +++ b/Lagrange.Core/Internal/Event/Action/GroupFSCreateFolderEvent.cs @@ -5,6 +5,8 @@ internal class GroupFSCreateFolderEvent : ProtocolEvent public uint GroupUin { get; } public string Name { get; } = string.Empty; + + public string RetMsg { get; set; } = string.Empty; private GroupFSCreateFolderEvent(uint groupUin, string name) : base(true) { @@ -12,9 +14,12 @@ private GroupFSCreateFolderEvent(uint groupUin, string name) : base(true) Name = name; } - private GroupFSCreateFolderEvent(int resultCode) : base(resultCode) { } + private GroupFSCreateFolderEvent(int resultCode, string retMsg) : base(resultCode) + { + RetMsg = retMsg; + } public static GroupFSCreateFolderEvent Create(uint groupUin, string name) => new(groupUin, name); - public static GroupFSCreateFolderEvent Result(int resultCode) => new(resultCode); + public static GroupFSCreateFolderEvent Result(int resultCode, string retMsg) => new(resultCode, retMsg); } \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Action/GroupFSDeleteFolderEvent.cs b/Lagrange.Core/Internal/Event/Action/GroupFSDeleteFolderEvent.cs new file mode 100644 index 000000000..b9c2a130f --- /dev/null +++ b/Lagrange.Core/Internal/Event/Action/GroupFSDeleteFolderEvent.cs @@ -0,0 +1,25 @@ +namespace Lagrange.Core.Internal.Event.Action; + +internal class GroupFSDeleteFolderEvent : ProtocolEvent +{ + public uint GroupUin { get; } + + public string FolderId { get; } = string.Empty; + + public string RetMsg { get; set; } = string.Empty; + + private GroupFSDeleteFolderEvent(uint groupUin, string folderId) : base(true) + { + GroupUin = groupUin; + FolderId = folderId; + } + + private GroupFSDeleteFolderEvent(int resultCode, string retMsg) : base(resultCode) + { + RetMsg = retMsg; + } + + public static GroupFSDeleteFolderEvent Create(uint groupUin, string folderId) => new(groupUin, folderId); + + public static GroupFSDeleteFolderEvent Result(int resultCode, string retMsg) => new(resultCode, retMsg); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_0.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_0.cs index 1a3c299f0..d138e346d 100644 --- a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_0.cs +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_0.cs @@ -1,4 +1,4 @@ -using ProtoBuf; +using ProtoBuf; namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; @@ -9,14 +9,14 @@ namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; /// Create Folder /// [ProtoContract] -[OidbSvcTrpcTcp(0x6D7, 9)] +[OidbSvcTrpcTcp(0x6D7, 0)] internal class OidbSvcTrpcTcp0x6D7_0 { - [ProtoMember(1)] public OidbSvcTrpcTcp0x6D7_0Folder Folder { get; set; } + [ProtoMember(1)] public OidbSvcTrpcTcp0x6D7_0Create Create { get; set; } } [ProtoContract] -internal class OidbSvcTrpcTcp0x6D7_0Folder +internal class OidbSvcTrpcTcp0x6D7_0Create { [ProtoMember(1)] public uint GroupUin { get; set; } diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_1.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_1.cs new file mode 100644 index 000000000..b518d6027 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_1.cs @@ -0,0 +1,24 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +/// +/// Delete Folder +/// +[ProtoContract] +[OidbSvcTrpcTcp(0x6D7, 1)] +internal class OidbSvcTrpcTcp0x6D7_1 +{ + [ProtoMember(2)] public OidbSvcTrpcTcp0x6D7_1Delete Delete { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D7_1Delete +{ + [ProtoMember(1)] public uint GroupUin { get; set; } + + [ProtoMember(3)] public string FolderId { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7Response.cs new file mode 100644 index 000000000..a898b54fa --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7Response.cs @@ -0,0 +1,14 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Response; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D7Response +{ + [ProtoMember(1)] public OidbSvcTrpcTcp0x6D7_0Response Create { get; set; } + + [ProtoMember(2)] public OidbSvcTrpcTcp0x6D7_1Response Delete { get; set; } +} diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_0Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_0Response.cs new file mode 100644 index 000000000..a70f4dbf9 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_0Response.cs @@ -0,0 +1,36 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Response; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D7_0Response +{ + [ProtoMember(1)] public int Retcode { get; set; } + + [ProtoMember(2)] public string RetMsg { get; set; } + + [ProtoMember(3)] public string ClientWording { get; set; } + + [ProtoMember(4)] public OidbSvcTrpcTcp0x6D7_0ResponseFolderInfo FolderInfo { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D7_0ResponseFolderInfo +{ + [ProtoMember(1)] public string FolderId { get; set; } + + [ProtoMember(2)] public string FolderPath { get; set; } + + [ProtoMember(3)] public string FolderName { get; set; } + + [ProtoMember(4)] public uint Timestamp4 { get; set; } + + [ProtoMember(5)] public uint Timestamp5 { get; set; } + + [ProtoMember(6)] public uint OperatorUin6 { get; set; } + + [ProtoMember(7)] public uint OperatorUin9 { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1Response.cs new file mode 100644 index 000000000..25e9b3757 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1Response.cs @@ -0,0 +1,16 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Response; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D7_1Response +{ + [ProtoMember(1)] public Int32 Retcode { get; set; } + + [ProtoMember(2)] public string RetMsg { get; set; } + + [ProtoMember(3)] public string ClientWording { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Action/GroupFSCreateFolderService.cs b/Lagrange.Core/Internal/Service/Action/GroupFSCreateFolderService.cs index bc1872483..da91cabf7 100644 --- a/Lagrange.Core/Internal/Service/Action/GroupFSCreateFolderService.cs +++ b/Lagrange.Core/Internal/Service/Action/GroupFSCreateFolderService.cs @@ -3,6 +3,7 @@ using Lagrange.Core.Internal.Event.Action; using Lagrange.Core.Internal.Packets.Service.Oidb; using Lagrange.Core.Internal.Packets.Service.Oidb.Request; +using Lagrange.Core.Internal.Packets.Service.Oidb.Response; using Lagrange.Core.Utility.Extension; using ProtoBuf; @@ -17,7 +18,7 @@ protected override bool Build(GroupFSCreateFolderEvent input, BotKeystore keysto { var packet = new OidbSvcTrpcTcpBase(new OidbSvcTrpcTcp0x6D7_0 { - Folder = new OidbSvcTrpcTcp0x6D7_0Folder + Create = new OidbSvcTrpcTcp0x6D7_0Create { GroupUin = input.GroupUin, RootDirectory = "/", @@ -33,9 +34,9 @@ protected override bool Build(GroupFSCreateFolderEvent input, BotKeystore keysto protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, out GroupFSCreateFolderEvent output, out List? extraEvents) { - var packet = Serializer.Deserialize>(input); + var packet = Serializer.Deserialize>(input); - output = GroupFSCreateFolderEvent.Result((int)packet.ErrorCode); + output = GroupFSCreateFolderEvent.Result(packet.Body.Create.Retcode, packet.Body.Create.RetMsg); extraEvents = null; return true; } diff --git a/Lagrange.Core/Internal/Service/Action/GroupFSDeleteFolderService.cs b/Lagrange.Core/Internal/Service/Action/GroupFSDeleteFolderService.cs new file mode 100644 index 000000000..00763fa09 --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/GroupFSDeleteFolderService.cs @@ -0,0 +1,42 @@ +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.Internal.Packets.Service.Oidb.Response; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(GroupFSDeleteFolderEvent))] +[Service("OidbSvcTrpcTcp.0x6d7_1")] +internal class GroupFSDeleteFolderService : BaseService +{ + protected override bool Build(GroupFSDeleteFolderEvent input, BotKeystore keystore, BotAppInfo appInfo, + BotDeviceInfo device, out Span output, out List>? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(new OidbSvcTrpcTcp0x6D7_1 + { + Delete = new OidbSvcTrpcTcp0x6D7_1Delete + { + GroupUin = input.GroupUin, + FolderId = input.FolderId + } + }, false, true); + + output = packet.Serialize(); + extraPackets = null; + return true; + } + + protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out GroupFSDeleteFolderEvent output, out List? extraEvents) + { + var packet = Serializer.Deserialize>(input); + + output = GroupFSDeleteFolderEvent.Result(packet.Body.Delete.Retcode, packet.Body.Delete.RetMsg); + extraEvents = null; + return true; + } +} \ No newline at end of file diff --git a/Lagrange.OneBot/Core/Entity/Action/OneBotDeleteFolder.cs b/Lagrange.OneBot/Core/Entity/Action/OneBotDeleteFolder.cs new file mode 100644 index 000000000..c53335aff --- /dev/null +++ b/Lagrange.OneBot/Core/Entity/Action/OneBotDeleteFolder.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace Lagrange.OneBot.Core.Entity.Action; + +[Serializable] +public class OneBotDeleteFolder +{ + [JsonPropertyName("group_id")] public uint GroupId { get; set; } + + [JsonPropertyName("folder_id")] public string FolderId { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/Lagrange.OneBot/Core/Operation/File/GroupFSOperations.cs b/Lagrange.OneBot/Core/Operation/File/GroupFSOperations.cs index 39c64bdaa..f88cdff4f 100644 --- a/Lagrange.OneBot/Core/Operation/File/GroupFSOperations.cs +++ b/Lagrange.OneBot/Core/Operation/File/GroupFSOperations.cs @@ -110,8 +110,23 @@ public async Task HandleOperation(BotContext context, JsonNode? pa { if (payload.Deserialize(SerializerOptions.DefaultOptions) is { } folder) { - await context.GroupFSCreateFolder(folder.GroupId, folder.Name); - return new OneBotResult(null, 0, "ok"); + var res = await context.GroupFSCreateFolder(folder.GroupId, folder.Name); + return new OneBotResult(new JsonObject { { "msg", res.Item2 } }, res.Item1, res.Item1 == 0 ? "ok" : "failed"); + } + + throw new Exception(); + } +} + +[Operation("delete_group_file_folder")] +public class DeleteGroupFileFolderOperation : IOperation +{ + public async Task HandleOperation(BotContext context, JsonNode? payload) + { + if (payload.Deserialize(SerializerOptions.DefaultOptions) is { } folder) + { + var res = await context.GroupFSDeleteFolder(folder.GroupId, folder.FolderId); + return new OneBotResult(new JsonObject { { "msg", res.Item2 } }, res.Item1, res.Item1 == 0 ? "ok" : "failed"); } throw new Exception(); From d04117e1893536dcaf55a6c2162790cedb6493a8 Mon Sep 17 00:00:00 2001 From: pk5ls20 Date: Sat, 24 Aug 2024 22:14:27 +0800 Subject: [PATCH 04/11] [Core] Use DNS instead of IP in parsing groupfs url (#550) --- Lagrange.Core/Internal/Service/Action/GroupFSDownloadService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lagrange.Core/Internal/Service/Action/GroupFSDownloadService.cs b/Lagrange.Core/Internal/Service/Action/GroupFSDownloadService.cs index 72fa52b4b..040d817a0 100644 --- a/Lagrange.Core/Internal/Service/Action/GroupFSDownloadService.cs +++ b/Lagrange.Core/Internal/Service/Action/GroupFSDownloadService.cs @@ -38,7 +38,7 @@ protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo var packet = Serializer.Deserialize>(input); var download = packet.Body.Download; - string url = $"https://{download.DownloadIp}:443/ftn_handler/{download.DownloadUrl.Hex(true)}/?fname="; + string url = $"https://{download.DownloadDns}/ftn_handler/{download.DownloadUrl.Hex(true)}/?fname="; output = GroupFSDownloadEvent.Result((int)packet.ErrorCode, url); extraEvents = null; From 9042bd4651804da495cc239475e8c4b41ea61730 Mon Sep 17 00:00:00 2001 From: Decrabbityyy <99632363+Decrabbityyy@users.noreply.github.com> Date: Sun, 25 Aug 2024 22:40:26 +0800 Subject: [PATCH 05/11] [Onebot] fix first start need input signserver (#544) * wtf * impossable * use a constant string instead of hardcoding text in a single line --- Lagrange.OneBot/Utility/OneBotSigner.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lagrange.OneBot/Utility/OneBotSigner.cs b/Lagrange.OneBot/Utility/OneBotSigner.cs index fece40cda..2aaa218e4 100644 --- a/Lagrange.OneBot/Utility/OneBotSigner.cs +++ b/Lagrange.OneBot/Utility/OneBotSigner.cs @@ -15,6 +15,8 @@ public class OneBotSigner : SignProvider { private ILogger _logger; + private const string Url = "https://sign.lagrangecore.org/api/sign/25765"; + private readonly string? _signServer; private readonly HttpClient _client; @@ -27,7 +29,7 @@ public OneBotSigner(IConfiguration config, ILogger logger, BotCont { _logger = logger; - _signServer = config["SignServerUrl"] ?? ""; + _signServer = string.IsNullOrEmpty(config["SignServerUrl"]) ? Url : config["SignServerUrl"]; string? signProxyUrl = config["SignProxyUrl"]; // Only support HTTP proxy _client = new HttpClient(handler: new HttpClientHandler From 02d160a34d2fa50f8ca3bf4db4ba4a479af09de8 Mon Sep 17 00:00:00 2001 From: dogdie233 Date: Mon, 26 Aug 2024 08:18:27 +0800 Subject: [PATCH 06/11] [Core] fix: #545 (#546) --- Lagrange.Core/Message/Entity/ImageEntity.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lagrange.Core/Message/Entity/ImageEntity.cs b/Lagrange.Core/Message/Entity/ImageEntity.cs index 01814e675..63468767a 100644 --- a/Lagrange.Core/Message/Entity/ImageEntity.cs +++ b/Lagrange.Core/Message/Entity/ImageEntity.cs @@ -88,7 +88,7 @@ IEnumerable IMessageEntity.PackElement() IMessageEntity? IMessageEntity.UnpackElement(Elem elems) { - if (elems.CommonElem is { BusinessType: 20 or 10 } common) + if (elems.CommonElem is { ServiceType: 48, BusinessType: 20 or 10 } common) { var extra = Serializer.Deserialize(common.PbElem.AsSpan()); var index = extra.MsgInfoBody[0].Index; From 361252c3a7ab8b8ffcbb8d8be1f256f2c64add25 Mon Sep 17 00:00:00 2001 From: pk5ls20 Date: Mon, 26 Aug 2024 08:20:33 +0800 Subject: [PATCH 07/11] [All] Add RenameGroupFolderOp (#551) --- .../Common/Interface/Api/GroupExt.cs | 3 ++ .../Logic/Implementation/OperationLogic.cs | 9 ++++ .../Event/Action/GroupFSRenameFolderEvent.cs | 28 ++++++++++++ .../Oidb/Request/OidbSvcTrpcTcp0x6D7_2.cs | 26 +++++++++++ .../Response/OidbSvcTrpcTcp0x6D7Response.cs | 4 +- ....cs => OidbSvcTrpcTcp0x6D7_1_2Response.cs} | 2 +- .../Action/GroupFSRenameFolderService.cs | 43 +++++++++++++++++++ .../Core/Entity/Action/OneBotRenameFolder.cs | 13 ++++++ .../Core/Operation/File/GroupFSOperations.cs | 15 +++++++ 9 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 Lagrange.Core/Internal/Event/Action/GroupFSRenameFolderEvent.cs create mode 100644 Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_2.cs rename Lagrange.Core/Internal/Packets/Service/Oidb/Response/{OidbSvcTrpcTcp0x6D7_1Response.cs => OidbSvcTrpcTcp0x6D7_1_2Response.cs} (88%) create mode 100644 Lagrange.Core/Internal/Service/Action/GroupFSRenameFolderService.cs create mode 100644 Lagrange.OneBot/Core/Entity/Action/OneBotRenameFolder.cs diff --git a/Lagrange.Core/Common/Interface/Api/GroupExt.cs b/Lagrange.Core/Common/Interface/Api/GroupExt.cs index 91dbca303..86d765464 100644 --- a/Lagrange.Core/Common/Interface/Api/GroupExt.cs +++ b/Lagrange.Core/Common/Interface/Api/GroupExt.cs @@ -113,6 +113,9 @@ public static Task GroupFSDelete(this BotContext bot, uint groupUin, strin public static Task<(int, string)> GroupFSDeleteFolder(this BotContext bot, uint groupUin, string folderId) => bot.ContextCollection.Business.OperationLogic.GroupFSDeleteFolder(groupUin, folderId); + public static Task<(int, string)> GroupFSRenameFolder(this BotContext bot, uint groupUin, string folderId, string newFolderName) + => bot.ContextCollection.Business.OperationLogic.GroupFSRenameFolder(groupUin, folderId, newFolderName); + public static Task GroupFSUpload(this BotContext bot, uint groupUin, FileEntity fileEntity, string targetDirectory = "/") => bot.ContextCollection.Business.OperationLogic.GroupFSUpload(groupUin, fileEntity, targetDirectory); diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs index 5fa9c786b..2e38a6107 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs @@ -182,6 +182,15 @@ public async Task GroupFSDelete(uint groupUin, string fileId) return new(retCode, retMsg); } + public async Task<(int, string)> GroupFSRenameFolder(uint groupUin, string folderId, string newFolderName) + { + var groupFSDeleteFolderEvent = GroupFSRenameFolderEvent.Create(groupUin, folderId, newFolderName); + var events = await Collection.Business.SendEvent(groupFSDeleteFolderEvent); + var retCode = events.Count > 0 ? ((GroupFSRenameFolderEvent)events[0]).ResultCode : -1; + var retMsg = events.Count > 0 ? ((GroupFSRenameFolderEvent)events[0]).RetMsg : ""; + return new(retCode, retMsg); + } + public Task GroupFSUpload(uint groupUin, FileEntity fileEntity, string targetDirectory) { try diff --git a/Lagrange.Core/Internal/Event/Action/GroupFSRenameFolderEvent.cs b/Lagrange.Core/Internal/Event/Action/GroupFSRenameFolderEvent.cs new file mode 100644 index 000000000..259c4c8f8 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Action/GroupFSRenameFolderEvent.cs @@ -0,0 +1,28 @@ +namespace Lagrange.Core.Internal.Event.Action; + +internal class GroupFSRenameFolderEvent : ProtocolEvent +{ + public uint GroupUin { get; } + + public string FolderId { get; } = string.Empty; + + public string NewFolderName { get; } = string.Empty; + + public string RetMsg { get; set; } = string.Empty; + + private GroupFSRenameFolderEvent(uint groupUin, string folderId, string newFolderName) : base(true) + { + GroupUin = groupUin; + FolderId = folderId; + NewFolderName = newFolderName; + } + + private GroupFSRenameFolderEvent(int resultCode, string retMsg) : base(resultCode) + { + RetMsg = retMsg; + } + + public static GroupFSRenameFolderEvent Create(uint groupUin, string folderId, string newFolderName) => new(groupUin, folderId, newFolderName); + + public static GroupFSRenameFolderEvent Result(int resultCode, string retMsg) => new(resultCode, retMsg); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_2.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_2.cs new file mode 100644 index 000000000..5ee84ac14 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D7_2.cs @@ -0,0 +1,26 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +/// +/// Delete Folder +/// +[ProtoContract] +[OidbSvcTrpcTcp(0x6D7, 2)] +internal class OidbSvcTrpcTcp0x6D7_2 +{ + [ProtoMember(3)] public OidbSvcTrpcTcp0x6D7_2Rename Rename { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D7_2Rename +{ + [ProtoMember(1)] public uint GroupUin { get; set; } + + [ProtoMember(3)] public string FolderId { get; set; } + + [ProtoMember(4)] public string NewFolderName { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7Response.cs index a898b54fa..344520a6f 100644 --- a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7Response.cs +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7Response.cs @@ -10,5 +10,7 @@ internal class OidbSvcTrpcTcp0x6D7Response { [ProtoMember(1)] public OidbSvcTrpcTcp0x6D7_0Response Create { get; set; } - [ProtoMember(2)] public OidbSvcTrpcTcp0x6D7_1Response Delete { get; set; } + [ProtoMember(2)] public OidbSvcTrpcTcp0x6D7_1_2Response Delete { get; set; } + + [ProtoMember(3)] public OidbSvcTrpcTcp0x6D7_1_2Response Rename { get; set; } } diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1_2Response.cs similarity index 88% rename from Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1Response.cs rename to Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1_2Response.cs index 25e9b3757..ca45872b1 100644 --- a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1Response.cs +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D7_1_2Response.cs @@ -6,7 +6,7 @@ namespace Lagrange.Core.Internal.Packets.Service.Oidb.Response; // ReSharper disable InconsistentNaming [ProtoContract] -internal class OidbSvcTrpcTcp0x6D7_1Response +internal class OidbSvcTrpcTcp0x6D7_1_2Response { [ProtoMember(1)] public Int32 Retcode { get; set; } diff --git a/Lagrange.Core/Internal/Service/Action/GroupFSRenameFolderService.cs b/Lagrange.Core/Internal/Service/Action/GroupFSRenameFolderService.cs new file mode 100644 index 000000000..d2b3cb26e --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/GroupFSRenameFolderService.cs @@ -0,0 +1,43 @@ +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.Internal.Packets.Service.Oidb.Response; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(GroupFSRenameFolderEvent))] +[Service("OidbSvcTrpcTcp.0x6d7_2")] +internal class GroupFSRenameFolderService : BaseService +{ + protected override bool Build(GroupFSRenameFolderEvent input, BotKeystore keystore, BotAppInfo appInfo, + BotDeviceInfo device, out Span output, out List>? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(new OidbSvcTrpcTcp0x6D7_2 + { + Rename = new OidbSvcTrpcTcp0x6D7_2Rename + { + GroupUin = input.GroupUin, + FolderId = input.FolderId, + NewFolderName = input.NewFolderName + } + }, false, true); + + output = packet.Serialize(); + extraPackets = null; + return true; + } + + protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out GroupFSRenameFolderEvent output, out List? extraEvents) + { + var packet = Serializer.Deserialize>(input); + + output = GroupFSRenameFolderEvent.Result(packet.Body.Rename.Retcode, packet.Body.Rename.RetMsg); + extraEvents = null; + return true; + } +} \ No newline at end of file diff --git a/Lagrange.OneBot/Core/Entity/Action/OneBotRenameFolder.cs b/Lagrange.OneBot/Core/Entity/Action/OneBotRenameFolder.cs new file mode 100644 index 000000000..dbf737fa4 --- /dev/null +++ b/Lagrange.OneBot/Core/Entity/Action/OneBotRenameFolder.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace Lagrange.OneBot.Core.Entity.Action; + +[Serializable] +public class OneBotRenameFolder +{ + [JsonPropertyName("group_id")] public uint GroupId { get; set; } + + [JsonPropertyName("folder_id")] public string FolderId { get; set; } = string.Empty; + + [JsonPropertyName("new_folder_name")] public string NewFolderName { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/Lagrange.OneBot/Core/Operation/File/GroupFSOperations.cs b/Lagrange.OneBot/Core/Operation/File/GroupFSOperations.cs index f88cdff4f..e95531af8 100644 --- a/Lagrange.OneBot/Core/Operation/File/GroupFSOperations.cs +++ b/Lagrange.OneBot/Core/Operation/File/GroupFSOperations.cs @@ -129,6 +129,21 @@ public async Task HandleOperation(BotContext context, JsonNode? pa return new OneBotResult(new JsonObject { { "msg", res.Item2 } }, res.Item1, res.Item1 == 0 ? "ok" : "failed"); } + throw new Exception(); + } +} + +[Operation("rename_group_file_folder")] +public class RenameGroupFileFolderOperation : IOperation +{ + public async Task HandleOperation(BotContext context, JsonNode? payload) + { + if (payload.Deserialize(SerializerOptions.DefaultOptions) is { } folder) + { + var res = await context.GroupFSRenameFolder(folder.GroupId, folder.FolderId, folder.NewFolderName); + return new OneBotResult(new JsonObject { { "msg", res.Item2 } }, res.Item1, res.Item1 == 0 ? "ok" : "failed"); + } + throw new Exception(); } } \ No newline at end of file From a36ba6743f567c05ba66a70681a9bca95f00fc56 Mon Sep 17 00:00:00 2001 From: pk5ls20 Date: Mon, 26 Aug 2024 08:21:40 +0800 Subject: [PATCH 08/11] [All] Add pagination to FetchGroupFSList to correctly fetch all group files, resolve https://github.com/LagrangeDev/Lagrange.Core/issues/356 (#558) --- .../Common/Interface/Api/GroupExt.cs | 4 ++-- .../Logic/Implementation/OperationLogic.cs | 17 +++++++++++++---- .../Internal/Event/Action/GroupFSListEvent.cs | 19 +++++++++++++------ .../Service/Action/GroupFSViewService.cs | 4 ++-- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Lagrange.Core/Common/Interface/Api/GroupExt.cs b/Lagrange.Core/Common/Interface/Api/GroupExt.cs index 86d765464..4e45d0fb9 100644 --- a/Lagrange.Core/Common/Interface/Api/GroupExt.cs +++ b/Lagrange.Core/Common/Interface/Api/GroupExt.cs @@ -95,8 +95,8 @@ public static Task FetchGroupFSSpace(this BotContext bot, uint groupUin) public static Task FetchGroupFSCount(this BotContext bot, uint groupUin) => bot.ContextCollection.Business.OperationLogic.FetchGroupFSCount(groupUin); - public static Task> FetchGroupFSList(this BotContext bot, uint groupUin, string targetDirectory = "/", uint startIndex = 0) - => bot.ContextCollection.Business.OperationLogic.FetchGroupFSList(groupUin, targetDirectory, startIndex); + public static Task> FetchGroupFSList(this BotContext bot, uint groupUin, string targetDirectory = "/") + => bot.ContextCollection.Business.OperationLogic.FetchGroupFSList(groupUin, targetDirectory); public static Task FetchGroupFSDownload(this BotContext bot, uint groupUin, string fileId) => bot.ContextCollection.Business.OperationLogic.FetchGroupFSDownload(groupUin, fileId); diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs index 2e38a6107..59aa9169d 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs @@ -136,11 +136,20 @@ public async Task FetchGroupFSCount(uint groupUin) return ((GroupFSCountEvent)events[0]).FileCount; } - public async Task> FetchGroupFSList(uint groupUin, string targetDirectory, uint startIndex) + public async Task> FetchGroupFSList(uint groupUin, string targetDirectory) { - var groupFSListEvent = GroupFSListEvent.Create(groupUin, targetDirectory, startIndex); - var events = await Collection.Business.SendEvent(groupFSListEvent); - return ((GroupFSListEvent)events[0]).FileEntries; + uint startIndex = 0; + var entries = new List(); + while (true) + { + var groupFSListEvent = GroupFSListEvent.Create(groupUin, targetDirectory, startIndex, 20); + var events = await Collection.Business.SendEvent(groupFSListEvent); + if (events.Count == 0) break; + entries.AddRange(((GroupFSListEvent)events[0]).FileEntries); + if (((GroupFSListEvent)events[0]).IsEnd) break; + startIndex += 20; + } + return entries; } public async Task FetchGroupFSDownload(uint groupUin, string fileId) diff --git a/Lagrange.Core/Internal/Event/Action/GroupFSListEvent.cs b/Lagrange.Core/Internal/Event/Action/GroupFSListEvent.cs index 34ab59235..be2e05b26 100644 --- a/Lagrange.Core/Internal/Event/Action/GroupFSListEvent.cs +++ b/Lagrange.Core/Internal/Event/Action/GroupFSListEvent.cs @@ -10,22 +10,29 @@ internal class GroupFSListEvent : GroupFSViewEvent public uint StartIndex { get; set; } + public uint FileCount { get; set; } + + public bool IsEnd { get; set; } + public List FileEntries { get; set; } - private GroupFSListEvent(uint groupUin, string targetDirectory, uint startIndex) : base(groupUin) + private GroupFSListEvent(uint groupUin, string targetDirectory, uint startIndex, uint fileCount) : base(groupUin) { TargetDirectory = targetDirectory; StartIndex = startIndex; + FileCount = fileCount; + IsEnd = false; } - private GroupFSListEvent(int resultCode, List fileEntries) : base(resultCode) + private GroupFSListEvent(int resultCode, List fileEntries, bool isEnd) : base(resultCode) { FileEntries = fileEntries; + IsEnd = isEnd; } - public static GroupFSListEvent Create(uint groupUin, string targetDirectory, uint startIndex) - => new(groupUin, targetDirectory, startIndex); + public static GroupFSListEvent Create(uint groupUin, string targetDirectory, uint startIndex, uint fileCount) + => new(groupUin, targetDirectory, startIndex, fileCount); - public static GroupFSListEvent Result(int resultCode, List fileEntries) - => new(resultCode, fileEntries); + public static GroupFSListEvent Result(int resultCode, List fileEntries, bool isEnd) + => new(resultCode, fileEntries, isEnd); } \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Action/GroupFSViewService.cs b/Lagrange.Core/Internal/Service/Action/GroupFSViewService.cs index b3b93d904..4b6ca54db 100644 --- a/Lagrange.Core/Internal/Service/Action/GroupFSViewService.cs +++ b/Lagrange.Core/Internal/Service/Action/GroupFSViewService.cs @@ -61,7 +61,7 @@ protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo extraEvents = null; - if (packet.Body.List != null) + if (packet.Body.List is { RetCode: 0 }) { var items = packet.Body.List.Items ?? new List(); var fileEntries = items.Select(x => @@ -83,7 +83,7 @@ protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo return entry; }).ToList(); - output = GroupFSListEvent.Result((int)packet.ErrorCode, fileEntries); + output = GroupFSListEvent.Result((int)packet.ErrorCode, fileEntries, packet.Body.List.IsEnd); return true; } From c2e7fe99ca7da21e7b031b13d52f4488eeb39ef9 Mon Sep 17 00:00:00 2001 From: CwkDark <177549718+CwkDark@users.noreply.github.com> Date: Mon, 26 Aug 2024 08:23:33 +0800 Subject: [PATCH 09/11] [Core] public file id (#552) --- Lagrange.Core/Common/Entity/BotFileEntry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lagrange.Core/Common/Entity/BotFileEntry.cs b/Lagrange.Core/Common/Entity/BotFileEntry.cs index e077485b4..393e8e66f 100644 --- a/Lagrange.Core/Common/Entity/BotFileEntry.cs +++ b/Lagrange.Core/Common/Entity/BotFileEntry.cs @@ -3,7 +3,7 @@ namespace Lagrange.Core.Common.Entity; [Serializable] public class BotFileEntry : IBotFSEntry { - internal string FileId { get; } + public string FileId { get; } public string FileName { get; } From 6c930b71611858927aff84c5342ef76ef97a46a4 Mon Sep 17 00:00:00 2001 From: CwkDark <177549718+CwkDark@users.noreply.github.com> Date: Mon, 26 Aug 2024 08:25:36 +0800 Subject: [PATCH 10/11] [Core] public image entity sub type (#554) --- Lagrange.Core/Message/Entity/ImageEntity.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lagrange.Core/Message/Entity/ImageEntity.cs b/Lagrange.Core/Message/Entity/ImageEntity.cs index 63468767a..350217e34 100644 --- a/Lagrange.Core/Message/Entity/ImageEntity.cs +++ b/Lagrange.Core/Message/Entity/ImageEntity.cs @@ -40,7 +40,7 @@ public class ImageEntity : IMessageEntity internal string? Summary { get; set; } - internal int SubType { get; set; } + public int SubType { get; set; } public ImageEntity() { } From aa7ca60b5c0109f4f2a1c7d21e0e4dbbf291fe00 Mon Sep 17 00:00:00 2001 From: sweetymajo <115923988+sweetymajo@users.noreply.github.com> Date: Mon, 26 Aug 2024 20:58:30 +0800 Subject: [PATCH 11/11] MultiMsg supports custom detail text. (#508) --- .../Message/Entity/MultiMsgEntity.cs | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Lagrange.Core/Message/Entity/MultiMsgEntity.cs b/Lagrange.Core/Message/Entity/MultiMsgEntity.cs index 7a8354ddf..fdbbbd70d 100644 --- a/Lagrange.Core/Message/Entity/MultiMsgEntity.cs +++ b/Lagrange.Core/Message/Entity/MultiMsgEntity.cs @@ -20,6 +20,8 @@ public class MultiMsgEntity : IMessageEntity public List Chains { get; } + public string? DetailStr { get; set; } + internal MultiMsgEntity() => Chains = new List(); public MultiMsgEntity(string resId) @@ -28,10 +30,11 @@ public MultiMsgEntity(string resId) Chains = new List(); } - public MultiMsgEntity(uint? groupUin, List chains) + public MultiMsgEntity(uint? groupUin, List chains, string? detail = null) { GroupUin = groupUin; Chains = chains; + DetailStr = detail; } IEnumerable IMessageEntity.PackElement() @@ -73,19 +76,26 @@ IEnumerable IMessageEntity.PackElement() View = "contact" }; - if (!Chains.Select(x => x.GetEntity()).Any()) + if (!string.IsNullOrEmpty(DetailStr)) { - json.Meta.Detail.News.Add(new News { Text = "[This message is send from Lagrange.Core]" }); + json.Meta.Detail.News.Add(new News { Text = DetailStr }); } else { - for (int i = 0; i < count; i++) + if (!Chains.Select(x => x.GetEntity()).Any()) + { + json.Meta.Detail.News.Add(new News { Text = "[This message is send from Lagrange.Core]" }); + } + else { - var chain = Chains[i]; - var member = chain.GroupMemberInfo; - var friend = chain.FriendInfo; - string text = $"{member?.MemberCard ?? member?.MemberName ?? friend?.Nickname}: {chain.ToPreviewText()}"; - json.Meta.Detail.News.Add(new News { Text = text }); + for (int i = 0; i < count; i++) + { + var chain = Chains[i]; + var member = chain.GroupMemberInfo; + var friend = chain.FriendInfo; + string text = $"{member?.MemberCard ?? member?.MemberName ?? friend?.Nickname}: {chain.ToPreviewText()}"; + json.Meta.Detail.News.Add(new News { Text = text }); + } } }