diff --git a/Lagrange.Core/Common/Interface/Api/GroupExt.cs b/Lagrange.Core/Common/Interface/Api/GroupExt.cs index 81d58a2..c272c89 100644 --- a/Lagrange.Core/Common/Interface/Api/GroupExt.cs +++ b/Lagrange.Core/Common/Interface/Api/GroupExt.cs @@ -27,4 +27,10 @@ public static class GroupExt 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 FetchGroupFSDownload(this BotContext bot, uint groupUin, string fileId) + => bot.ContextCollection.Business.OperationLogic.FetchGroupFSDownload(groupUin, fileId); + + public static Task GroupFSMove(this BotContext bot, uint groupUin, string fileId, string parentDirectory, string targetDirectory) + => bot.ContextCollection.Business.OperationLogic.GroupFSMove(groupUin, fileId, parentDirectory, targetDirectory); } \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSDeleteEvent.cs b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSDeleteEvent.cs new file mode 100644 index 0000000..6934b12 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSDeleteEvent.cs @@ -0,0 +1,24 @@ +namespace Lagrange.Core.Internal.Event.Protocol.Action; + +#pragma warning disable CS8618 + +internal class GroupFSDeleteEvent : GroupFSOperationEvent +{ + public string FileId { get; set; } + + public string ParentDirectory { get; set; } + + public GroupFSDeleteEvent(uint groupUin, string fileId, string parentDirectory) : base(groupUin) + { + FileId = fileId; + ParentDirectory = parentDirectory; + } + + public GroupFSDeleteEvent(int resultCode) : base(resultCode) { } + + public static GroupFSDeleteEvent Create(uint groupUin, string fileId, string parentDirectory) + => new(groupUin, fileId, parentDirectory); + + public static GroupFSDeleteEvent Result(int resultCode) + => new(resultCode); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSDownloadEvent.cs b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSDownloadEvent.cs new file mode 100644 index 0000000..650b3c4 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSDownloadEvent.cs @@ -0,0 +1,24 @@ +namespace Lagrange.Core.Internal.Event.Protocol.Action; + +internal class GroupFSDownloadEvent : GroupFSOperationEvent +{ + public string FileUrl { get; set; } + + public string FileId { get; set; } + + private GroupFSDownloadEvent(uint groupUin, string fileId) : base(groupUin) + { + FileId = fileId; + FileUrl = ""; + } + + private GroupFSDownloadEvent(int resultCode, string fileUrl) : base(resultCode) + { + FileUrl = fileUrl; + FileId = ""; + } + + public static GroupFSDownloadEvent Create(uint groupUin, string fileId) => new(groupUin, fileId); + + public static GroupFSDownloadEvent Result(int resultCode, string fileId) => new(resultCode, fileId); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSMoveEvent.cs b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSMoveEvent.cs new file mode 100644 index 0000000..db42dea --- /dev/null +++ b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSMoveEvent.cs @@ -0,0 +1,27 @@ +namespace Lagrange.Core.Internal.Event.Protocol.Action; + +#pragma warning disable CS8618 + +internal class GroupFSMoveEvent : GroupFSOperationEvent +{ + public string FileId { get; set; } + + public string ParentDirectory { get; set; } + + public string TargetDirectory { get; set; } + + private GroupFSMoveEvent(uint groupUin, string fileId, string parentDirectory, string targetDirectory) : base(groupUin) + { + FileId = fileId; + ParentDirectory = parentDirectory; + TargetDirectory = targetDirectory; + } + + private GroupFSMoveEvent(int resultCode) : base(resultCode) { } + + public static GroupFSMoveEvent Create(uint groupUin, string fileId, string parentDirectory, string targetDirectory) + => new(groupUin, fileId, parentDirectory, targetDirectory); + + public static GroupFSMoveEvent Result(int resultCode) + => new(resultCode); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSOperationEvent.cs b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSOperationEvent.cs new file mode 100644 index 0000000..5ee12b8 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSOperationEvent.cs @@ -0,0 +1,13 @@ +namespace Lagrange.Core.Internal.Event.Protocol.Action; + +internal abstract class GroupFSOperationEvent : ProtocolEvent +{ + public uint GroupUin { get; set; } + + protected GroupFSOperationEvent(uint groupUin) : base(true) + { + GroupUin = groupUin; + } + + protected GroupFSOperationEvent(int resultCode) : base(resultCode) { } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSRenameEvent.cs b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSRenameEvent.cs new file mode 100644 index 0000000..02b487d --- /dev/null +++ b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSRenameEvent.cs @@ -0,0 +1,27 @@ +namespace Lagrange.Core.Internal.Event.Protocol.Action; + +#pragma warning disable CS8618 + +internal class GroupFSRenameEvent : GroupFSOperationEvent +{ + public string FileId { get; set; } + + public string ParentDirectory { get; set; } + + public string TargetDirectory { get; set; } + + private GroupFSRenameEvent(uint groupUin, string fileId, string parentDirectory, string targetDirectory) : base(groupUin) + { + FileId = fileId; + ParentDirectory = parentDirectory; + TargetDirectory = targetDirectory; + } + + private GroupFSRenameEvent(int resultCode) : base(resultCode) { } + + public static GroupFSRenameEvent Create(uint groupUin, string fileId, string parentDirectory, string targetDirectory) + => new(groupUin, fileId, parentDirectory, targetDirectory); + + public static GroupFSRenameEvent Result(int resultCode) + => new(resultCode); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSUploadEvent.cs b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSUploadEvent.cs new file mode 100644 index 0000000..bfeed98 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Protocol/Action/GroupFSUploadEvent.cs @@ -0,0 +1,12 @@ +namespace Lagrange.Core.Internal.Event.Protocol.Action; + +internal class GroupFSUploadEvent : GroupFSOperationEvent +{ + public GroupFSUploadEvent(uint groupUin) : base(groupUin) + { + } + + public GroupFSUploadEvent(int resultCode) : base(resultCode) + { + } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_0.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_0.cs index b882bc9..55d4a74 100644 --- a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_0.cs +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_0.cs @@ -6,7 +6,7 @@ namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; // ReSharper disable InconsistentNaming /// -/// Group File Operation +/// Group File Upload /// [ProtoContract] [OidbSvcTrpcTcp(0x6d6, 0)] diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_2.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_2.cs new file mode 100644 index 0000000..c15c384 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_2.cs @@ -0,0 +1,28 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +/// +/// Group File Download +/// +[ProtoContract] +[OidbSvcTrpcTcp(0x6d6, 2)] +internal class OidbSvcTrpcTcp0x6D6_2 +{ + [ProtoMember(3)] public OidbSvcTrpcTcp0x6D6_2Download? Download { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D6_2Download +{ + [ProtoMember(1)] public uint GroupUin { get; set; } + + [ProtoMember(2)] public uint AppId { get; set; } // 7 + + [ProtoMember(3)] public uint BusId { get; set; } // 102 + + [ProtoMember(4)] public string FileId { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_5.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_5.cs new file mode 100644 index 0000000..915c000 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x6D6_5.cs @@ -0,0 +1,29 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +[ProtoContract] +[OidbSvcTrpcTcp(0x6d6, 5)] +internal class OidbSvcTrpcTcp0x6D6_5 +{ + [ProtoMember(6)] public OidbSvcTrpcTcp0x6D6_5Move? Move { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D6_5Move +{ + [ProtoMember(1)] public uint GroupUin { get; set; } + + [ProtoMember(2)] public uint AppId { get; set; } // 7 + + [ProtoMember(3)] public uint BusId { get; set; } // 102 + + [ProtoMember(4)] public string fileId { get; set; } + + [ProtoMember(5)] public string ParentDirectory { get; set; } + + [ProtoMember(6)] public string TargetDirectory { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTco0x6D6Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTco0x6D6Response.cs new file mode 100644 index 0000000..a125769 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTco0x6D6Response.cs @@ -0,0 +1,12 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Response; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +[ProtoContract] +internal class OidbSvcTrpcTco0x6D6Response +{ + [ProtoMember(3)] public OidbSvcTrpcTcp0x6D6_2Response Download { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D6_2Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D6_2Response.cs new file mode 100644 index 0000000..985098a --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x6D6_2Response.cs @@ -0,0 +1,34 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Response; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +[ProtoContract] +internal class OidbSvcTrpcTcp0x6D6_2Response +{ + [ProtoMember(1)] public int RetCode { get; set; } + + [ProtoMember(2)] public string RetMsg { get; set; } + + [ProtoMember(3)] public string ClientWording { get; set; } + + [ProtoMember(4)] public string DownloadIp { get; set; } + + [ProtoMember(5)] public string DownloadDns { get; set; } + + [ProtoMember(6)] public byte[] DownloadUrl { get; set; } + + [ProtoMember(7)] public byte[] FileSha1 { get; set; } + + [ProtoMember(8)] public byte[] FileSha3 { get; set; } // ? + + [ProtoMember(9)] public byte[] FileMd5 { get; set; } + + [ProtoMember(10)] public byte[] CookieVal { get; set; } + + [ProtoMember(11)] public string SaveFileName { get; set; } + + [ProtoMember(12)] public uint PreviewPort { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Action/GroupFSDownloadService.cs b/Lagrange.Core/Internal/Service/Action/GroupFSDownloadService.cs new file mode 100644 index 0000000..81386d9 --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/GroupFSDownloadService.cs @@ -0,0 +1,54 @@ +using Lagrange.Core.Common; +using Lagrange.Core.Internal.Event.Protocol; +using Lagrange.Core.Internal.Event.Protocol.Action; +using Lagrange.Core.Internal.Packets; +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.Internal.Service.Abstraction; +using Lagrange.Core.Utility.Extension; +using Lagrange.Core.Utility.Binary; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(GroupFSDownloadEvent))] +[Service("OidbSvcTrpcTcp.0x6d6_2")] +internal class GroupFSDownloadService : BaseService +{ + protected override bool Build(GroupFSDownloadEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out BinaryPacket output, out List? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(new OidbSvcTrpcTcp0x6D6_2 + { + Download = new OidbSvcTrpcTcp0x6D6_2Download + { + GroupUin = input.GroupUin, + AppId = 7, + BusId = 102, + FileId = input.FileId + } + }, false, true); + + var stream = new MemoryStream(); + Serializer.Serialize(stream, packet); + output = new BinaryPacket(stream); + + extraPackets = null; + return true; + } + + protected override bool Parse(SsoPacket input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out GroupFSDownloadEvent output, out List? extraEvents) + { + var payload = input.Payload.ReadBytes(BinaryPacket.Prefix.Uint32 | BinaryPacket.Prefix.WithPrefix); + var packet = Serializer.Deserialize>(payload.AsSpan()); + var download = packet.Body.Download; + + string url = $"https://{download.DownloadIp}:443/ftn_handler/{download.DownloadUrl.Hex(true)}/?fname="; + + output = GroupFSDownloadEvent.Result((int)packet.ErrorCode, url); + extraEvents = null; + return true; + } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Action/GroupFSMoveService.cs b/Lagrange.Core/Internal/Service/Action/GroupFSMoveService.cs new file mode 100644 index 0000000..cd11906 --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/GroupFSMoveService.cs @@ -0,0 +1,52 @@ +using Lagrange.Core.Common; +using Lagrange.Core.Internal.Event.Protocol; +using Lagrange.Core.Internal.Event.Protocol.Action; +using Lagrange.Core.Internal.Packets; +using Lagrange.Core.Internal.Packets.Service.Oidb; +using Lagrange.Core.Internal.Packets.Service.Oidb.Request; +using Lagrange.Core.Internal.Service.Abstraction; +using Lagrange.Core.Utility.Extension; +using Lagrange.Core.Utility.Binary; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(GroupFSMoveEvent))] +[Service("OidbSvcTrpcTcp.0x6d6_5")] +internal class GroupFSMoveService : BaseService +{ + protected override bool Build(GroupFSMoveEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out BinaryPacket output, out List? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(new OidbSvcTrpcTcp0x6D6_5 + { + Move = new OidbSvcTrpcTcp0x6D6_5Move + { + GroupUin = input.GroupUin, + AppId = 7, + BusId = 102, + fileId = input.FileId, + ParentDirectory = input.ParentDirectory, + TargetDirectory = input.TargetDirectory + } + }, false, true); + + var stream = new MemoryStream(); + Serializer.Serialize(stream, packet); + output = new BinaryPacket(stream); + + extraPackets = null; + return true; + } + + protected override bool Parse(SsoPacket input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, out GroupFSMoveEvent output, + out List? extraEvents) + { + var payload = input.Payload.ReadBytes(BinaryPacket.Prefix.Uint32 | BinaryPacket.Prefix.WithPrefix); + var packet = Serializer.Deserialize>(payload.AsSpan()); + + output = GroupFSMoveEvent.Result((int)packet.ErrorCode); + extraEvents = null; + return true; + } +} \ No newline at end of file