├── .gitignore ├── Icon.png ├── LICENSE ├── README.md ├── docs ├── api │ ├── HuajiTech.CoolQ.ApiException.html │ ├── HuajiTech.CoolQ.AppIdAttribute.html │ ├── HuajiTech.CoolQ.AppInitializationException.html │ ├── HuajiTech.CoolQ.AppLifecycle.html │ ├── HuajiTech.CoolQ.CurrentPluginContext.html │ ├── HuajiTech.CoolQ.CustomTitle.html │ ├── HuajiTech.CoolQ.DefaultInitializer.html │ ├── HuajiTech.CoolQ.Events.AnonymousMessageReceivedEventArgs.html │ ├── HuajiTech.CoolQ.Events.BotEventSource.html │ ├── HuajiTech.CoolQ.Events.CurrentUserEventSource.html │ ├── HuajiTech.CoolQ.Events.Extensions.html │ ├── HuajiTech.CoolQ.Events.FileUploadedEventArgs.html │ ├── HuajiTech.CoolQ.Events.FriendAddedEventArgs.html │ ├── HuajiTech.CoolQ.Events.FriendshipRequestedEventArgs.html │ ├── HuajiTech.CoolQ.Events.GroupEventArgs.html │ ├── HuajiTech.CoolQ.Events.GroupEventSource.html │ ├── HuajiTech.CoolQ.Events.GroupMessageReceivedEventArgs.html │ ├── HuajiTech.CoolQ.Events.GroupMuteEventArgs.html │ ├── HuajiTech.CoolQ.Events.IAdministratorshipEventSource.html │ ├── HuajiTech.CoolQ.Events.IBotEventSource.html │ ├── HuajiTech.CoolQ.Events.ICurrentUserEventSource.html │ ├── HuajiTech.CoolQ.Events.IFriendshipEventSource.html │ ├── HuajiTech.CoolQ.Events.IGroupEventSource.html │ ├── HuajiTech.CoolQ.Events.IMembershipEventSource.html │ ├── HuajiTech.CoolQ.Events.IMessageEventSource.html │ ├── HuajiTech.CoolQ.Events.IMuteEventSource.html │ ├── HuajiTech.CoolQ.Events.INotifyAdministratorAdded.html │ ├── HuajiTech.CoolQ.Events.INotifyAdministratorRemoved.html │ ├── HuajiTech.CoolQ.Events.INotifyAnonymousMessageReceived.html │ ├── HuajiTech.CoolQ.Events.INotifyAppDisabling.html │ ├── HuajiTech.CoolQ.Events.INotifyAppEnabled.html │ ├── HuajiTech.CoolQ.Events.INotifyBotStarted.html │ ├── HuajiTech.CoolQ.Events.INotifyBotStopping.html │ ├── HuajiTech.CoolQ.Events.INotifyFileUploaded.html │ ├── HuajiTech.CoolQ.Events.INotifyFriendAdded.html │ ├── HuajiTech.CoolQ.Events.INotifyFriendshipRequested.html │ ├── HuajiTech.CoolQ.Events.INotifyGroupMessageReceived.html │ ├── HuajiTech.CoolQ.Events.INotifyGroupMuted.html │ ├── HuajiTech.CoolQ.Events.INotifyGroupUnmuted.html │ ├── HuajiTech.CoolQ.Events.INotifyMemberJoined.html │ ├── HuajiTech.CoolQ.Events.INotifyMemberLeft.html │ ├── HuajiTech.CoolQ.Events.INotifyMemberMuted.html │ ├── HuajiTech.CoolQ.Events.INotifyMemberUnmuted.html │ ├── HuajiTech.CoolQ.Events.INotifyMembershipInvited.html │ ├── HuajiTech.CoolQ.Events.INotifyMembershipRequested.html │ ├── HuajiTech.CoolQ.Events.INotifyUserMessageReceived.html │ ├── HuajiTech.CoolQ.Events.MemberMutedEventArgs.html │ ├── HuajiTech.CoolQ.Events.MembershipInvitedEventArgs.html │ ├── HuajiTech.CoolQ.Events.MembershipRequestedEventArgs.html │ ├── HuajiTech.CoolQ.Events.MessageReceivedEventArgs.html │ ├── HuajiTech.CoolQ.Events.RoutedEventArgs.html │ ├── HuajiTech.CoolQ.Events.TimedEventArgs.html │ ├── HuajiTech.CoolQ.Events.UserMessageReceivedEventArgs.html │ ├── HuajiTech.CoolQ.Events.html │ ├── HuajiTech.CoolQ.Extensions.html │ ├── HuajiTech.CoolQ.File.html │ ├── HuajiTech.CoolQ.Gender.html │ ├── HuajiTech.CoolQ.IAliased.html │ ├── HuajiTech.CoolQ.IAnonymousMember.html │ ├── HuajiTech.CoolQ.IBot.html │ ├── HuajiTech.CoolQ.IChattable.html │ ├── HuajiTech.CoolQ.ICurrentUser.html │ ├── HuajiTech.CoolQ.IDisplayable.html │ ├── HuajiTech.CoolQ.IFriend.html │ ├── HuajiTech.CoolQ.IFriendshipRequest.html │ ├── HuajiTech.CoolQ.IGroup.html │ ├── HuajiTech.CoolQ.ILogger.html │ ├── HuajiTech.CoolQ.IMember.html │ ├── HuajiTech.CoolQ.IMembershipRequest.html │ ├── HuajiTech.CoolQ.IMuteable.html │ ├── HuajiTech.CoolQ.IRequest.html │ ├── HuajiTech.CoolQ.IRequestable.html │ ├── HuajiTech.CoolQ.ISendee.html │ ├── HuajiTech.CoolQ.ITimedMuteable.html │ ├── HuajiTech.CoolQ.IUser.html │ ├── HuajiTech.CoolQ.InitializerAttribute.html │ ├── HuajiTech.CoolQ.Loaders.AutofacLoader.html │ ├── HuajiTech.CoolQ.Loaders.ILoader.html │ ├── HuajiTech.CoolQ.Loaders.html │ ├── HuajiTech.CoolQ.LoggingExtensions.html │ ├── HuajiTech.CoolQ.MemberRole.html │ ├── HuajiTech.CoolQ.Message.html │ ├── HuajiTech.CoolQ.Messaging.AbstractionExtensions.html │ ├── HuajiTech.CoolQ.Messaging.Anonymous.html │ ├── HuajiTech.CoolQ.Messaging.At.html │ ├── HuajiTech.CoolQ.Messaging.CQCode.html │ ├── HuajiTech.CoolQ.Messaging.ComplexMessage.html │ ├── HuajiTech.CoolQ.Messaging.ComplexMessageExtensions.html │ ├── HuajiTech.CoolQ.Messaging.ContactShare.html │ ├── HuajiTech.CoolQ.Messaging.CustomEmoticon.html │ ├── HuajiTech.CoolQ.Messaging.CustomMusic.html │ ├── HuajiTech.CoolQ.Messaging.Dice.html │ ├── HuajiTech.CoolQ.Messaging.Emoji.html │ ├── HuajiTech.CoolQ.Messaging.Emoticon.html │ ├── HuajiTech.CoolQ.Messaging.Extensions.html │ ├── HuajiTech.CoolQ.Messaging.ISendable.html │ ├── HuajiTech.CoolQ.Messaging.Image.html │ ├── HuajiTech.CoolQ.Messaging.Location.html │ ├── HuajiTech.CoolQ.Messaging.Mention.html │ ├── HuajiTech.CoolQ.Messaging.MentionAll.html │ ├── HuajiTech.CoolQ.Messaging.MessageElement.html │ ├── HuajiTech.CoolQ.Messaging.MessageElementCollectionExtensions.html │ ├── HuajiTech.CoolQ.Messaging.Music.html │ ├── HuajiTech.CoolQ.Messaging.MusicPlatform.html │ ├── HuajiTech.CoolQ.Messaging.PlainText.html │ ├── HuajiTech.CoolQ.Messaging.Record.html │ ├── HuajiTech.CoolQ.Messaging.RedEnvelope.html │ ├── HuajiTech.CoolQ.Messaging.RichText.html │ ├── HuajiTech.CoolQ.Messaging.RockPaperScissors.html │ ├── HuajiTech.CoolQ.Messaging.RockPaperScissorsKind.html │ ├── HuajiTech.CoolQ.Messaging.Shake.html │ ├── HuajiTech.CoolQ.Messaging.Share.html │ ├── HuajiTech.CoolQ.Messaging.SignIn.html │ ├── HuajiTech.CoolQ.Messaging.SigningIn.html │ ├── HuajiTech.CoolQ.Messaging.SmallEmoticon.html │ ├── HuajiTech.CoolQ.Messaging.html │ ├── HuajiTech.CoolQ.Packing.ILRepacker.html │ ├── HuajiTech.CoolQ.Packing.IPacker.html │ ├── HuajiTech.CoolQ.Packing.html │ ├── HuajiTech.CoolQ.Plugin.html │ ├── HuajiTech.CoolQ.PluginAttribute.html │ ├── HuajiTech.CoolQ.PluginContext.html │ ├── HuajiTech.CoolQ.PluginContextExtensions.html │ ├── HuajiTech.CoolQ.PluginLoadException.html │ ├── HuajiTech.CoolQ.RegexMessage.html │ ├── HuajiTech.CoolQ.SdkInfo.html │ ├── HuajiTech.CoolQ.Status.html │ ├── HuajiTech.CoolQ.StatusColor.html │ ├── HuajiTech.CoolQ.html │ ├── index.html │ └── toc.html ├── favicon.ico ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── guides │ ├── events.html │ ├── getting_started.html │ ├── howto_handle_message.html │ ├── intro.html │ ├── menus_and_statuses.html │ ├── toc.html │ └── your_first_app.html ├── images │ └── favicon.ico ├── index.html ├── index.json ├── logo.svg ├── manifest.json ├── search-stopwords.json ├── styles │ ├── docfx.css │ ├── docfx.js │ ├── docfx.vendor.css │ ├── docfx.vendor.js │ ├── lunr.js │ ├── lunr.min.js │ ├── main.css │ ├── main.js │ └── search-worker.js ├── toc.html └── xrefmap.yml ├── documentation ├── .gitignore ├── api │ ├── .gitignore │ └── index.md ├── docfx.json ├── guides │ ├── events.md │ ├── getting_started.md │ ├── howto_handle_message.md │ ├── intro.md │ ├── menus_and_statuses.md │ ├── toc.md │ └── your_first_app.md ├── images │ └── favicon.ico ├── index.md └── toc.yml └── src ├── .editorconfig ├── .gitattributes ├── .gitignore ├── HuajiTech.CoolQ.Abstractions ├── AbstractionResources.Designer.cs ├── AbstractionResources.resx ├── AppIdAttribute.cs ├── AppLifecycle.cs ├── CurrentPluginContext.cs ├── CustomTitle.cs ├── Events │ ├── EventArgses │ │ ├── AnonymousMessageReceivedEventArgs.cs │ │ ├── FileUploadedEventArgs.cs │ │ ├── FriendAddedEventArgs.cs │ │ ├── FriendshipRequestedEventArgs.cs │ │ ├── GroupEventArgs.cs │ │ ├── GroupMessageReceivedEventArgs.cs │ │ ├── GroupMuteEventArgs.cs │ │ ├── MemberMutedEventArgs.cs │ │ ├── MembershipInvitedEventArgs.cs │ │ ├── MembershipRequestedEventArgs.cs │ │ ├── MessageReceivedEventArgs.cs │ │ ├── RoutedEventArgs.cs │ │ ├── TimedEventArgs.cs │ │ └── UserMessageReceivedEventArgs.cs │ ├── EventSources │ │ ├── IAdministratorshipEventSource.cs │ │ ├── IBotEventSource.cs │ │ ├── ICurrentUserEventSource.cs │ │ ├── IFriendshipEventSource.cs │ │ ├── IGroupEventSource.cs │ │ ├── IMembershipEventSource.cs │ │ ├── IMessageEventSource.cs │ │ └── IMuteEventSource.cs │ ├── Extensions.cs │ └── Notifications │ │ ├── INotifyAdministratorAdded.cs │ │ ├── INotifyAdministratorRemoved.cs │ │ ├── INotifyAnonymousMessageReceived.cs │ │ ├── INotifyAppDisabling.cs │ │ ├── INotifyAppEnabled.cs │ │ ├── INotifyBotStarted.cs │ │ ├── INotifyBotStopping.cs │ │ ├── INotifyFileUploaded.cs │ │ ├── INotifyFriendAdded.cs │ │ ├── INotifyFriendshipRequested.cs │ │ ├── INotifyGroupMessageReceived.cs │ │ ├── INotifyGroupMuted.cs │ │ ├── INotifyGroupUnmuted.cs │ │ ├── INotifyMemberJoined.cs │ │ ├── INotifyMemberLeft.cs │ │ ├── INotifyMemberMuted.cs │ │ ├── INotifyMemberUnmuted.cs │ │ ├── INotifyMembershipInvited.cs │ │ ├── INotifyMembershipRequested.cs │ │ └── INotifyUserMessageReceived.cs ├── Exceptions │ ├── ApiException.cs │ └── PluginLoadException.cs ├── File.cs ├── Gender.cs ├── HuajiTech.CoolQ.Abstractions.csproj ├── HuajiTech.CoolQ.Abstractions.xml ├── IAliased.cs ├── IAnonymousMember.cs ├── IBot.cs ├── IChattable.cs ├── ICurrentUser.cs ├── IDisplayable.cs ├── IFriend.cs ├── IFriendshipRequest.cs ├── IGroup.cs ├── ILoader.cs ├── ILogger.cs ├── IMember.cs ├── IMembershipRequest.cs ├── IMuteable.cs ├── IPacker.cs ├── IRequest.cs ├── IRequestable.cs ├── ISendee.cs ├── ITimedMuteable.cs ├── IUser.cs ├── LoggingExtensions.cs ├── MemberRole.cs ├── Message.cs ├── Plugin.cs ├── PluginAttribute.cs ├── PluginContext.cs ├── PluginContextExtensions.cs └── Properties │ └── AssemblyInfo.cs ├── HuajiTech.CoolQ.Core ├── .gitignore ├── AnonymousMember.cs ├── Bot.cs ├── Chat.cs ├── CoreResources.Designer.cs ├── CoreResources.resx ├── CurrentUser.cs ├── Enums │ ├── AdministratorsChangedType.cs │ ├── MessageSender.cs │ ├── Muting.cs │ ├── OperationKind.cs │ ├── Response.cs │ └── StatusColor.cs ├── ErrorHandlingExtensions.cs ├── Events │ ├── AdministratorsChangedEventArgs.cs │ ├── BotEventSource.cs │ ├── CurrentUserEventSource.cs │ └── GroupEventSource.cs ├── Exceptions │ └── AppInitializationException.cs ├── Friend.cs ├── FriendshipRequest.cs ├── Group.cs ├── HuajiTech.CoolQ.Core.csproj ├── HuajiTech.CoolQ.Core.xml ├── InitializerAttribute.cs ├── Interop │ ├── AnonymousMemberInfo.cs │ ├── AnonymousMemberInfoReader.cs │ ├── BasicGroupInfo.cs │ ├── BasicGroupInfoReader.cs │ ├── FileReader.cs │ ├── FriendInfo.cs │ ├── FriendInfoReader.cs │ ├── GroupInfo.cs │ ├── GroupInfoReader.cs │ ├── MemberInfo.cs │ ├── MemberInfoReader.cs │ ├── Reader{T}.cs │ ├── StatusWriter.cs │ ├── StringKeyValuePairReader.cs │ ├── UserInfo.cs │ ├── UserInfoReader.cs │ └── Writer{T}.cs ├── LogLevel.cs ├── Logger.cs ├── Member.cs ├── MembershipInvitation.cs ├── MembershipRequest.cs ├── MessageCore.cs ├── NativeMethods.cs ├── PluginContextCore.cs ├── Properties │ └── AssemblyInfo.cs ├── RegexMessage.cs ├── Status.cs ├── StringMarshaler.cs ├── User.cs ├── Utilities │ └── Timestamp.cs └── app.json ├── HuajiTech.CoolQ.Loaders.Autofac ├── AutofacLoader.cs ├── AutofacLoaderResources.Designer.cs ├── AutofacLoaderResources.resx ├── HuajiTech.CoolQ.Loaders.Autofac.csproj └── Properties │ └── AssemblyInfo.cs ├── HuajiTech.CoolQ.Messaging ├── CQCode.cs ├── CQCodes │ ├── Anonymous.cs │ ├── ContactShare.cs │ ├── CustomEmoticon.cs │ ├── CustomMusic.cs │ ├── Dice.cs │ ├── Emoji.cs │ ├── Emoticon.cs │ ├── Image.cs │ ├── Location.cs │ ├── Mention.cs │ ├── MentionAll.cs │ ├── Music.cs │ ├── MusicPlatform.cs │ ├── Record.cs │ ├── RedEnvelope.cs │ ├── RichText.cs │ ├── RockPaperScissors.cs │ ├── RockPaperScissorsKind.cs │ ├── Shake.cs │ ├── Share.cs │ ├── SigningIn.cs │ └── SmallEmoticon.cs ├── ComplexMessage.cs ├── ComplexMessageExtensions.cs ├── Extensions.cs ├── HuajiTech.CoolQ.Messaging.csproj ├── HuajiTech.CoolQ.Messaging.xml ├── ISendable.cs ├── MessageElement.cs ├── MessageElementCollectionExtensions.cs ├── PlainText.cs ├── Properties │ └── AssemblyInfo.cs ├── Resources.Designer.cs └── Resources.resx ├── HuajiTech.CoolQ.Packing.ILRepack ├── HuajiTech.CoolQ.Packing.ILRepack.csproj ├── ILRepacker.cs ├── Properties │ └── AssemblyInfo.cs ├── build │ ├── HuajiTech.CoolQ.Packing.ILRepack.Placeholder.targets │ ├── HuajiTech.CoolQ.Packing.ILRepack.props │ └── HuajiTech.CoolQ.Packing.ILRepack.targets └── tools │ └── net35 │ ├── InjectModuleInitializer.exe │ ├── Mono.Cecil.Mdb.dll │ ├── Mono.Cecil.Pdb.dll │ ├── Mono.Cecil.Rocks.dll │ └── Mono.Cecil.dll ├── HuajiTech.CoolQ.sln ├── HuajiTech.CoolQ ├── DefaultInitializer.cs ├── HuajiTech.CoolQ.csproj ├── HuajiTech.CoolQ.xml ├── Messaging │ └── AbstractionExtensions.cs ├── Properties │ ├── AppInfo.cs │ └── AssemblyInfo.cs └── SdkInfo.cs └── stylecop.json /.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # folder # 3 | ############### 4 | /**/DROP/ 5 | /**/TEMP/ 6 | /**/packages/ 7 | /**/bin/ 8 | /**/obj/ 9 | -------------------------------------------------------------------------------- /Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/Icon.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HuajiTech.CoolQ 2 | 3 | 用于*酷Q*应用的 .NET SDK。 4 | 5 | ## 项目状态 6 | 7 | ~~项目目前处于测试阶段,不建议用于生产环境。~~ 8 | 9 | 酷Q已无法使用,**本项目不再更新**。 10 | 11 | 已有应用可通过其他平台对于酷Q的兼容层继续使用,**不建议将本项目用于任何新的开发**。 12 | 13 | *如果事情出现巨大转机,不排除项目继续开发的可能性。* 14 | 15 | ## 特性 16 | 17 | - 通过 StdCall 导出。 18 | - 以 [NuGet 包](https://www.nuget.org/packages/HuajiTech.CoolQ/)发布。 19 | - **高度封装。** 20 | 21 | ## 复读机示例 22 | 23 | ```csharp 24 | using HuajiTech.CoolQ; 25 | using HuajiTech.CoolQ.Events; 26 | 27 | [assembly: AppId("com.example.repeater")] 28 | 29 | [Plugin] 30 | class RepeaterPlugin : Plugin 31 | { 32 | public RepeaterPlugin(IMessageEventSource eventSource) 33 | { 34 | eventSource.AddMessageReceivedEventHandler((sender, e) => e.Source.Send(e.Message)); 35 | } 36 | } 37 | ``` 38 | 39 | ## 文档 40 | 41 | [Github Pages](https://huajitech.github.io/coolq-dotnet-sdk/)(与代码库同步) 42 | 43 | [HuajiTech](https://www.huajitech.net/docs/coolq-dotnet-sdk/)(与最新的 NuGet 包同步) 44 | 45 | ## 讨论 46 | 47 | ~~[GitHub Issues](https://github.com/huajitech/coolq-dotnet-sdk/issues)~~ 或 [QQ群](https://jq.qq.com/?_wv=1027&k=5HPLCyU)(1094829331)。 48 | 49 | \*QQ群已不再讨论本项目。 50 | 51 | ## 许可 52 | 53 | 本项目使用 LGPL v3 进行许可。 54 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/docs/favicon.ico -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/docs/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/docs/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/docs/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/docs/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/guides/toc.html: -------------------------------------------------------------------------------- 1 |  2 |
3 |
4 |
5 |
6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 | 14 | 34 |
35 |
36 |
37 |
-------------------------------------------------------------------------------- /docs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/docs/images/favicon.ico -------------------------------------------------------------------------------- /docs/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by Docfx 9 | 10 | 12 | 15 | 21 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/search-stopwords.json: -------------------------------------------------------------------------------- 1 | [ 2 | "a", 3 | "able", 4 | "about", 5 | "across", 6 | "after", 7 | "all", 8 | "almost", 9 | "also", 10 | "am", 11 | "among", 12 | "an", 13 | "and", 14 | "any", 15 | "are", 16 | "as", 17 | "at", 18 | "be", 19 | "because", 20 | "been", 21 | "but", 22 | "by", 23 | "can", 24 | "cannot", 25 | "could", 26 | "dear", 27 | "did", 28 | "do", 29 | "does", 30 | "either", 31 | "else", 32 | "ever", 33 | "every", 34 | "for", 35 | "from", 36 | "get", 37 | "got", 38 | "had", 39 | "has", 40 | "have", 41 | "he", 42 | "her", 43 | "hers", 44 | "him", 45 | "his", 46 | "how", 47 | "however", 48 | "i", 49 | "if", 50 | "in", 51 | "into", 52 | "is", 53 | "it", 54 | "its", 55 | "just", 56 | "least", 57 | "let", 58 | "like", 59 | "likely", 60 | "may", 61 | "me", 62 | "might", 63 | "most", 64 | "must", 65 | "my", 66 | "neither", 67 | "no", 68 | "nor", 69 | "not", 70 | "of", 71 | "off", 72 | "often", 73 | "on", 74 | "only", 75 | "or", 76 | "other", 77 | "our", 78 | "own", 79 | "rather", 80 | "said", 81 | "say", 82 | "says", 83 | "she", 84 | "should", 85 | "since", 86 | "so", 87 | "some", 88 | "than", 89 | "that", 90 | "the", 91 | "their", 92 | "them", 93 | "then", 94 | "there", 95 | "these", 96 | "they", 97 | "this", 98 | "tis", 99 | "to", 100 | "too", 101 | "twas", 102 | "us", 103 | "wants", 104 | "was", 105 | "we", 106 | "were", 107 | "what", 108 | "when", 109 | "where", 110 | "which", 111 | "while", 112 | "who", 113 | "whom", 114 | "why", 115 | "will", 116 | "with", 117 | "would", 118 | "yet", 119 | "you", 120 | "your" 121 | ] 122 | -------------------------------------------------------------------------------- /docs/styles/main.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. 2 | -------------------------------------------------------------------------------- /docs/styles/search-worker.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | importScripts('lunr.min.js'); 3 | 4 | var lunrIndex; 5 | 6 | var stopWords = null; 7 | var searchData = {}; 8 | 9 | lunr.tokenizer.separator = /[\s\-\.]+/; 10 | 11 | var stopWordsRequest = new XMLHttpRequest(); 12 | stopWordsRequest.open('GET', '../search-stopwords.json'); 13 | stopWordsRequest.onload = function () { 14 | if (this.status != 200) { 15 | return; 16 | } 17 | stopWords = JSON.parse(this.responseText); 18 | buildIndex(); 19 | } 20 | stopWordsRequest.send(); 21 | 22 | var searchDataRequest = new XMLHttpRequest(); 23 | 24 | searchDataRequest.open('GET', '../index.json'); 25 | searchDataRequest.onload = function () { 26 | if (this.status != 200) { 27 | return; 28 | } 29 | searchData = JSON.parse(this.responseText); 30 | 31 | buildIndex(); 32 | 33 | postMessage({ e: 'index-ready' }); 34 | } 35 | searchDataRequest.send(); 36 | 37 | onmessage = function (oEvent) { 38 | var q = oEvent.data.q; 39 | var hits = lunrIndex.search(q); 40 | var results = []; 41 | hits.forEach(function (hit) { 42 | var item = searchData[hit.ref]; 43 | results.push({ 'href': item.href, 'title': item.title, 'keywords': item.keywords }); 44 | }); 45 | postMessage({ e: 'query-ready', q: q, d: results }); 46 | } 47 | 48 | function buildIndex() { 49 | if (stopWords !== null && !isEmpty(searchData)) { 50 | lunrIndex = lunr(function () { 51 | this.pipeline.remove(lunr.stopWordFilter); 52 | this.ref('href'); 53 | this.field('title', { boost: 50 }); 54 | this.field('keywords', { boost: 20 }); 55 | 56 | for (var prop in searchData) { 57 | if (searchData.hasOwnProperty(prop)) { 58 | this.add(searchData[prop]); 59 | } 60 | } 61 | 62 | var docfxStopWordFilter = lunr.generateStopWordFilter(stopWords); 63 | lunr.Pipeline.registerFunction(docfxStopWordFilter, 'docfxStopWordFilter'); 64 | this.pipeline.add(docfxStopWordFilter); 65 | this.searchPipeline.add(docfxStopWordFilter); 66 | }); 67 | } 68 | } 69 | 70 | function isEmpty(obj) { 71 | if(!obj) return true; 72 | 73 | for (var prop in obj) { 74 | if (obj.hasOwnProperty(prop)) 75 | return false; 76 | } 77 | 78 | return true; 79 | } 80 | })(); 81 | -------------------------------------------------------------------------------- /docs/toc.html: -------------------------------------------------------------------------------- 1 |  2 |
3 |
4 |
5 |
6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 | 14 | 22 |
23 |
24 |
25 |
-------------------------------------------------------------------------------- /documentation/.gitignore: -------------------------------------------------------------------------------- 1 | /templates -------------------------------------------------------------------------------- /documentation/api/.gitignore: -------------------------------------------------------------------------------- 1 | .manifest 2 | *.yml -------------------------------------------------------------------------------- /documentation/api/index.md: -------------------------------------------------------------------------------- 1 | # API 参考 2 | 3 | 浏览 HuajiTech.CoolQ 的 API。 -------------------------------------------------------------------------------- /documentation/docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": [ 3 | { 4 | "src": [ 5 | { 6 | "src": "../src", 7 | "files": [ 8 | "**.csproj" 9 | ] 10 | } 11 | ], 12 | "dest": "api", 13 | "disableGitFeatures": false, 14 | "disableDefaultFilter": false 15 | } 16 | ], 17 | "build": { 18 | "content": [ 19 | { 20 | "files": [ 21 | "api/**.yml", 22 | "api/index.md" 23 | ] 24 | }, 25 | { 26 | "files": [ 27 | "guides/**.md", 28 | "guides/**/toc.yml", 29 | "toc.yml", 30 | "*.md" 31 | ] 32 | } 33 | ], 34 | "resource": [ 35 | { 36 | "files": [ 37 | "images/**" 38 | ] 39 | } 40 | ], 41 | "overwrite": [ 42 | { 43 | "files": [ 44 | "apidoc/**.md" 45 | ], 46 | "exclude": [ 47 | "obj/**" 48 | ] 49 | } 50 | ], 51 | "dest": "../docs", 52 | "globalMetadataFiles": [], 53 | "fileMetadataFiles": [], 54 | "template": [ 55 | "default", 56 | "default(zh-cn)", 57 | "templates/material" 58 | ], 59 | "postProcessors": [ 60 | "ExtractSearchIndex" 61 | ], 62 | "noLangKeyword": false, 63 | "keepFileLink": false, 64 | "cleanupCacheHistory": false, 65 | "disableGitFeatures": false, 66 | "globalMetadata": { 67 | "_appTitle": "HuajiTech.CoolQ 文档", 68 | "_gitContribute": { 69 | "repo": "https://github.com/huajitech/coolq-dotnet-sdk", 70 | "branch": "master", 71 | "apiSpecFolder": "apidoc" 72 | }, 73 | "_gitUrlPattern": "github", 74 | "_appLogoPath": "images/favicon.ico", 75 | "_appFaviconPath": "images/favicon.ico", 76 | "_enableSearch": true, 77 | "_appFooter": "本文档使用 CC BY-NC-SA 4.0 进行许可。" 78 | }, 79 | } 80 | } -------------------------------------------------------------------------------- /documentation/guides/events.md: -------------------------------------------------------------------------------- 1 | # 事件 2 | 3 | | 类型 | 说明 | 事件 | 4 | | --: | :-- | :-- | 5 | | 1 | 私聊消息处理 | @"HuajiTech.CoolQ.Events.INotifyUserMessageReceived.UserMessageReceived" | 6 | | 2 | 群消息处理 | @"HuajiTech.CoolQ.Events.INotifyGroupMessageReceived.GroupMessageReceived" | 7 | | 11 | 群文件上传事件处理 | @"HuajiTech.CoolQ.Events.INotifyFileUploaded.FileUploaded" | 8 | | 101 | 群管理变动事件处理 | @"HuajiTech.CoolQ.Events.INotifyAdministratorAdded.AdministratorAdded"、@"HuajiTech.CoolQ.Events.INotifyAdministratorRemoved.AdministratorRemoved" | 9 | | 102 | 群成员减少事件处理 | @"HuajiTech.CoolQ.Events.INotifyMemberLeft.MemberLeft" | 10 | | 103 | 群成员增加事件处理 | @"HuajiTech.CoolQ.Events.INotifyMemberJoined.MemberJoined" | 11 | | 104 | 群禁言事件处理 | @"HuajiTech.CoolQ.Events.INotifyMemberMuted.MemberMuted"、@"HuajiTech.CoolQ.Events.INotifyMemberUnmuted.MemberUnmuted"、@"HuajiTech.CoolQ.Events.INotifyGroupMuted.GroupMuted"、@"HuajiTech.CoolQ.Events.INotifyGroupUnmuted.GroupUnmuted" | 12 | | 201 | 好友已添加事件处理 | @"HuajiTech.CoolQ.Events.INotifyFriendAdded.FriendAdded" | 13 | | 301 | 好友添加请求处理 | @"HuajiTech.CoolQ.Events.INotifyFriendshipRequested.FriendshipRequested" | 14 | | 302 | 群添加请求处理 | @"HuajiTech.CoolQ.Events.INotifyMembershipInvited.MembershipInvited"、@"HuajiTech.CoolQ.Events.INotifyMembershipRequested.MembershipRequested" | 15 | | 1001 | 酷Q启动事件 | @"HuajiTech.CoolQ.Events.INotifyBotStarted.BotStarted" | 16 | | 1002 | 酷Q关闭事件 | @"HuajiTech.CoolQ.Events.INotifyBotStopping.BotStopping" | 17 | | 1003 | 应用已被启用 | @"HuajiTech.CoolQ.Events.INotifyAppEnabled.AppEnabled" | 18 | | 1004 | 应用将被停用 | @"HuajiTech.CoolQ.Events.INotifyAppDisabling.AppDisabling" | 19 | -------------------------------------------------------------------------------- /documentation/guides/getting_started.md: -------------------------------------------------------------------------------- 1 | # 入门 2 | 3 | ## AppID 4 | 5 | 通过在程序集上应用 @"HuajiTech.CoolQ.AppIdAttribute" 指定 [AppID](https://docs.cqp.im/dev/v9/appid/)。 6 | 同一个应用中,@"HuajiTech.CoolQ.AppIdAttribute" 必须是唯一的。 7 | 8 | ## 插件类 9 | 10 | 通过为**可被实例化**的类应用 @"HuajiTech.CoolQ.PluginAttribute" 特性指定插件类。 11 | 在同一个应用中,可以指定多个插件类。插件类只会被实例化一次。 12 | 13 | 通常情况下,插件类应以 @"HuajiTech.CoolQ.Plugin" 类作为基类。 14 | 15 | 使用 @"HuajiTech.CoolQ.PluginAttribute" 特性的有参构造函数指定插件类的加载时机。 16 | 17 | ```csharp 18 | [Plugin((int)AppLifecycle.Initializing)] 19 | class MyPlugin : Plugin 20 | { 21 | } 22 | ``` 23 | 24 | > [!WARNING] 25 | > 不能直接将 @"HuajiTech.CoolQ.AppLifecycle" 枚举的值传入构造函数,否则将导致应用无法编译。 26 | 27 | 若在 @"HuajiTech.CoolQ.AppLifecycle.Enabled" 阶段加载,允许在构造函数内**调用 API**或**长时间阻塞线程**,并且可以显示引发的异常的详细信息。 28 | **必须**在 `app.json` 中向酷Q**注册应用启用事件**才能在 Enabled 阶段加载。 29 | 30 | 通过将加载阶段设置为 @"HuajiTech.CoolQ.AppLifecycle.NotLoaded" (`0`),可以禁止插件类的加载。 31 | 32 | 若在 @"HuajiTech.CoolQ.AppLifecycle.Initializing" 及其他非 @"HuajiTech.CoolQ.AppLifecycle.Enabled" 阶段加载,应遵循以下原则: 33 | 34 | - ✔ 在插件类构造函数内对**类**进行初始化。 35 | - ✔ 在 @"HuajiTech.CoolQ.Events.INotifyAppEnabled.AppEnabled" 事件中初始化**应用**。 36 | - ✘ 不应在插件类构造函数内调用酷Q API。 37 | - ✘ 插件类构造函数不应长时间阻塞线程。 38 | - ✘ 插件类构造函数不应抛出异常。 39 | 40 | 有关详细信息,请参见[酷Q文库](https://docs.cqp.im/dev/v9/tips/#%E5%90%AF%E5%8A%A8-%E5%88%9D%E5%A7%8B%E5%8C%96)。 41 | 42 | ## 事件 43 | 44 | 酷Q事件都被封装为了 .NET 事件。 45 | 当酷Q使用 StdCall 调用事件对应函数时,将会对事件数据进行封装并引发相应的事件。 46 | 47 | ✘ 不允许更改 `app.json` 中预定义的事件函数名。 48 | 49 | 部分酷Q事件被合并为一个或拆分为多个事件。若要获取详细信息,请参见[事件](events.md)。 50 | 51 | ### 事件源 52 | 53 | 事件源定义了一个或一组相关的事件。 54 | 事件源是接口类型。 55 | 定义了单个事件的事件源以 `Notify` 开头,如 @"HuajiTech.CoolQ.Events.INotifyGroupMessageReceived" 接口。 56 | 定义了多个事件的事件源以 `EventSource` 结尾,如 @"HuajiTech.CoolQ.Events.IBotEventSource" 接口。 57 | 58 | ### 处理事件 59 | 60 | 在插件类构造函数中添加参数以获取事件源。通过向事件源对象附加事件处理程序来处理事件。 61 | 62 | ```csharp 63 | public MyPlugin( 64 | INotifyGroupMessageReceived notifyGroupMessageReceived, 65 | IBotEventSource botEventSource) 66 | { 67 | notifyMessageReceived.MessageReceived += ... 68 | botEventSource.AppEnabled += ... 69 | } 70 | ``` 71 | 72 | > [!NOTE] 73 | > 尽可能使用定义事件最少的事件源。例如,若插件只需处理消息接收事件, 74 | 则应使用 @"HuajiTech.CoolQ.Events.INotifyGroupMessageReceived",而不是 @"HuajiTech.CoolQ.Events.ICurrentUserEventSource"。 75 | 76 | ### 路由 77 | 78 | 酷Q的所有事件数据类均派生自 @"HuajiTech.CoolQ.Events.RoutedEventArgs" 类。 79 | 将 @"HuajiTech.CoolQ.Events.RoutedEventArgs.Handled" 属性设置为 `true` 以阻断事件。 80 | 81 | ### 菜单和悬浮窗状态 82 | 83 | 菜单项被点击和悬浮窗状态更新均被视为事件。由于事件的数量无法确定,需要手动导出事件处理程序。 84 | 85 | 有关详细信息,请参见[菜单和悬浮窗状态](menus_and_statuses.md)。 86 | 87 | ## 调用酷Q API 88 | 89 | - 通过事件数据。 90 | 91 | ```csharp 92 | private void OnMemberJoined(object sender, GroupEventArgs e) 93 | { 94 | e.Operatee.Mute(TimeSpan.FromMinutes(5)); 95 | e.Source.Send("欢迎 " + e.Operatee.DisplayName); 96 | } 97 | ``` 98 | 99 | - 通过 @"HuajiTech.CoolQ.PluginContext" 类。对于 @"HuajiTech.CoolQ.PluginContext.Current",建议使用 @"HuajiTech.CoolQ.CurrentPluginContext" 类。 100 | 101 | ```csharp 102 | PluginContext.Current.GetUser(114514).Send("Hello!"); 103 | ``` 104 | 105 | - 通过 @"HuajiTech.CoolQ.Plugin" 类的 `protected` 实例方法。通常在插件类中使用此方法。 106 | 107 | ```csharp 108 | public class MyPlugin : Plugin 109 | { 110 | ... 111 | foreach (var member in Group(1919810).GetMembers()) 112 | ... 113 | } 114 | ``` 115 | 116 | - 通过 @"HuajiTech.CoolQ.CurrentPluginContext" 类提供的静态方法。通常在非插件类中使用此方法。 117 | 118 | ```csharp 119 | using static HuajiTech.CoolQ.CurrentPluginContext; 120 | 121 | User(114514).Send("Hello!"); 122 | ``` 123 | 124 | - 通过 @"HuajiTech.CoolQ.PluginContextExtensions" 类提供的常用扩展方法。 125 | 126 | ```csharp 127 | try 128 | { 129 | ... 130 | user.AsMemberOf(group); 131 | ... 132 | } 133 | catch (Exception ex) 134 | { 135 | ex.LogAsError(); 136 | } 137 | ``` 138 | 139 | - 通过 @"HuajiTech.CoolQ.Messaging.Image" 和 @"HuajiTech.CoolQ.Messaging.Record" 类。 140 | 141 | ```csharp 142 | image.GetFile(); 143 | ``` 144 | 145 | ## CQ码 146 | 147 | 可以使用 @"HuajiTech.CoolQ.Messaging.ComplexMessage" 类处理CQ码。 148 | 149 | 有关详细信息,请参见[如何:处理消息](howto_handle_message.md)中的`使用 ComplexMessage`部分。 150 | 151 | ## .NET Core 152 | 153 | 目前,HuajiTech.CoolQ 暂不支持在 .NET Core 上运行。有计划在未来的版本添加对 .NET Core 的支持。 154 | -------------------------------------------------------------------------------- /documentation/guides/howto_handle_message.md: -------------------------------------------------------------------------------- 1 | # 如何:处理消息 2 | 3 | ## 判断消息来源类型 4 | 5 | ```csharp 6 | if (e.Source is IGroup) { } // 群消息。 7 | if (e.Source is IUser) { } // 私聊消息(包括临时会话和好友消息)。 8 | if (e.Source is IMember) { } // 群临时会话消息(注意:由于酷Q限制,所在群为 Group(0))。 9 | if (e.Source is IFriend) { } // 好友消息。 10 | ``` 11 | 12 | ## 使用 @"HuajiTech.CoolQ.Messaging.ComplexMessage" 13 | 14 | 通过 @"HuajiTech.CoolQ.Messaging.AbstractionExtensions.Parse(HuajiTech.CoolQ.Message,System.Boolean)" 扩展方法解析消息。 15 | 16 | ```csharp 17 | var message = e.Message.Parse(); 18 | ``` 19 | 20 | 获取消息中的所有纯文本拼接成的字符串。 21 | 22 | ```csharp 23 | message.GetPlainText(); 24 | ``` 25 | 26 | 判断机器人是否被提及(@)。 27 | 28 | ```csharp 29 | if (message.Contains(CurrentUser.Mention())) 30 | { 31 | ... 32 | } 33 | ``` 34 | 35 | 使用 @"HuajiTech.CoolQ.Messaging.AbstractionExtensions.Mention(HuajiTech.CoolQ.IUser)" 提及消息的发送者。 36 | 37 | ```csharp 38 | e.Source.Send(e.Sender.Mention() + " How are you?"); 39 | // 或直接使用 Reply 扩展方法。 40 | e.Reply("How are you?"); 41 | ``` 42 | 43 | 解构复合消息。 44 | 45 | ```csharp 46 | var (a, b, c) = message; 47 | ``` 48 | 49 | 解构、模式匹配并获取剩余内容。 50 | 51 | ```csharp 52 | if (message is (Mention mention, Image image)) 53 | { 54 | var rest = message.Skip(2).ToComplexMessage(); 55 | ... 56 | } 57 | ``` 58 | 59 | ## 使用正则消息 60 | 61 | 通过 @"HuajiTech.CoolQ.RegexMessage.Decode(HuajiTech.CoolQ.Message)" 扩展方法解码正则消息。 62 | 63 | ```csharp 64 | var args = e.Message.Decode(); 65 | ``` 66 | 67 | 获取 `Name` 键的值。 68 | 69 | ```csharp 70 | args["Name"] 71 | ``` 72 | -------------------------------------------------------------------------------- /documentation/guides/intro.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | 3 | HuajiTech.CoolQ 是一个用于酷Q应用的 .NET SDK,旨在简化开发。 4 | 5 | ## 特性 6 | 7 | - 通过 StdCall 导出。 8 | - 以 [NuGet 包](https://www.nuget.org/packages/HuajiTech.CoolQ/)发布。 9 | - **高度封装。** 10 | 11 | ## 不适合使用此 SDK 的情况 12 | 13 | - 你希望直接操作酷Q API。 14 | - 你需要很强的自定义能力。 15 | 16 | ## 接下来 17 | 18 | [你的第一个应用](your_first_app.md) 19 | -------------------------------------------------------------------------------- /documentation/guides/menus_and_statuses.md: -------------------------------------------------------------------------------- 1 | # 菜单和悬浮窗状态 2 | 3 | ## 事件处理程序 4 | 5 | 菜单和悬浮窗状态的事件处理程序必须为静态方法。 6 | 7 | ### 菜单项被点击 8 | 9 | 菜单项被点击事件没有任何形参,也没有返回值。 10 | 11 | ```csharp 12 | static void OnMenuItemClicked(); 13 | ``` 14 | 15 | ### 悬浮窗状态更新 16 | 17 | 悬浮窗状态更新事件没有任何形参,返回一个字符串。返回的字符串是以 Base64 编码的状态数据。 18 | 19 | ```csharp 20 | static string OnStatusUpdating(); 21 | ``` 22 | 23 | 通过 @"HuajiTech.CoolQ.Status" 类和 @"HuajiTech.CoolQ.Status.Encode" 方法可以方便地创建状态数据并进行编码。 24 | 25 | ```csharp 26 | static string OnStatusUpdating() 27 | { 28 | return new HuajiTech.CoolQ.Status( 29 | value: "值", 30 | unit: "单位", 31 | color: HuajiTech.CoolQ.StatusColor.Green 32 | ).Encode(); 33 | } 34 | ``` 35 | 36 | ## 将托管方法导出为非托管方法 37 | 38 | 上面创建的事件处理程序是托管方法,但酷Q只能调用以 StdCall 导出的非托管方法。 39 | 通过 `HuajiTech.UnmanagedExports.DllExportAttribute` 可以标记要导出的方法。 40 | 41 | ```csharp 42 | [HuajiTech.UnmanagedExports.DllExport] 43 | static string OnStatusUpdating(); 44 | ``` 45 | 46 | 通过设置 `HuajiTech.UnmanagedExports.DllExportAttribute.EntryPoint` 属性,可以自定义导出后的方法的入口点名称。 47 | 如果 `EntryPoint` 属性为 `null`,将会使用方法名称作为入口点名称。 48 | 不能定义重复的入口点名称。 49 | 50 | ```csharp 51 | [HuajiTech.UnmanagedExports.DllExport(EntryPoint = "OnMenuItemClicked")] 52 | static void OpenConfiguration(); 53 | ``` 54 | 55 | ## 配置 `app.json` 56 | 57 | 在 `app.json` 中的 `status` 或 `menu` 下增加相应格式的元素,并将 `function` 的值设为导出的入口点名称。 58 | 59 | ```json 60 | "menu": [ 61 | { 62 | "name": "菜单项", 63 | "function": "OnMenuItemClicked" 64 | } 65 | ], 66 | "status": [ 67 | { 68 | "id": 1, 69 | "name": "悬浮窗", 70 | "title": "FLOAT", 71 | "function": "OnStatusUpdating", 72 | "period": "1000" 73 | } 74 | ] 75 | ``` 76 | -------------------------------------------------------------------------------- /documentation/guides/toc.md: -------------------------------------------------------------------------------- 1 | # [简介](intro.md) 2 | 3 | # [你的第一个应用](your_first_app.md) 4 | 5 | # [入门](getting_started.md) 6 | 7 | # [事件](events.md) 8 | 9 | # [菜单和悬浮窗状态](menus_and_statuses.md) 10 | 11 | # [如何:处理消息](howto_handle_message.md) -------------------------------------------------------------------------------- /documentation/guides/your_first_app.md: -------------------------------------------------------------------------------- 1 | # 你的第一个应用 2 | 3 | 1. 创建一个新的 C# 类库项目,并选择 **.NET Framework 4.6.1** 及以上版本作为目标框架。 4 | 2. 安装 HuajiTech.CoolQ NuGet 包。 5 | 3. 将以下代码粘贴到 `MyPlugin.cs`。 6 | 7 | ```csharp 8 | using HuajiTech.CoolQ; 9 | using HuajiTech.CoolQ.Events; 10 | 11 | [Plugin] 12 | public class MyPlugin : Plugin 13 | { 14 | public MyPlugin(IMessageEventSource eventSource) 15 | { 16 | eventSource.AddMessageReceivedEventHandler((sender, e) => 17 | { 18 | // 向消息来源聊天发送收到的消息,即复读。 19 | e.Source.Send(e.Message); 20 | }); 21 | } 22 | } 23 | ``` 24 | 25 | 4. 编译。 26 | 5. 将 `{输出目录}\app.publish\` 中的文件复制到酷Q的 `dev\com.example.app\` 目录。 27 | 6. 重载应用并启用。 28 | 29 | ## 接下来 30 | 31 | [入门](getting_started.md) 32 | -------------------------------------------------------------------------------- /documentation/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/documentation/images/favicon.ico -------------------------------------------------------------------------------- /documentation/index.md: -------------------------------------------------------------------------------- 1 | # HuajiTech.CoolQ 文档 2 | 3 | - 通过 [GitHub 主页](https://github.com/huajitech/coolq-dotnet-sdk) 认识该项目。 4 | - 查看 [指南](guides/intro.md) 以快速入门。 5 | - 在 [API 参考](api/index.md) 中了解技术细节。 6 | -------------------------------------------------------------------------------- /documentation/toc.yml: -------------------------------------------------------------------------------- 1 | - name: 指南 2 | href: guides/ 3 | - name: API 参考 4 | href: api/ 5 | homepage: api/index.md -------------------------------------------------------------------------------- /src/.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/AppIdAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 指定当前程序集的 AppID。 7 | /// 此类不能被继承。 8 | /// 9 | [AttributeUsage(AttributeTargets.Assembly)] 10 | public sealed class AppIdAttribute : Attribute 11 | { 12 | /// 13 | /// 以指定的 ID 初始化一个 类的新实例。 14 | /// 15 | /// 应用的 AppID。 16 | public AppIdAttribute(string id) => Id = id; 17 | 18 | /// 19 | /// 获取当前 实例的 ID。 20 | /// 21 | public string Id { get; } 22 | } 23 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/AppLifecycle.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 指定应用生命周期。 5 | /// 6 | public enum AppLifecycle 7 | { 8 | /// 9 | /// 应用未被加载。 10 | /// 11 | NotLoaded, 12 | 13 | /// 14 | /// 应用已被加载。 15 | /// 16 | Loaded, 17 | 18 | /// 19 | /// 应用正在初始化。 20 | /// 21 | Initializing, 22 | 23 | /// 24 | /// 机器人已启动。 25 | /// 26 | BotStarted, 27 | 28 | /// 29 | /// 应用已被启用。 30 | /// 31 | Enabled, 32 | 33 | /// 34 | /// 应用正在停用。 35 | /// 36 | Disabling, 37 | 38 | /// 39 | /// 机器人正在关闭。 40 | /// 41 | BotStopping 42 | } 43 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/CurrentPluginContext.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 提供操作 的静态方法。 5 | /// 6 | public static class CurrentPluginContext 7 | { 8 | /// 9 | /// 获取 。 10 | /// 11 | public static IBot Bot => PluginContext.Current.Bot; 12 | 13 | /// 14 | /// 获取 。 15 | /// 16 | public static ICurrentUser CurrentUser => Bot.CurrentUser; 17 | 18 | /// 19 | /// 获取 。 20 | /// 21 | public static ILogger Logger => Bot.Logger; 22 | 23 | /// 24 | /// 创建指定号码的好友。 25 | /// 26 | /// 号码。 27 | public static IFriend Friend(long number) => PluginContext.Current.GetFriend(number); 28 | 29 | /// 30 | /// 创建指定号码的群。 31 | /// 32 | /// 号码。 33 | public static IGroup Group(long number) => PluginContext.Current.GetGroup(number); 34 | 35 | /// 36 | /// 创建指定号码和群的成员。 37 | /// 38 | /// 号码。 39 | /// 群。 40 | public static IMember Member(long number, IGroup group) => PluginContext.Current.GetMember(number, group); 41 | 42 | /// 43 | /// 创建指定号码和群号码的成员。 44 | /// 45 | /// 号码。 46 | /// 群号码。 47 | public static IMember Member(long number, long groupNumber) => PluginContext.Current.GetMember(number, groupNumber); 48 | 49 | /// 50 | /// 创建指定号码的用户。 51 | /// 52 | /// 号码。 53 | public static IUser User(long number) => PluginContext.Current.GetUser(number); 54 | 55 | /// 56 | /// 创建指定 ID 的消息。 57 | /// 58 | /// ID。 59 | public static Message Message(int id) => PluginContext.Current.GetMessage(id); 60 | } 61 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/CustomTitle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 表示自定义头衔。 7 | /// 8 | public class CustomTitle 9 | { 10 | /// 11 | /// 以指定的文本和过期时间初始化一个 类的新实例。 12 | /// 13 | /// 文本。 14 | /// 过期时间。 15 | /// 或仅由空白字符组成。 16 | public CustomTitle(string text, DateTime? expirationTime = null) 17 | { 18 | if (string.IsNullOrWhiteSpace(text)) 19 | { 20 | throw new ArgumentException(AbstractionResources.FieldCannotBeEmptyOrWhiteSpace, nameof(text)); 21 | } 22 | 23 | Text = text; 24 | ExpirationTime = expirationTime; 25 | } 26 | 27 | /// 28 | /// 获取当前 实例的过期时间。 29 | /// 如果没有过期时间,则为 。 30 | /// 31 | public DateTime? ExpirationTime { get; } 32 | 33 | /// 34 | /// 获取当前 的文本。 35 | /// 36 | public string Text { get; } 37 | } 38 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/AnonymousMessageReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 为 事件提供数据。 5 | /// 6 | public class AnonymousMessageReceivedEventArgs : RoutedEventArgs 7 | { 8 | public AnonymousMessageReceivedEventArgs(Message message, IGroup source, IAnonymousMember sender) 9 | { 10 | Message = message; 11 | Source = source; 12 | Sender = sender; 13 | } 14 | 15 | /// 16 | /// 获取消息。 17 | /// 18 | public virtual Message Message { get; } 19 | 20 | /// 21 | /// 获取发送者。 22 | /// 23 | public virtual IAnonymousMember Sender { get; } 24 | 25 | /// 26 | /// 获取来源群。 27 | /// 28 | public virtual IGroup Source { get; } 29 | } 30 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/FileUploadedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为 事件提供数据。 7 | /// 8 | public class FileUploadedEventArgs : TimedEventArgs 9 | { 10 | public FileUploadedEventArgs(DateTime time, IGroup source, IMember uploader, File file) 11 | : base(time) 12 | { 13 | Source = source; 14 | Uploader = uploader; 15 | File = file; 16 | } 17 | 18 | /// 19 | /// 获取来源群。 20 | /// 21 | public virtual IGroup Source { get; } 22 | 23 | /// 24 | /// 获取上传用户。 25 | /// 26 | public virtual IMember Uploader { get; } 27 | 28 | /// 29 | /// 获取上传的文件。 30 | /// 31 | public virtual File File { get; } 32 | } 33 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/FriendAddedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为 事件提供数据。 7 | /// 8 | public class FriendAddedEventArgs : TimedEventArgs 9 | { 10 | public FriendAddedEventArgs(DateTime time, IFriend operatee) 11 | : base(time) 12 | { 13 | Operatee = operatee; 14 | } 15 | 16 | /// 17 | /// 获取添加的好友。 18 | /// 19 | public virtual IFriend Operatee { get; } 20 | } 21 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/FriendshipRequestedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为 事件提供数据。 7 | /// 8 | public class FriendshipRequestedEventArgs : TimedEventArgs 9 | { 10 | public FriendshipRequestedEventArgs(DateTime time, IUser requester, IFriendshipRequest request) 11 | : base(time) 12 | { 13 | Requester = requester; 14 | Request = request; 15 | } 16 | 17 | /// 18 | /// 获取请求用户。 19 | /// 20 | public virtual IUser Requester { get; } 21 | 22 | /// 23 | /// 获取请求。 24 | /// 25 | public virtual IFriendshipRequest Request { get; } 26 | } 27 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/GroupEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为群事件提供数据。 7 | /// 8 | public class GroupEventArgs : TimedEventArgs 9 | { 10 | public GroupEventArgs(DateTime time, IGroup source, IMember @operator, IMember operatee) 11 | : base(time) 12 | { 13 | Source = source; 14 | Operator = @operator; 15 | Operatee = operatee; 16 | } 17 | 18 | /// 19 | /// 获取来源群。 20 | /// 21 | public virtual IGroup Source { get; } 22 | 23 | /// 24 | /// 获取操作人。 25 | /// 26 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 27 | "Naming", "CA1716:标识符不应与关键字匹配", Justification = "<挂起>")] 28 | public virtual IMember Operator { get; } 29 | 30 | /// 31 | /// 获取被操作人。 32 | /// 33 | public virtual IMember Operatee { get; } 34 | } 35 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/GroupMessageReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 为 事件提供数据。 5 | /// 6 | public class GroupMessageReceivedEventArgs : MessageReceivedEventArgs 7 | { 8 | public GroupMessageReceivedEventArgs(Message message, IGroup source, IMember sender) 9 | : base(message, source, sender) 10 | { 11 | Source = source; 12 | Sender = sender; 13 | } 14 | 15 | /// 16 | /// 获取来源群。 17 | /// 18 | public new virtual IGroup Source { get; } 19 | 20 | /// 21 | /// 获取发送成员。 22 | /// 23 | public new virtual IMember Sender { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/GroupMuteEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为 事件提供数据。 7 | /// 8 | public class GroupMuteEventArgs : TimedEventArgs 9 | { 10 | public GroupMuteEventArgs(DateTime time, IGroup source, IMember @operator) 11 | : base(time) 12 | { 13 | Source = source; 14 | Operator = @operator; 15 | } 16 | 17 | /// 18 | /// 获取来源群。 19 | /// 20 | public virtual IGroup Source { get; } 21 | 22 | /// 23 | /// 获取操作者。 24 | /// 25 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 26 | "Naming", "CA1716:标识符不应与关键字匹配", Justification = "<挂起>")] 27 | public virtual IMember Operator { get; } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/MemberMutedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为 事件提供数据。 7 | /// 8 | public class MemberMutedEventArgs : GroupEventArgs 9 | { 10 | public MemberMutedEventArgs( 11 | DateTime time, IGroup source, IMember @operator, IMember operatee, TimeSpan duration) 12 | : base(time, source, @operator, operatee) 13 | { 14 | Duration = duration; 15 | } 16 | 17 | /// 18 | /// 获取禁言时长。 19 | /// 20 | public virtual TimeSpan Duration { get; } 21 | } 22 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/MembershipInvitedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为 事件提供数据。 7 | /// 8 | public class MembershipInvitedEventArgs : TimedEventArgs 9 | { 10 | public MembershipInvitedEventArgs( 11 | DateTime time, IGroup target, IUser inviter, IRequest invitation) 12 | : base(time) 13 | { 14 | Target = target; 15 | Inviter = inviter; 16 | Invitation = invitation; 17 | } 18 | 19 | /// 20 | /// 获取目标群。 21 | /// 22 | public virtual IGroup Target { get; } 23 | 24 | /// 25 | /// 获取邀请用户。 26 | /// 27 | public virtual IUser Inviter { get; } 28 | 29 | /// 30 | /// 获取邀请。 31 | /// 32 | public virtual IRequest Invitation { get; } 33 | } 34 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/MembershipRequestedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为 事件提供数据。 7 | /// 8 | public class MembershipRequestedEventArgs : TimedEventArgs 9 | { 10 | public MembershipRequestedEventArgs( 11 | DateTime time, IGroup source, IUser requester, IMembershipRequest request) 12 | : base(time) 13 | { 14 | Source = source; 15 | Requester = requester; 16 | Request = request; 17 | } 18 | 19 | /// 20 | /// 获取来源群。 21 | /// 22 | public virtual IGroup Source { get; } 23 | 24 | /// 25 | /// 获取请求用户。 26 | /// 27 | public virtual IUser Requester { get; } 28 | 29 | /// 30 | /// 获取请求。 31 | /// 32 | public virtual IMembershipRequest Request { get; } 33 | } 34 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/MessageReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 为消息接收事件数据提供基类。 5 | /// 6 | public class MessageReceivedEventArgs : RoutedEventArgs 7 | { 8 | public MessageReceivedEventArgs(Message message, IChattable source, IUser sender) 9 | { 10 | Message = message; 11 | Source = source; 12 | Sender = sender; 13 | } 14 | 15 | /// 16 | /// 获取消息。 17 | /// 18 | public virtual Message Message { get; } 19 | 20 | /// 21 | /// 获取来源聊天。 22 | /// 23 | public virtual IChattable Source { get; } 24 | 25 | /// 26 | /// 获取发送者。 27 | /// 28 | public virtual IUser Sender { get; } 29 | } 30 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/RoutedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 表示路由事件的数据,并为所有事件数据提供基类。 7 | /// 8 | public class RoutedEventArgs : EventArgs 9 | { 10 | /// 11 | /// 获取或设置一个值,指示事件是否已处理完毕。 12 | /// 13 | public virtual bool Handled { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/TimedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 为可以提供引发时间的事件数据提供基类。 7 | /// 8 | public class TimedEventArgs : RoutedEventArgs 9 | { 10 | public TimedEventArgs(DateTime time) 11 | { 12 | Time = time; 13 | } 14 | 15 | /// 16 | /// 获取事件发生的时间。 17 | /// 18 | public virtual DateTime Time { get; } 19 | } 20 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventArgses/UserMessageReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 为 事件提供数据。 5 | /// 6 | public class UserMessageReceivedEventArgs : MessageReceivedEventArgs 7 | { 8 | public UserMessageReceivedEventArgs(Message message, IUser source, IUser sender) 9 | : base(message, source, sender) 10 | { 11 | Source = source; 12 | } 13 | 14 | /// 15 | /// 获取来源用户。 16 | /// 17 | public new virtual IUser Source { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventSources/IAdministratorshipEventSource.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 定义管理员事件。 5 | /// 6 | public interface IAdministratorshipEventSource : INotifyAdministratorAdded, INotifyAdministratorRemoved 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventSources/IBotEventSource.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 定义机器人事件。 5 | /// 6 | public interface IBotEventSource : 7 | INotifyAppDisabling, 8 | INotifyAppEnabled, 9 | INotifyBotStarted, 10 | INotifyBotStopping 11 | { 12 | } 13 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventSources/ICurrentUserEventSource.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 定义当前用户事件。 5 | /// 6 | public interface ICurrentUserEventSource : IMessageEventSource, IFriendshipEventSource 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventSources/IFriendshipEventSource.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 定义好友事件。 5 | /// 6 | public interface IFriendshipEventSource : INotifyFriendAdded, INotifyFriendshipRequested 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventSources/IGroupEventSource.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 定义群事件。 5 | /// 6 | public interface IGroupEventSource : 7 | IMuteEventSource, 8 | IMembershipEventSource, 9 | IAdministratorshipEventSource, 10 | INotifyFileUploaded 11 | { 12 | } 13 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventSources/IMembershipEventSource.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 定义群成员事件。 5 | /// 6 | public interface IMembershipEventSource : 7 | INotifyMemberJoined, 8 | INotifyMemberLeft, 9 | INotifyMembershipRequested, 10 | INotifyMembershipInvited 11 | { 12 | } 13 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventSources/IMessageEventSource.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 定义消息事件。 5 | /// 6 | public interface IMessageEventSource : 7 | INotifyAnonymousMessageReceived, 8 | INotifyUserMessageReceived, 9 | INotifyGroupMessageReceived 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/EventSources/IMuteEventSource.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Events 2 | { 3 | /// 4 | /// 定义禁言事件。 5 | /// 6 | public interface IMuteEventSource : 7 | INotifyMemberMuted, 8 | INotifyMemberUnmuted, 9 | INotifyGroupMuted, 10 | INotifyGroupUnmuted 11 | { 12 | } 13 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义扩展方法。 7 | /// 8 | public static class Extensions 9 | { 10 | /// 11 | /// 添加消息接收事件处理程序。 12 | /// 即同时添加私聊消息接收事件和群消息接收事件的事件处理程序。 13 | /// 14 | /// 事件源。 15 | /// 事件处理程序。 16 | public static void AddMessageReceivedEventHandler( 17 | this IMessageEventSource messageEventSource, 18 | EventHandler handler) 19 | { 20 | if (messageEventSource is null) 21 | { 22 | throw new ArgumentNullException(nameof(messageEventSource)); 23 | } 24 | 25 | messageEventSource.UserMessageReceived += new EventHandler(handler); 26 | messageEventSource.GroupMessageReceived += new EventHandler(handler); 27 | } 28 | 29 | /// 30 | /// 移除消息接收事件处理程序。 31 | /// 即同时移除私聊消息接收事件和群消息接收事件的事件处理程序。 32 | /// 33 | /// 事件源。 34 | /// 事件处理程序。 35 | public static void RemoveMessageReceivedEventHandler( 36 | this IMessageEventSource messageEventSource, 37 | EventHandler handler) 38 | { 39 | if (messageEventSource is null) 40 | { 41 | throw new ArgumentNullException(nameof(messageEventSource)); 42 | } 43 | 44 | messageEventSource.UserMessageReceived -= new EventHandler(handler); 45 | messageEventSource.GroupMessageReceived -= new EventHandler(handler); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyAdministratorAdded.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义管理员添加事件。 7 | /// 8 | public interface INotifyAdministratorAdded 9 | { 10 | /// 11 | /// 在添加管理员时引发。 12 | /// 13 | event EventHandler AdministratorAdded; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyAdministratorRemoved.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义管理员移除事件。 7 | /// 8 | public interface INotifyAdministratorRemoved 9 | { 10 | /// 11 | /// 在移除管理员时引发。 12 | /// 13 | event EventHandler AdministratorRemoved; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyAnonymousMessageReceived.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义匿名消息接收事件。 7 | /// 8 | public interface INotifyAnonymousMessageReceived 9 | { 10 | /// 11 | /// 在收到匿名消息时引发。 12 | /// 13 | event EventHandler AnonymousMessageReceived; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyAppDisabling.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义应用禁用事件。 7 | /// 8 | public interface INotifyAppDisabling 9 | { 10 | /// 11 | /// 在应用被禁用时引发。 12 | /// 13 | event EventHandler AppDisabling; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyAppEnabled.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义应用启用事件。 7 | /// 8 | public interface INotifyAppEnabled 9 | { 10 | /// 11 | /// 在应用被启用时引发。 12 | /// 13 | event EventHandler AppEnabled; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyBotStarted.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义机器人启动事件。 7 | /// 8 | public interface INotifyBotStarted 9 | { 10 | /// 11 | /// 在机器人启动时引发。 12 | /// 13 | event EventHandler BotStarted; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyBotStopping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义机器人停止事件。 7 | /// 8 | public interface INotifyBotStopping 9 | { 10 | /// 11 | /// 在机器人停止时引发。 12 | /// 13 | event EventHandler BotStopping; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyFileUploaded.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义文件上传事件。 7 | /// 8 | public interface INotifyFileUploaded 9 | { 10 | /// 11 | /// 在上传文件时引发。 12 | /// 13 | event EventHandler FileUploaded; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyFriendAdded.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义好友已添加事件。 7 | /// 8 | public interface INotifyFriendAdded 9 | { 10 | /// 11 | /// 在好友已添加时引发。 12 | /// 13 | event EventHandler FriendAdded; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyFriendshipRequested.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义好友正在添加事件。 7 | /// 8 | public interface INotifyFriendshipRequested 9 | { 10 | /// 11 | /// 在收到好友请求时引发。 12 | /// 13 | event EventHandler FriendshipRequested; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyGroupMessageReceived.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义群消息接收事件。 7 | /// 8 | public interface INotifyGroupMessageReceived 9 | { 10 | /// 11 | /// 在收到群消息时引发。 12 | /// 13 | event EventHandler GroupMessageReceived; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyGroupMuted.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义群禁言事件。 7 | /// 8 | public interface INotifyGroupMuted 9 | { 10 | /// 11 | /// 在禁言时引发。 12 | /// 13 | event EventHandler GroupMuted; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyGroupUnmuted.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义群解除禁言事件。 7 | /// 8 | public interface INotifyGroupUnmuted 9 | { 10 | /// 11 | /// 在解除禁言时引发。 12 | /// 13 | event EventHandler GroupUnmuted; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyMemberJoined.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义成员加入事件。 7 | /// 8 | public interface INotifyMemberJoined 9 | { 10 | /// 11 | /// 在成员加入时引发。 12 | /// 13 | event EventHandler MemberJoined; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyMemberLeft.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义成员离开事件。 7 | /// 8 | public interface INotifyMemberLeft 9 | { 10 | /// 11 | /// 在成员离开时引发。 12 | /// 13 | event EventHandler MemberLeft; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyMemberMuted.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义成员禁言事件。 7 | /// 8 | public interface INotifyMemberMuted 9 | { 10 | /// 11 | /// 在禁言时引发。 12 | /// 13 | event EventHandler MemberMuted; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyMemberUnmuted.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义成员解除禁言事件。 7 | /// 8 | public interface INotifyMemberUnmuted 9 | { 10 | /// 11 | /// 在解除禁言时引发。 12 | /// 13 | event EventHandler MemberUnmuted; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyMembershipInvited.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义入群邀请事件。 7 | /// 8 | public interface INotifyMembershipInvited 9 | { 10 | /// 11 | /// 在被邀请加群时引发。 12 | /// 13 | event EventHandler MembershipInvited; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyMembershipRequested.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义入群请求事件。 7 | /// 8 | public interface INotifyMembershipRequested 9 | { 10 | /// 11 | /// 在收到入群请求时引发。 12 | /// 13 | event EventHandler MembershipRequested; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Events/Notifications/INotifyUserMessageReceived.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Events 4 | { 5 | /// 6 | /// 定义私聊消息接收事件。 7 | /// 8 | public interface INotifyUserMessageReceived 9 | { 10 | /// 11 | /// 在收到私聊消息时引发。 12 | /// 13 | event EventHandler UserMessageReceived; 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Exceptions/ApiException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace HuajiTech.CoolQ 5 | { 6 | /// 7 | /// 在 API 调用发生错误时引发的异常。 8 | /// 9 | [Serializable] 10 | public class ApiException : Exception 11 | { 12 | public ApiException() 13 | { 14 | } 15 | 16 | public ApiException(string message) 17 | : base(message) 18 | { 19 | } 20 | 21 | public ApiException(string message, int errorCode) 22 | : this(message) 23 | { 24 | ErrorCode = errorCode; 25 | } 26 | 27 | public ApiException(string message, Exception innerException) 28 | : base(message, innerException) 29 | { 30 | } 31 | 32 | protected ApiException(SerializationInfo info, StreamingContext context) 33 | : base(info, context) 34 | { 35 | } 36 | 37 | /// 38 | /// 获取当前 实例的错误代码。 39 | /// 如果没有错误代码,则为 。 40 | /// 41 | public int? ErrorCode { get; } 42 | } 43 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Exceptions/PluginLoadException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace HuajiTech.CoolQ 5 | { 6 | [Serializable] 7 | public class PluginLoadException : Exception 8 | { 9 | public PluginLoadException() 10 | { 11 | } 12 | 13 | public PluginLoadException(string message) 14 | : base(message) 15 | { 16 | } 17 | 18 | public PluginLoadException(string message, Exception innerException) 19 | : base(message, innerException) 20 | { 21 | } 22 | 23 | protected PluginLoadException(SerializationInfo info, StreamingContext context) 24 | : base(info, context) 25 | { 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/File.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 表示文件。 5 | /// 6 | public class File 7 | { 8 | /// 9 | /// 以指定的 ID、名称、长度和 BusID 初始化一个 类的新实例。 10 | /// 11 | /// ID。 12 | /// 名称。 13 | /// 长度。 14 | /// BusID。 15 | public File(string id, string name, long length, long busId) 16 | { 17 | Id = id; 18 | Name = name; 19 | Length = length; 20 | BusId = busId; 21 | } 22 | 23 | /// 24 | /// 获取当前 实例的 BusID。 25 | /// 26 | public long BusId { get; } 27 | 28 | /// 29 | /// 获取当前 实例的 ID。 30 | /// 31 | public string Id { get; } 32 | 33 | /// 34 | /// 获取当前 实例的长度。 35 | /// 36 | public long Length { get; } 37 | 38 | /// 39 | /// 获取当前 实例的名称。 40 | /// 41 | public string Name { get; } 42 | } 43 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Gender.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 指定性别。 5 | /// 6 | public enum Gender 7 | { 8 | /// 9 | /// 男。 10 | /// 11 | Male, 12 | 13 | /// 14 | /// 女。 15 | /// 16 | Female, 17 | 18 | /// 19 | /// 未知。 20 | /// 21 | Unknown = 255 22 | } 23 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/HuajiTech.CoolQ.Abstractions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HuajiTech.CoolQ 5 | netstandard2.0;net461;net45 6 | 8 7 | enable 8 | true 9 | HuajiTech.CoolQ.Abstractions.pfx 10 | 0.4.0-beta 11 | SYC 12 | HuajiTech 13 | 对于 HuajiTech.CoolQ 的抽象。 14 | Copyright (C) 2020 HuajiTech 15 | LGPL-3.0-or-later 16 | https://github.com/huajitech/coolq-dotnet-sdk 17 | Icon.png 18 | https://github.com/huajitech/coolq-dotnet-sdk 19 | git 20 | HuajiTech, CoolQ, 酷Q, QQ, Bot, Robot, 机器人 21 | 这是一个测试版本,不建议用于生产环境。 22 | zh-CN 23 | true 24 | true 25 | C:\Users\SYC\source\repos\HuajiTech.CoolQ\src\HuajiTech.CoolQ.Abstractions\HuajiTech.CoolQ.Abstractions.xml 26 | 27 | 28 | 29 | 30 | True 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | all 42 | runtime; build; native; contentfiles; analyzers; buildtransitive 43 | 44 | 45 | all 46 | runtime; build; native; contentfiles; analyzers; buildtransitive 47 | 48 | 49 | 50 | 51 | 52 | AbstractionResources.resx 53 | True 54 | True 55 | 56 | 57 | 58 | 59 | 60 | AbstractionResources.Designer.cs 61 | ResXFileCodeGenerator 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IAliased.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 提供别名。 5 | /// 6 | public interface IAliased 7 | { 8 | /// 9 | /// 获取当前 实例的别名。 10 | /// 11 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 12 | "Naming", "CA1716:标识符不应与关键字匹配", Justification = "<挂起>")] 13 | string? Alias { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IAnonymousMember.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 定义匿名成员。 7 | /// 8 | public interface IAnonymousMember : IDisplayable, IMuteable, IEquatable 9 | { 10 | /// 11 | /// 获取当前 实例的标识符。 12 | /// 13 | long Id { get; } 14 | 15 | /// 16 | /// 获取当前 实例的所属群。 17 | /// 18 | public IGroup Group { get; } 19 | 20 | /// 21 | /// 获取当前 实例的名称。 22 | /// 23 | public string? Name { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IBot.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 定义机器人。 7 | /// 8 | public interface IBot 9 | { 10 | /// 11 | /// 获取一个值,指示当前 实例是否可以发送图片。 12 | /// 13 | bool CanSendImage { get; } 14 | 15 | /// 16 | /// 获取一个值,指示当前 实例是否可以发送录音。 17 | /// 18 | bool CanSendRecord { get; } 19 | 20 | /// 21 | /// 获取当前 实例的当前用户。 22 | /// 23 | ICurrentUser CurrentUser { get; } 24 | 25 | /// 26 | /// 获取当前 实例的日志记录器。 27 | /// 28 | ILogger Logger { get; } 29 | 30 | /// 31 | /// 获取当前 实例的应用目录。 32 | /// 33 | DirectoryInfo AppDirectory { get; } 34 | 35 | /// 36 | /// 请求指定文件名的图片。 37 | /// 38 | /// 请求获取的图片的文件名。 39 | FileInfo GetImage(string fileName); 40 | 41 | /// 42 | /// 请求指定文件名的录音。 43 | /// 44 | /// 请求获取的录音的文件名。 45 | /// 请求获取的录音的格式。 46 | FileInfo GetRecord(string fileName, string fileFormat); 47 | } 48 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IChattable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 定义聊天。 7 | /// 8 | public interface IChattable : ISendee, IDisplayable, IEquatable 9 | { 10 | /// 11 | /// 获取当前 实例的号码。 12 | /// 13 | long Number { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/ICurrentUser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 定义当前用户。 7 | /// 8 | public interface ICurrentUser : IUser 9 | { 10 | /// 11 | /// 获取当前 实例的所有好友。 12 | /// 13 | IReadOnlyCollection GetFriends(); 14 | 15 | /// 16 | /// 获取当前 实例在指定域下的 Cookies。 17 | /// 18 | string GetCookies(string domain); 19 | 20 | /// 21 | /// 获取当前 实例的 CSRF 令牌。 22 | /// 23 | int GetCsrfToken(); 24 | 25 | /// 26 | /// 获取当前 实例的所有群。 27 | /// 28 | IReadOnlyCollection GetGroups(); 29 | } 30 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IDisplayable.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 提供用于显示的属性。 5 | /// 6 | public interface IDisplayable 7 | { 8 | /// 9 | /// 获取当前 实例的显示名称。 10 | /// 11 | string DisplayName { get; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IFriend.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 定义好友。 5 | /// 6 | public interface IFriend : IUser, IAliased 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IFriendshipRequest.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 定义好友请求。 5 | /// 6 | public interface IFriendshipRequest : IRequest 7 | { 8 | /// 9 | /// 同意当前请求,并为好友设置别名。 10 | /// 11 | /// 要设置的别名。 12 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 13 | "Naming", "CA1716:标识符不应与关键字匹配", Justification = "<挂起>")] 14 | void Accept(string alias); 15 | } 16 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IGroup.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 定义群。 7 | /// 8 | public interface IGroup : IChattable, IMuteable, IRequestable 9 | { 10 | /// 11 | /// 获取当前 实例的名称。 12 | /// 13 | public string? Name { get; } 14 | 15 | /// 16 | /// 获取当前 实例的成员容量。 17 | /// 18 | int MemberCapacity { get; } 19 | 20 | /// 21 | /// 获取当前 实例的成员数。 22 | /// 23 | int MemberCount { get; } 24 | 25 | /// 26 | /// 禁用当前 实例的匿名功能。 27 | /// 28 | void DisableAnonymous(); 29 | 30 | /// 31 | /// 解散当前 实例。 32 | /// 33 | void Disband(); 34 | 35 | /// 36 | /// 启用当前 实例的匿名功能。 37 | /// 38 | void EnableAnonymous(); 39 | 40 | /// 41 | /// 获取当前 实例的所有成员。 42 | /// 43 | IReadOnlyCollection GetMembers(); 44 | 45 | /// 46 | /// 离开当前 实例。 47 | /// 48 | void Leave(); 49 | } 50 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/ILoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace HuajiTech.CoolQ.Loaders 5 | { 6 | /// 7 | /// 定义加载器。 8 | /// 9 | public interface ILoader 10 | { 11 | /// 12 | /// 获取指定类型的插件。 13 | /// 14 | /// 插件的类型。 15 | /// 指定的插件类型的实例。 16 | T GetPlugin() 17 | where T : notnull; 18 | 19 | /// 20 | /// 获取指定类型的插件。 21 | /// 22 | /// 插件的类型。 23 | /// 指定的插件类型的实例。 24 | object GetPlugin(Type pluginType); 25 | 26 | /// 27 | /// 获取在指定加载时机加载的插件。 28 | /// 29 | /// 加载时机。 30 | /// 取在指定加载时机加载的插件集合。 31 | /// 如果没有在指定的加载时机加载的插件,则该方法返回空序列。 32 | IReadOnlyCollection GetPlugins(AppLifecycle loadTiming); 33 | } 34 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/ILogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 提供记录日志的方法。 7 | /// 8 | public interface ILogger 9 | { 10 | /// 11 | /// 记录一条等级为调试的日志。 12 | /// 13 | /// 日志的类型。 14 | /// 日志的消息。 15 | void LogDebug(string type, string message); 16 | 17 | /// 18 | /// 记录一条等级为错误的日志。 19 | /// 20 | /// 日志的类型。 21 | /// 日志的消息。 22 | void LogError(string type, string message); 23 | 24 | /// 25 | /// 记录一条等级为致命的日志。 26 | /// 27 | /// 28 | /// 该方法弹出一个错误提示窗口,该窗口不包括调用堆栈和重载应用选项。 29 | /// 如非必要,请改为使用 。 30 | /// 31 | /// 日志的类型。 32 | /// 日志的消息。 33 | [Obsolete("在适用处使用 RaiseFatal。有关详细信息,请参阅备注部分。")] 34 | void LogFatal(string type, string message); 35 | 36 | /// 37 | /// 记录一条日志。 38 | /// 39 | /// 日志的类型。 40 | /// 日志的消息。 41 | void Log(string type, string message); 42 | 43 | /// 44 | /// 记录一条等级为接收的日志。 45 | /// 46 | /// 日志的类型。 47 | /// 日志的消息。 48 | void LogReceiving(string type, string message); 49 | 50 | /// 51 | /// 记录一条等级为发送的日志。 52 | /// 53 | /// 日志的类型。 54 | /// 日志的消息。 55 | void LogSending(string type, string message); 56 | 57 | /// 58 | /// 记录一条等级为成功的日志。 59 | /// 60 | /// 日志的类型。 61 | /// 日志的消息。 62 | void LogSuccess(string type, string message); 63 | 64 | /// 65 | /// 记录一条等级为警告的日志。 66 | /// 67 | /// 日志的类型。 68 | /// 日志的消息。 69 | void LogWarning(string type, string message); 70 | 71 | /// 72 | /// 引发一个致命错误。 73 | /// 74 | /// 致命错误的消息。 75 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 76 | "Design", "CA1030:在适用处使用事件", Justification = "<挂起>")] 77 | void RaiseFatal(string message); 78 | } 79 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IMember.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 定义成员。 7 | /// 8 | public interface IMember : IUser, IAliased, ITimedMuteable, IEquatable 9 | { 10 | /// 11 | /// 获取一个值,指示当前 实例是否可以编辑 。 12 | /// 13 | bool CanEditAlias { get; } 14 | 15 | /// 16 | /// 获取当前 实例的自定义头衔。 17 | /// 若当前 实例没有自定义头衔,则为 。 18 | /// 19 | CustomTitle? CustomTitle { get; } 20 | 21 | /// 22 | /// 获取当前 实例加入 的时间。 23 | /// 24 | DateTime TimeJoined { get; } 25 | 26 | /// 27 | /// 获取一个值,指示当前 实例是否有不良记录。 28 | /// 29 | bool HasBadRecord { get; } 30 | 31 | /// 32 | /// 获取或设置一个值,指示当前 实例是否为管理员。 33 | /// 若当前 实例是群主,则该属性也返回 。 34 | /// 35 | bool IsAdministrator { get; } 36 | 37 | /// 38 | /// 获取当前 实例的最后发言时间。 39 | /// 40 | DateTime LastSpeakTime { get; } 41 | 42 | /// 43 | /// 获取当前 实例的等级。 44 | /// 45 | string? Level { get; } 46 | 47 | /// 48 | /// 获取当前 实例的位置。 49 | /// 50 | string? Location { get; } 51 | 52 | /// 53 | /// 获取当前 实例的角色。 54 | /// 55 | MemberRole Role { get; } 56 | 57 | /// 58 | /// 获取当前 实例的所属 实例。 59 | /// 60 | IGroup Group { get; } 61 | 62 | /// 63 | /// 设置当前 实例的别名,即 属性的值。 64 | /// 如果 ,则移除当前 实例的别名。 65 | /// 66 | /// 要设置的别名。 67 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 68 | "Naming", "CA1716:标识符不应与关键字匹配", Justification = "<挂起>")] 69 | void SetAlias(string? alias); 70 | 71 | /// 72 | /// 将当前 实例踢出所在群。 73 | /// 74 | /// 75 | /// 如果不再接收当前 实例的 ,则为 ;否则为 。 76 | /// 77 | void Kick(bool ignoreFurtherRequests = false); 78 | 79 | /// 80 | /// 使当前 实例成为管理员。 81 | /// 82 | void MakeAdministrator(); 83 | 84 | /// 85 | /// 使当前 实例不再是管理员。 86 | /// 87 | void UnmakeAdministrator(); 88 | 89 | /// 90 | /// 设置当前 实例的自定义头衔,即 属性的值。 91 | /// 如果 ,则移除当前 实例的自定义头衔。 92 | /// 93 | /// 要设置的头衔。 94 | void SetCustomTitle(CustomTitle? title); 95 | } 96 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IMembershipRequest.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 定义成员请求。 5 | /// 6 | public interface IMembershipRequest : IRequest 7 | { 8 | /// 9 | /// 拒绝当前请求,并指定拒绝的原因。 10 | /// 11 | /// 原因。 12 | void Reject(string reason); 13 | } 14 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IMuteable.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 提供用于禁言的方法。 5 | /// 6 | public interface IMuteable 7 | { 8 | /// 9 | /// 将当前 实例禁言。 10 | /// 11 | void Mute(); 12 | 13 | /// 14 | /// 将当前 实例解除禁言。 15 | /// 16 | void Unmute(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IPacker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Reflection; 3 | 4 | namespace HuajiTech.CoolQ.Packing 5 | { 6 | /// 7 | /// 定义打包器。 8 | /// 9 | public interface IPacker 10 | { 11 | /// 12 | /// 获取由打包器打包的程序集。 13 | /// 14 | IReadOnlyCollection GetPackedAssemblies(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IRequest.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 定义请求。 5 | /// 6 | public interface IRequest 7 | { 8 | /// 9 | /// 获取当前 实例的消息。 10 | /// 11 | string Message { get; } 12 | 13 | /// 14 | /// 同意当前请求。 15 | /// 16 | void Accept(); 17 | 18 | /// 19 | /// 拒绝当前请求。 20 | /// 21 | void Reject(); 22 | } 23 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IRequestable.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 提供用于请求的方法。 5 | /// 6 | public interface IRequestable 7 | { 8 | /// 9 | /// 获取一个值,指示当前 实例是否已请求。 10 | /// 11 | bool IsRequested { get; } 12 | 13 | /// 14 | /// 获取一个值,指示当前 实例是否已成功请求。 15 | /// 16 | bool IsRequestedSuccessfully { get; } 17 | 18 | /// 19 | /// 请求当前 实例。 20 | /// 21 | void Request(); 22 | 23 | /// 24 | /// 刷新当前 实例。 25 | /// 26 | void Refresh(); 27 | } 28 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/ISendee.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 定义消息的接收者。 5 | /// 6 | public interface ISendee 7 | { 8 | /// 9 | /// 向当前 实例发送指定的字符串。 10 | /// 11 | /// 要发送的字符串。 12 | /// 一个 实例,表示已发送的消息。 13 | Message Send(string message); 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/ITimedMuteable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 提供用于禁言指定时间的方法。 7 | /// 8 | public interface ITimedMuteable : IMuteable 9 | { 10 | /// 11 | /// 将当前 实例禁言指定时长。 12 | /// 13 | /// 要禁言的时长。 14 | void Mute(TimeSpan duration); 15 | } 16 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/IUser.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 定义用户。 5 | /// 6 | public interface IUser : IChattable, IRequestable 7 | { 8 | /// 9 | /// 获取当前 实例的昵称。 10 | /// 11 | string? Nickname { get; } 12 | 13 | /// 14 | /// 获取当前 实例的年龄。 15 | /// 16 | public int Age { get; } 17 | 18 | /// 19 | /// 获取当前 实例的性别。 20 | /// 21 | public Gender Gender { get; } 22 | 23 | /// 24 | /// 给予当前 实例指定数量的赞。 25 | /// 26 | /// 赞的数量。 27 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 28 | "Naming", "CA1716:标识符不应与关键字匹配", Justification = "<挂起>")] 29 | void Like(int count = 1); 30 | } 31 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/MemberRole.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 指定成员角色。 5 | /// 6 | public enum MemberRole 7 | { 8 | None, 9 | 10 | /// 11 | /// 成员。 12 | /// 13 | Member, 14 | 15 | /// 16 | /// 管理员。 17 | /// 18 | Administrator, 19 | 20 | /// 21 | /// 群主。 22 | /// 23 | Owner 24 | } 25 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Message.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/src/HuajiTech.CoolQ.Abstractions/Message.cs -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Plugin.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 用作插件的基类,并提供操作 的实例方法。 5 | /// 此类为抽象类。 6 | /// 7 | public abstract class Plugin 8 | { 9 | /// 10 | /// 以指定的 初始化一个 类的新实例。 11 | /// 12 | /// 当前 实例所使用的 。 13 | protected Plugin(PluginContext context) => Context = context; 14 | 15 | /// 16 | /// 以 初始化一个 类的新实例。 17 | /// 18 | protected Plugin() 19 | : this(PluginContext.Current) 20 | { 21 | } 22 | 23 | /// 24 | /// 获取当前 实例的 。 25 | /// 26 | public virtual PluginContext Context { get; } 27 | 28 | /// 29 | /// 获取当前 实例的 。 30 | /// 31 | protected IBot Bot => Context.Bot; 32 | 33 | /// 34 | /// 获取当前 实例的 。 35 | /// 36 | protected ICurrentUser CurrentUser => Bot.CurrentUser; 37 | 38 | /// 39 | /// 获取当前 实例的 。 40 | /// 41 | protected ILogger Logger => Bot.Logger; 42 | 43 | /// 44 | /// 创建指定号码的好友。 45 | /// 46 | /// 号码。 47 | protected IFriend Friend(long number) => Context.GetFriend(number); 48 | 49 | /// 50 | /// 创建指定号码的群。 51 | /// 52 | /// 号码。 53 | protected IGroup Group(long number) => Context.GetGroup(number); 54 | 55 | /// 56 | /// 创建指定号码和群的成员。 57 | /// 58 | /// 号码。 59 | /// 群。 60 | protected IMember Member(long number, IGroup group) => Context.GetMember(number, group); 61 | 62 | /// 63 | /// 创建指定号码和群号码的成员。 64 | /// 65 | /// 号码。 66 | /// 群号码。 67 | protected IMember Member(long number, long groupNumber) => Context.GetMember(number, groupNumber); 68 | 69 | /// 70 | /// 创建指定号码的用户。 71 | /// 72 | /// 号码。 73 | protected IUser User(long number) => Context.GetUser(number); 74 | 75 | /// 76 | /// 创建指定 ID 的消息。 77 | /// 78 | /// ID。 79 | protected Message Message(int id) => Context.GetMessage(id); 80 | } 81 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/PluginAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 指定插件类。 7 | /// 此类不能被继承。 8 | /// 9 | [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] 10 | public sealed class PluginAttribute : Attribute 11 | { 12 | /// 13 | /// 以指定的加载时机初始化一个 类的新实例。 14 | /// 15 | /// 加载时机。 16 | public PluginAttribute(AppLifecycle loadTiming) => LoadTiming = loadTiming; 17 | 18 | /// 19 | /// 以 初始化一个 的新实例。 20 | /// 21 | public PluginAttribute() 22 | : this(AppLifecycle.Initializing) 23 | { 24 | } 25 | 26 | /// 27 | /// 以指定的加载时机初始化一个 类的新实例。 28 | /// 29 | /// 加载时机的 值,如 (int)LoadTiming.Enabled。 30 | public PluginAttribute(int loadTiming) 31 | : this((AppLifecycle)loadTiming) 32 | { 33 | } 34 | 35 | /// 36 | /// 以指定的加载时机初始化一个 类的新实例。 37 | /// 38 | /// 加载时机的 表示形式,如 nameof(AppLifecycle.Enabled)。 39 | public PluginAttribute(string loadTiming) 40 | : this((AppLifecycle)Enum.Parse(typeof(AppLifecycle), loadTiming)) 41 | { 42 | } 43 | 44 | /// 45 | /// 获取插件的加载时机。 46 | /// 47 | public AppLifecycle LoadTiming { get; } 48 | } 49 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/PluginContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 表示插件上下文。 7 | /// 此类为抽象类。 8 | /// 9 | public abstract class PluginContext 10 | { 11 | private static PluginContext? _current; 12 | 13 | /// 14 | /// 获取或设置当前插件上下文。 15 | /// 16 | /// 17 | public static PluginContext Current 18 | { 19 | get => _current ?? throw new InvalidOperationException(AbstractionResources.ContextNotInitialized); 20 | set => _current = value ?? throw new ArgumentNullException(nameof(value)); 21 | } 22 | 23 | /// 24 | /// 在派生类中重写时,获取当前 实例的 。 25 | /// 26 | public abstract IBot Bot { get; } 27 | 28 | /// 29 | /// 在派生类中重写时,获取指定号码的用户。 30 | /// 31 | /// 号码。 32 | public abstract IUser GetUser(long number); 33 | 34 | /// 35 | /// 在派生类中重写时,获取指定号码的好友。 36 | /// 37 | /// 号码。 38 | public abstract IFriend GetFriend(long number); 39 | 40 | /// 41 | /// 在派生类中重写时,获取指定号码的群。 42 | /// 43 | /// 号码。 44 | public abstract IGroup GetGroup(long number); 45 | 46 | /// 47 | /// 在派生类中重写时,获取指定号码和群的成员。 48 | /// 49 | /// 号码。 50 | /// 群。 51 | public abstract IMember GetMember(long number, IGroup group); 52 | 53 | /// 54 | /// 获取指定号码和群号码的成员。 55 | /// 56 | /// 号码。 57 | /// 群号码。 58 | public virtual IMember GetMember(long number, long groupNumber) 59 | => GetMember(number, GetGroup(groupNumber)); 60 | 61 | /// 62 | /// 获取号码为指定用户的号码,群为指定群的 实例。 63 | /// 64 | /// 用户。 65 | /// 群。 66 | public virtual IMember GetMember(IUser user, IGroup group) 67 | { 68 | if (user is null) 69 | { 70 | throw new ArgumentNullException(nameof(user)); 71 | } 72 | 73 | return GetMember(user.Number, group); 74 | } 75 | 76 | /// 77 | /// 获取号码为指定用户的号码,群为指定群号码的群的 实例。 78 | /// 79 | /// 用户。 80 | /// 群号码。 81 | public virtual IMember GetMember(IUser user, long groupNumber) => GetMember(user, GetGroup(groupNumber)); 82 | 83 | /// 84 | /// 在派生类中重写时,获取指定 ID 的 实例。 85 | /// 86 | /// 消息 ID。 87 | public abstract Message GetMessage(int id); 88 | } 89 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/PluginContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 定义用于操作 的扩展方法。 7 | /// 8 | public static class PluginContextExtensions 9 | { 10 | public static IUser AsUser(this IUser user, PluginContext context) 11 | { 12 | if (user is null) 13 | { 14 | throw new ArgumentNullException(nameof(user)); 15 | } 16 | 17 | if (context is null) 18 | { 19 | throw new ArgumentNullException(nameof(context)); 20 | } 21 | 22 | return context.GetUser(user.Number); 23 | } 24 | 25 | public static IUser AsUser(this IUser user) => user.AsUser(PluginContext.Current); 26 | 27 | public static IMember AsMemberOf(this IUser user, IGroup group, PluginContext context) 28 | { 29 | if (user is null) 30 | { 31 | throw new ArgumentNullException(nameof(user)); 32 | } 33 | 34 | if (group is null) 35 | { 36 | throw new ArgumentNullException(nameof(group)); 37 | } 38 | 39 | if (context is null) 40 | { 41 | throw new ArgumentNullException(nameof(context)); 42 | } 43 | 44 | return context.GetMember(user, group); 45 | } 46 | 47 | public static IMember AsMemberOf(this IUser user, IGroup group) 48 | => user.AsMemberOf(group, PluginContext.Current); 49 | 50 | public static IMember? AsMemberOf(this IUser user, long groupNumber, PluginContext context) 51 | { 52 | if (user is null) 53 | { 54 | throw new ArgumentNullException(nameof(user)); 55 | } 56 | 57 | if (context is null) 58 | { 59 | throw new ArgumentNullException(nameof(context)); 60 | } 61 | 62 | return context.GetMember(user, groupNumber); 63 | } 64 | 65 | public static IMember? AsMemberOf(this IUser user, long groupNumber) 66 | => user.AsMemberOf(groupNumber, PluginContext.Current); 67 | } 68 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Abstractions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [assembly: CLSCompliant(true)] -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ############### 3 | # folder # 4 | ############### 5 | /**/DROP/ 6 | /**/TEMP/ 7 | /**/packages/ 8 | /**/bin/ 9 | /**/obj/ 10 | _site 11 | templates 12 | log.txt -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/AnonymousMember.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using HuajiTech.CoolQ.Interop; 3 | 4 | namespace HuajiTech.CoolQ 5 | { 6 | internal class AnonymousMember : IAnonymousMember 7 | { 8 | public static readonly TimeSpan MaxMuteDuration = TimeSpan.FromDays(30); 9 | 10 | private readonly string _rawInfo; 11 | private AnonymousMemberInfo? _info = null; 12 | 13 | public AnonymousMember(string rawInfo, IGroup group) 14 | { 15 | _rawInfo = rawInfo; 16 | Group = group; 17 | } 18 | 19 | public long Id => GetInfo().Id; 20 | 21 | public string? Name => GetInfo().Name; 22 | 23 | public string DisplayName => Name ?? ToString(); 24 | 25 | public IGroup Group { get; } 26 | 27 | public bool Equals(IAnonymousMember? other) => other?.Id == Id && Group.Equals(other?.Group); 28 | 29 | public void Mute(TimeSpan duration) 30 | { 31 | if (duration <= TimeSpan.Zero) 32 | { 33 | throw new ArgumentOutOfRangeException(nameof(duration)); 34 | } 35 | 36 | NativeMethods.AnonymousMember_Mute( 37 | Bot.Instance.AuthCode, Group.Number, _rawInfo, (long)duration.TotalSeconds).CheckError(); 38 | } 39 | 40 | public void Mute() => Mute(MaxMuteDuration); 41 | 42 | public void Unmute() 43 | => NativeMethods.AnonymousMember_Mute( 44 | Bot.Instance.AuthCode, Group.Number, _rawInfo, 0).CheckError(); 45 | 46 | private AnonymousMemberInfo GetInfo() 47 | { 48 | if (_info is null) 49 | { 50 | using var reader = new AnonymousMemberInfoReader(_rawInfo); 51 | _info = reader.Read(); 52 | } 53 | 54 | return _info; 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Chat.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal abstract class Chat : IChattable 4 | { 5 | protected Chat() 6 | { 7 | } 8 | 9 | protected Chat(long number) => Number = number; 10 | 11 | public abstract string DisplayName { get; } 12 | 13 | public virtual long Number { get; } 14 | 15 | public override bool Equals(object? obj) => Equals(obj as IChattable); 16 | 17 | public virtual bool Equals(IChattable? other) 18 | => base.Equals(other) || (other is Chat && other?.Number == Number); 19 | 20 | public override int GetHashCode() => (int)Number; 21 | 22 | public abstract Message Send(string message); 23 | 24 | public override string ToString() => $"{GetType().Name}({Number})"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/CurrentUser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using HuajiTech.CoolQ.Interop; 4 | 5 | namespace HuajiTech.CoolQ 6 | { 7 | internal class CurrentUser : User, ICurrentUser 8 | { 9 | public override long Number => NativeMethods.CurrentUser_GetNumber(Bot.Instance.AuthCode); 10 | 11 | public override string Nickname => NativeMethods.CurrentUser_GetNickname(Bot.Instance.AuthCode); 12 | 13 | internal static IReadOnlyCollection GetFriendInfos() 14 | { 15 | using var reader = new FriendInfoReader( 16 | NativeMethods.CurrentUser_GetFriends(Bot.Instance.AuthCode).CheckError()); 17 | 18 | return reader.ReadAll().ToList(); 19 | } 20 | 21 | public IReadOnlyCollection GetFriends() 22 | { 23 | return GetFriendInfos() 24 | .Select(info => new Friend(info)) 25 | .ToList(); 26 | } 27 | 28 | public string GetCookies(string domain) 29 | => NativeMethods.CurrentUser_GetCookies(Bot.Instance.AuthCode, domain).CheckError(); 30 | 31 | public int GetCsrfToken() 32 | => NativeMethods.CurrentUser_GetCsrfToken(Bot.Instance.AuthCode).CheckError(); 33 | 34 | public IReadOnlyCollection GetGroups() 35 | { 36 | using var reader = new BasicGroupInfoReader( 37 | NativeMethods.CurrentUser_GetGroups(Bot.Instance.AuthCode).CheckError()); 38 | 39 | return reader.ReadAll() 40 | .Select(info => new Group(info.Number, info.Name!)) 41 | .ToList(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Enums/AdministratorsChangedType.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal enum AdministratorsChangedType 4 | { 5 | None, 6 | Remove, 7 | Add 8 | } 9 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Enums/MessageSender.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal enum MessageSender 4 | { 5 | None, 6 | User, 7 | Member, 8 | Friend = 11 9 | } 10 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Enums/Muting.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal enum Muting 4 | { 5 | None, 6 | Unmute, 7 | Mute 8 | } 9 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Enums/OperationKind.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal enum OperationKind 4 | { 5 | None, 6 | Active, 7 | Passive 8 | } 9 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Enums/Response.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal enum Response 4 | { 5 | None, 6 | Accept, 7 | Reject 8 | } 9 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Enums/StatusColor.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 指定状态颜色。 5 | /// 6 | public enum StatusColor 7 | { 8 | None, 9 | 10 | /// 11 | /// 绿。 12 | /// 13 | Green, 14 | 15 | /// 16 | /// 橙。 17 | /// 18 | Orange, 19 | 20 | /// 21 | /// 红。 22 | /// 23 | Red, 24 | 25 | /// 26 | /// 深红。 27 | /// 28 | DarkRed, 29 | 30 | /// 31 | /// 黑。 32 | /// 33 | Black, 34 | 35 | /// 36 | /// 灰。 37 | /// 38 | Gray 39 | } 40 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/ErrorHandlingExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal static class ErrorHandlingExtensions 4 | { 5 | internal static int CheckError(this int returnValue) 6 | { 7 | if (returnValue < 0) 8 | { 9 | throw new ApiException( 10 | string.Format( 11 | System.Globalization.CultureInfo.CurrentCulture, 12 | CoreResources.UnexpectedReturnValue, 13 | returnValue), 14 | returnValue); 15 | } 16 | 17 | return returnValue; 18 | } 19 | 20 | internal static T CheckError(this T? returnValue) 21 | where T : class 22 | { 23 | if (returnValue is null) 24 | { 25 | throw new ApiException(CoreResources.NullReturnValue); 26 | } 27 | 28 | return returnValue; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Events/AdministratorsChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace HuajiTech.CoolQ.Events 5 | { 6 | internal class AdministratorsChangedEventArgs : GroupEventArgs 7 | { 8 | public AdministratorsChangedEventArgs(DateTime time, IGroup source, IMember operatee) 9 | : base(time, source, null!, operatee) 10 | { 11 | } 12 | 13 | public override IMember Operator 14 | => Source.GetMembers().First(member => member.Role is MemberRole.Owner); 15 | } 16 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Events/BotEventSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using HuajiTech.UnmanagedExports; 3 | 4 | namespace HuajiTech.CoolQ.Events 5 | { 6 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 7 | "Usage", "CA1801:检查未使用的参数", Justification = "<挂起>")] 8 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 9 | "Style", "IDE0060:删除未使用的参数", Justification = "<挂起>")] 10 | public sealed class BotEventSource : IBotEventSource 11 | { 12 | public static readonly BotEventSource Instance = new BotEventSource(); 13 | 14 | private BotEventSource() 15 | { 16 | } 17 | 18 | public event EventHandler? AppDisabling; 19 | 20 | public event EventHandler? AppEnabled; 21 | 22 | public event EventHandler? BotStarted; 23 | 24 | public event EventHandler? BotStopping; 25 | 26 | [DllExport] 27 | internal static int OnAppDisabling() 28 | { 29 | Instance.AppDisabling?.Invoke(Instance, EventArgs.Empty); 30 | return 0; 31 | } 32 | 33 | [DllExport] 34 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 35 | "Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")] 36 | internal static int OnAppEnabled() 37 | { 38 | try 39 | { 40 | Instance.AppEnabled?.Invoke(Instance, EventArgs.Empty); 41 | } 42 | catch (Exception ex) 43 | { 44 | Logger.LogUnhandledException(ex); 45 | return 1; 46 | } 47 | 48 | return 0; 49 | } 50 | 51 | [DllExport] 52 | internal static int OnBotStarted() 53 | { 54 | Instance.BotStarted?.Invoke(Instance, EventArgs.Empty); 55 | return 0; 56 | } 57 | 58 | [DllExport] 59 | internal static int OnBotStopping() 60 | { 61 | Instance.BotStopping?.Invoke(Instance, EventArgs.Empty); 62 | return 0; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Exceptions/AppInitializationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace HuajiTech.CoolQ 5 | { 6 | [Serializable] 7 | public class AppInitializationException : Exception 8 | { 9 | public AppInitializationException() 10 | { 11 | } 12 | 13 | public AppInitializationException(string message) 14 | : base(message) 15 | { 16 | } 17 | 18 | public AppInitializationException(string message, Exception innerException) 19 | : base(message, innerException) 20 | { 21 | } 22 | 23 | protected AppInitializationException(SerializationInfo info, StreamingContext context) 24 | : base(info, context) 25 | { 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Friend.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using HuajiTech.CoolQ.Interop; 4 | 5 | namespace HuajiTech.CoolQ 6 | { 7 | internal class Friend : User, IFriend 8 | { 9 | private FriendInfo? _info = null; 10 | private bool _isRequested = false; 11 | 12 | public Friend(long number) 13 | : base(number) 14 | { 15 | } 16 | 17 | internal Friend(FriendInfo info) 18 | : base(info.Number) 19 | { 20 | _info = info; 21 | } 22 | 23 | public override bool IsRequested => _isRequested; 24 | 25 | public override bool IsRequestedSuccessfully => !(_info is null); 26 | 27 | public string? Alias => GetInfo().Alias; 28 | 29 | public override string? Nickname => _info?.Nickname ?? base.Nickname; 30 | 31 | public override string DisplayName => Alias ?? base.DisplayName; 32 | 33 | public override void Request() 34 | { 35 | base.Request(); 36 | GetInfo(true); 37 | } 38 | 39 | public override void Refresh() 40 | { 41 | base.Refresh(); 42 | Request(); 43 | } 44 | 45 | private FriendInfo GetInfo(bool requesting = false) 46 | { 47 | if (_isRequested && !IsRequestedSuccessfully && !requesting) 48 | { 49 | return FriendInfo.Empty; 50 | } 51 | 52 | _isRequested = true; 53 | 54 | try 55 | { 56 | _info = CurrentUser.GetFriendInfos().First(info => info.Number == Number); 57 | return _info; 58 | } 59 | catch (ApiException) when (!requesting) 60 | { 61 | } 62 | catch (InvalidOperationException) 63 | { 64 | if (requesting) 65 | { 66 | throw new InvalidOperationException(CoreResources.FriendNotExist); 67 | } 68 | } 69 | 70 | return FriendInfo.Empty; 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/FriendshipRequest.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal class FriendshipRequest : IFriendshipRequest 4 | { 5 | private readonly string _token; 6 | 7 | public FriendshipRequest(string token, string message) 8 | { 9 | _token = token; 10 | Message = message; 11 | } 12 | 13 | public string Message { get; } 14 | 15 | public void Accept(string? alias) => Respond(Response.Accept, alias); 16 | 17 | public void Accept() => Accept(null); 18 | 19 | public void Reject() => Respond(Response.Reject, null); 20 | 21 | private void Respond(Response response, string? alias) 22 | => NativeMethods.FriendshipRequest_Respond( 23 | Bot.Instance.AuthCode, _token, response, alias).CheckError(); 24 | } 25 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Group.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using HuajiTech.CoolQ.Interop; 5 | 6 | namespace HuajiTech.CoolQ 7 | { 8 | internal class Group : Chat, IGroup 9 | { 10 | public static readonly Group Empty = new Group(0); 11 | 12 | private readonly string? _name; 13 | private GroupInfo? _info = null; 14 | private bool _isRequested; 15 | 16 | public Group(long number) 17 | : base(number) 18 | { 19 | } 20 | 21 | internal Group(long number, string? name) 22 | : this(number) 23 | { 24 | _name = name; 25 | } 26 | 27 | public string? Name => _name ?? GetInfo().Name; 28 | 29 | public override string DisplayName => Name ?? ToString(); 30 | 31 | public bool IsRequestedSuccessfully => !(_info is null); 32 | 33 | public bool IsRequested => _isRequested; 34 | 35 | public int MemberCapacity => GetInfo().MemberCapacity; 36 | 37 | public int MemberCount => GetInfo().MemberCount; 38 | 39 | public void DisableAnonymous() 40 | => NativeMethods.Group_SetIsAnonymousEnabled(Bot.Instance.AuthCode, Number, false).CheckError(); 41 | 42 | public void Disband() => Leave(true); 43 | 44 | public void EnableAnonymous() 45 | => NativeMethods.Group_SetIsAnonymousEnabled(Bot.Instance.AuthCode, Number, true).CheckError(); 46 | 47 | public IReadOnlyCollection GetMembers() 48 | { 49 | using var reader = new MemberInfoReader( 50 | NativeMethods.Group_GetMembers(Bot.Instance.AuthCode, Number).CheckError()); 51 | return reader.ReadAll() 52 | .Select(info => new Member(info)) 53 | .ToList(); 54 | } 55 | 56 | public void Leave() => Leave(false); 57 | 58 | public void Mute() 59 | => NativeMethods.Group_SetIsMuted(Bot.Instance.AuthCode, Number, true).CheckError(); 60 | 61 | public void Request() => GetInfo(true, false); 62 | 63 | public void Refresh() => GetInfo(true, true); 64 | 65 | public override Message Send(string message) 66 | { 67 | if (string.IsNullOrEmpty(message)) 68 | { 69 | throw new ArgumentException(CoreResources.FieldCannotBeEmpty, nameof(message)); 70 | } 71 | 72 | var id = NativeMethods.Group_Send(Bot.Instance.AuthCode, Number, message).CheckError(); 73 | 74 | return new MessageCore(id, message); 75 | } 76 | 77 | public void Unmute() 78 | => NativeMethods.Group_SetIsMuted(Bot.Instance.AuthCode, Number, false).CheckError(); 79 | 80 | public override bool Equals(IChattable? other) => base.Equals(other) && other is Group; 81 | 82 | private GroupInfo GetInfo(bool requesting = false, bool refresh = false) 83 | { 84 | if (_isRequested && !IsRequestedSuccessfully && !requesting) 85 | { 86 | return GroupInfo.Empty; 87 | } 88 | 89 | _isRequested = true; 90 | 91 | try 92 | { 93 | using var reader = new GroupInfoReader( 94 | NativeMethods.Group_GetInfo(Bot.Instance.AuthCode, Number, refresh).CheckError()); 95 | _info = reader.Read(); 96 | } 97 | catch (ApiException) when (!requesting) 98 | { 99 | return GroupInfo.Empty; 100 | } 101 | 102 | return _info; 103 | } 104 | 105 | private void Leave(bool disband) 106 | => NativeMethods.Group_Leave(Bot.Instance.AuthCode, Number, disband).CheckError(); 107 | } 108 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/HuajiTech.CoolQ.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HuajiTech.CoolQ 5 | netstandard2.0;net461;net45 6 | 8 7 | enable 8 | true 9 | HuajiTech.CoolQ.Core.pfx 10 | 0.4.0-beta.2 11 | true 12 | SYC 13 | HuajiTech 14 | HuajiTech.CoolQ 的实现。 15 | Copyright (C) 2020 HuajiTech 16 | LGPL-3.0-or-later 17 | https://github.com/huajitech/coolq-dotnet-sdk 18 | Icon.png 19 | https://github.com/huajitech/coolq-dotnet-sdk 20 | git 21 | HuajiTech, CoolQ, 酷Q, QQ, Bot, Robot, 机器人 22 | 这是一个测试版本,不建议用于生产环境。 23 | zh-CN 24 | true 25 | true 26 | C:\Users\SYC\source\repos\HuajiTech.CoolQ\src\HuajiTech.CoolQ.Core\HuajiTech.CoolQ.Core.xml 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | True 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | all 52 | runtime; build; native; contentfiles; analyzers; buildtransitive 53 | 54 | 55 | all 56 | runtime; build; native; contentfiles; analyzers; buildtransitive 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | True 67 | True 68 | CoreResources.resx 69 | 70 | 71 | 72 | 73 | 74 | ResXFileCodeGenerator 75 | CoreResources.Designer.cs 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/InitializerAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 指定程序集的初始化器。 7 | /// 8 | [AttributeUsage(AttributeTargets.Assembly)] 9 | public sealed class InitializerAttribute : Attribute 10 | { 11 | /// 12 | /// 使用指定的初始化器初始化一个 的新实例。 13 | /// 14 | /// 要使用的初始化器。 15 | public InitializerAttribute(Type initializer) 16 | => Initializer = initializer ?? throw new ArgumentNullException(nameof(initializer)); 17 | 18 | /// 19 | /// 使用指定的初始化器初始化一个 的新实例。 20 | /// 21 | /// 要使用的初始化器。 22 | public InitializerAttribute(string initializer) 23 | : this(Type.GetType(initializer)) 24 | { 25 | } 26 | 27 | /// 28 | /// 获取当前 的初始化器。 29 | /// 30 | public Type Initializer { get; } 31 | } 32 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/AnonymousMemberInfo.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal class AnonymousMemberInfo 4 | { 5 | public static readonly AnonymousMemberInfo Empty = new AnonymousMemberInfo(); 6 | 7 | public long Id { get; set; } 8 | 9 | public string? Name { get; set; } 10 | 11 | public byte[]? Token { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/AnonymousMemberInfoReader.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal sealed class AnonymousMemberInfoReader : Reader 4 | { 5 | public AnonymousMemberInfoReader(string base64String) 6 | : base(base64String) 7 | { 8 | } 9 | 10 | public override AnonymousMemberInfo Read() 11 | => new AnonymousMemberInfo 12 | { 13 | Id = ReadInt64(), 14 | Name = ReadString(), 15 | Token = ReadBytes() 16 | }; 17 | } 18 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/BasicGroupInfo.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal class BasicGroupInfo 4 | { 5 | public static readonly BasicGroupInfo Empty = new BasicGroupInfo(); 6 | 7 | public string? Name { get; set; } 8 | 9 | public long Number { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/BasicGroupInfoReader.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal sealed class BasicGroupInfoReader : Reader 4 | { 5 | public BasicGroupInfoReader(string base64String) 6 | : base(base64String) 7 | { 8 | } 9 | 10 | public override BasicGroupInfo Read() 11 | => new BasicGroupInfo 12 | { 13 | Number = ReadInt64(), 14 | Name = ReadString() 15 | }; 16 | } 17 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/FileReader.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal class FileReader : Reader 4 | { 5 | public FileReader(string base64String) 6 | : base(base64String) 7 | { 8 | } 9 | 10 | public override File Read() 11 | => new File( 12 | id: ReadString()!, 13 | name: ReadString()!, 14 | length: ReadInt64(), 15 | busId: ReadInt64()); 16 | } 17 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/FriendInfo.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal class FriendInfo 4 | { 5 | public static readonly FriendInfo Empty = new FriendInfo(); 6 | 7 | public string? Alias { get; set; } 8 | 9 | public string? Nickname { get; set; } 10 | 11 | public long Number { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/FriendInfoReader.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal sealed class FriendInfoReader : Reader 4 | { 5 | public FriendInfoReader(string base64String) 6 | : base(base64String) 7 | { 8 | } 9 | 10 | public override FriendInfo Read() 11 | => new FriendInfo 12 | { 13 | Number = ReadInt64(), 14 | Nickname = ReadString(), 15 | Alias = ReadString() 16 | }; 17 | } 18 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/GroupInfo.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal class GroupInfo 4 | { 5 | public static readonly GroupInfo Empty = new GroupInfo(); 6 | 7 | public int MemberCapacity { get; set; } 8 | 9 | public int MemberCount { get; set; } 10 | 11 | public string? Name { get; set; } 12 | 13 | public long Number { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/GroupInfoReader.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal sealed class GroupInfoReader : Reader 4 | { 5 | public GroupInfoReader(string base64String) 6 | : base(base64String) 7 | { 8 | } 9 | 10 | public override GroupInfo Read() 11 | => new GroupInfo 12 | { 13 | Number = ReadInt64(), 14 | Name = ReadString(), 15 | MemberCount = ReadInt32(), 16 | MemberCapacity = ReadInt32() 17 | }; 18 | } 19 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/MemberInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Interop 4 | { 5 | internal class MemberInfo 6 | { 7 | public static readonly MemberInfo Empty = new MemberInfo(); 8 | 9 | public int Age { get; set; } 10 | 11 | public string? Alias { get; set; } 12 | 13 | public bool CanEditAlias { get; set; } 14 | 15 | public CustomTitle? CustomTitle { get; set; } 16 | 17 | public DateTime TimeEntered { get; set; } 18 | 19 | public Gender Gender { get; set; } 20 | 21 | public long GroupNumber { get; set; } 22 | 23 | public bool HasBadRecord { get; set; } 24 | 25 | public DateTime LastSpeakTime { get; set; } 26 | 27 | public string? Level { get; set; } 28 | 29 | public string? Location { get; set; } 30 | 31 | public string? Nickname { get; set; } 32 | 33 | public long Number { get; set; } 34 | 35 | public MemberRole Role { get; set; } 36 | } 37 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/MemberInfoReader.cs: -------------------------------------------------------------------------------- 1 | using HuajiTech.CoolQ.Utilities; 2 | 3 | namespace HuajiTech.CoolQ.Interop 4 | { 5 | internal sealed class MemberInfoReader : Reader 6 | { 7 | public MemberInfoReader(string base64String) 8 | : base(base64String) 9 | { 10 | } 11 | 12 | public override MemberInfo Read() 13 | { 14 | var info = new MemberInfo 15 | { 16 | GroupNumber = ReadInt64(), 17 | Number = ReadInt64(), 18 | Nickname = ReadString(), 19 | Alias = ReadString(), 20 | Gender = (Gender)ReadInt32(), 21 | Age = ReadInt32(), 22 | Location = ReadString(), 23 | TimeEntered = ReadDateTime(), 24 | LastSpeakTime = ReadDateTime(), 25 | Level = ReadString(), 26 | Role = (MemberRole)ReadInt32(), 27 | HasBadRecord = ReadBoolean() 28 | }; 29 | 30 | var titleText = ReadString(); 31 | var titleExpirationTime = ReadDateTime(); 32 | info.CanEditAlias = ReadBoolean(); 33 | 34 | if (!(titleText is null)) 35 | { 36 | info.CustomTitle = titleExpirationTime <= Timestamp.Zero ? 37 | new CustomTitle(titleText) : 38 | new CustomTitle(titleText, titleExpirationTime); 39 | } 40 | 41 | return info; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/Reader{T}.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Net; 5 | using System.Text; 6 | using HuajiTech.CoolQ.Utilities; 7 | 8 | namespace HuajiTech.CoolQ.Interop 9 | { 10 | internal abstract class Reader : IDisposable 11 | { 12 | protected static readonly Encoding Encoding = Encoding.GetEncoding("GB18030"); 13 | 14 | protected Reader(string base64String) 15 | { 16 | BinaryReader = new BinaryReader( 17 | new MemoryStream(Convert.FromBase64String(base64String))); 18 | } 19 | 20 | protected BinaryReader BinaryReader { get; } 21 | 22 | protected static short FromBigEndian(short bigEndian) => IPAddress.NetworkToHostOrder(bigEndian); 23 | 24 | protected static int FromBigEndian(int bigEndian) => IPAddress.NetworkToHostOrder(bigEndian); 25 | 26 | protected static long FromBigEndian(long bigEndian) => IPAddress.NetworkToHostOrder(bigEndian); 27 | 28 | public void Dispose() => BinaryReader.Dispose(); 29 | 30 | public abstract T Read(); 31 | 32 | public IEnumerable ReadAll() 33 | { 34 | var length = ReadInt32(); 35 | 36 | for (var i = 0; i < length; i++) 37 | { 38 | _ = ReadInt16(); 39 | yield return Read(); 40 | } 41 | } 42 | 43 | protected byte[] ReadBytes() 44 | { 45 | var length = ReadInt16(); 46 | return BinaryReader.ReadBytes(length); 47 | } 48 | 49 | protected short ReadInt16() => FromBigEndian(BinaryReader.ReadInt16()); 50 | 51 | protected int ReadInt32() => FromBigEndian(BinaryReader.ReadInt32()); 52 | 53 | protected bool ReadBoolean() => ReadInt32() > 0; 54 | 55 | protected DateTime ReadDateTime() => Timestamp.ToDateTime(ReadInt32()); 56 | 57 | protected long ReadInt64() => FromBigEndian(BinaryReader.ReadInt64()); 58 | 59 | protected string? ReadString() 60 | { 61 | var bytes = ReadBytes(); 62 | 63 | if (bytes.Length is 0) 64 | { 65 | return null; 66 | } 67 | 68 | return Encoding.GetString(bytes); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/StatusWriter.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal class StatusWriter : Writer 4 | { 5 | public override void Write(Status status) 6 | { 7 | Write(status.Value); 8 | Write(status.Unit); 9 | Write((int)status.Color); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/StringKeyValuePairReader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Interop 4 | { 5 | internal class StringKeyValuePairReader : Reader> 6 | { 7 | public StringKeyValuePairReader(string base64String) 8 | : base(base64String) 9 | { 10 | } 11 | 12 | public override KeyValuePair Read() 13 | => new KeyValuePair(ReadString()!, ReadString()!); 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/UserInfo.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal class UserInfo 4 | { 5 | public static readonly UserInfo Empty = new UserInfo(); 6 | 7 | public int Age { get; set; } 8 | 9 | public Gender Gender { get; set; } 10 | 11 | public string? Nickname { get; set; } 12 | 13 | public long Number { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/UserInfoReader.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Interop 2 | { 3 | internal sealed class UserInfoReader : Reader 4 | { 5 | public UserInfoReader(string base64String) 6 | : base(base64String) 7 | { 8 | } 9 | 10 | public override UserInfo Read() 11 | => new UserInfo 12 | { 13 | Number = ReadInt64(), 14 | Nickname = ReadString(), 15 | Gender = (Gender)ReadInt32(), 16 | Age = ReadInt32() 17 | }; 18 | } 19 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Interop/Writer{T}.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Text; 5 | 6 | namespace HuajiTech.CoolQ.Interop 7 | { 8 | internal abstract class Writer : IDisposable 9 | { 10 | protected static readonly Encoding Encoding = Encoding.GetEncoding("GB18030"); 11 | 12 | protected Writer() 13 | { 14 | MemoryStream = new MemoryStream(); 15 | BinaryWriter = new BinaryWriter(MemoryStream); 16 | } 17 | 18 | protected BinaryWriter BinaryWriter { get; } 19 | 20 | protected MemoryStream MemoryStream { get; } 21 | 22 | protected static short ToBigEndian(short littleEndian) => IPAddress.HostToNetworkOrder(littleEndian); 23 | 24 | protected static int ToBigEndian(int littleEndian) => IPAddress.HostToNetworkOrder(littleEndian); 25 | 26 | protected static long ToBigEndian(long littleEndian) => IPAddress.HostToNetworkOrder(littleEndian); 27 | 28 | public void Dispose() 29 | { 30 | MemoryStream.Dispose(); 31 | BinaryWriter.Dispose(); 32 | } 33 | 34 | public string GetBase64() => Convert.ToBase64String(MemoryStream.ToArray()); 35 | 36 | public abstract void Write(T value); 37 | 38 | protected void Write(byte[] bytes) 39 | { 40 | var length = (short)bytes.Length; 41 | Write(length); 42 | BinaryWriter.Write(bytes); 43 | } 44 | 45 | protected void Write(string str) => Write(Encoding.GetBytes(str)); 46 | 47 | protected void Write(short value) => BinaryWriter.Write(ToBigEndian(value)); 48 | 49 | protected void Write(int value) => BinaryWriter.Write(ToBigEndian(value)); 50 | } 51 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/LogLevel.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | /// 4 | /// 指定日志级别。 5 | /// 6 | internal enum LogLevel 7 | { 8 | /// 9 | /// 调试。 10 | /// 11 | Debug = 0, 12 | 13 | /// 14 | /// 信息。 15 | /// 16 | Info = 10, 17 | 18 | /// 19 | /// 成功。 20 | /// 21 | Success = 11, 22 | 23 | /// 24 | /// 接收。 25 | /// 26 | Receiving = 12, 27 | 28 | /// 29 | /// 发送。 30 | /// 31 | Sending = 13, 32 | 33 | /// 34 | /// 警告。 35 | /// 36 | Warning = 20, 37 | 38 | /// 39 | /// 错误。 40 | /// 41 | Error = 30, 42 | 43 | /// 44 | /// 致命错误。 45 | /// 46 | Fatal = 40 47 | } 48 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 6 | "Performance", "CA1806:不要忽略方法结果", Justification = "<挂起>")] 7 | internal class Logger : ILogger 8 | { 9 | internal const LogLevel UnhandledExceptionLogLevel = LogLevel.Error; 10 | 11 | public static void Log(LogLevel level, string? type, string? message) 12 | => NativeMethods.Bot_Log(Bot.Instance.AuthCode, level, type, message); 13 | 14 | internal static void LogUnhandledException(Exception ex) 15 | => Log(UnhandledExceptionLogLevel, CoreResources.UnhandledException, ex.ToString()); 16 | 17 | public void RaiseFatal(string? message) 18 | => NativeMethods.Bot_LogFatal(Bot.Instance.AuthCode, message); 19 | 20 | public void LogDebug(string? type, string? message) => Log(LogLevel.Debug, type, message); 21 | 22 | public void Log(string? type, string? message) => Log(LogLevel.Info, type, message); 23 | 24 | public void LogSuccess(string? type, string? message) => Log(LogLevel.Success, type, message); 25 | 26 | public void LogReceiving(string? type, string? message) => Log(LogLevel.Receiving, type, message); 27 | 28 | public void LogSending(string? type, string? message) => Log(LogLevel.Sending, type, message); 29 | 30 | public void LogWarning(string? type, string? message) => Log(LogLevel.Warning, type, message); 31 | 32 | public void LogError(string? type, string? message) => Log(LogLevel.Error, type, message); 33 | 34 | public void LogFatal(string type, string message) => Log(LogLevel.Fatal, type, message); 35 | } 36 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/MembershipInvitation.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal class MembershipInvitation : IRequest 4 | { 5 | private readonly string _token; 6 | 7 | public MembershipInvitation(string token, string message) 8 | { 9 | _token = token; 10 | Message = message; 11 | } 12 | 13 | public string Message { get; } 14 | 15 | public void Accept() => Respond(Response.Accept); 16 | 17 | public void Reject() => Respond(Response.Reject); 18 | 19 | private void Respond(Response response) 20 | => NativeMethods.EntranceRequest_Respond( 21 | Bot.Instance.AuthCode, _token, OperationKind.Passive, response, null).CheckError(); 22 | } 23 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/MembershipRequest.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ 2 | { 3 | internal class MembershipRequest : IMembershipRequest 4 | { 5 | private readonly string _token; 6 | 7 | public MembershipRequest(string token, string message) 8 | { 9 | _token = token; 10 | Message = message; 11 | } 12 | 13 | public string Message { get; } 14 | 15 | public void Accept() => Respond(Response.Accept, null); 16 | 17 | public void Reject(string? reason) => Respond(Response.Reject, reason); 18 | 19 | public void Reject() => Reject(null); 20 | 21 | private void Respond(Response response, string? rejectReason) 22 | => NativeMethods.EntranceRequest_Respond( 23 | Bot.Instance.AuthCode, _token, OperationKind.Active, response, rejectReason).CheckError(); 24 | } 25 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/MessageCore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | internal class MessageCore : Message 6 | { 7 | private readonly string? _content; 8 | 9 | public MessageCore(int id, string? content = null) 10 | { 11 | Id = id; 12 | _content = content; 13 | } 14 | 15 | public override int Id { get; } 16 | 17 | public override string Content => _content ?? throw new NotSupportedException(); 18 | 19 | public override void Recall() 20 | => NativeMethods.Message_Recall(Bot.Instance.AuthCode, Id).CheckError(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/PluginContextCore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | internal class PluginContextCore : PluginContext 6 | { 7 | public PluginContextCore(IBot bot) 8 | { 9 | Bot = bot ?? throw new ArgumentNullException(nameof(bot)); 10 | } 11 | 12 | public override IBot Bot { get; } 13 | 14 | public override IFriend GetFriend(long number) => new Friend(number); 15 | 16 | public override IGroup GetGroup(long number) => new Group(number); 17 | 18 | public override IMember GetMember(long number, IGroup group) => new Member(number, group); 19 | 20 | public override IUser GetUser(long number) => new User(number); 21 | 22 | public override Message GetMessage(int id) => new MessageCore(id); 23 | } 24 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [assembly: CLSCompliant(true)] -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/RegexMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using HuajiTech.CoolQ.Interop; 6 | 7 | namespace HuajiTech.CoolQ 8 | { 9 | /// 10 | /// 提供用于操作正则消息的扩展方法。 11 | /// 12 | public static class RegexMessage 13 | { 14 | /// 15 | /// 将 为编码后的正则消息匹配结果的 实例解码为只读字典。 16 | /// 17 | /// 要解析为只读字典的 实例。 18 | /// 等效的只读字典。 19 | /// 不合法。 20 | public static IReadOnlyDictionary? Decode(this Message message) 21 | { 22 | if (message is null) 23 | { 24 | return null; 25 | } 26 | 27 | using var reader = new StringKeyValuePairReader(message.Content); 28 | 29 | try 30 | { 31 | return reader.ReadAll().ToDictionary(pair => pair.Key, pair => pair.Value); 32 | } 33 | catch (Exception ex) 34 | { 35 | throw new InvalidDataException(CoreResources.FailedToDecodeRegexMessage, ex); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Status.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using HuajiTech.CoolQ.Interop; 3 | 4 | namespace HuajiTech.CoolQ 5 | { 6 | /// 7 | /// 表示状态。 8 | /// 9 | public class Status : IEquatable 10 | { 11 | /// 12 | /// 以指定的值,单位和颜色初始化一个 类的新实例。 13 | /// 14 | /// 状态的值。 15 | /// 状态的单位。 16 | /// 状态的颜色。 17 | /// 18 | /// 19 | public Status(string value, string unit, StatusColor color) 20 | { 21 | Value = value ?? throw new ArgumentNullException(nameof(value)); 22 | Unit = unit ?? throw new ArgumentNullException(nameof(unit)); 23 | Color = color; 24 | } 25 | 26 | /// 27 | /// 获取当前 实例的颜色。 28 | /// 29 | public StatusColor Color { get; } 30 | 31 | /// 32 | /// 获取当前 实例的单位。 33 | /// 34 | public string Unit { get; } 35 | 36 | /// 37 | /// 获取当前 实例的值。 38 | /// 39 | public string Value { get; } 40 | 41 | public static bool operator ==(Status left, Status right) => left?.Equals(right) ?? right is null; 42 | 43 | public static bool operator !=(Status left, Status right) => !(left == right); 44 | 45 | /// 46 | /// 将当前 实例的值编码为可被酷Q使用的 Base64 字符串。 47 | /// 48 | /// 编码后的 Base64 字符串。 49 | public string Encode() 50 | { 51 | using var writer = new StatusWriter(); 52 | writer.Write(this); 53 | return writer.GetBase64(); 54 | } 55 | 56 | public bool Equals(Status? other) => other?.Value == Value && other?.Unit == Unit && other?.Color == Color; 57 | 58 | public override bool Equals(object? obj) => base.Equals(obj) || Equals(obj as Status); 59 | 60 | public override int GetHashCode() => (int)Color ^ Value.GetHashCode() ^ Unit.GetHashCode(); 61 | } 62 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/StringMarshaler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Text; 4 | 5 | namespace HuajiTech.CoolQ 6 | { 7 | internal class StringMarshaler : ICustomMarshaler 8 | { 9 | private static readonly Encoding Encoding = Encoding.GetEncoding("GB18030"); 10 | private static readonly StringMarshaler Instance = new StringMarshaler(); 11 | 12 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 13 | "Usage", "CA1801:检查未使用的参数", Justification = "<挂起>")] 14 | public static ICustomMarshaler GetInstance(string cookie) => Instance; 15 | 16 | public void CleanUpManagedData(object ManagedObj) 17 | { 18 | } 19 | 20 | public void CleanUpNativeData(IntPtr pNativeData) 21 | { 22 | } 23 | 24 | public int GetNativeDataSize() => -1; 25 | 26 | public IntPtr MarshalManagedToNative(object? ManagedObj) 27 | { 28 | if (ManagedObj is null) 29 | { 30 | return IntPtr.Zero; 31 | } 32 | 33 | if (ManagedObj is string str) 34 | { 35 | var bytes = Encoding.GetBytes(str); 36 | IntPtr pNativeData = Marshal.AllocHGlobal(bytes.Length + 1); 37 | 38 | Marshal.Copy(bytes, 0, pNativeData, bytes.Length); 39 | Marshal.WriteByte(pNativeData, bytes.Length, 0); 40 | 41 | return pNativeData; 42 | } 43 | 44 | throw new MarshalDirectiveException(); 45 | } 46 | 47 | public unsafe object? MarshalNativeToManaged(IntPtr pNativeData) 48 | { 49 | if (pNativeData == IntPtr.Zero) 50 | { 51 | return null; 52 | } 53 | 54 | var ptr = (sbyte*)pNativeData.ToPointer(); 55 | var length = 0; 56 | 57 | while (!(*(ptr + length) is 0)) 58 | { 59 | length++; 60 | } 61 | 62 | return new string(ptr, 0, length, Encoding); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using HuajiTech.CoolQ.Interop; 3 | 4 | namespace HuajiTech.CoolQ 5 | { 6 | internal class User : Chat, IUser 7 | { 8 | private UserInfo? _info = null; 9 | private bool _isRequested; 10 | 11 | public User(long number) 12 | : base(number) 13 | { 14 | } 15 | 16 | internal User(UserInfo info) 17 | : this(info.Number) 18 | { 19 | _info = info; 20 | } 21 | 22 | private protected User() 23 | { 24 | } 25 | 26 | public virtual bool IsRequested => _isRequested; 27 | 28 | public virtual bool IsRequestedSuccessfully => !(_info is null); 29 | 30 | public override string DisplayName => Nickname ?? ToString(); 31 | 32 | public virtual string? Nickname => GetInfo().Nickname; 33 | 34 | public virtual int Age => GetInfo().Age; 35 | 36 | public virtual Gender Gender => GetInfo().Gender; 37 | 38 | public void Like(int count = 1) 39 | { 40 | if (count <= 0 || count > 10) 41 | { 42 | throw new ArgumentOutOfRangeException(nameof(count)); 43 | } 44 | 45 | NativeMethods.User_Like(Bot.Instance.AuthCode, Number, count).CheckError(); 46 | } 47 | 48 | public virtual void Request() => GetInfo(true, false); 49 | 50 | public virtual void Refresh() => GetInfo(true, true); 51 | 52 | public override Message Send(string message) 53 | { 54 | if (string.IsNullOrEmpty(message)) 55 | { 56 | throw new ArgumentException(CoreResources.FieldCannotBeEmpty, nameof(message)); 57 | } 58 | 59 | var id = NativeMethods.User_Send(Bot.Instance.AuthCode, Number, message).CheckError(); 60 | 61 | return new MessageCore(id, message); 62 | } 63 | 64 | public override bool Equals(IChattable? other) => base.Equals(other) && other is User; 65 | 66 | private UserInfo GetInfo(bool requesting = false, bool refresh = false) 67 | { 68 | if (_isRequested && !IsRequestedSuccessfully && !requesting) 69 | { 70 | return UserInfo.Empty; 71 | } 72 | 73 | _isRequested = true; 74 | 75 | try 76 | { 77 | using var reader = new UserInfoReader( 78 | NativeMethods.User_GetInfo(Bot.Instance.AuthCode, Number, refresh).CheckError()); 79 | _info = reader.Read(); 80 | return _info; 81 | } 82 | catch (ApiException) when (!requesting) 83 | { 84 | return UserInfo.Empty; 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Core/Utilities/Timestamp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Utilities 4 | { 5 | internal static class Timestamp 6 | { 7 | public static readonly DateTime Zero = 8 | TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Local); 9 | 10 | public static DateTime ToDateTime(int timestamp) => Zero.AddSeconds(timestamp); 11 | } 12 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Loaders.Autofac/AutofacLoaderResources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace HuajiTech.CoolQ.Loaders { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class AutofacLoaderResources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal AutofacLoaderResources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HuajiTech.CoolQ.Loaders.AutofacLoaderResources", typeof(AutofacLoaderResources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找类似 插件加载失败。 的本地化字符串。 65 | /// 66 | internal static string FailedToLoadPlugin { 67 | get { 68 | return ResourceManager.GetString("FailedToLoadPlugin", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// 查找类似 尚未构建容器。 的本地化字符串。 74 | /// 75 | internal static string NotBuilt { 76 | get { 77 | return ResourceManager.GetString("NotBuilt", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// 查找类似 已加载类型 '{0}'。 的本地化字符串。 83 | /// 84 | internal static string PluginLoadMessage { 85 | get { 86 | return ResourceManager.GetString("PluginLoadMessage", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// 查找类似 插件加载 的本地化字符串。 92 | /// 93 | internal static string PluginLoadTitle { 94 | get { 95 | return ResourceManager.GetString("PluginLoadTitle", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// 查找类似 指定的类型不是插件类型。 的本地化字符串。 101 | /// 102 | internal static string TypeIsNotPlugin { 103 | get { 104 | return ResourceManager.GetString("TypeIsNotPlugin", resourceCulture); 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Loaders.Autofac/HuajiTech.CoolQ.Loaders.Autofac.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HuajiTech.CoolQ.Loaders 5 | netstandard2.0;net461 6 | 8 7 | enable 8 | true 9 | HuajiTech.CoolQ.Loaders.Autofac.pfx 10 | 0.4.1-beta 11 | SYC 12 | HuajiTech 13 | 使用 Autofac 加载 HuajiTech.CoolQ 应用。 14 | Copyright (C) 2020 HuajiTech 15 | LGPL-3.0-or-later 16 | https://github.com/huajitech/coolq-dotnet-sdk 17 | Icon.png 18 | https://github.com/huajitech/coolq-dotnet-sdk 19 | git 20 | HuajiTech, CoolQ, 酷Q, QQ, Bot, Robot, 机器人, Loaders, Autofac 21 | 这是一个测试版本,不建议用于生产环境。 22 | zh-CN 23 | true 24 | true 25 | 26 | 27 | 28 | 29 | True 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | all 42 | runtime; build; native; contentfiles; analyzers; buildtransitive 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | AutofacLoaderResources.resx 53 | True 54 | True 55 | 56 | 57 | 58 | 59 | 60 | AutofacLoaderResources.Designer.cs 61 | ResXFileCodeGenerator 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Loaders.Autofac/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [assembly: CLSCompliant(true)] -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Anonymous.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示匿名消息的 。 7 | /// 8 | public class Anonymous : CQCode 9 | { 10 | public Anonymous() 11 | : base("anonymous") 12 | { 13 | } 14 | 15 | public Anonymous(IDictionary parameters) 16 | : base("anonymous", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置一个值,指示是否在不能发送匿名消息时回退到普通消息。 22 | /// 23 | public bool CanFallback 24 | { 25 | get => GetParameterAsBoolean("ignore"); 26 | set => SetParameter("ignore", value); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/ContactShare.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace HuajiTech.CoolQ.Messaging 5 | { 6 | /// 7 | /// 表示联系人分享的 。 8 | /// 9 | public class ContactShare : CQCode 10 | { 11 | public ContactShare() 12 | : base("contact") 13 | { 14 | } 15 | 16 | public ContactShare(IDictionary parameters) 17 | : base("contact", parameters) 18 | { 19 | } 20 | 21 | /// 22 | /// 获取或设置当前 实例的内容类型。 23 | /// 24 | public string? ContentType 25 | { 26 | get => this["type"]; 27 | set => this["type"] = value; 28 | } 29 | 30 | /// 31 | /// 获取或设置当前 实例的内容号码。 32 | /// 33 | public long ContentNumber 34 | { 35 | get => GetParameterAsInt64("id"); 36 | set => SetParameter("id", value); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/CustomEmoticon.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示自定义表情的 。 7 | /// 8 | public class CustomEmoticon : CQCode 9 | { 10 | public CustomEmoticon() 11 | : base("bface") 12 | { 13 | } 14 | 15 | public CustomEmoticon(IDictionary parameters) 16 | : base("bface", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的 ID。 22 | /// 23 | public int Id 24 | { 25 | get => GetParameterAsInt32("id"); 26 | set => SetParameter("id", value); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/CustomMusic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace HuajiTech.CoolQ.Messaging 5 | { 6 | /// 7 | /// 表示自定义音乐的 。 8 | /// 9 | public class CustomMusic : CQCode 10 | { 11 | public CustomMusic() 12 | : base("music") 13 | { 14 | this["type"] = "custom"; 15 | } 16 | 17 | public CustomMusic(IDictionary parameters) 18 | : base("music", parameters) 19 | { 20 | } 21 | 22 | /// 23 | /// 获取或设置当前 实例的音频 URL。 24 | /// 25 | public Uri? AudioUrl 26 | { 27 | get => GetParameterAsUri("audio"); 28 | set => SetParameter("audio", value); 29 | } 30 | 31 | /// 32 | /// 获取或设置当前 实例的内容 URL。 33 | /// 34 | public Uri? ContentUrl 35 | { 36 | get => GetParameterAsUri("url"); 37 | set => SetParameter("url", value); 38 | } 39 | 40 | /// 41 | /// 获取或设置当前 实例的描述。 42 | /// 43 | public string? Description 44 | { 45 | get => this["content"]; 46 | set => this["content"] = value; 47 | } 48 | 49 | /// 50 | /// 获取或设置当前 实例的图片URL。 51 | /// 52 | public Uri? ImageUrl 53 | { 54 | get => GetParameterAsUri("image"); 55 | set => SetParameter("image", value); 56 | } 57 | 58 | /// 59 | /// 获取或设置当前 实例的标题。 60 | /// 61 | public string? Title 62 | { 63 | get => this["title"]; 64 | set => this["title"] = value; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Dice.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示骰子的 。 7 | /// 8 | public class Dice : CQCode 9 | { 10 | public Dice() 11 | : base("dice") 12 | { 13 | } 14 | 15 | public Dice(IDictionary parameters) 16 | : base("dice", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的点数。 22 | /// 23 | public int Point 24 | { 25 | get => GetParameterAsInt32("type"); 26 | set => SetParameter("type", value); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Emoji.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示 Emoji 的 。 7 | /// 8 | public class Emoji : CQCode 9 | { 10 | public Emoji() 11 | : base("emoji") 12 | { 13 | } 14 | 15 | public Emoji(IDictionary parameters) 16 | : base("emoji", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的 ID。 22 | /// 23 | public int Id 24 | { 25 | get => GetParameterAsInt32("id"); 26 | set => SetParameter("id", value); 27 | } 28 | 29 | public string ConvertToString() => char.ConvertFromUtf32(Id); 30 | } 31 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Emoticon.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示表情的 。 7 | /// 8 | public class Emoticon : CQCode 9 | { 10 | public Emoticon() 11 | : base("face") 12 | { 13 | } 14 | 15 | public Emoticon(IDictionary parameters) 16 | : base("face", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的 ID。 22 | /// 23 | public int Id 24 | { 25 | get => GetParameterAsInt32("id"); 26 | set => SetParameter("id", value); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Image.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示图片的 。 7 | /// 8 | public class Image : CQCode 9 | { 10 | public Image() 11 | : base("image") 12 | { 13 | } 14 | 15 | public Image(IDictionary parameters) 16 | : base("image", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的文件名。 22 | /// 23 | public string? FileName 24 | { 25 | get => this["file"]; 26 | set => this["file"] = value; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Location.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示位置的 。 7 | /// 8 | public class Location : CQCode 9 | { 10 | public Location() 11 | : base("location") 12 | { 13 | } 14 | 15 | public Location(IDictionary parameters) 16 | : base("location", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的地址。 22 | /// 23 | public string? Address 24 | { 25 | get => this["content"]; 26 | set => this["content"] = value; 27 | } 28 | 29 | /// 30 | /// 获取或设置当前 实例的纬度。 31 | /// 32 | public double Latitude 33 | { 34 | get => GetParameterAsDouble("lat"); 35 | set => SetParameter("lat", value); 36 | } 37 | 38 | /// 39 | /// 获取或设置当前 实例的经度。 40 | /// 41 | public double Longitude 42 | { 43 | get => GetParameterAsDouble("lon"); 44 | set => SetParameter("lon", value); 45 | } 46 | 47 | /// 48 | /// 获取或设置当前 实例的名称。 49 | /// 50 | public string? Name 51 | { 52 | get => this["title"]; 53 | set => this["title"] = value; 54 | } 55 | 56 | /// 57 | /// 获取或设置当前 实例的缩放等级。 58 | /// 59 | public int Scale 60 | { 61 | get => GetParameterAsInt32("zoom"); 62 | set => SetParameter("zoom", value); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Mention.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace HuajiTech.CoolQ.Messaging 5 | { 6 | /// 7 | /// 表示提及 (@) 的 。 8 | /// 9 | public class Mention : CQCode 10 | { 11 | public Mention() 12 | : base("at") 13 | { 14 | } 15 | 16 | public Mention(IDictionary parameters) 17 | : base("at", parameters) 18 | { 19 | } 20 | 21 | /// 22 | /// 获取或设置当前 实例的目标号码。 23 | /// 24 | public long TargetNumber 25 | { 26 | get => GetParameterAsInt64("qq"); 27 | set => SetParameter("qq", value); 28 | } 29 | } 30 | 31 | [Obsolete("请改为使用 Mention。")] 32 | [System.Diagnostics.CodeAnalysis.SuppressMessage( 33 | "StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "<挂起>")] 34 | public class At : Mention 35 | { 36 | public At() 37 | { 38 | } 39 | 40 | public At(IDictionary parameters) 41 | : base(parameters) 42 | { 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/MentionAll.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示提及 (@) 全体成员的 。 7 | /// 8 | public class MentionAll : CQCode 9 | { 10 | public MentionAll() 11 | : base("at") 12 | { 13 | this["qq"] = "all"; 14 | } 15 | 16 | public MentionAll(IDictionary parameters) 17 | : base("at", parameters) 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Music.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | 4 | namespace HuajiTech.CoolQ.Messaging 5 | { 6 | /// 7 | /// 表示音乐的 。 8 | /// 9 | public class Music : CQCode 10 | { 11 | public Music() 12 | : base("music") 13 | { 14 | } 15 | 16 | public Music(IDictionary parameters) 17 | : base("music", parameters) 18 | { 19 | } 20 | 21 | /// 22 | /// 获取或设置当前 实例的 ID。 23 | /// 24 | public long Id 25 | { 26 | get => GetParameterAsInt64("id"); 27 | set => SetParameter("id", value); 28 | } 29 | 30 | /// 31 | /// 获取或设置当前 实例的提供商。 32 | /// 33 | /// 不是有效的 值。 34 | public MusicPlatform Platform 35 | { 36 | get => this["type"] switch 37 | { 38 | "qq" => MusicPlatform.QQ, 39 | "163" => MusicPlatform.Netease, 40 | "xiami" => MusicPlatform.Xiami, 41 | _ => MusicPlatform.Unknown 42 | }; 43 | 44 | set => this["type"] = value switch 45 | { 46 | MusicPlatform.QQ => "qq", 47 | MusicPlatform.Netease => "163", 48 | MusicPlatform.Xiami => "xiami", 49 | MusicPlatform.Unknown => null, 50 | _ => throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(MusicPlatform)) 51 | }; 52 | } 53 | 54 | /// 55 | /// 获取或设置当前 实例的样式。 56 | /// 57 | public int Style 58 | { 59 | get => GetParameterAsInt32("style"); 60 | set => SetParameter("style", value); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/MusicPlatform.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Messaging 2 | { 3 | /// 4 | /// 指定音乐提供商。 5 | /// 6 | public enum MusicPlatform 7 | { 8 | Unknown, 9 | 10 | /// 11 | /// QQ音乐。 12 | /// 13 | QQ, 14 | 15 | /// 16 | /// 网易云音乐。 17 | /// 18 | Netease, 19 | 20 | /// 21 | /// 虾米音乐。 22 | /// 23 | Xiami 24 | } 25 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Record.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示录音的 。 7 | /// 8 | public class Record : CQCode 9 | { 10 | public Record() 11 | : base("record") 12 | { 13 | } 14 | 15 | public Record(IDictionary parameters) 16 | : base("record", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的文件名。 22 | /// 23 | public string? FileName 24 | { 25 | get => this["file"]; 26 | set => this["file"] = value; 27 | } 28 | 29 | /// 30 | /// 获取或设置一个值,指示当前 实例是否经过变声。 31 | /// 32 | public bool IsVoiceChanged 33 | { 34 | get => GetParameterAsBoolean("magic"); 35 | set => SetParameter("magic", value); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/RedEnvelope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace HuajiTech.CoolQ.Messaging 6 | { 7 | /// 8 | /// 表示红包的 。 9 | /// 10 | public class RedEnvelope : CQCode 11 | { 12 | public RedEnvelope() 13 | : base("hb") 14 | { 15 | } 16 | 17 | public RedEnvelope(IDictionary parameters) 18 | : base("hb", parameters) 19 | { 20 | } 21 | 22 | /// 23 | /// 获取或设置当前 实例的标题。 24 | /// 25 | public string? Title 26 | { 27 | get => this["title"]; 28 | set => this["title"] = value; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/RichText.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示富文本的 。 7 | /// 8 | public class RichText : CQCode 9 | { 10 | public RichText() 11 | : base("rich") 12 | { 13 | } 14 | 15 | public RichText(IDictionary parameters) 16 | : base("rich", parameters) 17 | { 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/RockPaperScissors.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示猜拳的 。 7 | /// 8 | public class RockPaperScissors : CQCode 9 | { 10 | public RockPaperScissors() 11 | : base("rps") 12 | { 13 | } 14 | 15 | public RockPaperScissors(IDictionary parameters) 16 | : base("rps", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的类别。 22 | /// 23 | public RockPaperScissorsKind Kind 24 | { 25 | get => (RockPaperScissorsKind)GetParameterAsInt32("type"); 26 | set => SetParameter("type", (int)value); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/RockPaperScissorsKind.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Messaging 2 | { 3 | /// 4 | /// 指定猜拳的类别。 5 | /// 6 | public enum RockPaperScissorsKind 7 | { 8 | None, 9 | 10 | /// 11 | /// 石头。 12 | /// 13 | Rock, 14 | 15 | /// 16 | /// 剪刀。 17 | /// 18 | Scissors, 19 | 20 | /// 21 | /// 布。 22 | /// 23 | Paper 24 | } 25 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Shake.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示抖动的 。 7 | /// 8 | public class Shake : CQCode 9 | { 10 | public Shake() 11 | : base("shake") 12 | { 13 | } 14 | 15 | public Shake(IDictionary parameters) 16 | : base("shake", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的ID。 22 | /// 23 | public int Id 24 | { 25 | get => GetParameterAsInt32("id"); 26 | set => SetParameter("id", value); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/Share.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace HuajiTech.CoolQ.Messaging 5 | { 6 | /// 7 | /// 表示分享的 。 8 | /// 9 | public class Share : CQCode 10 | { 11 | public Share() 12 | : base("share") 13 | { 14 | } 15 | 16 | public Share(IDictionary parameters) 17 | : base("share", parameters) 18 | { 19 | } 20 | 21 | /// 22 | /// 获取或设置当前 实例的描述。 23 | /// 24 | public string? Description 25 | { 26 | get => this["content"]; 27 | set => this["content"] = value; 28 | } 29 | 30 | /// 31 | /// 获取或设置当前 实例的图片 URL。 32 | /// 33 | public Uri? ImageUrl 34 | { 35 | get => GetParameterAsUri("image"); 36 | set => SetParameter("image", value); 37 | } 38 | 39 | /// 40 | /// 获取或设置当前 实例的标题。 41 | /// 42 | public string? Title 43 | { 44 | get => this["title"]; 45 | set => this["title"] = value; 46 | } 47 | 48 | /// 49 | /// 获取或设置当前 实例的 URL。 50 | /// 51 | public Uri? Url 52 | { 53 | get => GetParameterAsUri("url"); 54 | set => SetParameter("url", value); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/SigningIn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace HuajiTech.CoolQ.Messaging 5 | { 6 | /// 7 | /// 表示签到的 。 8 | /// 9 | public class SigningIn : CQCode 10 | { 11 | public SigningIn() 12 | : base("sign") 13 | { 14 | } 15 | 16 | public SigningIn(IDictionary parameters) 17 | : base("sign", parameters) 18 | { 19 | } 20 | 21 | /// 22 | /// 获取或设置当前 实例的图片 URL。 23 | /// 24 | public Uri? ImageUrl 25 | { 26 | get => GetParameterAsUri("image"); 27 | set => SetParameter("image", value); 28 | } 29 | 30 | /// 31 | /// 获取或设置当前 实例的发布位置。 32 | /// 33 | public string? Location 34 | { 35 | get => this["location"]; 36 | set => this["location"] = value; 37 | } 38 | 39 | /// 40 | /// 获取或设置当前 实例的标题。 41 | /// 42 | public string? Title 43 | { 44 | get => this["title"]; 45 | set => this["title"] = value; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/CQCodes/SmallEmoticon.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示小表情的 。 7 | /// 8 | public class SmallEmoticon : CQCode 9 | { 10 | public SmallEmoticon() 11 | : base("sface") 12 | { 13 | } 14 | 15 | public SmallEmoticon(IDictionary parameters) 16 | : base("sface", parameters) 17 | { 18 | } 19 | 20 | /// 21 | /// 获取或设置当前 实例的 ID。 22 | /// 23 | public int Id 24 | { 25 | get => GetParameterAsInt32("id"); 26 | set => SetParameter("id", value); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/Extensions.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Messaging 2 | { 3 | /// 4 | /// 定义扩展方法。 5 | /// 6 | public static class Extensions 7 | { 8 | public static PlainText ToPlainText(this string? str) => new PlainText(str); 9 | } 10 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/HuajiTech.CoolQ.Messaging.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net461;net45 5 | 8 6 | enable 7 | true 8 | HuajiTech.CoolQ.Messaging.pfx 9 | 0.4.0-beta 10 | SYC 11 | HuajiTech 12 | 用于处理酷Q消息。 13 | Copyright (C) 2020 HuajiTech 14 | LGPL-3.0-or-later 15 | https://github.com/huajitech/coolq-dotnet-sdk 16 | https://github.com/huajitech/coolq-dotnet-sdk 17 | git 18 | Icon.png 19 | HuajiTech, CoolQ, 酷Q, QQ, Bot, Robot, 机器人, Message, Messaging, 消息, CQCode, CQ码 20 | 这是一个测试版本,不建议用于生产环境。 21 | zh-CN 22 | true 23 | true 24 | C:\Users\SYC\source\repos\HuajiTech.CoolQ\src\HuajiTech.CoolQ.Messaging\HuajiTech.CoolQ.Messaging.xml 25 | 26 | 27 | 28 | 29 | True 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | all 41 | runtime; build; native; contentfiles; analyzers; buildtransitive 42 | 43 | 44 | 45 | 46 | 47 | Resources.resx 48 | True 49 | True 50 | 51 | 52 | 53 | 54 | 55 | Resources.Designer.cs 56 | ResXFileCodeGenerator 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/ISendable.cs: -------------------------------------------------------------------------------- 1 | namespace HuajiTech.CoolQ.Messaging 2 | { 3 | /// 4 | /// 定义用于发送的方法。 5 | /// 6 | public interface ISendable 7 | { 8 | /// 9 | /// 获取当前 实例的可发送字符串表示形式。 10 | /// 11 | string ToSendableString(); 12 | } 13 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/MessageElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示消息元素。 7 | /// 此类为抽象类。 8 | /// 9 | public abstract class MessageElement : ISendable, IEquatable 10 | { 11 | public static implicit operator MessageElement(string? str) => FromString(str); 12 | 13 | public static implicit operator ComplexMessage(MessageElement? element) 14 | => element?.ToComplexMessage() ?? new ComplexMessage(); 15 | 16 | public static bool operator !=(MessageElement? left, MessageElement? right) 17 | => !(left == right); 18 | 19 | public static bool operator ==(MessageElement? left, MessageElement? right) 20 | => left?.Equals(right) ?? right is null; 21 | 22 | public static ComplexMessage operator +(MessageElement? left, MessageElement? right) 23 | => right is null ? left ?? new ComplexMessage() : left?.Add(right) ?? right; 24 | 25 | public static MessageElement FromString(string? str) => new PlainText(str); 26 | 27 | public ComplexMessage Add(MessageElement element) => ToComplexMessage().Add(element); 28 | 29 | public ComplexMessage ToComplexMessage() => new ComplexMessage(this); 30 | 31 | public abstract string ToSendableString(); 32 | 33 | public override string ToString() => ToSendableString(); 34 | 35 | public override int GetHashCode() => ToSendableString().GetHashCode(); 36 | 37 | public override bool Equals(object? obj) => Equals(obj as MessageElement); 38 | 39 | public bool Equals(MessageElement? other) 40 | => base.Equals(other) || other?.ToSendableString() == ToSendableString(); 41 | } 42 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/MessageElementCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace HuajiTech.CoolQ.Messaging 6 | { 7 | /// 8 | /// 定义从 创建 的扩展方法。 9 | /// 10 | public static class MessageElementCollectionExtensions 11 | { 12 | /// 13 | /// 从 创建 。 14 | /// 15 | /// 要用于创建 的消息元素集合。 16 | /// 一个 ,其中包含输入序列中的元素。 17 | /// 18 | public static ComplexMessage ToComplexMessage(this IEnumerable elements) 19 | => new ComplexMessage(elements); 20 | 21 | /// 22 | /// 使用指定的分隔符从 创建 。 23 | /// 24 | /// 要用于创建 的消息元素集合。 25 | /// 要用作分隔符的 实例。 26 | /// 27 | /// 一个包含 中所有成员的 实例,这些成员以 分隔。 28 | /// 如果 没有成员,则该方法返回一个空的 实例。 29 | /// 30 | /// 31 | public static ComplexMessage ToComplexMessage(this IEnumerable elements, MessageElement separator) 32 | { 33 | if (elements is null) 34 | { 35 | throw new ArgumentNullException(nameof(elements)); 36 | } 37 | 38 | if (!elements.Any()) 39 | { 40 | return new ComplexMessage(); 41 | } 42 | 43 | if (elements.Count() is 1) 44 | { 45 | return new ComplexMessage(elements.First()); 46 | } 47 | 48 | return new ComplexMessage(GetMessageElements()); 49 | 50 | IEnumerable GetMessageElements() 51 | { 52 | yield return elements.First(); 53 | 54 | foreach (var element in elements.Skip(1)) 55 | { 56 | yield return separator; 57 | yield return element; 58 | } 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/PlainText.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace HuajiTech.CoolQ.Messaging 4 | { 5 | /// 6 | /// 表示纯文本。 7 | /// 此类不能被继承。 8 | /// 9 | [DebuggerDisplay("Content = {Content}")] 10 | public sealed class PlainText : MessageElement 11 | { 12 | /// 13 | /// 以指定内容初始化一个 类的新实例。 14 | /// 15 | /// 要被 包装的字符串。 16 | public PlainText(string? content) 17 | { 18 | Content = content ?? string.Empty; 19 | } 20 | 21 | /// 22 | /// 获取未经转义的原始内容。 23 | /// 24 | public string Content { get; } 25 | 26 | public static implicit operator string(PlainText? text) => text?.Content ?? string.Empty; 27 | 28 | /// 29 | /// 将指定的字符串转换为可以让酷Q按原义解释字符的语法。 30 | /// 31 | /// 要转换的字符串。 32 | /// 指定字符串的已转换值。 33 | public static string Escape(string str) 34 | { 35 | if (str is null) 36 | { 37 | throw new System.ArgumentNullException(nameof(str)); 38 | } 39 | 40 | return str 41 | .Replace("&", "&") 42 | .Replace("[", "[") 43 | .Replace("]", "]"); 44 | } 45 | 46 | /// 47 | /// 将字符串中的转义字符转换为具有特殊意义的酷Q字符。 48 | /// 49 | /// 要转换的字符串。 50 | /// 指定字符串的已转换值。 51 | public static string Unescape(string str) 52 | { 53 | if (str is null) 54 | { 55 | throw new System.ArgumentNullException(nameof(str)); 56 | } 57 | 58 | return str 59 | .Replace("[", "[") 60 | .Replace("]", "]") 61 | .Replace("&", "&"); 62 | } 63 | 64 | /// 65 | /// 返回经过 后的 。 66 | /// 67 | public override string ToSendableString() => Escape(Content); 68 | 69 | /// 70 | /// 获取当前 实例的字符串表示形式。 71 | /// 72 | /// 的值。 73 | public override string ToString() => Content; 74 | } 75 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [assembly: CLSCompliant(true)] -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Messaging/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace HuajiTech.CoolQ.Messaging { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HuajiTech.CoolQ.Messaging.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找类似 该字段不能为空。 的本地化字符串。 65 | /// 66 | internal static string FieldCannotBeEmpty { 67 | get { 68 | return ResourceManager.GetString("FieldCannotBeEmpty", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// 查找类似 该字段不能为空或空白字符。 的本地化字符串。 74 | /// 75 | internal static string FieldCannotBeEmptyOrWhiteSpace { 76 | get { 77 | return ResourceManager.GetString("FieldCannotBeEmptyOrWhiteSpace", resourceCulture); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/HuajiTech.CoolQ.Packing.ILRepack.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | HuajiTech.CoolQ.Packing 5 | netstandard2.0;net461;net45 6 | 8 7 | enable 8 | 0.4.0-beta 9 | SYC 10 | HuajiTech 11 | 使用 ILRepack 打包 HuajiTech.CoolQ 应用。 12 | Copyright (C) 2020 HuajiTech 13 | LGPL-3.0-or-later 14 | https://github.com/huajitech/coolq-dotnet-sdk 15 | https://github.com/huajitech/coolq-dotnet-sdk 16 | git 17 | Icon.png 18 | HuajiTech, CoolQ, 酷Q, QQ, Bot, Robot, 机器人, Packing, ILRepack 19 | 这是一个测试版本,不建议用于生产环境。 20 | zh-CN 21 | true 22 | true 23 | build\HuajiTech.CoolQ.Packing.ILRepack.Placeholder.targets 24 | true 25 | HuajiTech.CoolQ.Packing.ILRepack.pfx 26 | 27 | 28 | 29 | 30 | True 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | True 42 | build 43 | 44 | 45 | True 46 | tools 47 | 48 | 49 | 50 | 51 | 52 | build 53 | 54 | 55 | build 56 | 57 | 58 | all 59 | runtime; build; native; contentfiles; analyzers; buildtransitive 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/ILRepacker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Runtime.Serialization.Formatters.Binary; 6 | 7 | namespace HuajiTech.CoolQ.Packing 8 | { 9 | /// 10 | /// 提供对 ILRepack 的访问。 11 | /// 12 | public class ILRepacker : IPacker 13 | { 14 | internal const string ILRepackListResourceName = "ILRepack.List"; 15 | public static readonly ILRepacker Instance = new ILRepacker(); 16 | 17 | private ILRepacker() 18 | { 19 | } 20 | 21 | internal static void Init() 22 | { 23 | AppDomain.CurrentDomain.AssemblyResolve += 24 | (sender, e) => Assembly.GetExecutingAssembly(); 25 | 26 | AppDomain.CurrentDomain.ResourceResolve += 27 | (sender, e) => Assembly.GetExecutingAssembly(); 28 | } 29 | 30 | public IReadOnlyCollection GetPackedAssemblies() 31 | { 32 | var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ILRepackListResourceName); 33 | var packedAssemblyNames = (string[])new BinaryFormatter().Deserialize(resourceStream); 34 | return packedAssemblyNames.Select(name => new AssemblyName(name)).ToList(); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [assembly: CLSCompliant(true)] -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/build/HuajiTech.CoolQ.Packing.ILRepack.Placeholder.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/build/HuajiTech.CoolQ.Packing.ILRepack.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildThisFileDirectory)HuajiTech.CoolQ.Packing.ILRepack.Placeholder.targets 5 | $([MSBuild]::NormalizePath('$(MSBuildThisFileDirectory)..\tools\net35\InjectModuleInitializer.exe')) 6 | 7 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/build/HuajiTech.CoolQ.Packing.ILRepack.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/InjectModuleInitializer.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/InjectModuleInitializer.exe -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/Mono.Cecil.Mdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/Mono.Cecil.Mdb.dll -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/Mono.Cecil.Pdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/Mono.Cecil.Pdb.dll -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/Mono.Cecil.Rocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/Mono.Cecil.Rocks.dll -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huajitech/coolq-dotnet-sdk/6d7fdbf4ae6bb41c2f2df24d9011fe08505072fa/src/HuajiTech.CoolQ.Packing.ILRepack/tools/net35/Mono.Cecil.dll -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29409.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E2DA7FEA-02DF-4654-BE5C-226A6DA1D429}" 7 | ProjectSection(SolutionItems) = preProject 8 | .editorconfig = .editorconfig 9 | stylecop.json = stylecop.json 10 | EndProjectSection 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuajiTech.CoolQ.Abstractions", "HuajiTech.CoolQ.Abstractions\HuajiTech.CoolQ.Abstractions.csproj", "{4E8B373F-5453-45FC-98C2-C1572B280057}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuajiTech.CoolQ.Messaging", "HuajiTech.CoolQ.Messaging\HuajiTech.CoolQ.Messaging.csproj", "{D4B1BF88-9F4F-40E1-836B-1ABB4AA381C9}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuajiTech.CoolQ.Core", "HuajiTech.CoolQ.Core\HuajiTech.CoolQ.Core.csproj", "{C2E3024C-B14B-4FAD-B9EA-09A57B69FFA4}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuajiTech.CoolQ.Packing.ILRepack", "HuajiTech.CoolQ.Packing.ILRepack\HuajiTech.CoolQ.Packing.ILRepack.csproj", "{FA66149F-A8BD-44F2-8C5B-97E5FDC68DC7}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuajiTech.CoolQ.Loaders.Autofac", "HuajiTech.CoolQ.Loaders.Autofac\HuajiTech.CoolQ.Loaders.Autofac.csproj", "{FC710009-2797-4F39-87E7-8D6319080427}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuajiTech.CoolQ", "HuajiTech.CoolQ\HuajiTech.CoolQ.csproj", "{794BA126-B482-4A10-A4D9-AEA394EA1C90}" 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Release|Any CPU = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {4E8B373F-5453-45FC-98C2-C1572B280057}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {4E8B373F-5453-45FC-98C2-C1572B280057}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {4E8B373F-5453-45FC-98C2-C1572B280057}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {4E8B373F-5453-45FC-98C2-C1572B280057}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {D4B1BF88-9F4F-40E1-836B-1ABB4AA381C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {D4B1BF88-9F4F-40E1-836B-1ABB4AA381C9}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {D4B1BF88-9F4F-40E1-836B-1ABB4AA381C9}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {D4B1BF88-9F4F-40E1-836B-1ABB4AA381C9}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {C2E3024C-B14B-4FAD-B9EA-09A57B69FFA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {C2E3024C-B14B-4FAD-B9EA-09A57B69FFA4}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {C2E3024C-B14B-4FAD-B9EA-09A57B69FFA4}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {C2E3024C-B14B-4FAD-B9EA-09A57B69FFA4}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {FA66149F-A8BD-44F2-8C5B-97E5FDC68DC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {FA66149F-A8BD-44F2-8C5B-97E5FDC68DC7}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {FA66149F-A8BD-44F2-8C5B-97E5FDC68DC7}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {FA66149F-A8BD-44F2-8C5B-97E5FDC68DC7}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {FC710009-2797-4F39-87E7-8D6319080427}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {FC710009-2797-4F39-87E7-8D6319080427}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {FC710009-2797-4F39-87E7-8D6319080427}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {FC710009-2797-4F39-87E7-8D6319080427}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {794BA126-B482-4A10-A4D9-AEA394EA1C90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {794BA126-B482-4A10-A4D9-AEA394EA1C90}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {794BA126-B482-4A10-A4D9-AEA394EA1C90}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {794BA126-B482-4A10-A4D9-AEA394EA1C90}.Release|Any CPU.Build.0 = Release|Any CPU 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(ExtensibilityGlobals) = postSolution 59 | SolutionGuid = {C1DB6D39-45C8-4D3F-8D95-502DC631A493} 60 | EndGlobalSection 61 | EndGlobal 62 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ/DefaultInitializer.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using Autofac; 3 | using HuajiTech.CoolQ.Loaders; 4 | 5 | namespace HuajiTech.CoolQ 6 | { 7 | /// 8 | /// 提供默认的初始化实现。 9 | /// 10 | public static class DefaultInitializer 11 | { 12 | /// 13 | /// 初始化 。 14 | /// 15 | public static void Init() 16 | { 17 | new AutofacLoader(new ContainerBuilder()) 18 | .RegisterSdk() 19 | .RegisterPlugins(Assembly.GetExecutingAssembly()) 20 | .Build() 21 | .Init(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ/HuajiTech.CoolQ.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net461 5 | 8 6 | enable 7 | true 8 | HuajiTech.CoolQ.pfx 9 | true 10 | 0.4.0-beta 11 | SYC 12 | HuajiTech 13 | 用于酷Q应用的 .NET SDK。 14 | Copyright (C) 2020 HuajiTech 15 | LGPL-3.0-or-later 16 | https://github.com/huajitech/coolq-dotnet-sdk 17 | Icon.png 18 | https://github.com/huajitech/coolq-dotnet-sdk 19 | git 20 | HuajiTech, CoolQ, 酷Q, QQ, Bot, Robot, 机器人 21 | 这是一个测试版本,不建议用于生产环境。 22 | zh-CN 23 | true 24 | true 25 | C:\Users\SYC\source\repos\HuajiTech.CoolQ\src\HuajiTech.CoolQ\HuajiTech.CoolQ.xml 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | True 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | all 50 | runtime; build; native; contentfiles; analyzers; buildtransitive 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ/Properties/AppInfo.cs: -------------------------------------------------------------------------------- 1 | // 用于 HuajiTech.CoolQ 的应用信息配置文件。 2 | // 最后更新于 2020-6-18 20:59。 3 | 4 | using HuajiTech.CoolQ; 5 | 6 | // 指定资源管理器的默认区域性信息。通常情况下,无需更改此项。 7 | [assembly: System.Resources.NeutralResourcesLanguage("zh-CN")] 8 | 9 | // 指定应用的初始化器。 10 | // 应用初始化器必须包含一个名为 Init 的无参数静态方法。 11 | // 注意:必须使用字符串指定初始化器。 12 | [assembly: Initializer("HuajiTech.CoolQ.DefaultInitializer")] 13 | 14 | // 指定应用的 AppID。必须更改此项。 15 | // dev 目录下存放应用的目录名必须与 AppID 匹配。 16 | [assembly: AppId("com.example.app")] -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | [assembly: CLSCompliant(true)] -------------------------------------------------------------------------------- /src/HuajiTech.CoolQ/SdkInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HuajiTech.CoolQ 4 | { 5 | /// 6 | /// 包含有关 HuajiTech.CoolQ 的信息。 7 | /// 8 | public static class SdkInfo 9 | { 10 | /// 11 | /// SDK 的版本。 12 | /// 该字段为常量。 13 | /// 14 | public const string Version = "0.4.0-beta"; 15 | } 16 | } -------------------------------------------------------------------------------- /src/stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | // ACTION REQUIRED: This file was automatically added to your project, but it 3 | // will not take effect until additional steps are taken to enable it. See the 4 | // following page for additional information: 5 | // 6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md 7 | 8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 9 | 10 | "settings": { 11 | "orderingRules": { 12 | "usingDirectivesPlacement": "outsideNamespace", 13 | "elementOrder": [ 14 | "kind", 15 | "constant", 16 | "static", 17 | "accessibility", 18 | "readonly" 19 | ] 20 | }, 21 | "documentationRules": { 22 | "documentInterfaces": false, 23 | "documentExposedElements": false, 24 | "documentInternalElements": false 25 | } 26 | } 27 | } --------------------------------------------------------------------------------