├── .gitattributes ├── .gitignore ├── .net.dllexport.targets ├── DllExport.bat ├── DllExport_Configure.bat ├── LICENSE ├── Lib └── Newtonsoft.Json.dll ├── README.md ├── XQ.Core ├── Export │ ├── Export.cs │ ├── Global.cs │ └── Init.cs ├── ExportMain.cs ├── FodyWeavers.xml ├── Properties │ └── AssemblyInfo.cs ├── XQ.Core.csproj └── packages.config ├── XQ.Enhance ├── HttpHelper.cs ├── Properties │ └── AssemblyInfo.cs ├── QqHeadPic.cs └── XQ.Enhance.csproj ├── XQ.Plugin ├── PluginExample.cs ├── Properties │ └── AssemblyInfo.cs └── XQ.Plugin.csproj ├── XQ.SDK ├── Core │ ├── Expand.cs │ ├── Kernel32.cs │ └── TinyIOC │ │ ├── NamedParameterOverloads.cs │ │ ├── NamedResolutionFailureActions.cs │ │ ├── ResolveOptions.cs │ │ ├── ReverseTypeExtender.cs │ │ ├── SafeDictionary.cs │ │ ├── TinyIoCConstructorAttribute.cs │ │ ├── TinyIoCContainer.cs │ │ ├── TinyIoCRegistrationTypeException.cs │ │ ├── TinyIoCResolutionException.cs │ │ ├── TypeExtensions.cs │ │ └── UnregisteredResolutionActions.cs ├── Enum │ ├── Event │ │ ├── FrameEventEventType.cs │ │ ├── FriendEventEventType.cs │ │ ├── GroupEventEventType.cs │ │ └── RobotEventEventType.cs │ ├── FriendAddRequestType.cs │ ├── FriendRequestHandlerType.cs │ ├── GroupRequestHandlerType.cs │ ├── ImageMessageType.cs │ ├── MessageType.cs │ ├── OnlineStatusType.cs │ ├── PrivateMessageType.cs │ ├── QqSex.cs │ ├── ShowPicType.cs │ ├── WithdrawMessageType.cs │ └── XqEventReturnType.cs ├── EventArgs │ ├── BeInvitedToGroupEventArgs.cs │ ├── FrameEventArgs.cs │ ├── FriendAddRequestEventArgs.cs │ ├── FriendEventArgs.cs │ ├── GroupEchoMessageEventArgs.cs │ ├── GroupEventEventArgs.cs │ ├── GroupMessageEventArgs.cs │ ├── JoinGroupRequestEventArgs.cs │ ├── PrivateMessageEventArgs.cs │ ├── RobotEventEventArgs.cs │ ├── TransferEventArgs.cs │ ├── WithDrawMessageEventArgs.cs │ ├── XqEventArgs.cs │ └── XqMessageEventArgs.cs ├── Interface │ ├── Event │ │ ├── IAppDisable.cs │ │ ├── IAppEnable.cs │ │ ├── IBeInvitedToGroup.cs │ │ ├── ICallMenu.cs │ │ ├── IFrameEvent.cs │ │ ├── IFriendAddRequest.cs │ │ ├── IFriendEvent.cs │ │ ├── IGroupEchoMessage.cs │ │ ├── IGroupEvent.cs │ │ ├── IGroupMessage.cs │ │ ├── IJoinGroupRequest.cs │ │ ├── IPluginDestroy.cs │ │ ├── IPrivateMessage.cs │ │ ├── IRobotEvent.cs │ │ ├── ITransfer.cs │ │ └── IWithDrawMessage.cs │ ├── IToSendString.cs │ └── IXqEvent.cs ├── Model │ ├── BasisModel.cs │ ├── Group.cs │ ├── Json │ │ ├── FriendInfoJson.cs │ │ ├── FriendList.cs │ │ ├── FriendListItem.cs │ │ ├── GroupInfoJson.cs │ │ ├── GroupList.cs │ │ ├── GroupMemberInfoJson.cs │ │ ├── GroupMemberItems.cs │ │ ├── GroupMemberList.cs │ │ ├── GroupMemberListQqonly.cs │ │ ├── OcrInfo.cs │ │ ├── OcrItem.cs │ │ ├── OcrItemCollection.cs │ │ └── RobotInfo.cs │ ├── MessageObject │ │ ├── ImageMessage.cs │ │ ├── PlainMessage.cs │ │ └── VoiceMessage.cs │ ├── PluginInfo.cs │ ├── Qq.cs │ ├── QqMessage.cs │ ├── Robot.cs │ └── XqRawEvent.cs ├── Properties │ └── AssemblyInfo.cs ├── XQ.SDK.csproj └── XQ │ ├── XqApi.cs │ └── Xqdll.cs ├── XQCSharpSDK.sln ├── XQCsharpSDK.png └── packages ├── Costura.Fody.1.6.2 ├── build │ ├── dotnet │ │ └── Costura.Fody.targets │ └── portable-net+sl+win+wpa+wp │ │ └── Costura.Fody.targets ├── lib │ ├── dotnet │ │ └── Costura.dll │ └── portable-net+sl+win+wpa+wp │ │ └── Costura.dll └── tools │ ├── install.ps1 │ └── uninstall.ps1 ├── DllExport.1.6.1 ├── build │ └── net20 │ │ └── DllExport.targets ├── gcache │ └── metalib │ │ ├── RGiesecke.DllExport │ │ ├── DllExport.dll │ │ └── DllExport.dll.ddNSi │ │ └── System.Runtime.InteropServices │ │ ├── DllExport.dll │ │ └── DllExport.dll.ddNSi ├── lib │ └── net20 │ │ └── _._ └── tools │ ├── Conari.dll │ ├── Conari.xml │ ├── Microsoft.Build.Framework.dll │ ├── Microsoft.Build.Utilities.v4.0.dll │ ├── Microsoft.Build.dll │ ├── Microsoft.Management.Infrastructure.dll │ ├── Mono.Cecil.dll │ ├── MvsSln.dll │ ├── MvsSln.xml │ ├── NSBin.dll │ ├── PeViewer.exe │ ├── RGiesecke.DllExport.MSBuild.dll │ ├── RGiesecke.DllExport.dll │ ├── System.Management.Automation.dll │ ├── build.targets │ ├── coreclr │ ├── LICENSE.TXT │ ├── PATENTS.TXT │ ├── README.md │ ├── _Version.txt │ ├── changelog.txt │ ├── coreclr.dll │ ├── ilasm.exe │ ├── ildasm.exe │ ├── ildasmrc.dll │ ├── mscordaccore.dll │ └── mscordbi.dll │ ├── net.r_eg.DllExport.Configurator.dll │ ├── net.r_eg.DllExport.Wizard.dll │ ├── net.r_eg.DllExport.Wizard.targets │ ├── net.r_eg.DllExport.targets │ └── raw │ └── lib │ └── net20 │ └── DllExport.dll └── Fody.2.2.1.0 ├── Content └── FodyWeavers.xml ├── Tools └── install.ps1 └── build ├── net452 └── Fody.targets ├── netstandard1.2 └── Fody.targets └── portable-net+sl+win+wpa+wp └── Fody.targets /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text= 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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # Uncomment if you have tasks that create the project's static files in wwwroot 29 | #wwwroot/ 30 | 31 | # MSTest test Results 32 | [Tt]est[Rr]esult*/ 33 | [Bb]uild[Ll]og.* 34 | 35 | # NUNIT 36 | *.VisualState.xml 37 | TestResult.xml 38 | 39 | # Build Results of an ATL Project 40 | [Dd]ebugPS/ 41 | [Rr]eleasePS/ 42 | dlldata.c 43 | 44 | # DNX 45 | project.lock.json 46 | project.fragment.lock.json 47 | artifacts/ 48 | 49 | *_i.c 50 | *_p.c 51 | *_i.h 52 | *.ilk 53 | *.meta 54 | *.obj 55 | *.pch 56 | *.pdb 57 | *.pgc 58 | *.pgd 59 | *.rsp 60 | *.sbr 61 | *.tlb 62 | *.tli 63 | *.tlh 64 | *.tmp 65 | *.tmp_proj 66 | *.log 67 | *.vspscc 68 | *.vssscc 69 | .builds 70 | *.pidb 71 | *.svclog 72 | *.scc 73 | 74 | # Chutzpah Test files 75 | _Chutzpah* 76 | 77 | # Visual C++ cache files 78 | ipch/ 79 | *.aps 80 | *.ncb 81 | *.opendb 82 | *.opensdf 83 | *.sdf 84 | *.cachefile 85 | *.VC.db 86 | *.VC.VC.opendb 87 | 88 | # Visual Studio profiler 89 | *.psess 90 | *.vsp 91 | *.vspx 92 | *.sap 93 | 94 | # TFS 2012 Local Workspace 95 | $tf/ 96 | 97 | # Guidance Automation Toolkit 98 | *.gpState 99 | 100 | # ReSharper is a .NET coding add-in 101 | _ReSharper*/ 102 | *.[Rr]e[Ss]harper 103 | *.DotSettings.user 104 | 105 | # JustCode is a .NET coding add-in 106 | .JustCode 107 | 108 | # TeamCity is a build add-in 109 | _TeamCity* 110 | 111 | # DotCover is a Code Coverage Tool 112 | *.dotCover 113 | 114 | # NCrunch 115 | _NCrunch_* 116 | .*crunch*.local.xml 117 | nCrunchTemp_* 118 | 119 | # MightyMoose 120 | *.mm.* 121 | AutoTest.Net/ 122 | 123 | # Web workbench (sass) 124 | .sass-cache/ 125 | 126 | # Installshield output folder 127 | [Ee]xpress/ 128 | 129 | # DocProject is a documentation generator add-in 130 | DocProject/buildhelp/ 131 | DocProject/Help/*.HxT 132 | DocProject/Help/*.HxC 133 | DocProject/Help/*.hhc 134 | DocProject/Help/*.hhk 135 | DocProject/Help/*.hhp 136 | DocProject/Help/Html2 137 | DocProject/Help/html 138 | 139 | # Click-Once directory 140 | publish/ 141 | 142 | *.bat 143 | 144 | packages/*/*.* 145 | 146 | # Publish Web Output 147 | *.[Pp]ublish.xml 148 | *.azurePubxml 149 | # TODO: Comment the next line if you want to checkin your web deploy settings 150 | # but database connection strings (with potential passwords) will be unencrypted 151 | #*.pubxml 152 | *.publishproj 153 | 154 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 155 | # checkin your Azure Web App publish settings, but sensitive information contained 156 | # in these scripts will be unencrypted 157 | PublishScripts/ 158 | 159 | # Microsoft Azure Build Output 160 | csx/ 161 | *.build.csdef 162 | 163 | # Microsoft Azure Emulator 164 | ecf/ 165 | rcf/ 166 | 167 | # Windows Store app package directories and files 168 | AppPackages/ 169 | BundleArtifacts/ 170 | Package.StoreAssociation.xml 171 | _pkginfo.txt 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | ~$* 182 | *~ 183 | *.dbmdl 184 | *.dbproj.schemaview 185 | *.jfm 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # Since there are multiple workflows, uncomment next line to ignore bower_components 192 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 193 | #bower_components/ 194 | 195 | # RIA/Silverlight projects 196 | Generated_Code/ 197 | 198 | # Backup & report files from converting an old project file 199 | # to a newer Visual Studio version. Backup files are not needed, 200 | # because we have git ;-) 201 | _UpgradeReport_Files/ 202 | Backup*/ 203 | UpgradeLog*.XML 204 | UpgradeLog*.htm 205 | 206 | # SQL Server files 207 | *.mdf 208 | *.ldf 209 | 210 | # Business Intelligence projects 211 | *.rdl.data 212 | *.bim.layout 213 | *.bim_*.settings 214 | 215 | # Microsoft Fakes 216 | FakesAssemblies/ 217 | 218 | # GhostDoc plugin setting file 219 | *.GhostDoc.xml 220 | 221 | # Node.js Tools for Visual Studio 222 | .ntvs_analysis.dat 223 | 224 | # Visual Studio 6 build log 225 | *.plg 226 | 227 | # Visual Studio 6 workspace options file 228 | *.opt 229 | 230 | # Visual Studio LightSwitch build output 231 | **/*.HTMLClient/GeneratedArtifacts 232 | **/*.DesktopClient/GeneratedArtifacts 233 | **/*.DesktopClient/ModelManifest.xml 234 | **/*.Server/GeneratedArtifacts 235 | **/*.Server/ModelManifest.xml 236 | _Pvt_Extensions 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | paket-files/ 241 | 242 | # FAKE - F# Make 243 | .fake/ 244 | 245 | # JetBrains Rider 246 | .idea/ 247 | *.sln.iml 248 | 249 | # CodeRush 250 | .cr/ 251 | 252 | # Python Tools for Visual Studio (PTVS) 253 | __pycache__/ 254 | *.pyc 255 | 256 | Output/TestPlugin.XQ.dll 257 | -------------------------------------------------------------------------------- /.net.dllexport.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | DllExport.dll 5 | System.Runtime.InteropServices 6 | true 7 | x86 8 | 1 9 | false 10 | false 11 | false 12 | 30000 13 | 2 14 | 48DB866E-4517-44DF-8EA5-516A2D0F10D8 15 | XQ.Plugin\XQ.Plugin.csproj 16 | 17 | 18 | DllExport.dll 19 | System.Runtime.InteropServices 20 | true 21 | x86 22 | 1 23 | false 24 | false 25 | false 26 | 30000 27 | 2 28 | E13B30A4-CBED-4E84-B475-A1E43EF59B52 29 | XQ.SDK\XQ.SDK.csproj 30 | 31 | 32 | DllExport.dll 33 | System.Runtime.InteropServices 34 | true 35 | x86 36 | 1 37 | false 38 | false 39 | false 40 | 30000 41 | 2 42 | D63C3FB7-18B9-4CDE-A8F4-F2ACE3FC382F 43 | XQ.Core\XQ.Core.csproj 44 | 45 | 46 | 47 | $(SolutionDir)packages\DllExport.1.6.1\gcache\metalib\$(DllExportNamespace)\$(DllExportMetaLibName) 48 | False 49 | False 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /DllExport_Configure.bat: -------------------------------------------------------------------------------- 1 | DllExport -action Configure %* -------------------------------------------------------------------------------- /Lib/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/Lib/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ## XQCSharpSDK 4 | icon 5 | 6 | 使用C#8.0编写的先驱机器人插件开发框架 7 | 8 | 2021/12/24 由于先驱跑路,本SDK不再维护 9 | 10 |
11 | 12 | ---- 13 | 14 | ## 特点 15 | 16 | * 封装了XQ提供的接口,提供基于抽象数据类型的XQApi 17 | * 在事件中保留并封装了XQ的Event原参数,提供用户扩展空间 18 | * 提供了托管异常处理 19 | * 支持导出函数 20 | * 支持整合Dll依赖项 21 | 22 | ## 感谢 23 | 24 | * fumiko为项目设计了Icon 25 | * 整体SDK架构参考了Jie2GG/Native.Framework 26 | * 部分消息解析逻辑参考了w4123/CQXQ 27 | * XqDll.cs的使用授权由赫尔heer提供 28 | 29 | ## 开发文档 30 | + 修改 XQ.Plugin/PluginExample.cs 31 | + 继承希望处理的事件的对应接口,并实现 32 | + 修改 XQ.Core/ExportMain.cs 33 | + 注册需要处理的事件接口和插件 并设置插件信息 34 | + 打开 XQ.Core => 属性 35 | + 将 程序集名称 修改为插件名称 36 | + Release x86模式进行编译 37 | + 打开XQCSharpSDK/Output文件夹 38 | + 插件名称.XQ.dll 即为 XQ可调用的插件 39 | 40 | ## 常见问题 41 | + 由于托管环境限制和XQ插件缓存机制 导致插件的 卸载、更新后重载 功能无法使用 42 | + 解决方案 : 更新插件后(无论之前是否加载成功) 重启XQ框架 43 | + Intellisense 报错 CS0103 CS0234 CS0246 (不影响DLL生成) 44 | + 解决方案 : 将 XQ.Core 对 XQ.Plugin,XQ.SDK 的引用取消,再重新引用 以刷新Intellisense 45 | + 多插件报错问题 46 | + 解决方案 : 修改 XQ.Plugin 的命名空间 47 | 48 | ## QQ交流群 49 | + XQCsharp 807465006 50 | + 提供最新SDK下载及常见问题解答 51 | -------------------------------------------------------------------------------- /XQ.Core/Export/Global.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading; 4 | using XQ.SDK.Model; 5 | using XQ.SDK.XQ; 6 | 7 | namespace XQ.Core.Export 8 | { 9 | public static class Global 10 | { 11 | /// 12 | /// 获取Api是否已经加载完成 13 | /// 14 | public static bool LoadCompleted { get; private set; } 15 | 16 | /// 17 | /// XqApi单例 18 | /// 19 | public static XqApi XqApi { get; private set; } 20 | 21 | /// 22 | /// 插件信息单例 23 | /// 24 | public static PluginInfo PluginInfo { get; private set; } 25 | 26 | /// 27 | /// 配置文件路径 28 | /// 29 | public static string ConfigPath => AppContext.BaseDirectory + $@"\Config\{PluginInfo.Name}\"; 30 | 31 | /// 32 | /// 设置XqApi单例 33 | /// 请不要在插件运行时更改 34 | /// 35 | /// 插件AuthId 36 | public static void SetApi(byte[] authId) 37 | { 38 | XqApi = new XqApi(authId); 39 | XqApi.SetPluginInfo(PluginInfo); 40 | LoadCompleted = true; 41 | } 42 | 43 | /// 44 | /// 清除XqApi单例 45 | /// 请不要在插件运行时更改 46 | /// 47 | public static void DisposeApi() 48 | { 49 | XqApi = null; 50 | LoadCompleted = false; 51 | } 52 | 53 | /// 54 | /// 设置插件信息单例 55 | /// 请不要在插件运行时更改 56 | /// 57 | /// 插件信息 58 | public static void SetInfo(PluginInfo info) 59 | { 60 | PluginInfo = info; 61 | if(LoadCompleted) 62 | XqApi.SetPluginInfo(info); 63 | } 64 | 65 | /// 66 | /// 向Log中写入异常信息 67 | /// 68 | /// 69 | /// 是否在框架UI输出 70 | public static void ExceptionReport(Exception ex, bool output = true) 71 | { 72 | var dir = $"{AppContext.BaseDirectory}/Log/{DateTime.Now:yyyy-M-d}/"; 73 | if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); 74 | try 75 | { 76 | File.AppendAllText($"{dir}XQCSharp_Err.log", $"{DateTime.Now:T}\n{ex}\n\n"); 77 | if (output) XqApi.OutPutLogToFrame($"[{PluginInfo.Name}] 发生异常:" + ex.Message); 78 | } 79 | catch 80 | { 81 | Thread.Sleep(2000); 82 | ExceptionReport(ex); 83 | } 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /XQ.Core/Export/Init.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Core.TinyIOC; 2 | using XQ.SDK.Interface; 3 | 4 | namespace XQ.Core.Export 5 | { 6 | internal static class Init 7 | { 8 | internal static TinyIoCContainer Container { get; } = new TinyIoCContainer(); 9 | 10 | internal static void Register() where TU : class, T where T : class, IXqEvent 11 | { 12 | Container.Register(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.Core/ExportMain.cs: -------------------------------------------------------------------------------- 1 | using XQ.Core.Export; 2 | using XQ.Plugin; 3 | using XQ.SDK.Interface; 4 | using XQ.SDK.Model; 5 | 6 | namespace XQ.Core 7 | { 8 | public class ExportMain 9 | { 10 | /// 11 | /// 将需要处理的事件接口和插件注册 12 | /// 并设置插件信息 13 | /// (在Release x86模式下)生成的dll文件在Output文件夹下 (注:可在 {XQ.Core => (右键菜单最底)属性 => 生成 => 输出路径} 进行修改) 14 | /// dll名称为 {XQ.Core => (右键菜单最底)属性 => 应用程序 => 程序集名称}.XQ.dll 15 | /// 16 | public static PluginInfo AddRegister() 17 | { 18 | Init.Register(); 19 | Init.Register(); 20 | Init.Register(); 21 | Init.Register(); 22 | Init.Register(); 23 | Init.Register(); 24 | 25 | return new PluginInfo( 26 | "TestPlugin", //此参数应与 XQ.Core => 属性 => 应用程序 => 程序集名称 保持一致,否则XQ将报错 27 | "littlenine12", 28 | "1.0.0", 29 | "测试用插件" 30 | ); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /XQ.Core/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /XQ.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // 有关程序集的一般信息由以下 5 | // 控制。更改这些特性值可修改 6 | // 与程序集关联的信息。 7 | [assembly: AssemblyTitle("XQ.Core")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("XQ.Core")] 12 | [assembly: AssemblyCopyright("Copyright © Microsoft 2021")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // 将 ComVisible 设置为 false 会使此程序集中的类型 17 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 18 | //请将此类型的 ComVisible 特性设置为 true。 19 | [assembly: ComVisible(false)] 20 | 21 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 22 | [assembly: Guid("c03c5bb7-91d0-4894-aaf9-127090dfad91")] 23 | 24 | // 程序集的版本信息由下列四个值组成: 25 | // 26 | // 主版本 27 | // 次版本 28 | // 生成号 29 | // 修订号 30 | // 31 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 32 | //通过使用 "*",如下所示: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /XQ.Core/XQ.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C03C5BB7-91D0-4894-AAF9-127090DFAD91} 8 | Library 9 | Properties 10 | XQ.Core 11 | TestPlugin 12 | v4.7.2 13 | 512 14 | true 15 | 16 | 17 | 18 | 19 | 20 | true 21 | bin\x86\Debug\ 22 | DEBUG;TRACE 23 | full 24 | prompt 25 | MinimumRecommendedRules.ruleset 26 | 27 | 28 | ..\Output\ 29 | TRACE 30 | true 31 | pdbonly 32 | x86 33 | prompt 34 | MinimumRecommendedRules.ruleset 35 | 36 | 37 | 38 | $(SolutionDir)packages\DllExport.1.6.1\gcache\metalib\$(DllExportNamespace)\$(DllExportMetaLibName) 39 | False 40 | False 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | {517f57ee-4882-4054-a122-734903ba9ab3} 64 | XQ.Plugin 65 | 66 | 67 | {6b6664a8-e436-4b35-9040-8247de86ec89} 68 | XQ.SDK 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | if exist "$(TargetDir)$(TargetName).dll" ( 89 | move "$(TargetDir)$(TargetName).dll" "$(TargetDir)$(TargetName).XQ.dll" 90 | ) 91 | 92 | 93 | D63C3FB7-18B9-4CDE-A8F4-F2ACE3FC382F 94 | DllExport.dll 95 | System.Runtime.InteropServices 96 | true 97 | x86 98 | 1 99 | false 100 | false 101 | false 102 | 30000 103 | 2 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /XQ.Core/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 7 | -------------------------------------------------------------------------------- /XQ.Enhance/HttpHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Text; 3 | 4 | namespace XQ.Enhance 5 | { 6 | public static class HttpHelper 7 | { 8 | private static string GetStringFromUrl(string url) 9 | { 10 | ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 11 | ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; 12 | var wc = new WebClient { Encoding = Encoding.UTF8 }; 13 | return wc.DownloadString(url); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /XQ.Enhance/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("XQ.Enhance")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("XQ.Enhance")] 13 | [assembly: AssemblyCopyright("Copyright © 2021")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("787b0c99-5d19-4fd9-adbb-2b5d8e810197")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 33 | //通过使用 "*",如下所示: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /XQ.Enhance/QqHeadPic.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Model.MessageObject; 2 | using XQ.SDK.XQ; 3 | 4 | namespace XQ.Enhance 5 | { 6 | public static class QqHeadPic 7 | { 8 | public static ImageMessage Get(XqApi xqApi, string robotqq, string qqid) => ImageMessage.FromUrl(xqApi, robotqq, $"https://q1.qlogo.cn/g?b=qq&nk={qqid}&s=640"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /XQ.Enhance/XQ.Enhance.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197} 8 | Library 9 | Properties 10 | XQ.Enhance 11 | XQ.Enhance 12 | v4.7.2 13 | 512 14 | true 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x86\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x86 39 | 7.3 40 | prompt 41 | 42 | 43 | bin\x86\Release\ 44 | TRACE 45 | true 46 | pdbonly 47 | x86 48 | 7.3 49 | prompt 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {6b6664a8-e436-4b35-9040-8247de86ec89} 63 | XQ.SDK 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /XQ.Plugin/PluginExample.cs: -------------------------------------------------------------------------------- 1 | //using XQ.SDK.Enum; 2 | //using XQ.SDK.Model.MessageObject; 3 | 4 | using XQ.SDK.Enum.Event; 5 | using XQ.SDK.EventArgs; 6 | using XQ.SDK.Interface; 7 | using XQ.SDK.XQ; 8 | 9 | namespace XQ.Plugin 10 | { 11 | public class MyPlugin : IPrivateMessage 12 | //举例 : 此处 MyPlugin 未在 XQ.Core.ExportMain.cs 中的AddRegister函数中注册,故不会被调用 13 | { 14 | public void PrivateMessage(PrivateMessageEventArgs e) 15 | { 16 | // do something 17 | } 18 | } 19 | 20 | /// 21 | /// 此处为插件例子 22 | /// 这里是插件逻辑部分,需要处理什么事件就继承接口 接口介绍:XQ.SDK\Interface\Event\ 23 | /// 建议自行新建类以实现功能 24 | /// 需要在XQ.Core.ExportMain.cs 中的AddRegister函数中注册插件 25 | /// 由于托管环境限制和XQ插件缓存机制,更新插件后(无论之前是否加载成功)请重启XQ框架 26 | /// 27 | public class PluginExample : IPrivateMessage, IGroupMessage, IGroupEvent, IBeInvitedToGroup, IJoinGroupRequest, IAppEnable, IAppDisable, IPluginDestroy 28 | //举例 : 此处 PluginExample 的 IBeInvitedToGroup, IJoinGroupRequest 未在 XQ.Core.ExportMain.cs 中的AddRegister函数中注册,故不会被调用 29 | { 30 | //public static XqApi Api; 31 | 32 | public void GroupEvent(GroupEventEventArgs e) 33 | { 34 | switch (e.Type) //GroupEvent处理方式举例 35 | { 36 | case GroupEventEventType.SomeoneLeaveGroup: 37 | //e.FromGroup.SendGroupMessage("某人离开群聊。"); 38 | return; 39 | 40 | case GroupEventEventType.SomeoneBeRemovedFromGroup: 41 | //e.FromGroup.SendGroupMessage("某人被移除群聊。"); 42 | return; 43 | 44 | default: 45 | return; 46 | } 47 | } 48 | 49 | public void BeInvitedToGroupRequest(BeInvitedToGroupEventArgs e) 50 | { 51 | //e.Handle(GroupRequestHandlerType.Refuse); //举例: 机器人被邀请入群时,自动拒绝 52 | } 53 | 54 | public void JoinGroupRequest(JoinGroupRequestEventArgs e) 55 | { 56 | //e.Handle(GroupRequestHandlerType.Agree); //举例: 收到入群申请时,自动同意 57 | } 58 | 59 | public void GroupMessage(GroupMessageEventArgs e) //群聊消息处理方式举例 60 | { 61 | /* 62 | var image = ImageMessage.GetFromMessage(e.XqApi, e.Robot, e.Message); 63 | if (image?.Count != 0) 64 | e.FromGroup.SendGroupMessage(image?[0]); 65 | 66 | e.ReplyAsGroupMessage(false, PlainMessage.At(e.FromQq), e.Message); //复读消息 67 | 68 | e.XqApi.SendPrivateMessage( 69 | e.Robot, "123456789", PrivateMessageType.Friend, "", 70 | $"收到群{e.FromGroup}消息\n{e.Message}");//向某人发送消息 71 | e.Handler = false; //不允许低优先级插件处理 72 | */ 73 | } 74 | 75 | public void PrivateMessage(PrivateMessageEventArgs e) //私聊消息处理方式举例 76 | { 77 | //e.ReplyPrivateMessage("收到消息。"); 78 | } 79 | 80 | public void AppEnable(XqApi xqApi) //插件初始化 81 | //一般进行初始化操作 82 | //注意 此时QQ可能尚未登录 83 | { 84 | //Api = xqApi; //此处仅为举例:将XQApi用static变量保存,从而实现全局Api 85 | //File.ReadAllText(xqApi.GetConfigPath() + "loading.ini");//配置项路径获取举例 86 | } 87 | 88 | public void PluginDestroy(XqApi xqApi) //插件销毁 89 | { 90 | //在此函数内释放资源及线程 91 | } 92 | 93 | public void AppDisable(XqApi xqApi) 94 | { 95 | //在执行此处函数后会自动执行 PluginDestroy 函数 96 | //故一般建议只继承 IPluginDestroy 以简化插件流程 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /XQ.Plugin/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // 有关程序集的一般信息由以下 5 | // 控制。更改这些特性值可修改 6 | // 与程序集关联的信息。 7 | [assembly: AssemblyTitle("XQ.Plugin")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("XQ.Plugin")] 12 | [assembly: AssemblyCopyright("Copyright © 2021")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // 将 ComVisible 设置为 false 会使此程序集中的类型 17 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 18 | //请将此类型的 ComVisible 特性设置为 true。 19 | [assembly: ComVisible(true)] 20 | 21 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 22 | [assembly: Guid("517f57ee-4882-4054-a122-734903ba9ab3")] 23 | 24 | // 程序集的版本信息由下列四个值组成: 25 | // 26 | // 主版本 27 | // 次版本 28 | // 生成号 29 | // 修订号 30 | // 31 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 32 | //通过使用 "*",如下所示: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /XQ.Plugin/XQ.Plugin.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {517F57EE-4882-4054-A122-734903BA9AB3} 8 | Library 9 | Properties 10 | XQ.Plugin 11 | XQ.Plugin 12 | v4.7.2 13 | 512 14 | true 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x86\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x86 39 | 7.3 40 | prompt 41 | MinimumRecommendedRules.ruleset 42 | 43 | 44 | bin\x86\Release\ 45 | TRACE 46 | true 47 | pdbonly 48 | x86 49 | 7.3 50 | none 51 | MinimumRecommendedRules.ruleset 52 | false 53 | 54 | 55 | 48DB866E-4517-44DF-8EA5-516A2D0F10D8 56 | DllExport.dll 57 | System.Runtime.InteropServices 58 | true 59 | x86 60 | 1 61 | false 62 | false 63 | false 64 | 30000 65 | 2 66 | 67 | 68 | 69 | $(SolutionDir)packages\DllExport.1.6.1\gcache\metalib\$(DllExportNamespace)\$(DllExportMetaLibName) 70 | False 71 | False 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | {6b6664a8-e436-4b35-9040-8247de86ec89} 83 | XQ.SDK 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /XQ.SDK/Core/Expand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Text.RegularExpressions; 8 | 9 | using XQ.SDK.Interface; 10 | 11 | namespace XQ.SDK.Core 12 | { 13 | /// 14 | /// 扩展函数 15 | /// 16 | [SuppressMessage("ReSharper", "CommentTypo")] 17 | public static class Expand 18 | { 19 | private static readonly Lazy Reg = new Lazy(() => 20 | new Regex("( |\\[em\\](e[0-9]{1,6})\\[\\/em\\])", RegexOptions.IgnoreCase | RegexOptions.ECMAScript)); 21 | 22 | private static readonly Encoding Gb18030 = Encoding.GetEncoding("gb18030"); 23 | 24 | /// 25 | /// 将以换行符分割的string转换为list 26 | /// 27 | public static List SplitToList(this string str) 28 | { 29 | return str.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(i => i.Trim()).ToList(); 30 | } 31 | 32 | /// 33 | /// 将IntPtrToString中未转换的[em]exxxxxx[/em]转换为Emoji码 34 | /// 代码逻辑来自w4123/CQXQ 35 | /// 36 | private static string EmojiToSendString(this string msg) 37 | { 38 | var ret = new StringBuilder(); 39 | var last = 0; 40 | Match rslt; 41 | while ((rslt = Reg.Value.Match(msg.Substring(last))).Success) 42 | { 43 | var m = rslt.Groups; 44 | ret.Append(msg.Substring(last, m[0].Index)); 45 | if (m[0].Value[0] == '&') 46 | { 47 | ret.Append(" "); 48 | } 49 | else 50 | { 51 | var codePoint = int.Parse(m[2].Value.Substring(1)); 52 | if (codePoint > 200000) 53 | ret.Append( 54 | $"[emoji={Encoding.Convert(Encoding.UTF32, Encoding.UTF8, BitConverter.GetBytes(codePoint - 200000)).Aggregate("", (current, i) => current + i.ToString("X2"))}]"); 55 | else if (codePoint >= 100000) 56 | ret.Append($"[Face{codePoint - 100000}.gif]"); 57 | else 58 | ret.Append($"[pic=http://qzonestyle.gtimg.cn/qzone/em/{m[2].Value}.gif]"); 59 | } 60 | 61 | last += rslt.Index + rslt.Length; 62 | } 63 | 64 | ret.Append(msg.Substring(last)); 65 | return ret.ToString(); 66 | } 67 | 68 | /// 69 | /// 将Api返回的IntPtr转换为string和Emoji码 70 | /// 71 | public static string IntPtrToString(this IntPtr intPtr) 72 | { 73 | if (intPtr == IntPtr.Zero) return ""; 74 | try 75 | { 76 | var length = Marshal.ReadInt32(intPtr); 77 | if (length <= 0) return ""; 78 | var bin = new byte[length]; 79 | Marshal.Copy(IntPtr.Add(intPtr, 4), bin, 0, length); 80 | return EmojiToSendString(BytesToString(bin)); 81 | } 82 | finally 83 | { 84 | Kernel32.HeapFree(Kernel32.GetProcessHeap(), 0, intPtr); 85 | } 86 | } 87 | 88 | /// 89 | /// 将文本中的编码错位部分转换成Emoji码 90 | /// 91 | /// 要发送的消息 92 | /// 93 | private static string Utf8ToSendString(this string utf8String) 94 | { 95 | return BytesToString(Encoding.Convert(Encoding.UTF8, Gb18030, Encoding.UTF8.GetBytes(utf8String))); 96 | } 97 | 98 | private static string BytesToString(byte[] bin) 99 | { 100 | var length = bin.Length; 101 | if (length == 1) return Gb18030.GetString(bin); 102 | 103 | var sb = new StringBuilder(); 104 | for (var i = 0; i < length;) 105 | sb.Append(EncodingGetString(Gb18030, bin, 106 | ref i, bin[i] < 0x80 ? 1 : bin[i + 1] > 0x3F ? 2 : 4)); 107 | 108 | return sb.ToString(); 109 | } 110 | 111 | /// 112 | /// 使用Gb18030编码 113 | /// 114 | private static string EncodingGetString(Encoding encoding, byte[] bin, ref int index, int count) 115 | { 116 | index += count; 117 | 118 | return count < 4 119 | ? encoding.GetString(bin, index - count, count) 120 | : Encoding.Convert(encoding, Encoding.UTF8, 121 | bin.Skip(index - count).Take(4).ToArray()).Aggregate("[emoji=", (current, bi) 122 | => current + bi.ToString("X2")) + "]"; 123 | } 124 | 125 | /// 126 | /// 将对象转换为可发送的字符串, 如果待转换的对象继承自 将使用该接口的方法获取字符串 127 | /// 128 | /// 消息参数 129 | /// 可发送的字符串 130 | public static string ToSend(this object[] objects) 131 | { 132 | var builder = new StringBuilder(); 133 | foreach (var t in objects) 134 | switch (t) 135 | { 136 | case null: 137 | continue; 138 | case object[] objs: 139 | builder.Append(objs.ToSend()); 140 | break; 141 | case string str: 142 | builder.Append(str.Utf8ToSendString()); 143 | break; 144 | case IToSendString toSend: 145 | builder.Append(toSend.ToSendString().Utf8ToSendString()); 146 | break; 147 | default: 148 | builder.Append(t.ToString().Utf8ToSendString()); 149 | break; 150 | } 151 | 152 | return builder.ToString(); 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/Kernel32.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace XQ.SDK.Core 5 | { 6 | public class Kernel32 7 | { 8 | [DllImport("kernel32.dll", EntryPoint = "GetProcessHeap")] 9 | public static extern int GetProcessHeap(); 10 | 11 | [DllImport("kernel32.dll", EntryPoint = "HeapFree")] 12 | public static extern int HeapFree(int hheap, int dwflags, IntPtr lpmeem); 13 | } 14 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/NamedParameterOverloads.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace XQ.SDK.Core.TinyIOC 4 | { 5 | public sealed class NamedParameterOverloads : Dictionary 6 | { 7 | public static NamedParameterOverloads Default { get; } = new NamedParameterOverloads(); 8 | } 9 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/NamedResolutionFailureActions.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Core.TinyIOC 2 | { 3 | public enum NamedResolutionFailureActions 4 | { 5 | AttemptUnnamedResolution, 6 | Fail 7 | } 8 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/ResolveOptions.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Core.TinyIOC 2 | { 3 | public sealed class ResolveOptions 4 | { 5 | public UnregisteredResolutionActions UnregisteredResolutionAction { get; set; } = 6 | UnregisteredResolutionActions.AttemptResolve; 7 | 8 | public NamedResolutionFailureActions NamedResolutionFailureAction { get; set; } = 9 | NamedResolutionFailureActions.Fail; 10 | 11 | /// 12 | /// Gets the default options (attempt resolution of unregistered types, fail on named resolution if name not found) 13 | /// 14 | public static ResolveOptions Default { get; } = new ResolveOptions(); 15 | } 16 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/ReverseTypeExtender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Core.TinyIOC 4 | { 5 | internal static class ReverseTypeExtender 6 | { 7 | public static bool IsAbstract(this Type type) 8 | { 9 | return type.IsAbstract; 10 | } 11 | 12 | public static bool IsInterface(this Type type) 13 | { 14 | return type.IsInterface; 15 | } 16 | 17 | public static bool IsPrimitive(this Type type) 18 | { 19 | return type.IsPrimitive; 20 | } 21 | 22 | public static bool IsValueType(this Type type) 23 | { 24 | return type.IsValueType; 25 | } 26 | 27 | public static bool IsGenericType(this Type type) 28 | { 29 | return type.IsGenericType; 30 | } 31 | 32 | public static bool IsGenericTypeDefinition(this Type type) 33 | { 34 | return type.IsGenericTypeDefinition; 35 | } 36 | 37 | public static Type BaseType(this Type type) 38 | { 39 | return type.BaseType; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/SafeDictionary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | 6 | namespace XQ.SDK.Core.TinyIOC 7 | { 8 | public class SafeDictionary : IDisposable 9 | { 10 | private readonly Dictionary _dictionary = new Dictionary(); 11 | private readonly ReaderWriterLockSlim _padlock = new ReaderWriterLockSlim(); 12 | 13 | public TValue this[TKey key] 14 | { 15 | set 16 | { 17 | _padlock.EnterWriteLock(); 18 | 19 | try 20 | { 21 | if (_dictionary.TryGetValue(key, out var current)) 22 | if (current is IDisposable disposable) 23 | disposable.Dispose(); 24 | 25 | _dictionary[key] = value; 26 | } 27 | finally 28 | { 29 | _padlock.ExitWriteLock(); 30 | } 31 | } 32 | } 33 | 34 | public void Dispose() 35 | { 36 | _padlock.EnterWriteLock(); 37 | 38 | try 39 | { 40 | var disposableItems = from item in _dictionary.Values 41 | where item is IDisposable 42 | select item as IDisposable; 43 | 44 | foreach (var item in disposableItems) item.Dispose(); 45 | } 46 | finally 47 | { 48 | _padlock.ExitWriteLock(); 49 | } 50 | 51 | GC.SuppressFinalize(this); 52 | } 53 | 54 | 55 | public bool TryGetValue(TKey key, out TValue value) 56 | { 57 | _padlock.EnterReadLock(); 58 | try 59 | { 60 | return _dictionary.TryGetValue(key, out value); 61 | } 62 | finally 63 | { 64 | _padlock.ExitReadLock(); 65 | } 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/TinyIoCConstructorAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Core.TinyIOC 4 | { 5 | public sealed class TinyIoCConstructorAttribute : Attribute 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/TinyIoCRegistrationTypeException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Core.TinyIOC 4 | { 5 | [Serializable] 6 | public class TinyIoCRegistrationTypeException : Exception 7 | { 8 | private const string RegisterErrorText = 9 | "Cannot register type {0} - abstract classes or interfaces are not valid implementation types for {1}."; 10 | 11 | public TinyIoCRegistrationTypeException(Type type, string factory) 12 | : base(string.Format(RegisterErrorText, type.FullName, factory)) 13 | { 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/TinyIoCResolutionException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Core.TinyIOC 4 | { 5 | [Serializable] 6 | public class TinyIoCResolutionException : Exception 7 | { 8 | private const string ErrorText = "Unable to resolve type: {0}"; 9 | 10 | public TinyIoCResolutionException(Type type) 11 | : base(string.Format(ErrorText, type.FullName)) 12 | { 13 | } 14 | 15 | public TinyIoCResolutionException(Type type, Exception innerException) 16 | : base(string.Format(ErrorText, type.FullName), innerException) 17 | { 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | 5 | namespace XQ.SDK.Core.TinyIOC 6 | { 7 | public static class TypeExtensions 8 | { 9 | private static readonly SafeDictionary GenericMethodCache; 10 | 11 | static TypeExtensions() 12 | { 13 | GenericMethodCache = new SafeDictionary(); 14 | } 15 | 16 | /// 17 | /// Gets a generic method from a type given the method name, binding flags, generic types and parameter types 18 | /// 19 | /// Source type 20 | /// Binding flags 21 | /// Name of the method 22 | /// Generic types to use to make the method generic 23 | /// Method parameters 24 | /// MethodInfo or null if no matches found 25 | /// 26 | /// 27 | public static MethodInfo GetGenericMethod(this Type sourceType, BindingFlags bindingFlags, string methodName, 28 | Type[] genericTypes, Type[] parameterTypes) 29 | { 30 | var cacheKey = new GenericMethodCacheKey(sourceType, methodName, genericTypes, parameterTypes); 31 | 32 | // Shouldn't need any additional locking 33 | // we don't care if we do the method info generation 34 | // more than once before it gets cached. 35 | if (GenericMethodCache.TryGetValue(cacheKey, out var method)) return method; 36 | method = GetMethod(sourceType, bindingFlags, methodName, genericTypes, parameterTypes); 37 | GenericMethodCache[cacheKey] = method; 38 | 39 | return method; 40 | } 41 | 42 | private static MethodInfo GetMethod(Type sourceType, BindingFlags bindingFlags, string methodName, 43 | Type[] genericTypes, Type[] parameterTypes) 44 | { 45 | var validMethods = from method in sourceType.GetMethods(bindingFlags) 46 | where method.Name == methodName 47 | where method.IsGenericMethod 48 | where method.GetGenericArguments().Length == genericTypes.Length 49 | let genericMethod = method.MakeGenericMethod(genericTypes) 50 | where genericMethod.GetParameters().Count() == parameterTypes.Length 51 | where genericMethod.GetParameters().Select(pi => pi.ParameterType).SequenceEqual(parameterTypes) 52 | select genericMethod; 53 | 54 | var methods = validMethods.ToList(); 55 | 56 | if (methods.Count > 1) throw new AmbiguousMatchException(); 57 | 58 | return methods.FirstOrDefault(); 59 | } 60 | 61 | private sealed class GenericMethodCacheKey 62 | { 63 | private readonly Type[] _genericTypes; 64 | 65 | private readonly int _hashCode; 66 | 67 | private readonly string _methodName; 68 | 69 | private readonly Type[] _parameterTypes; 70 | private readonly Type _sourceType; 71 | 72 | public GenericMethodCacheKey(Type sourceType, string methodName, Type[] genericTypes, Type[] parameterTypes) 73 | { 74 | _sourceType = sourceType; 75 | _methodName = methodName; 76 | _genericTypes = genericTypes; 77 | _parameterTypes = parameterTypes; 78 | _hashCode = GenerateHashCode(); 79 | } 80 | 81 | public override bool Equals(object obj) 82 | { 83 | if (!(obj is GenericMethodCacheKey cacheKey)) 84 | return false; 85 | 86 | if (_sourceType != cacheKey._sourceType) 87 | return false; 88 | 89 | if (!string.Equals(_methodName, cacheKey._methodName, StringComparison.Ordinal)) 90 | return false; 91 | 92 | if (_genericTypes.Length != cacheKey._genericTypes.Length) 93 | return false; 94 | 95 | if (_parameterTypes.Length != cacheKey._parameterTypes.Length) 96 | return false; 97 | 98 | if (_genericTypes.Where((t, i) => t != cacheKey._genericTypes[i]).Any()) return false; 99 | 100 | return !_parameterTypes.Where((t, i) => t != cacheKey._parameterTypes[i]).Any(); 101 | } 102 | 103 | public override int GetHashCode() 104 | { 105 | return _hashCode; 106 | } 107 | 108 | private int GenerateHashCode() 109 | { 110 | unchecked 111 | { 112 | var result = _sourceType.GetHashCode(); 113 | 114 | result = (result * 397) ^ _methodName.GetHashCode(); 115 | 116 | result = _genericTypes.Aggregate(result, (current, t) => (current * 397) ^ t.GetHashCode()); 117 | 118 | return _parameterTypes.Aggregate(result, (current, t) => (current * 397) ^ t.GetHashCode()); 119 | } 120 | } 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /XQ.SDK/Core/TinyIOC/UnregisteredResolutionActions.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | 3 | namespace XQ.SDK.Core.TinyIOC 4 | { 5 | [SuppressMessage("ReSharper", "UnusedMember.Global")] 6 | public enum UnregisteredResolutionActions 7 | { 8 | /// 9 | /// Attempt to resolve type, even if the type isn't registered. 10 | /// Registered types/options will always take precedence. 11 | /// 12 | AttemptResolve, 13 | 14 | /// 15 | /// Fail resolution if type not explicitly registered 16 | /// 17 | Fail, 18 | 19 | /// 20 | /// Attempt to resolve unregistered type if requested type is generic 21 | /// and no registration exists for the specific generic parameters used. 22 | /// Registered types/options will always take precedence. 23 | /// 24 | GenericsOnly 25 | } 26 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/Event/FrameEventEventType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Enum.Event 4 | { 5 | /// 6 | /// XQ框架事件的EventType 7 | /// 8 | public enum FrameEventEventType 9 | { 10 | /// 11 | /// 框架启动完成 12 | /// 13 | FrameStarted = 10000, 14 | 15 | /// 16 | /// 框架即将关闭 17 | /// 请在 IAppDisable 接口进行处理 18 | /// 19 | [Obsolete] 20 | FrameClosing = 10001, 21 | 22 | /// 23 | /// 插件被点击 24 | /// 点击方式: 子类型: 1:左键单击 2:右键单击 3:左键双击 25 | /// 26 | PluginClicked = 12003 27 | } 28 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/Event/FriendEventEventType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Enum.Event 4 | { 5 | /// 6 | /// 好友、群临时事件对应的eventType 7 | /// 8 | public enum FriendEventEventType 9 | { 10 | /// 11 | /// 被单项添加为好友 12 | /// 13 | BeAddedAsOneWayFriend = 100, 14 | 15 | /// 16 | /// 某人请求加为好友 17 | /// 请在 IFriendAddRequest 接口进行处理 18 | /// 19 | [Obsolete] 20 | AddFriendRequest = 101, 21 | 22 | /// 23 | /// 被同意加为好友 24 | /// 25 | FriendAddRequestPermitted = 102, 26 | 27 | /// 28 | /// 被拒绝加为好友 29 | /// 30 | FriendAddRequestDenied = 103, 31 | 32 | /// 33 | /// 被删除好友 34 | /// 35 | BeDeletedByFriend = 104, 36 | 37 | /// 38 | /// 好友离线文件接收 39 | /// 40 | FriendOfflineFileReceive = 105, 41 | 42 | /// 43 | /// 好友签名变更 44 | /// 45 | FriendSignatureChanged = 106, 46 | 47 | /// 48 | /// 说说被某人评论 49 | /// 50 | QZoneCommented = 107, 51 | 52 | /// 53 | /// 好友视频接收 54 | /// 55 | ReceiveFriendVideo = 108, 56 | 57 | /// 58 | /// 被好友抖动 59 | /// 60 | ShakedByFriend = 109, 61 | 62 | /// 63 | /// 群临时文件接收 64 | /// 65 | ReceiveTempGroupFile = 110, 66 | 67 | /// 68 | /// 群临时视频接收 69 | /// 70 | ReceiveTempGroupVideo = 111 71 | } 72 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/Event/GroupEventEventType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Enum.Event 4 | { 5 | /// 6 | /// 群事件对应的eventType 7 | /// 8 | public enum GroupEventEventType 9 | { 10 | /// 11 | /// 某人离开了群聊 12 | /// 13 | SomeoneLeaveGroup = 201, 14 | 15 | /// 16 | /// 某人被管理移除群 17 | /// 18 | SomeoneBeRemovedFromGroup = 202, 19 | 20 | /// 21 | /// 某人被禁言 22 | /// 23 | SomeoneBeBannedSpeaking = 203, 24 | 25 | /// 26 | /// 某人被解除禁言 27 | /// 28 | SomeoneBeUnBannedSpeaking = 204, 29 | 30 | /// 31 | /// 开启全群禁言 32 | /// 33 | GroupBannedSpeaking = 205, 34 | 35 | /// 36 | /// 关闭全群禁言 37 | /// 38 | GroupUnBannedSpeaking = 206, 39 | 40 | /// 41 | /// 开启匿名聊天 42 | /// 43 | AnonymousModeTurnedOn = 207, 44 | 45 | /// 46 | /// 关闭匿名聊天 47 | /// 48 | AnonymousModeTurnedOff = 208, 49 | 50 | /// 51 | /// 群公告变动 52 | /// 53 | GroupAnnouncementChanged = 209, 54 | 55 | /// 56 | /// 某人成为管理 57 | /// 58 | AdminListNumIncrease = 210, 59 | 60 | /// 61 | /// 某人被取消管理 62 | /// 63 | AdminListNumDecrease = 211, 64 | 65 | /// 66 | /// 某人被批准加入群 67 | /// 68 | AllowedJoinGroup = 212, 69 | 70 | /// 71 | /// 某人申请入群 72 | /// 请在 IJoinGroupRequest 接口进行处理 73 | /// 74 | [Obsolete] 75 | JoinGroupRequest = 213, 76 | 77 | /// 78 | /// Robot被邀请入群 79 | /// 请在 IGroupAddRequest 接口进行处理 80 | /// 81 | [Obsolete] 82 | RobotBeInvitedToGroup = 214, 83 | 84 | /// 85 | /// 某人被邀请入群 86 | /// 请在 IJoinGroupRequest 接口进行处理 87 | /// 88 | [Obsolete] 89 | SomeoneBeInvitedToGroup = 215, 90 | 91 | /// 92 | /// 某群被解散 93 | /// 94 | GroupDissolved = 216, 95 | 96 | /// 97 | /// 群名片变动 98 | /// 99 | GroupCardChanged = 217, 100 | 101 | /// 102 | /// 群文件接收 103 | /// 104 | RecieveGroupFile = 218, 105 | 106 | /// 107 | /// 某人被群主或管理员邀请并且进入了群(或100以内免审核) 108 | /// 109 | SomeoneHasBeenInvitedIntoGroupByAdminOrOwner = 219, 110 | 111 | /// 112 | /// 群名称变动 113 | /// 114 | GroupNameChanged = 220, 115 | 116 | /// 117 | /// 被拒绝入群 118 | /// 119 | JoinGroupRequestRefused = 221, 120 | 121 | /// 122 | /// 群视频接收 123 | /// 124 | RecieveGroupVideo = 222 125 | } 126 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/Event/RobotEventEventType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum.Event 2 | { 3 | /// 4 | /// Robot事件事件的EventType 5 | /// 6 | public enum RobotEventEventType 7 | { 8 | /// 9 | /// 列表添加了新帐号 10 | /// 11 | RobotNewAccount = 1100, 12 | 13 | /// 14 | /// QQ登录完成 15 | /// 16 | RobotLoggedIn = 1101, 17 | 18 | /// 19 | /// QQ被手动离线 20 | /// 21 | RobotManualOffline = 1102, 22 | 23 | /// 24 | /// QQ被强制离线 25 | /// 26 | RobotForcedOffline = 1103, 27 | 28 | /// 29 | /// QQ掉线 30 | /// 31 | RobotOffline = 1104, 32 | 33 | /// 34 | /// QQ二次数据缓存完成 35 | /// 36 | RobotSecondaryDataBuffered = 1105, 37 | 38 | /// 39 | /// QQ登录需要令牌 40 | /// 41 | RobotNeedTokenVerify = 1106, 42 | 43 | /// 44 | /// QQ登录需要短信 45 | /// 46 | RobotNeedSmsVerify = 1107, 47 | 48 | /// 49 | /// QQ登录失败 50 | /// 51 | RobotLoginFailed = 1108 52 | } 53 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/FriendAddRequestType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// 好友请求的QQ处理方式 5 | /// 6 | public enum FriendAddRequestType 7 | { 8 | /// 9 | /// 允许任何人 10 | /// 11 | Anyone = 0, 12 | 13 | /// 14 | /// 需要验证消息 15 | /// 16 | NeedValidate = 1, 17 | 18 | /// 19 | /// 不允许任何人 20 | /// 21 | Nobody = 2, 22 | 23 | /// 24 | /// 需要正确回答问题 25 | /// 26 | NeedAnswerQuestionCorrectly = 3, 27 | 28 | /// 29 | /// 需要回答问题并由我确认 30 | /// 31 | NeedAnswerQuestionAndValidate = 4 32 | } 33 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/FriendRequestHandlerType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// 处理加好友请求类型 5 | /// 6 | public enum FriendRequestHandlerType 7 | { 8 | /// 9 | /// 同意 10 | /// 11 | Agree = 10, 12 | 13 | /// 14 | /// 拒绝 15 | /// 16 | Refuse = 20, 17 | 18 | /// 19 | /// 忽略 20 | /// 21 | Ingore = 30, 22 | 23 | /// 24 | /// 同意被单项加为好友 25 | /// 26 | AgreeAsOneWayFriend = 40 27 | } 28 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/GroupRequestHandlerType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// 处理加群请求类型 5 | /// 6 | public enum GroupRequestHandlerType 7 | { 8 | /// 9 | /// 同意 10 | /// 11 | Agree = 10, 12 | 13 | /// 14 | /// 拒绝 15 | /// 16 | Refuse = 20, 17 | 18 | /// 19 | /// 忽略 20 | /// 21 | Ingore = 30 22 | } 23 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/ImageMessageType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// 图片消息的来源 5 | /// 6 | public enum ImageMessageType 7 | { 8 | /// 9 | /// 来自文件 10 | /// 11 | FromFile = 0, 12 | 13 | /// 14 | /// 来自Url 15 | /// 16 | FromWebUrl = 1, 17 | 18 | /// 19 | /// 来自收到的消息 20 | /// 21 | FromMessage = 2 22 | } 23 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/MessageType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Enum 4 | { 5 | /// 6 | /// 消息类型 7 | /// 8 | public enum MessageType 9 | { 10 | /// 11 | /// 未定义 12 | /// 13 | Undefined = -1, 14 | 15 | /// 16 | /// 在线状态临时会话 17 | /// 18 | TempOnlineSession = 0, 19 | 20 | /// 21 | /// 好友私聊消息 22 | /// 23 | Friend = 1, 24 | 25 | /// 26 | /// 群消息 27 | /// 28 | Group = 2, 29 | 30 | /// 31 | /// 讨论组 32 | /// 33 | [Obsolete] Discuss = 3, 34 | 35 | /// 36 | /// 来自群的临时消息 37 | /// 38 | TempGroupMessage = 4, 39 | 40 | /// 41 | /// 来自讨论组的临时消息 42 | /// 43 | [Obsolete] TempDiscussMessage = 5, 44 | 45 | /// 46 | /// 收到财付通转账 47 | /// 48 | Transfer = 6, 49 | 50 | /// 51 | /// 来自好友验证的对话消息 52 | /// 53 | AddFriendReply = 7, 54 | 55 | /// 56 | /// 其他客户端发来消息 57 | /// 58 | MessageFromOtherClient = 8, 59 | 60 | /// 61 | /// 消息被撤回 62 | /// 子类型 1:好友,2:群 63 | /// 64 | MsgWithdrawn = 9, 65 | 66 | /// 67 | /// 群回音消息 68 | /// 69 | GroupEchoMsg = 10 70 | } 71 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/OnlineStatusType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// QQ在线状态类型 5 | /// 6 | public enum OnlineStatusType 7 | { 8 | /// 9 | /// 我在线上 10 | /// 11 | Online = 1, 12 | 13 | /// 14 | /// Q我吧 15 | /// 16 | QMe = 2, 17 | 18 | /// 19 | /// 离开 20 | /// 21 | Leave = 3, 22 | 23 | /// 24 | /// 忙碌 25 | /// 26 | Busy = 4, 27 | 28 | /// 29 | /// 请勿打扰 30 | /// 31 | DoNotDisturb = 5, 32 | 33 | /// 34 | /// 隐身 35 | /// 36 | Stealth = 6 37 | } 38 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/PrivateMessageType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Enum 4 | { 5 | /// 6 | /// 私聊消息类型 7 | /// 8 | public enum PrivateMessageType 9 | { 10 | /// 11 | /// 在线状态临时会话 12 | /// 13 | TempOnlineSession = 0, 14 | 15 | /// 16 | /// 好友私聊消息 17 | /// 18 | Friend = 1, 19 | 20 | /// 21 | /// 来自群的临时消息 22 | /// 23 | TempGroupMessage = 4, 24 | 25 | /// 26 | /// 来自讨论组的临时消息 27 | /// 28 | [Obsolete] TempDiscussMessage = 5, 29 | 30 | /// 31 | /// 来自好友验证的对话消息 32 | /// 33 | AddFriendReply = 7 34 | } 35 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/QqSex.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// QQ性别类型 5 | /// 6 | public enum QqSex 7 | { 8 | /// 9 | /// 男 10 | /// 11 | Male = 1, 12 | 13 | /// 14 | /// 女 15 | /// 16 | Female = 2, 17 | 18 | /// 19 | /// 未知 20 | /// 21 | Unknown = 255 22 | } 23 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/ShowPicType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// 秀图特效类型 5 | /// 6 | public enum ShowPicType 7 | { 8 | /// 9 | /// 无特效 10 | /// 11 | None = 0, 12 | 13 | /// 14 | /// 抖动特效 15 | /// 16 | Shake = 1, 17 | 18 | /// 19 | /// 幻影特效 20 | /// 21 | Mirage = 2, 22 | 23 | /// 24 | /// 生日特效 25 | /// 26 | Birthday = 3, 27 | 28 | /// 29 | /// 爱你特效 30 | /// 31 | Love = 4, 32 | 33 | /// 34 | /// 征友特效 35 | /// 36 | SeekFriend = 5 37 | } 38 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/WithdrawMessageType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// 被撤回的消息来源 5 | /// 6 | public enum WithdrawMessageType 7 | { 8 | /// 9 | /// 私聊 10 | /// 11 | Friend = 1, 12 | 13 | /// 14 | /// 群聊或讨论组 15 | /// 16 | Group = 2 17 | } 18 | } -------------------------------------------------------------------------------- /XQ.SDK/Enum/XqEventReturnType.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Enum 2 | { 3 | /// 4 | /// XQEvent的返回值类型 5 | /// 6 | public enum XqEventReturnType 7 | { 8 | /// 9 | /// 忽略,允许优先级较低的其他插件继续处理 10 | /// 11 | Ignore = 1, 12 | 13 | /// 14 | /// 拦截,不允许优先级较低的其他插件处理 15 | /// 16 | Intercept = 2 17 | } 18 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/BeInvitedToGroupEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Enum; 2 | using XQ.SDK.Model; 3 | using XQ.SDK.XQ; 4 | 5 | namespace XQ.SDK.EventArgs 6 | { 7 | /// 8 | /// 被邀请入群事件 9 | /// 对应IBeInvitedToGroup接口 10 | /// 11 | public class BeInvitedToGroupEventArgs : GroupEventEventArgs 12 | { 13 | /// 14 | /// 事件构造函数 15 | /// 16 | /// XQApi 17 | /// XQEvent的原始参数 18 | public BeInvitedToGroupEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 19 | { 20 | } 21 | 22 | /// 23 | /// 处理邀请加群请求 24 | /// 25 | /// 处理类型 26 | /// 拒绝时可填写拒绝理由 27 | public void Handle(GroupRequestHandlerType type, string refuseMessage = "") 28 | { 29 | XqApi.HandleGroupEvent(Robot, 214, FromQq, FromGroup, RawEvent.Udpmsg, type, 30 | refuseMessage); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/FrameEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using XQ.SDK.Enum.Event; 3 | using XQ.SDK.Model; 4 | using XQ.SDK.XQ; 5 | 6 | namespace XQ.SDK.EventArgs 7 | { 8 | /// 9 | /// 框架事件 10 | /// 对应IFrameEvent接口 11 | /// 12 | public class FrameEventArgs : XqEventArgs 13 | { 14 | /// 15 | /// 事件构造函数 16 | /// 17 | /// XQApi 18 | /// XQEvent的原始参数 19 | public FrameEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 20 | { 21 | } 22 | 23 | /// 24 | /// 框架事件类型 25 | /// 26 | public FrameEventEventType Type => 27 | System.Enum.IsDefined(typeof(FrameEventEventType), RawEvent.EventType) 28 | ? (FrameEventEventType) RawEvent.EventType 29 | : throw new ArgumentException("type不正确"); 30 | } 31 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/FriendAddRequestEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Enum; 2 | using XQ.SDK.Model; 3 | using XQ.SDK.XQ; 4 | 5 | namespace XQ.SDK.EventArgs 6 | { 7 | /// 8 | /// 好友添加请求事件 9 | /// 对应IFriendAddRequest接口 10 | /// 11 | public class FriendAddRequestEventArgs : FriendEventArgs 12 | { 13 | /// 14 | /// 事件构造函数 15 | /// 16 | /// XQApi 17 | /// XQEvent的原始参数 18 | public FriendAddRequestEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 19 | { 20 | } 21 | 22 | /// 23 | /// 处理好友添加请求 24 | /// 25 | /// 处理类型 26 | /// 拒绝时可填写拒绝理由 27 | public void Handle(FriendRequestHandlerType type, string refuseMessage = "") 28 | { 29 | XqApi.HandleFriendEvent(Robot, FromQq, type, refuseMessage); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/FriendEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using XQ.SDK.Enum; 3 | using XQ.SDK.Enum.Event; 4 | using XQ.SDK.Model; 5 | using XQ.SDK.XQ; 6 | 7 | namespace XQ.SDK.EventArgs 8 | { 9 | /// 10 | /// 好友、群临时事件接口 11 | /// 12 | public class FriendEventArgs : XqEventArgs 13 | { 14 | /// 15 | /// 事件构造函数 16 | /// 17 | /// XQApi 18 | /// XQEvent的原始参数 19 | public FriendEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 20 | { 21 | } 22 | 23 | /// 24 | /// 事件来源QQ 25 | /// 26 | public Qq FromQq => string.IsNullOrWhiteSpace(RawEvent.FromQq) 27 | ? null 28 | : new Qq(XqApi, Robot, RawEvent.FromQq, MessageType.Friend, null); 29 | 30 | /// 31 | /// 事件类型 32 | /// 33 | public FriendEventEventType Type => 34 | System.Enum.IsDefined(typeof(FriendEventEventType), RawEvent.EventType) 35 | ? (FriendEventEventType) RawEvent.EventType 36 | : throw new ArgumentException("type不正确"); 37 | } 38 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/GroupEchoMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Enum; 2 | using XQ.SDK.Model; 3 | using XQ.SDK.XQ; 4 | 5 | namespace XQ.SDK.EventArgs 6 | { 7 | /// 8 | /// 群回音消息事件 9 | /// 对应IGroupEchoMessage接口 10 | /// 11 | public class GroupEchoMessageEventArgs : XqEventArgs 12 | { 13 | /// 14 | /// 事件构造函数 15 | /// 16 | /// XQApi 17 | /// XQEvent的原始参数 18 | public GroupEchoMessageEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 19 | { 20 | } 21 | 22 | /// 23 | /// 事件来源群聊 24 | /// 25 | public Group FromGroup => 26 | string.IsNullOrWhiteSpace(RawEvent.From) ? null : new Group(XqApi, Robot, RawEvent.From); 27 | 28 | /// 29 | /// 撤回消息 30 | /// 31 | public void WithdrawMessage() 32 | { 33 | XqApi.WithdrawMsg(Robot, MessageType.Group, FromGroup, Robot, RawEvent.Index, RawEvent.Msgid, 34 | RawEvent.Unix); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/GroupEventEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using XQ.SDK.Enum; 3 | using XQ.SDK.Enum.Event; 4 | using XQ.SDK.Model; 5 | using XQ.SDK.XQ; 6 | 7 | namespace XQ.SDK.EventArgs 8 | { 9 | /// 10 | /// 群聊事件事件 11 | /// 对应IGroupEvent接口 12 | /// 13 | public class GroupEventEventArgs : XqEventArgs 14 | { 15 | /// 16 | /// 事件构造函数 17 | /// 18 | /// XQApi 19 | /// XQEvent的原始参数 20 | public GroupEventEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 21 | { 22 | } 23 | 24 | /// 25 | /// 事件来源QQ 26 | /// 27 | public Qq FromQq => string.IsNullOrWhiteSpace(RawEvent.FromQq) 28 | ? null 29 | : new Qq(XqApi, Robot, RawEvent.FromQq, MessageType.Group, RawEvent.From); 30 | 31 | /// 32 | /// 事件目标QQ 33 | /// 34 | public Qq TargetQq => string.IsNullOrWhiteSpace(RawEvent.TargetQq) 35 | ? null 36 | : new Qq(XqApi, Robot, RawEvent.TargetQq, MessageType.Group, RawEvent.From); 37 | 38 | /// 39 | /// 事件来源群聊 40 | /// 41 | public Group FromGroup => 42 | string.IsNullOrWhiteSpace(RawEvent.From) ? null : new Group(XqApi, Robot, RawEvent.From); 43 | 44 | /// 45 | /// 事件类型 46 | /// 47 | public GroupEventEventType Type => 48 | System.Enum.IsDefined(typeof(GroupEventEventType), RawEvent.EventType) 49 | ? (GroupEventEventType) RawEvent.EventType 50 | : throw new ArgumentException("type不正确"); 51 | } 52 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/GroupMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Enum; 2 | using XQ.SDK.Model; 3 | using XQ.SDK.Model.MessageObject; 4 | using XQ.SDK.XQ; 5 | 6 | namespace XQ.SDK.EventArgs 7 | { 8 | /// 9 | /// 群消息事件 10 | /// 对应IGroupMessage接口 11 | /// 12 | public class GroupMessageEventArgs : XqMessageEventArgs 13 | { 14 | /// 15 | /// 事件构造函数 16 | /// 17 | /// XQApi 18 | /// XQEvent的原始参数 19 | public GroupMessageEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 20 | { 21 | } 22 | 23 | /// 24 | /// 事件来源群聊 25 | /// 26 | public Group FromGroup => 27 | string.IsNullOrWhiteSpace(RawEvent.From) ? null : new Group(XqApi, Robot, RawEvent.From); 28 | 29 | /// 30 | /// 撤回此条消息 31 | /// 32 | public void WithdrawMessage() => 33 | XqApi.WithdrawMsg(Robot, MessageType.Group, FromGroup, FromQq, RawEvent.Index, 34 | RawEvent.Msgid, RawEvent.Unix); 35 | 36 | /// 37 | /// 群聊回复消息 38 | /// 39 | /// 选择是否at 40 | /// 要发送的消息 41 | public void ReplyAsGroupMessage(bool at, params object[] msg) 42 | { 43 | FromGroup.SendGroupMessage(at ? PlainMessage.At(FromQq) + "\n" : null, msg); 44 | } 45 | 46 | /// 47 | /// 私聊回复消息 48 | /// 49 | /// 要发送的消息 50 | public void ReplyAsPrivateMessage(params object[] msg) 51 | { 52 | FromQq.SendPrivateMessage(msg); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/JoinGroupRequestEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Enum; 2 | using XQ.SDK.Model; 3 | using XQ.SDK.XQ; 4 | 5 | namespace XQ.SDK.EventArgs 6 | { 7 | /// 8 | /// 申请入群事件 9 | /// 对应IJoinGroupRequest接口 10 | /// 11 | public class JoinGroupRequestEventArgs : GroupEventEventArgs 12 | { 13 | /// 14 | /// 事件构造函数 15 | /// 16 | /// XQApi 17 | /// XQEvent的原始参数 18 | public JoinGroupRequestEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 19 | { 20 | } 21 | 22 | /// 23 | /// 处理申请入群请求 24 | /// 25 | /// 处理类型 26 | /// 拒绝时可填写拒绝理由 27 | public void Handle(GroupRequestHandlerType type, string refuseMessage = "") 28 | { 29 | XqApi.HandleGroupEvent(Robot, (int)Type, FromQq, FromGroup, RawEvent.Udpmsg, type, 30 | refuseMessage); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/PrivateMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Enum; 2 | using XQ.SDK.Model; 3 | using XQ.SDK.XQ; 4 | 5 | namespace XQ.SDK.EventArgs 6 | { 7 | /// 8 | /// 私聊消息事件 9 | /// 对应IPrivateMessage接口 10 | /// 11 | public class PrivateMessageEventArgs : XqMessageEventArgs 12 | { 13 | /// 14 | /// 事件构造函数 15 | /// 16 | /// XQApi 17 | /// XQEvent的原始参数 18 | public PrivateMessageEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 19 | { 20 | } 21 | 22 | /// 23 | /// 事件类型 24 | /// 25 | public new PrivateMessageType Type => (PrivateMessageType) RawEvent.EventType; 26 | 27 | /// 28 | /// 回复私聊消息 29 | /// 30 | /// 31 | public void ReplyPrivateMessage(params object[] msg) 32 | { 33 | FromQq.SendPrivateMessage(msg); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/RobotEventEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using XQ.SDK.Enum.Event; 3 | using XQ.SDK.Model; 4 | using XQ.SDK.XQ; 5 | 6 | namespace XQ.SDK.EventArgs 7 | { 8 | /// 9 | /// 框架Robot事件事件 10 | /// 对应IRobotEvent接口 11 | /// 12 | public class RobotEventEventArgs : XqEventArgs 13 | { 14 | /// 15 | /// 事件构造函数 16 | /// 17 | /// XQApi 18 | /// XQEvent的原始参数 19 | public RobotEventEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 20 | { 21 | } 22 | 23 | /// 24 | /// 事件类型 25 | /// 26 | public RobotEventEventType Type => 27 | System.Enum.IsDefined(typeof(RobotEventEventType), RawEvent.EventType) 28 | ? (RobotEventEventType) RawEvent.EventType 29 | : throw new ArgumentException("type不正确"); 30 | } 31 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/TransferEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Model; 2 | using XQ.SDK.XQ; 3 | 4 | namespace XQ.SDK.EventArgs 5 | { 6 | /// 7 | /// 收到财付通转账事件 8 | /// 对应ITransfer接口 9 | /// 10 | public class TransferEventArgs : FriendEventArgs 11 | { 12 | /// 13 | /// 事件构造函数 14 | /// 15 | /// XQApi 16 | /// XQEvent的原始参数 17 | public TransferEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/WithDrawMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Enum; 2 | using XQ.SDK.Model; 3 | using XQ.SDK.XQ; 4 | 5 | namespace XQ.SDK.EventArgs 6 | { 7 | /// 8 | /// 撤回消息事件 9 | /// 对应IWithDrawMessage接口 10 | /// 11 | public class WithDrawMessageEventArgs : XqMessageEventArgs 12 | { 13 | /// 14 | /// 事件构造函数 15 | /// 16 | /// XQApi 17 | /// XQEvent的原始参数 18 | public WithDrawMessageEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 19 | { 20 | } 21 | 22 | /// 23 | /// 事件类型 24 | /// 25 | public new WithdrawMessageType Type => (WithdrawMessageType) RawEvent.ExtraType; 26 | } 27 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/XqEventArgs.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Model; 2 | using XQ.SDK.XQ; 3 | 4 | namespace XQ.SDK.EventArgs 5 | { 6 | /// 7 | /// XQ事件的抽象基类 8 | /// 对应IXqEvent接口 9 | /// 10 | public abstract class XqEventArgs 11 | { 12 | /// 13 | /// 事件构造函数 14 | /// 15 | /// XQApi 16 | /// XQEvent的原始参数 17 | protected XqEventArgs(XqApi xqApi, XqRawEvent rawEvent) 18 | { 19 | XqApi = xqApi; 20 | RawEvent = rawEvent; 21 | } 22 | 23 | /// 24 | /// 获取XQApi 25 | /// 26 | public XqApi XqApi { get; } 27 | 28 | /// 29 | /// 获取XQEvent的原始参数 30 | /// 31 | public XqRawEvent RawEvent { get; } 32 | 33 | /// 34 | /// 获取或设置一个值, 指示该事件是否允许其他插件处理 35 | /// 36 | public bool Handler { get; set; } 37 | 38 | /// 39 | /// 获取接收到当前事件的Robot实例 40 | /// 部分事件中为null 41 | /// 42 | public Robot Robot => string.IsNullOrWhiteSpace(RawEvent.RobotQq) ? null : new Robot(XqApi, RawEvent.RobotQq); 43 | } 44 | } -------------------------------------------------------------------------------- /XQ.SDK/EventArgs/XqMessageEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using XQ.SDK.Enum; 3 | using XQ.SDK.Model; 4 | using XQ.SDK.XQ; 5 | 6 | namespace XQ.SDK.EventArgs 7 | { 8 | public abstract class XqMessageEventArgs : XqEventArgs 9 | { 10 | /// 11 | /// 事件构造函数 12 | /// 13 | /// XQApi 14 | /// XQEvent的原始参数 15 | protected XqMessageEventArgs(XqApi xqApi, XqRawEvent rawEvent) : base(xqApi, rawEvent) 16 | { 17 | } 18 | 19 | /// 20 | /// 事件来源QQ 21 | /// 22 | public Qq FromQq => string.IsNullOrWhiteSpace(RawEvent.FromQq) 23 | ? null 24 | : new Qq(XqApi, Robot, RawEvent.FromQq, Type, RawEvent.From, RawEvent.ExtraType); 25 | 26 | /// 27 | /// 事件消息 28 | /// 29 | public QqMessage Message => new QqMessage(XqApi, Robot, RawEvent.Content); 30 | 31 | /// 32 | /// 事件类型 33 | /// 34 | public MessageType Type => 35 | System.Enum.IsDefined(typeof(MessageType), RawEvent.EventType) 36 | ? (MessageType) RawEvent.EventType 37 | : throw new ArgumentException("type不正确"); 38 | } 39 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IAppDisable.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.XQ; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 应用关闭事件接口 7 | /// 8 | public interface IAppDisable : IXqEvent 9 | { 10 | /// 11 | /// 处理应用关闭事件 12 | /// 13 | void AppDisable(XqApi xqApi); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IAppEnable.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.XQ; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 应用初始化事件接口 7 | /// 8 | public interface IAppEnable : IXqEvent 9 | { 10 | /// 11 | /// 处理应用初始化事件 12 | /// 13 | void AppEnable(XqApi xqApi); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IBeInvitedToGroup.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 被邀请入群事件接口 7 | /// 8 | public interface IBeInvitedToGroup : IXqEvent 9 | { 10 | /// 11 | /// 处理被邀请入群事件 12 | /// 13 | void BeInvitedToGroupRequest(BeInvitedToGroupEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/ICallMenu.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.XQ; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 调用菜单事件接口 7 | /// 8 | public interface ICallMenu : IXqEvent 9 | { 10 | /// 11 | /// 处理调用菜单事件 12 | /// 13 | void CallMenu(XqApi xqApi); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IFrameEvent.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 框架事件接口 7 | /// 8 | public interface IFrameEvent : IXqEvent 9 | { 10 | /// 11 | /// 处理框架事件 12 | /// 13 | void FrameEvent(FrameEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IFriendAddRequest.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 好友添加请求事件接口 7 | /// 8 | public interface IFriendAddRequest : IXqEvent 9 | { 10 | /// 11 | /// 处理好友添加请求事件 12 | /// 13 | void FriendAddRequest(FriendAddRequestEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IFriendEvent.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 好友、群临时事件接口 7 | /// 8 | public interface IFriendEvent : IXqEvent 9 | { 10 | /// 11 | /// 处理好友、群临时事件 12 | /// 13 | void FriendEvent(FriendEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IGroupEchoMessage.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 群回音消息事件接口 7 | /// 8 | public interface IGroupEchoMessage : IXqEvent 9 | { 10 | /// 11 | /// 处理群回音消息事件 12 | /// 13 | void GroupEchoMessage(GroupEchoMessageEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IGroupEvent.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 群聊事件事件接口 7 | /// 8 | public interface IGroupEvent : IXqEvent 9 | { 10 | /// 11 | /// 处理群聊事件事件 12 | /// 13 | void GroupEvent(GroupEventEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IGroupMessage.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 群聊消息事件接口 7 | /// 8 | public interface IGroupMessage : IXqEvent 9 | { 10 | /// 11 | /// 处理群聊消息事件 12 | /// 13 | void GroupMessage(GroupMessageEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IJoinGroupRequest.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 申请入群事件接口 7 | /// 8 | public interface IJoinGroupRequest : IXqEvent 9 | { 10 | /// 11 | /// 处理申请入群事件 12 | /// 13 | void JoinGroupRequest(JoinGroupRequestEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IPluginDestroy.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.XQ; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 插件实例销毁事件接口 7 | /// 8 | public interface IPluginDestroy : IXqEvent 9 | { 10 | /// 11 | /// 处理插件实例销毁事件 12 | /// 应在此函数内释放资源及线程 13 | /// 14 | void PluginDestroy(XqApi xqApi); 15 | } 16 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IPrivateMessage.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 私聊消息事件接口 7 | /// 8 | public interface IPrivateMessage : IXqEvent 9 | { 10 | /// 11 | /// 处理私聊消息事件 12 | /// 13 | void PrivateMessage(PrivateMessageEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IRobotEvent.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 框架Robot事件事件接口 7 | /// 8 | public interface IRobotEvent : IXqEvent 9 | { 10 | /// 11 | /// 处理框架Robot相关事件 12 | /// 13 | void RobotEvent(RobotEventEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/ITransfer.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 收到财付通转账事件接口 7 | /// 8 | public interface ITransfer : IXqEvent 9 | { 10 | /// 11 | /// 处理收到财付通转账事件 12 | /// 13 | void Transfer(TransferEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/Event/IWithDrawMessage.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.EventArgs; 2 | 3 | namespace XQ.SDK.Interface 4 | { 5 | /// 6 | /// 撤回消息事件接口 7 | /// 8 | public interface IWithDrawMessage : IXqEvent 9 | { 10 | /// 11 | /// 处理撤回消息事件 12 | /// 13 | void WithDrawMessage(WithDrawMessageEventArgs e); 14 | } 15 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/IToSendString.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Interface 2 | { 3 | /// 4 | /// 将抽象Message转换为string的接口 5 | /// 6 | public interface IToSendString 7 | { 8 | /// 9 | /// 将抽象Message转换为string 10 | /// 11 | string ToSendString(); 12 | } 13 | } -------------------------------------------------------------------------------- /XQ.SDK/Interface/IXqEvent.cs: -------------------------------------------------------------------------------- 1 | namespace XQ.SDK.Interface 2 | { 3 | /// 4 | /// 事件接口的抽象接口 5 | /// 对应XqEventArgs 6 | /// 7 | public interface IXqEvent 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/BasisModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using XQ.SDK.XQ; 3 | 4 | namespace XQ.SDK.Model 5 | { 6 | /// 7 | /// 描述XQ模型的基础抽象类 8 | /// 9 | public abstract class BasisModel 10 | { 11 | /// 参数: api 为 null 12 | protected BasisModel(XqApi api, string robot) 13 | { 14 | XqApi = api ?? throw new ArgumentNullException(nameof(api)); 15 | Robot = new Robot(api, robot); 16 | } 17 | 18 | public XqApi XqApi { get; } 19 | 20 | public Robot Robot { get; } 21 | } 22 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Group.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using XQ.SDK.Enum; 4 | using XQ.SDK.Model.Json; 5 | using XQ.SDK.XQ; 6 | 7 | namespace XQ.SDK.Model 8 | { 9 | /// 10 | /// 事件中的来源群 11 | /// 12 | public class Group : BasisModel 13 | { 14 | private List _adminList; 15 | 16 | private List _groupmemberlist; 17 | 18 | private string _name; 19 | 20 | private Qq _owner; 21 | 22 | public Group(XqApi api, string robotqq, string id) : base(api, robotqq) 23 | { 24 | Id = id; 25 | } 26 | 27 | public Group(XqApi api, string robotqq, GroupInfoJson info) : base(api, robotqq) 28 | { 29 | Id = info.Id; 30 | _name = info.Name; 31 | _owner = new Qq(api, robotqq, info.Owner, MessageType.Group, info.Id); 32 | } 33 | 34 | /// 35 | /// QQ群号 36 | /// 37 | public string Id { get; } 38 | 39 | /// 40 | /// QQ群名称 41 | /// 42 | public string Name => _name ??= XqApi.GetGroupName(Robot, Id); 43 | 44 | public Qq Owner => _owner ??= GetAdminList()[0]; 45 | 46 | /// 47 | /// 获取群管理员列表 48 | /// 49 | public List GetAdminList() 50 | { 51 | return _adminList ??= XqApi.GetAdminList(Robot, Id); 52 | } 53 | 54 | /// 55 | /// 获取群成员名片 56 | /// 57 | public string GetGroupCard(Qq qq) 58 | { 59 | return XqApi.GetGroupCard(Robot, Id, qq.Id); 60 | } 61 | 62 | /// 63 | /// 取群成员列表 64 | /// 65 | public List GetGroupMemberList() 66 | { 67 | return _groupmemberlist ??= XqApi.GetGroupMemberList(Robot, Id); 68 | } 69 | 70 | /// 71 | /// 取当前群人数和群人数上限 72 | /// 73 | /// item1 :当前群人数; item2 :群人数上限 74 | public (string, string) GetGroupMemberNum() 75 | { 76 | return XqApi.GetGroupMemberNum(Robot, Id); 77 | } 78 | 79 | /// 80 | /// 查询是否允许发送匿名消息 81 | /// 82 | public bool GetAnon() 83 | { 84 | return XqApi.GetAnon(Robot, Id); 85 | } 86 | 87 | /// 88 | /// 退出群 89 | /// 90 | public void QuitGroup() 91 | { 92 | XqApi.QuitGroup(Robot, Id); 93 | } 94 | 95 | /// 96 | /// 删除群成员 97 | /// 当Bot不为管理员时报错 98 | /// 99 | /// 群成员QQ 100 | /// 指定是否不再允许接受申请入群 101 | public void KickGroupMember(Qq qq, bool notallowagain) 102 | { 103 | XqApi.KickGroupMember(Robot, Id, qq.Id, notallowagain); 104 | } 105 | 106 | /// 107 | /// 修改群成员昵称 108 | /// 109 | public bool SetGroupCard(Qq qq, string card) 110 | { 111 | return XqApi.SetGroupCard(Robot, Id, qq.Id, card); 112 | } 113 | 114 | /// 115 | /// 群禁言 116 | /// 117 | /// 对象QQ(为空则为全员禁言) 118 | /// 禁言时间(单位:秒)(0:解除禁言) 119 | public void BanSpeak(Qq qq, int time) 120 | { 121 | XqApi.BanSpeak(Robot, Id, qq?.Id ?? "", time); 122 | } 123 | 124 | /// 125 | /// 开关群匿名功能 126 | /// 127 | /// True 则开启群匿名 ,False 则关闭群匿名 128 | public bool SetAnon(bool openOrClose) 129 | { 130 | return XqApi.SetAnon(Robot, Id, openOrClose); 131 | } 132 | 133 | /// 134 | /// 屏蔽本群消息 135 | /// 136 | /// True 则屏蔽 ,False 则取消屏蔽 137 | public void ShieldThisGroup(bool openOrClose) 138 | { 139 | XqApi.SetShieldedGroup(Robot, Id, openOrClose); 140 | } 141 | 142 | /// 143 | /// 发送群聊消息 144 | /// 145 | /// 146 | public void SendGroupMessage(params object[] msg) 147 | { 148 | XqApi.SendGroupMessage(Robot, Id, false, msg); 149 | } 150 | 151 | public static implicit operator string(Group group) 152 | { 153 | return group.Id; 154 | } 155 | } 156 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/FriendInfoJson.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace XQ.SDK.Model.Json 4 | { 5 | public class FriendInfoJson 6 | { 7 | /// 8 | /// 昵称 9 | /// 10 | [JsonProperty(PropertyName = "name")] 11 | public string Name { get; set; } 12 | 13 | /// 14 | /// QQ号 15 | /// 16 | [JsonProperty(PropertyName = "uin")] 17 | public string Id { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/FriendList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Newtonsoft.Json; 4 | 5 | namespace XQ.SDK.Model.Json 6 | { 7 | public class FriendList 8 | { 9 | /// 10 | /// 指示是否获取成功 11 | /// 12 | [JsonProperty(PropertyName = "ec")] 13 | public int Ec { get; set; } 14 | 15 | /// 16 | /// 错误码 17 | /// 18 | [JsonProperty(PropertyName = "errcode")] 19 | public int Errcode { get; set; } 20 | 21 | /// 22 | /// 错误Msg 23 | /// 24 | [JsonProperty(PropertyName = "em")] 25 | public string ErrMessage { get; set; } 26 | 27 | /// 28 | /// 好友列表 29 | /// 30 | [JsonProperty(PropertyName = "result")] 31 | public Dictionary List { get; set; } 32 | 33 | public List GetList() 34 | { 35 | var infos = new List(); 36 | foreach (var i in List.Values.Select(i => i.Members)) infos.AddRange(i); 37 | return infos; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/FriendListItem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace XQ.SDK.Model.Json 5 | { 6 | public class FriendListItem 7 | { 8 | [JsonProperty(PropertyName = "mems")] public List Members { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/GroupInfoJson.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | using Newtonsoft.Json; 3 | 4 | namespace XQ.SDK.Model.Json 5 | { 6 | public class GroupInfoJson 7 | { 8 | private string _name; 9 | 10 | /// 11 | /// 群号 12 | /// 13 | [JsonProperty(PropertyName = "gc")] 14 | public string Id { get; set; } 15 | 16 | /// 17 | /// 群名称 18 | /// 19 | [JsonProperty(PropertyName = "gn")] 20 | public string Name 21 | { 22 | get => _name; 23 | set => _name = Regex.Unescape(value); 24 | } 25 | 26 | /// 27 | /// 群主 28 | /// 29 | [JsonProperty(PropertyName = "owner")] 30 | public string Owner { get; set; } 31 | } 32 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/GroupList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace XQ.SDK.Model.Json 6 | { 7 | public class GroupList 8 | { 9 | private List _joinList; 10 | private List _manageList; 11 | private List _createList; 12 | 13 | /// 14 | /// 指示是否获取成功 15 | /// 16 | [JsonProperty(PropertyName = "ec")] 17 | public int Ec { get; set; } 18 | 19 | /// 20 | /// 错误码 21 | /// 22 | [JsonProperty(PropertyName = "errcode")] 23 | public int Errcode { get; set; } 24 | 25 | /// 26 | /// 错误Msg 27 | /// 28 | [JsonProperty(PropertyName = "em")] 29 | public string ErrMessage { get; set; } 30 | 31 | /// 32 | /// 加入的群列表 33 | /// 34 | [JsonProperty(PropertyName = "join")] 35 | public List JoinList 36 | { 37 | get => Ec == 0 && Errcode == 0 38 | ? _joinList 39 | : throw new ApplicationException( 40 | $"XQApi_GroupList 返回值异常\nErrCode : {Errcode}\nErrMessage{ErrMessage}"); 41 | set => _joinList = value; 42 | } 43 | 44 | /// 45 | /// 管理的群列表 46 | /// 47 | [JsonProperty(PropertyName = "manage")] 48 | public List ManageList 49 | { 50 | get => Ec == 0 && Errcode == 0 51 | ? _manageList 52 | : throw new ApplicationException( 53 | $"XQApi_GroupList 返回值异常\nErrCode : {Errcode}\nErrMessage{ErrMessage}"); 54 | set => _manageList = value; 55 | } 56 | 57 | /// 58 | /// 创建的群列表 59 | /// 60 | [JsonProperty(PropertyName = "create")] 61 | public List CreateList 62 | { 63 | get => Ec == 0 && Errcode == 0 64 | ? _createList 65 | : throw new ApplicationException( 66 | $"XQApi_GroupList 返回值异常\nErrCode : {Errcode}\nErrMessage{ErrMessage}"); 67 | set => _createList = value; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/GroupMemberInfoJson.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace XQ.SDK.Model.Json 4 | { 5 | public class GroupMemberInfoJson 6 | { 7 | /// 8 | /// 上次发言时间时间戳 9 | /// 10 | [JsonProperty(PropertyName = "lst")] 11 | public long LastTime { get; set; } 12 | 13 | /// 14 | /// 加群时间时间戳 15 | /// 16 | [JsonProperty(PropertyName = "jt")] 17 | public long JoinTime { get; set; } 18 | 19 | /// 20 | /// 名称 21 | /// 22 | [JsonProperty(PropertyName = "cd")] 23 | public string Name { get; set; } 24 | 25 | /// 26 | /// 群昵称 27 | /// 28 | [JsonProperty(PropertyName = "nk")] 29 | public string Nick { get; set; } 30 | 31 | /// 32 | /// 禁言剩余时间(秒) 33 | /// 34 | [JsonProperty(PropertyName = "sut")] 35 | public long? BanSpeckTime { get; set; } = 0; 36 | 37 | /// 38 | /// 是否为好友,0为否 39 | /// 40 | [JsonProperty(PropertyName = "fr")] 41 | public int? IsFriend { get; set; } = 0; 42 | } 43 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/GroupMemberItems.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace XQ.SDK.Model.Json 4 | { 5 | public class GroupMemberItems 6 | { 7 | [JsonProperty(PropertyName = "QQ")] public string Qq { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/GroupMemberList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace XQ.SDK.Model.Json 5 | { 6 | public class GroupMemberList 7 | { 8 | /// 9 | /// 指示是否获取成功 10 | /// 11 | [JsonProperty(PropertyName = "ec")] 12 | public int Ec { get; set; } 13 | 14 | /// 15 | /// 错误码 16 | /// 17 | [JsonProperty(PropertyName = "errcode")] 18 | public int Errcode { get; set; } 19 | 20 | /// 21 | /// 错误Msg 22 | /// 23 | [JsonProperty(PropertyName = "em")] 24 | public string ErrMessage { get; set; } 25 | 26 | /// 27 | /// 群等级 28 | /// 29 | [JsonProperty(PropertyName = "level")] 30 | public int Level { get; set; } 31 | 32 | /// 33 | /// 34 | [JsonProperty(PropertyName = "mem_num")] 35 | public int MemberNum { get; set; } 36 | 37 | /// 38 | /// 39 | [JsonProperty(PropertyName = "max_num")] 40 | public int MaxMemberNum { get; set; } 41 | 42 | /// 43 | /// 44 | [JsonProperty(PropertyName = "max_admin")] 45 | public int MaxAdminNum { get; set; } 46 | 47 | /// 48 | /// 49 | [JsonProperty(PropertyName = "owner")] 50 | public string Owner { get; set; } 51 | 52 | /// 53 | /// 54 | [JsonProperty(PropertyName = "adm")] 55 | public List AdminList { get; set; } 56 | 57 | /// 58 | /// 59 | [JsonProperty(PropertyName = "members")] 60 | public Dictionary Members { get; set; } 61 | } 62 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/GroupMemberListQqonly.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace XQ.SDK.Model.Json 5 | { 6 | public class GroupMemberListQqonly 7 | { 8 | [JsonProperty(PropertyName = "list")] public List List { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/OcrInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace XQ.SDK.Model.Json 5 | { 6 | public class OcrInfo 7 | { 8 | /// 9 | /// 10 | [JsonProperty(PropertyName = "list")] 11 | public List List { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/OcrItem.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace XQ.SDK.Model.Json 4 | { 5 | public class OcrItem 6 | { 7 | /// 8 | /// 文字 9 | /// 10 | [JsonProperty(PropertyName = "txt")] 11 | public string Text { get; set; } 12 | 13 | /// 14 | /// 15 | [JsonProperty(PropertyName = "a")] 16 | public string A { get; set; } 17 | 18 | /// 19 | /// 20 | [JsonProperty(PropertyName = "b")] 21 | public string B { get; set; } 22 | 23 | /// 24 | /// 25 | [JsonProperty(PropertyName = "c")] 26 | public string C { get; set; } 27 | 28 | /// 29 | /// 30 | [JsonProperty(PropertyName = "d")] 31 | public string D { get; set; } 32 | } 33 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/OcrItemCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace XQ.SDK.Model.Json 5 | { 6 | public class OcrItemCollection 7 | { 8 | public OcrItemCollection(List list) 9 | { 10 | List = list; 11 | } 12 | 13 | public List List { get; } 14 | 15 | public List AllText => List.Select(i => i.Text).ToList(); 16 | } 17 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Json/RobotInfo.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace XQ.SDK.Model.Json 4 | { 5 | public class RobotInfo 6 | { 7 | /// 8 | /// RobotQQ 9 | /// 10 | [JsonProperty(PropertyName = "QQ")] 11 | public string Qq { get; set; } 12 | 13 | /// 14 | /// Robot昵称 15 | /// 16 | [JsonProperty(PropertyName = "昵称")] 17 | public string NickName { get; set; } 18 | 19 | /// 20 | /// Robot在线状态 21 | /// 22 | [JsonProperty(PropertyName = "在线状态")] 23 | public string Status { get; set; } 24 | 25 | /// 26 | /// 当前发送消息速度(每秒) 27 | /// 28 | [JsonProperty(PropertyName = "速度")] 29 | public int Speed { get; set; } 30 | 31 | /// 32 | /// 收到消息次数 33 | /// 34 | [JsonProperty(PropertyName = "收信")] 35 | public int RecieveNum { get; set; } 36 | 37 | /// 38 | /// 发送消息次数 39 | /// 40 | [JsonProperty(PropertyName = "发信")] 41 | public int SendNum { get; set; } 42 | 43 | /// 44 | /// 在线时长(秒) 45 | /// 46 | [JsonProperty(PropertyName = "在线时长")] 47 | public long OnlineTime { get; set; } 48 | 49 | /// 50 | /// 登录时间时间戳(秒) 51 | /// 52 | [JsonProperty(PropertyName = "登录时间")] 53 | public long LoginTime { get; set; } 54 | 55 | /// 56 | /// 当前时间时间戳(秒) 57 | /// 58 | [JsonProperty(PropertyName = "当前时间")] 59 | public long NowTime { get; set; } 60 | } 61 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/MessageObject/ImageMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.CodeAnalysis; 4 | using System.Drawing; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Net.Http; 9 | using System.Text.RegularExpressions; 10 | using XQ.SDK.Enum; 11 | using XQ.SDK.Interface; 12 | using XQ.SDK.Model.Json; 13 | using XQ.SDK.XQ; 14 | 15 | namespace XQ.SDK.Model.MessageObject 16 | { 17 | /// 18 | /// 图片消息 19 | /// 20 | [SuppressMessage("ReSharper", "UnusedMember.Global")] 21 | [SuppressMessage("ReSharper", "CommentTypo")] 22 | public class ImageMessage : IToSendString 23 | { 24 | private static readonly Lazy 25 | PrivateImage = 26 | new Lazy(() => 27 | new Regex("{[0-9]{5,15}[-][0-9]{5,15}[-]([0-9A-Fa-f]{32})}.(jpg|png|gif|bmp|jpeg).*", 28 | RegexOptions.IgnoreCase | RegexOptions.ECMAScript)), 29 | GroupImage = new Lazy(() => new Regex( 30 | "{([0-9A-Fa-f]{8})[-]([0-9A-Fa-f]{4})[-]([0-9A-Fa-f]{4})[-]([0-9A-Fa-f]{4})[-]([0-9A-Fa-f]{12})}.(jpg|png|gif|bmp|jpeg).*", 31 | RegexOptions.IgnoreCase | RegexOptions.ECMAScript)); 32 | 33 | private readonly string _sendString; 34 | private readonly ImageMessageType _type; 35 | 36 | private readonly XqApi _xqApi; 37 | 38 | public readonly string RobotQq; 39 | 40 | 41 | private ImageMessage(XqApi xqApi, string robotqq, string toSendString, ImageMessageType type) 42 | { 43 | _sendString = toSendString; 44 | _type = type; 45 | _xqApi = xqApi; 46 | RobotQq = robotqq; 47 | } 48 | 49 | private string Rawmsg => _sendString.Substring(5, _sendString.Length - 6); 50 | 51 | public string ToSendString() 52 | { 53 | return _sendString; 54 | } 55 | 56 | /// 57 | /// 将群聊图片消息进行转换,使其可在私聊中发送 58 | /// 代码逻辑来自w4123/CQXQ 59 | /// 60 | public PlainMessage GroupToPrivate() 61 | { 62 | var rslt = GroupImage.Value.Match(_sendString); 63 | if (!rslt.Success) return ""; 64 | var m = rslt.Groups; 65 | var guid = m[1].Value; 66 | return 67 | $"[pic={{{guid.Substring(0, 8)}-{guid.Substring(8, 4)}-{guid.Substring(12, 4)}-{guid.Substring(16, 4)}-{guid.Substring(20)}}}.{m[2].Value}]"; 68 | } 69 | 70 | /// 71 | /// 将私聊图片消息进行转换,使其可在群聊中发送 72 | /// 代码逻辑来自w4123/CQXQ 73 | /// 74 | /// botQQ 75 | public PlainMessage PrivateToGroup(string robot) 76 | { 77 | var rslt = PrivateImage.Value.Match(_sendString); 78 | if (!rslt.Success) return ""; 79 | var m = rslt.Groups; 80 | return 81 | $"[pic={{{robot}-1234567879-{m[1].Value}{m[2].Value}{m[3].Value}{m[4].Value}{m[5].Value}}}.{m[6].Value}]"; 82 | } 83 | 84 | /// 85 | /// 从文件绝对路径构造ImageMessage 86 | /// 代码逻辑来自w4123/CQXQ 87 | /// 88 | /// Api 89 | /// botQQ 90 | /// 文件绝对路径 91 | /// 92 | public static ImageMessage FromFileName(XqApi xqApi, string robot, string filename) 93 | { 94 | return new ImageMessage(xqApi, robot, $"[pic={filename}]", ImageMessageType.FromFile); 95 | } 96 | 97 | /// 98 | /// 上传图片 99 | /// 100 | /// Api 101 | /// botQQ 102 | /// 消息类型 103 | /// 发送对象的群号或QQ 104 | /// 要上传的图片 105 | public static ImageMessage UpLoadPic(XqApi xqApi, string robot, MessageType imageType, string groupOrQq, 106 | byte[] file) 107 | { 108 | return xqApi.UpLoadPic(robot, imageType, groupOrQq, file); 109 | } 110 | 111 | /// 112 | /// 从网络链接构造ImageMessage 113 | /// 114 | /// 115 | /// 116 | /// 117 | /// 118 | public static ImageMessage FromUrl(XqApi xqApi, string robotqq, string url) 119 | { 120 | return new ImageMessage(xqApi, robotqq, $"[pic={url}]", ImageMessageType.FromWebUrl); 121 | } 122 | 123 | /// 124 | /// 转换为秀图 125 | /// 126 | public PlainMessage ToShowPic(ShowPicType type) 127 | { 128 | return new PlainMessage(_sendString.Replace("[pic=", "[ShowPic=") + $",type={(int) type}]"); 129 | } 130 | 131 | /// 132 | /// 转换为闪照 133 | /// 134 | public PlainMessage ToFlashPic() 135 | { 136 | return new PlainMessage(_sendString.Replace("[pic=", "[FlashPic=")); 137 | } 138 | 139 | /// 140 | /// 获取消息中所有图片消息 141 | /// 若转发可能需要进行格式转换 142 | /// 143 | /// 144 | /// 145 | /// 146 | public static List GetFromMessage(XqApi xqApi, string robotqq, string message) 147 | { 148 | try 149 | { 150 | return !message.Contains("[pic=") 151 | ? null 152 | : (from Match item in Regex.Matches(message, 153 | @"([pic])(.)+?(?=\])") 154 | select $"[{item.Value}]").Select(i => 155 | new ImageMessage(xqApi, robotqq, i, ImageMessageType.FromMessage)) 156 | .ToList(); 157 | } 158 | catch 159 | { 160 | return null; 161 | } 162 | } 163 | 164 | /// 165 | /// 获取图片Ocr 166 | /// 只能获取消息中得到的图片 167 | /// 从文件路径或url构造的ImageMessage无效 168 | /// 169 | /// 图片Ocr后的信息 170 | public OcrItemCollection GetImageOcrResult() 171 | { 172 | return _xqApi.GetImageOcrResult(this); 173 | } 174 | 175 | /// 176 | /// 从文件路径或url构造的ImageMessage转byte[] 177 | /// 从消息获得的ImageMessage无法转换,但可先下载再转换 178 | /// 179 | public byte[] ToBytes() 180 | { 181 | Stream fs = null; 182 | BinaryReader binaryWriter = null; 183 | try 184 | { 185 | fs = _type switch 186 | { 187 | ImageMessageType.FromFile => new FileStream(Rawmsg, FileMode.Open, FileAccess.Read), 188 | ImageMessageType.FromWebUrl => GetFromWeb(Rawmsg), 189 | ImageMessageType.FromMessage => throw new ArgumentOutOfRangeException(), 190 | _ => throw new ArgumentOutOfRangeException() 191 | }; 192 | binaryWriter = new BinaryReader(fs); 193 | return binaryWriter.ReadBytes((int) fs.Length); 194 | } 195 | finally 196 | { 197 | binaryWriter?.Close(); 198 | fs?.Close(); 199 | binaryWriter?.Dispose(); 200 | fs?.Dispose(); 201 | } 202 | } 203 | 204 | private static Stream GetFromWeb(string url) 205 | { 206 | ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 207 | ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; 208 | var httpClient = new HttpClient(); 209 | var request = new HttpRequestMessage 210 | { 211 | RequestUri = new Uri(url), 212 | Method = HttpMethod.Get 213 | }; 214 | return httpClient.SendAsync(request).Result.Content.ReadAsStreamAsync().Result; 215 | } 216 | 217 | /// 218 | /// 获取图片下载链接 219 | /// 只能获取消息中得到的图片下载链接 220 | /// 从文件路径或url构造ImageMessage的无效 221 | /// 222 | /// 消息类型 223 | /// 群号,在图片为群聊图片时填写 224 | public string GetImageDownloadLink(string group, MessageType type) 225 | { 226 | return _xqApi.GetPicLink(type, group, this); 227 | } 228 | 229 | /// 230 | /// 下载消息中的图片到本地 231 | /// 232 | /// 消息类型 233 | /// 群号,在图片为群聊图片时填写 234 | /// 相对先驱.exe的相对路径 235 | public ImageMessage Download(string group, MessageType type, string filename) 236 | { 237 | if (_type != ImageMessageType.FromMessage) throw new ArgumentOutOfRangeException(); 238 | 239 | Image i = null; 240 | try 241 | { 242 | i = Image.FromStream(GetFromWeb(GetImageDownloadLink(group, type))); 243 | i.Save(filename); 244 | return FromFileName(_xqApi, RobotQq, $@"{AppContext.BaseDirectory}\{filename}"); 245 | } 246 | finally 247 | { 248 | i?.Dispose(); 249 | } 250 | } 251 | 252 | public override string ToString() 253 | { 254 | return ToSendString(); 255 | } 256 | } 257 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/MessageObject/PlainMessage.cs: -------------------------------------------------------------------------------- 1 | using XQ.SDK.Interface; 2 | 3 | namespace XQ.SDK.Model.MessageObject 4 | { 5 | /// 6 | /// 文字消息、XQ自带的部分消息缩写 7 | /// 8 | public class PlainMessage : IToSendString 9 | { 10 | 11 | /// 12 | /// At全群 13 | /// 14 | public static PlainMessage AtAll = new PlainMessage("[@all]"); 15 | 16 | /// 17 | /// At某人 18 | /// 19 | /// 对象QQ 20 | /// 21 | public static PlainMessage At(string qq) 22 | { 23 | return new PlainMessage($"[@{qq}]"); 24 | } 25 | 26 | /// 27 | /// 表情 28 | /// 对照表请参考 https://github.com/kyubotics/coolq-http-api/wiki/%E8%A1%A8%E6%83%85-CQ-%E7%A0%81-ID-%E8%A1%A8 29 | /// 30 | /// 表情代码 31 | /// 32 | public static PlainMessage Face(int number) 33 | { 34 | return new PlainMessage($"[Face{number}.gif]"); 35 | } 36 | 37 | private readonly string _sendString; 38 | 39 | public PlainMessage(string sendString) 40 | { 41 | _sendString = sendString; 42 | } 43 | 44 | public string ToSendString() 45 | { 46 | return _sendString; 47 | } 48 | 49 | public override string ToString() 50 | { 51 | return ToSendString(); 52 | } 53 | 54 | public static implicit operator PlainMessage(string str) 55 | { 56 | return new PlainMessage(str); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/MessageObject/VoiceMessage.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using System.Text.RegularExpressions; 3 | using XQ.SDK.Enum; 4 | using XQ.SDK.Interface; 5 | using XQ.SDK.XQ; 6 | 7 | namespace XQ.SDK.Model.MessageObject 8 | { 9 | /// 10 | /// 语音消息 11 | /// 12 | [SuppressMessage("ReSharper", "UnusedMember.Global")] 13 | public class VoiceMessage : IToSendString 14 | { 15 | private readonly string _sendString; 16 | private readonly XqApi _xqapi; 17 | 18 | public readonly string RobotQq; 19 | 20 | private VoiceMessage(XqApi xqapi, string robotQq, string sendString) 21 | { 22 | _sendString = sendString; 23 | RobotQq = robotQq; 24 | _xqapi = xqapi; 25 | } 26 | 27 | public string ToSendString() 28 | { 29 | return _sendString; 30 | } 31 | 32 | public override string ToString() 33 | { 34 | return ToSendString(); 35 | } 36 | 37 | /// 38 | /// 语音信息的下载链接(silk格式) 39 | /// 40 | public string GetVoiceMessageDownloadLink() 41 | { 42 | return _xqapi.GetVoiLink(this); 43 | } 44 | 45 | /// 46 | /// 语音转文字 47 | /// 48 | /// 发送对象的群号或QQ 49 | /// 50 | public string VoiceMessageText(string groupOrQq, MessageType type) 51 | { 52 | return _xqapi.VoiToText(groupOrQq, type, this); 53 | } 54 | 55 | 56 | /// 57 | /// 获取语音消息 58 | /// 59 | /// 60 | /// 61 | /// 62 | public static VoiceMessage GetFromMessage(XqApi api, string robotqq, string message) 63 | { 64 | try 65 | { 66 | return !message.Contains("[Voi=") 67 | ? null 68 | : new VoiceMessage(api, robotqq, $"[{Regex.Match(message, @"([Voi])(.)+?(?=\])").Value}]"); 69 | } 70 | catch 71 | { 72 | return null; 73 | } 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/PluginInfo.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace XQ.SDK.Model 4 | { 5 | /// 6 | /// 描述插件信息 7 | /// 8 | public class PluginInfo 9 | { 10 | /// 插件名 11 | /// 插件作者 12 | /// 插件版本 13 | /// 插件描述 14 | public PluginInfo(string name, string author, string version, string desc) 15 | { 16 | Name = name; 17 | Author = author; 18 | Version = version; 19 | Desc = desc; 20 | Sver = 3; 21 | } 22 | 23 | [JsonProperty(PropertyName = "name")] public string Name { get; set; } 24 | 25 | [JsonProperty(PropertyName = "pver")] public string Version { get; set; } 26 | 27 | [JsonProperty(PropertyName = "sver")] public int Sver { get; set; } 28 | 29 | [JsonProperty(PropertyName = "author")] public string Author { get; set; } 30 | 31 | [JsonProperty(PropertyName = "desc")] public string Desc { get; set; } 32 | 33 | public string GetJson() 34 | { 35 | return JsonConvert.SerializeObject(this); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Qq.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using XQ.SDK.Enum; 3 | using XQ.SDK.XQ; 4 | 5 | namespace XQ.SDK.Model 6 | { 7 | /// 8 | /// 事件中的来源QQ、对象QQ等 9 | /// 10 | public class Qq : BasisModel 11 | { 12 | private readonly int _extratype; 13 | 14 | private readonly string _fromgroup; 15 | 16 | private readonly MessageType _type; 17 | 18 | private string _name; 19 | 20 | public Qq(XqApi api, string robot, string id, MessageType type, string fromgroup) : base(api, robot) 21 | { 22 | Id = id; 23 | _type = type; 24 | _fromgroup = fromgroup; 25 | } 26 | 27 | public Qq(XqApi api, string robot, string id, MessageType type, string fromgroup, int extratype) : this( 28 | api, robot, id, type, fromgroup) 29 | { 30 | _extratype = extratype; 31 | } 32 | 33 | 34 | public Qq(XqApi api, string robot, string id, string name, MessageType type, string fromgroup) : this( 35 | api, robot, id, type, fromgroup) 36 | { 37 | _name = name; 38 | } 39 | 40 | /// 41 | /// QQ号 42 | /// 43 | public string Id { get; } 44 | 45 | /// 46 | /// 昵称 47 | /// 48 | public string Name => _name ??= XqApi.GetNick(Robot, Id); 49 | 50 | /// 51 | /// 年龄,未知为255 52 | /// 53 | public int Age => XqApi.GetAge(Robot, Id); 54 | 55 | /// 56 | /// 性别 57 | /// 58 | public QqSex Gender => XqApi.GetGender(Robot, Id); 59 | 60 | /// 61 | /// 赞数量 62 | /// 63 | public int ObjVote => XqApi.GetObjVote(Robot, Id); 64 | 65 | /// 66 | /// 查询是否是好友 67 | /// 68 | public bool IfFriend() 69 | { 70 | return XqApi.IfFriend(Robot, Id); 71 | } 72 | 73 | /// 74 | /// 删除好友 75 | /// 76 | public void DeleteFriend() 77 | { 78 | XqApi.DeleteFriend(Robot, Id); 79 | } 80 | 81 | /// 82 | /// 添加好友 83 | /// 84 | /// 验证消息 85 | public bool AddFriend(string msg) 86 | { 87 | return XqApi.AddFriend(Robot, Id, msg); 88 | } 89 | 90 | /// 91 | /// 获取好友备注名称 92 | /// 93 | public void GetRemark() 94 | { 95 | XqApi.GetFriendsRemark(Robot, Id); 96 | } 97 | 98 | /// 99 | /// 修改好友备注名称 100 | /// 101 | /// 备注 102 | public void SetRemark(string remark) 103 | { 104 | XqApi.SetFriendsRemark(Robot, Id, remark); 105 | } 106 | 107 | /// 108 | /// 向好友发送窗口抖动消息 109 | /// 110 | public void ShakeWindow() 111 | { 112 | XqApi.ShakeWindow(Robot, Id); 113 | } 114 | 115 | 116 | /// 117 | /// 发送私聊消息 118 | /// 119 | /// 120 | public void SendPrivateMessage(params object[] msg) 121 | { 122 | XqApi.SendPrivateMessage(Robot, Id, GetPrivateMessageType(_type), 123 | _type == MessageType.TempGroupMessage ? _fromgroup : "", msg); 124 | } 125 | 126 | private PrivateMessageType GetPrivateMessageType(MessageType type) 127 | { 128 | if (System.Enum.IsDefined(typeof(PrivateMessageType), (int)type)) return (PrivateMessageType) type; 129 | 130 | return type switch 131 | { 132 | MessageType.Group => IfFriend() ? PrivateMessageType.Friend : PrivateMessageType.TempGroupMessage, 133 | MessageType.MsgWithdrawn => GetPrivateMessageType((MessageType) _extratype), 134 | MessageType.Transfer => GetPrivateMessageType((MessageType) _extratype), 135 | _ => throw new ArgumentOutOfRangeException(nameof(type), type, null) 136 | }; 137 | } 138 | 139 | 140 | public static implicit operator string(Qq qq) 141 | { 142 | return qq.Id; 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/QqMessage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using XQ.SDK.Interface; 3 | using XQ.SDK.Model.MessageObject; 4 | using XQ.SDK.XQ; 5 | 6 | namespace XQ.SDK.Model 7 | { 8 | /// 9 | /// 事件中的消息 10 | /// 11 | public class QqMessage : IToSendString 12 | { 13 | private readonly string _robotqq; 14 | 15 | private readonly XqApi _xqapi; 16 | 17 | public QqMessage(XqApi xqapi, string robotqq, string message) 18 | { 19 | RawContent = message; 20 | _xqapi = xqapi; 21 | _robotqq = robotqq; 22 | } 23 | 24 | /// 25 | /// 消息原始文本 26 | /// 27 | public string RawContent { get; } 28 | 29 | public string ToSendString() 30 | { 31 | return RawContent; 32 | } 33 | 34 | public override string ToString() 35 | { 36 | return ToSendString(); 37 | } 38 | 39 | /// 40 | /// 获取语音消息 41 | /// 若不是语音消息将返回null 42 | /// 43 | /// 44 | public VoiceMessage GetVoiceMessage() 45 | { 46 | return VoiceMessage.GetFromMessage(_xqapi, _robotqq, RawContent); 47 | } 48 | 49 | /// 50 | /// 获取图片消息 51 | /// 若不含图片消息将返回null 52 | /// 注意:只能获取普通图片,特殊类型图片请参考ImageMessage.GetFromMessage的实现自行解析 53 | /// 54 | public List GetImageMessages() 55 | { 56 | return ImageMessage.GetFromMessage(_xqapi, _robotqq, RawContent); 57 | } 58 | 59 | public static implicit operator string(QqMessage msg) 60 | { 61 | return msg.RawContent; 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/Robot.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using XQ.SDK.Enum; 3 | using XQ.SDK.Model.Json; 4 | using XQ.SDK.Model.MessageObject; 5 | using XQ.SDK.XQ; 6 | 7 | namespace XQ.SDK.Model 8 | { 9 | /// 10 | /// 事件中的RobotQQ 11 | /// 12 | public class Robot 13 | { 14 | private readonly XqApi _api; 15 | 16 | private readonly string _robotQq; 17 | 18 | 19 | private List _friendlist; 20 | 21 | 22 | private List _grouplist; 23 | 24 | public Robot(XqApi api, string robotQq) 25 | { 26 | _api = api; 27 | _robotQq = robotQq; 28 | PsKey = new PsKeyApi(api, robotQq); 29 | } 30 | 31 | /// 32 | /// PsKey相关的Api 33 | /// 34 | public PsKeyApi PsKey { get; } 35 | 36 | /// 37 | /// 获取好友列表 38 | /// 39 | public List GetFriendList() 40 | { 41 | return _friendlist ??= _api.GetFriendList(_robotQq); 42 | } 43 | 44 | /// 45 | /// 创建群 46 | /// 47 | /// 返回创建群的群号 48 | public string CreateGroup() 49 | { 50 | return _api.CreateGroup(_robotQq); 51 | } 52 | 53 | /// 54 | /// 修改机器人自身头像 55 | /// 56 | public bool SetHeadPic(ImageMessage obj) 57 | { 58 | return _api.SetHeadPic(_robotQq, obj.ToBytes()); 59 | } 60 | 61 | /// 62 | /// 获取群列表 63 | /// 64 | public List GetGroupList() 65 | { 66 | return _grouplist ??= _api.GetGroupList(_robotQq); 67 | } 68 | 69 | /// 70 | /// 取机器人账号在线信息 71 | /// 72 | public RobotInfo GetRobotInfo() 73 | { 74 | return _api.GetRobotInfo(_robotQq); 75 | } 76 | 77 | /// 78 | /// 修改机器人账号在线状态 79 | /// 80 | /// 在线状态类型 81 | public void SetOnlineStatus(OnlineStatusType onLineType) 82 | { 83 | _api.SetOnlineStatus(_robotQq, onLineType); 84 | } 85 | 86 | /// 87 | /// 修改机器人账号个性签名 88 | /// 89 | /// 个性签名 90 | public void SetSignature(string signature) 91 | { 92 | _api.SetSignature(_robotQq, signature); 93 | } 94 | 95 | /// 96 | /// 修改机器人账号性别 97 | /// 98 | /// 性别 99 | public void SetSex(QqSex type) 100 | { 101 | _api.SetSex(_robotQq, type); 102 | } 103 | 104 | /// 105 | /// 邀请好友加入群 106 | /// 107 | /// 被邀请加入的群号 108 | /// 109 | public void InviteFriendInfoGroup(string group, string qq) 110 | { 111 | _api.InviteFriendInfoGroup(_robotQq, group, qq); 112 | } 113 | 114 | 115 | /// 116 | /// 邀请群成员加入群 117 | /// 118 | /// 邀请到哪个群 119 | /// 被邀请成员所在群 120 | /// 被邀请人的QQ 121 | public bool InviteGroupMemberInfoGroup(string group, string groupY, string qq) 122 | { 123 | return _api.InviteGroupMemberInfoGroup(_robotQq, group, groupY, qq); 124 | } 125 | 126 | 127 | /// 128 | /// 主动加群 129 | /// 130 | /// 群号 131 | /// 附加理由,可留空(需回答正确问题时,请填写问题答案 132 | public void JoinGroup(string group, string message) 133 | { 134 | _api.JoinGroup(_robotQq, group, message); 135 | } 136 | 137 | /// 138 | /// 设置机器人被添加好友时的验证方式 139 | /// 140 | public void SetCation(string group, FriendAddRequestType type) 141 | { 142 | _api.SetCation(_robotQq, type); 143 | } 144 | 145 | /// 146 | /// 设置机器人被添加好友时的问题与答案 147 | /// 148 | /// 设置的问题 149 | /// 设置的问题答案 150 | public void SetCationWithQuestion(string problem, string answer) 151 | { 152 | _api.SetCationWithQuestion(_robotQq, problem, answer); 153 | } 154 | 155 | /// 156 | /// 设置机器人被添加好友时的三个可选问题 157 | /// 158 | /// 设置问题一 159 | /// 设置问题二 160 | /// 设置问题三 161 | public void SetCationWithThreeQuestion(string problem1, string problem2, string problem3) 162 | { 163 | _api.SetCationWithThreeQuestion(_robotQq, problem1, problem2, problem3); 164 | } 165 | 166 | public static implicit operator string(Robot robot) 167 | { 168 | return robot._robotQq; 169 | } 170 | 171 | public class PsKeyApi 172 | { 173 | private readonly XqApi _api; 174 | private readonly string _robotQq; 175 | 176 | public PsKeyApi(XqApi api, string robotQq) 177 | { 178 | _api = api; 179 | _robotQq = robotQq; 180 | } 181 | 182 | /// 183 | /// 取得QQ群页面操作用参数P_skey 184 | /// 185 | /// "; p_uin=o{robotQq}; p_skey={p_skeyvalue}" 186 | /// 187 | public string GetGroupPsKey() 188 | { 189 | return _api.GetGroupPsKey(_robotQq); 190 | } 191 | 192 | /// 193 | /// 取得QQ空间页面操作用参数P_skey 194 | /// 195 | /// "; p_uin=o{robotQq}; p_skey={p_skeyvalue}" 196 | /// 197 | public string GetZonePsKey() 198 | { 199 | return _api.GetZonePsKey(_robotQq); 200 | } 201 | 202 | /// 203 | /// 取得机器人网页操作用的Cookies 204 | /// 205 | /// "uin=o{robotQq}; skey={skeyvalue}" 206 | /// 207 | public string GetCookies() 208 | { 209 | return _api.GetCookies(_robotQq); 210 | } 211 | 212 | /// 213 | /// 取短Clientkey 214 | /// 215 | /// 16进制字符串 216 | public string GetClientkey() 217 | { 218 | return _api.GetClientkey(_robotQq); 219 | } 220 | 221 | /// 222 | /// 取得机器人网页操作用的长Clientkey 223 | /// 224 | /// 16进制字符串 225 | public string GetLongClientkey() 226 | { 227 | return _api.GetLongClientkey(_robotQq); 228 | } 229 | 230 | /// 231 | /// 取得腾讯课堂页面操作用参数P_skey 232 | /// 233 | /// "; p_uin=o{robotQq}; p_skey={p_skeyvalue}" 234 | /// 235 | public string GetClassRoomPsKey() 236 | { 237 | return _api.GetClassRoomPsKey(_robotQq); 238 | } 239 | 240 | /// 241 | /// 取得QQ举报页面操作用参数P_skey 242 | /// 243 | /// "; p_uin=o{robotQq}; p_skey={p_skeyvalue}" 244 | /// 245 | public string GetRepPsKey() 246 | { 247 | return _api.GetRepPsKey(_robotQq); 248 | } 249 | 250 | /// 251 | /// 取得财付通页面操作用参数P_skey 252 | /// 253 | /// "; p_uin=o{robotQq}; p_skey={p_skeyvalue}" 254 | /// 255 | public string GetTenPayPsKey() 256 | { 257 | return _api.GetTenPayPsKey(_robotQq); 258 | } 259 | 260 | /// 261 | /// 取bkn 262 | /// 263 | /// bkn (一串数字) 264 | public string GetBkn() 265 | { 266 | return _api.GetBkn(_robotQq); 267 | } 268 | } 269 | } 270 | } -------------------------------------------------------------------------------- /XQ.SDK/Model/XqRawEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace XQ.SDK.Model 4 | { 5 | public class XqRawEvent 6 | { 7 | /// 8 | /// 机器人QQ 9 | /// 用于判定哪个QQ接收到该消息 10 | /// 11 | public string RobotQq { get; } 12 | 13 | /// 14 | /// 消息类型 15 | /// 可在对应枚举中查询具体定义 16 | /// 17 | public int EventType { get; } 18 | 19 | /// 20 | /// 消息子类型 21 | /// 在不同消息类型下有不同的定义 22 | /// eg.:接收财付通转账时 1为好友 4为群临时会话 5为讨论组临时会话 23 | /// 有人请求入群时,不良成员为1 24 | /// 25 | public int ExtraType { get; } 26 | 27 | /// 28 | /// 此消息的来源 29 | /// 如:群号、讨论组ID、临时会话QQ、好友QQ等 30 | /// 31 | public string From { get; } 32 | 33 | /// 34 | /// 触发对象_主动 35 | /// 主动发送这条消息的QQ,踢人时为踢人管理员QQ 36 | /// 37 | public string FromQq { get; } 38 | 39 | /// 40 | /// 触发对象_被动 41 | /// 被动触发的QQ,如某人被踢出群,则此参数为被踢出人QQ 42 | /// 43 | public string TargetQq { get; } 44 | 45 | /// 46 | /// 消息内容 47 | /// 此参数有多重含义,一般为对方发送的消息内容 48 | /// eg.:当某人申请入群时,为入群申请理由 49 | /// 50 | public string Content { get; } 51 | 52 | /// 53 | /// 消息序号 54 | /// 用于消息回复,消息撤回 55 | /// 56 | public string Index { get; } 57 | 58 | /// 59 | /// 消息ID 60 | /// 用于消息回复,消息撤回 61 | /// 62 | public string Msgid { get; } 63 | 64 | /// 65 | /// UDP收到的原始信息 66 | /// 特殊情况下会返回JSON结构 67 | /// (入群事件时,这里为该事件seq) 68 | /// 69 | public string Udpmsg { get; } 70 | 71 | /// 72 | /// 接受到消息的时间戳 73 | /// 74 | public string Unix { get; } 75 | 76 | /// 77 | /// 回传文本指针,此参数用于插件加载拒绝理由 78 | /// 易语言用法:写到内存(“拒绝理由”,XQ_回传文本指针,255) 79 | /// 最大写入字节数量为255,超过此长度可能导致插件异常崩溃 80 | /// 81 | public IntPtr Intptr { get; } 82 | 83 | public XqRawEvent(string robotQq, int eventType, int extraType, string from, string fromQq, 84 | string targetQq, string content, string index, string msgid, string udpmsg, string unix, int p) 85 | { 86 | RobotQq = robotQq?.Trim(); 87 | EventType = eventType; 88 | ExtraType = extraType; 89 | From = from?.Trim(); 90 | FromQq = fromQq?.Trim(); 91 | TargetQq = targetQq?.Trim(); 92 | Content = content?.Trim(); 93 | Index = index?.Trim(); 94 | Msgid = msgid?.Trim(); 95 | Udpmsg = udpmsg?.Trim(); 96 | Unix = unix?.Trim(); 97 | Intptr = new IntPtr(p); 98 | } 99 | 100 | public override string ToString() 101 | { 102 | return 103 | $"RobotQq : {RobotQq}\n" + 104 | $"EventType : {EventType}\n" + 105 | $"ExtraType : {ExtraType}\n" + 106 | $"From : {From}\n" + 107 | $"FromQq : {FromQq}\n" + 108 | $"TargetQq : {TargetQq}\n" + 109 | $"Content : {Content}\n" + 110 | $"Index : {Index}\n" + 111 | $"Udpmsg : {Udpmsg}\n" + 112 | $"Udpmsg : {Udpmsg}\n" + 113 | $"Unix : {Unix}\n" + 114 | $"Intptr : {Intptr}"; 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /XQ.SDK/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // 有关程序集的一般信息由以下 5 | // 控制。更改这些特性值可修改 6 | // 与程序集关联的信息。 7 | [assembly: AssemblyTitle("XQ.SDK")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("XQ.SDK")] 12 | [assembly: AssemblyCopyright("Copyright © 2021")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // 将 ComVisible 设置为 false 会使此程序集中的类型 17 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 18 | //请将此类型的 ComVisible 特性设置为 true。 19 | [assembly: ComVisible(false)] 20 | 21 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 22 | [assembly: Guid("6b6664a8-e436-4b35-9040-8247de86ec89")] 23 | 24 | // 程序集的版本信息由下列四个值组成: 25 | // 26 | // 主版本 27 | // 次版本 28 | // 生成号 29 | // 修订号 30 | // 31 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 32 | //通过使用 "*",如下所示: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /XQ.SDK/XQ.SDK.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6B6664A8-E436-4B35-9040-8247DE86EC89} 8 | Library 9 | Properties 10 | XQ.SDK 11 | XQ.SDK 12 | v4.7.2 13 | 512 14 | true 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 8 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 8 34 | 35 | 36 | true 37 | bin\x86\Debug\ 38 | DEBUG;TRACE 39 | full 40 | x86 41 | 8 42 | prompt 43 | MinimumRecommendedRules.ruleset 44 | 45 | 46 | bin\x86\Release\ 47 | TRACE 48 | true 49 | pdbonly 50 | x86 51 | 8 52 | prompt 53 | MinimumRecommendedRules.ruleset 54 | 55 | 56 | E13B30A4-CBED-4E84-B475-A1E43EF59B52 57 | DllExport.dll 58 | System.Runtime.InteropServices 59 | true 60 | x86 61 | 1 62 | false 63 | false 64 | false 65 | 30000 66 | 2 67 | 68 | 69 | 70 | $(SolutionDir)packages\DllExport.1.6.1\gcache\metalib\$(DllExportNamespace)\$(DllExportMetaLibName) 71 | False 72 | False 73 | 74 | 75 | False 76 | ..\Lib\Newtonsoft.Json.dll 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /XQCSharpSDK.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30621.155 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XQ.Plugin", "XQ.Plugin\XQ.Plugin.csproj", "{517F57EE-4882-4054-A122-734903BA9AB3}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XQ.SDK", "XQ.SDK\XQ.SDK.csproj", "{6B6664A8-E436-4B35-9040-8247DE86EC89}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XQ.Core", "XQ.Core\XQ.Core.csproj", "{C03C5BB7-91D0-4894-AAF9-127090DFAD91}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XQ.Enhance", "XQ.Enhance\XQ.Enhance.csproj", "{787B0C99-5D19-4FD9-ADBB-2B5D8E810197}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Debug|x86 = Debug|x86 18 | Release|Any CPU = Release|Any CPU 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {517F57EE-4882-4054-A122-734903BA9AB3}.Debug|x86.ActiveCfg = Debug|x86 23 | {517F57EE-4882-4054-A122-734903BA9AB3}.Debug|x86.Build.0 = Debug|x86 24 | {517F57EE-4882-4054-A122-734903BA9AB3}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {517F57EE-4882-4054-A122-734903BA9AB3}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {517F57EE-4882-4054-A122-734903BA9AB3}.Release|x86.ActiveCfg = Release|x86 27 | {517F57EE-4882-4054-A122-734903BA9AB3}.Release|x86.Build.0 = Release|x86 28 | {517F57EE-4882-4054-A122-734903BA9AB3}.Debug|Any CPU.ActiveCfg = Release|x86 29 | {517F57EE-4882-4054-A122-734903BA9AB3}.Debug|Any CPU.Build.0 = Release|x86 30 | {6B6664A8-E436-4B35-9040-8247DE86EC89}.Debug|x86.ActiveCfg = Debug|Any CPU 31 | {6B6664A8-E436-4B35-9040-8247DE86EC89}.Debug|x86.Build.0 = Debug|Any CPU 32 | {6B6664A8-E436-4B35-9040-8247DE86EC89}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {6B6664A8-E436-4B35-9040-8247DE86EC89}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {6B6664A8-E436-4B35-9040-8247DE86EC89}.Release|x86.ActiveCfg = Release|x86 35 | {6B6664A8-E436-4B35-9040-8247DE86EC89}.Release|x86.Build.0 = Release|x86 36 | {6B6664A8-E436-4B35-9040-8247DE86EC89}.Debug|Any CPU.ActiveCfg = Release|x86 37 | {6B6664A8-E436-4B35-9040-8247DE86EC89}.Debug|Any CPU.Build.0 = Release|x86 38 | {C03C5BB7-91D0-4894-AAF9-127090DFAD91}.Debug|x86.ActiveCfg = Debug|x86 39 | {C03C5BB7-91D0-4894-AAF9-127090DFAD91}.Debug|x86.Build.0 = Debug|x86 40 | {C03C5BB7-91D0-4894-AAF9-127090DFAD91}.Release|Any CPU.ActiveCfg = Release|x86 41 | {C03C5BB7-91D0-4894-AAF9-127090DFAD91}.Release|x86.ActiveCfg = Release|x86 42 | {C03C5BB7-91D0-4894-AAF9-127090DFAD91}.Release|x86.Build.0 = Release|x86 43 | {C03C5BB7-91D0-4894-AAF9-127090DFAD91}.Debug|Any CPU.ActiveCfg = Release|x86 44 | {C03C5BB7-91D0-4894-AAF9-127090DFAD91}.Debug|Any CPU.Build.0 = Release|x86 45 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197}.Debug|x86.ActiveCfg = Debug|Any CPU 46 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197}.Debug|x86.Build.0 = Debug|Any CPU 47 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197}.Release|Any CPU.Build.0 = Release|Any CPU 49 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197}.Release|x86.ActiveCfg = Release|x86 50 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197}.Release|x86.Build.0 = Release|x86 51 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197}.Debug|Any CPU.ActiveCfg = Release|x86 52 | {787B0C99-5D19-4FD9-ADBB-2B5D8E810197}.Debug|Any CPU.Build.0 = Release|x86 53 | EndGlobalSection 54 | GlobalSection(SolutionProperties) = preSolution 55 | HideSolutionNode = FALSE 56 | EndGlobalSection 57 | GlobalSection(ExtensibilityGlobals) = postSolution 58 | SolutionGuid = {EE9D5E5A-55AA-4FD1-A2AC-7091CBED6C85} 59 | EndGlobalSection 60 | EndGlobal 61 | -------------------------------------------------------------------------------- /XQCsharpSDK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/XQCsharpSDK.png -------------------------------------------------------------------------------- /packages/Costura.Fody.1.6.2/build/dotnet/Costura.Fody.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | $(MSBuildThisFileDirectory)..\..\ 6 | 7 | 8 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /packages/Costura.Fody.1.6.2/build/portable-net+sl+win+wpa+wp/Costura.Fody.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | $(MSBuildThisFileDirectory)..\..\ 6 | 7 | 8 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /packages/Costura.Fody.1.6.2/lib/dotnet/Costura.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/Costura.Fody.1.6.2/lib/dotnet/Costura.dll -------------------------------------------------------------------------------- /packages/Costura.Fody.1.6.2/lib/portable-net+sl+win+wpa+wp/Costura.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/Costura.Fody.1.6.2/lib/portable-net+sl+win+wpa+wp/Costura.dll -------------------------------------------------------------------------------- /packages/Costura.Fody.1.6.2/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | 4 | function RemoveForceProjectLevelHack($project) 5 | { 6 | Write-Host "RemoveForceProjectLevelHack" 7 | Foreach ($item in $project.ProjectItems) 8 | { 9 | if ($item.Name -eq "Fody_ToBeDeleted.txt") 10 | { 11 | $item.Delete() 12 | } 13 | } 14 | } 15 | 16 | function FlushVariables() 17 | { 18 | Write-Host "Flushing environment variables" 19 | $env:FodyLastProjectPath = "" 20 | $env:FodyLastWeaverName = "" 21 | $env:FodyLastXmlContents = "" 22 | } 23 | 24 | function Update-FodyConfig($addinName, $project) 25 | { 26 | Write-Host "Update-FodyConfig" 27 | $fodyWeaversPath = [System.IO.Path]::Combine([System.IO.Path]::GetDirectoryName($project.FullName), "FodyWeavers.xml") 28 | 29 | $FodyLastProjectPath = $env:FodyLastProjectPath 30 | $FodyLastWeaverName = $env:FodyLastWeaverName 31 | $FodyLastXmlContents = $env:FodyLastXmlContents 32 | 33 | if ( 34 | ($FodyLastProjectPath -eq $project.FullName) -and 35 | ($FodyLastWeaverName -eq $addinName)) 36 | { 37 | Write-Host "Upgrade detected. Restoring content for $addinName" 38 | [System.IO.File]::WriteAllText($fodyWeaversPath, $FodyLastXmlContents) 39 | FlushVariables 40 | return 41 | } 42 | 43 | FlushVariables 44 | 45 | $xml = [xml](get-content $fodyWeaversPath) 46 | 47 | $weavers = $xml["Weavers"] 48 | $node = $weavers.SelectSingleNode($addinName) 49 | 50 | if (-not $node) 51 | { 52 | Write-Host "Appending node" 53 | $newNode = $xml.CreateElement($addinName) 54 | $weavers.AppendChild($newNode) 55 | } 56 | 57 | $xml.Save($fodyWeaversPath) 58 | } 59 | 60 | function Fix-ReferencesCopyLocal($package, $project) 61 | { 62 | Write-Host "Fix-ReferencesCopyLocal $($package.Id)" 63 | $asms = $package.AssemblyReferences | %{$_.Name} 64 | 65 | foreach ($reference in $project.Object.References) 66 | { 67 | if ($asms -contains $reference.Name + ".dll") 68 | { 69 | if($reference.CopyLocal -eq $true) 70 | { 71 | $reference.CopyLocal = $false; 72 | } 73 | } 74 | } 75 | } 76 | 77 | function UnlockWeaversXml($project) 78 | { 79 | $fodyWeaversProjectItem = $project.ProjectItems.Item("FodyWeavers.xml"); 80 | if ($fodyWeaversProjectItem) 81 | { 82 | $fodyWeaversProjectItem.Open("{7651A701-06E5-11D1-8EBD-00A0C90F26EA}") 83 | $fodyWeaversProjectItem.Save() 84 | $fodyWeaversProjectItem.Document.Close() 85 | } 86 | } 87 | 88 | UnlockWeaversXml($project) 89 | 90 | RemoveForceProjectLevelHack $project 91 | 92 | Update-FodyConfig $package.Id.Replace(".Fody", "") $project 93 | 94 | Fix-ReferencesCopyLocal $package $project -------------------------------------------------------------------------------- /packages/Costura.Fody.1.6.2/tools/uninstall.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | 4 | function Update-FodyConfig($addinName, $project) 5 | { 6 | $fodyWeaversPath = [System.IO.Path]::Combine([System.IO.Path]::GetDirectoryName($project.FullName), "FodyWeavers.xml") 7 | 8 | if (!(Test-Path ($fodyWeaversPath))) 9 | { 10 | return 11 | } 12 | 13 | Write-Host "Caching variables for possible update" 14 | $env:FodyLastProjectPath = $project.FullName 15 | $env:FodyLastWeaverName = $addinName 16 | $env:FodyLastXmlContents = [IO.File]::ReadAllText($fodyWeaversPath) 17 | 18 | 19 | $xml = [xml](get-content $fodyWeaversPath) 20 | 21 | $weavers = $xml["Weavers"] 22 | $node = $weavers.SelectSingleNode($addinName) 23 | 24 | if ($node) 25 | { 26 | Write-Host "Removing node from FodyWeavers.xml" 27 | $weavers.RemoveChild($node) 28 | } 29 | 30 | $xml.Save($fodyWeaversPath) 31 | } 32 | 33 | 34 | function UnlockWeaversXml($project) 35 | { 36 | $fodyWeaversProjectItem = $project.ProjectItems.Item("FodyWeavers.xml"); 37 | if ($fodyWeaversProjectItem) 38 | { 39 | $fodyWeaversProjectItem.Open("{7651A701-06E5-11D1-8EBD-00A0C90F26EA}") 40 | $fodyWeaversProjectItem.Save() 41 | $fodyWeaversProjectItem.Document.Close() 42 | } 43 | } 44 | 45 | UnlockWeaversXml($project) 46 | 47 | Update-FodyConfig $package.Id.Replace(".Fody", "") $project -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/build/net20/DllExport.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | $(MSBuildThisFileDirectory)..\..\ 6 | $(NuPkgRootPath)tools\net.r_eg.DllExport.Wizard.targets 7 | 8 | 9 | 10 | Info 11 | $(SolutionPath) 12 | $(SolutionDir) 13 | $(NuPkgRootPath) 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/gcache/metalib/RGiesecke.DllExport/DllExport.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/gcache/metalib/RGiesecke.DllExport/DllExport.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/gcache/metalib/RGiesecke.DllExport/DllExport.dll.ddNSi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/gcache/metalib/RGiesecke.DllExport/DllExport.dll.ddNSi -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/gcache/metalib/System.Runtime.InteropServices/DllExport.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/gcache/metalib/System.Runtime.InteropServices/DllExport.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/gcache/metalib/System.Runtime.InteropServices/DllExport.dll.ddNSi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/gcache/metalib/System.Runtime.InteropServices/DllExport.dll.ddNSi -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/lib/net20/_._: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/lib/net20/_._ -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/Conari.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/Conari.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/Microsoft.Build.Framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/Microsoft.Build.Framework.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/Microsoft.Build.Utilities.v4.0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/Microsoft.Build.Utilities.v4.0.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/Microsoft.Build.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/Microsoft.Build.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/Microsoft.Management.Infrastructure.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/Microsoft.Management.Infrastructure.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/Mono.Cecil.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/MvsSln.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/MvsSln.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/NSBin.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/NSBin.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/PeViewer.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/PeViewer.exe -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/RGiesecke.DllExport.MSBuild.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/RGiesecke.DllExport.MSBuild.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/RGiesecke.DllExport.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/RGiesecke.DllExport.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/System.Management.Automation.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/System.Management.Automation.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/build.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | $(MSBuildThisFileDirectory)..\..\ 6 | $(NuPkgRootPath)tools\net.r_eg.DllExport.Wizard.targets 7 | 8 | 9 | 10 | Info 11 | $(SolutionPath) 12 | $(SolutionDir) 13 | $(NuPkgRootPath) 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/LICENSE.TXT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) .NET Foundation and Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/PATENTS.TXT: -------------------------------------------------------------------------------- 1 | Microsoft Patent Promise for .NET Libraries and Runtime Components 2 | 3 | Microsoft Corporation and its affiliates ("Microsoft") promise not to assert 4 | any .NET Patents against you for making, using, selling, offering for sale, 5 | importing, or distributing Covered Code, as part of either a .NET Runtime or 6 | as part of any application designed to run on a .NET Runtime. 7 | 8 | If you file, maintain, or voluntarily participate in any claim in a lawsuit 9 | alleging direct or contributory patent infringement by any Covered Code, or 10 | inducement of patent infringement by any Covered Code, then your rights under 11 | this promise will automatically terminate. 12 | 13 | This promise is not an assurance that (i) any .NET Patents are valid or 14 | enforceable, or (ii) Covered Code does not infringe patents or other 15 | intellectual property rights of any third party. No rights except those 16 | expressly stated in this promise are granted, waived, or received by 17 | Microsoft, whether by implication, exhaustion, estoppel, or otherwise. 18 | This is a personal promise directly from Microsoft to you, and you agree as a 19 | condition of benefiting from it that no Microsoft rights are received from 20 | suppliers, distributors, or otherwise from any other person in connection with 21 | this promise. 22 | 23 | Definitions: 24 | 25 | "Covered Code" means those Microsoft .NET libraries and runtime components as 26 | made available by Microsoft at https://github.com/dotnet/coreclr, 27 | https://github.com/dotnet/corefx and https://github.com/dotnet/corert. 28 | 29 | ".NET Patents" are those patent claims, both currently owned by Microsoft and 30 | acquired in the future, that are necessarily infringed by Covered Code. .NET 31 | Patents do not include any patent claims that are infringed by any Enabling 32 | Technology, that are infringed only as a consequence of modification of 33 | Covered Code, or that are infringed only by the combination of Covered Code 34 | with third party code. 35 | 36 | ".NET Runtime" means any compliant implementation in software of (a) all of 37 | the required parts of the mandatory provisions of Standard ECMA-335 – Common 38 | Language Infrastructure (CLI); and (b) if implemented, any additional 39 | functionality in Microsoft's .NET Framework, as described in Microsoft's API 40 | documentation on its MSDN website. For example, .NET Runtimes include 41 | Microsoft's .NET Framework and those portions of the Mono Project compliant 42 | with (a) and (b). 43 | 44 | "Enabling Technology" means underlying or enabling technology that may be 45 | used, combined, or distributed in connection with Microsoft's .NET Framework 46 | or other .NET Runtimes, such as hardware, operating systems, and applications 47 | that run on .NET Framework or other .NET Runtimes. -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/README.md: -------------------------------------------------------------------------------- 1 | [.NET Core Runtime (CoreCLR)](https://github.com/3F/coreclr) 2 | =========================== 3 | 4 | This repo contains the .NET Core runtime, called CoreCLR, and the base library, called mscorlib. It includes the garbage collector, JIT compiler, base .NET data types and many low-level classes. 5 | 6 | Build Status 7 | ------------ 8 | 9 | | CI 10 | --------------------| ---------------- 11 | Win.x86-x64.Release | [![Build status](https://ci.appveyor.com/api/projects/status/4gwh8k5wn62tk8iv/branch/master?svg=true)](https://ci.appveyor.com/project/3Fs/coreclr/branch/master) 12 | 13 | 14 | License 15 | ------- 16 | 17 | .NET Core (including the coreclr repo) is licensed under the [MIT license](LICENSE.TXT). 18 | 19 | -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/_Version.txt: -------------------------------------------------------------------------------- 1 | 2 | Architecture | Platform | Config | commit-sha1 | ILD/Asm | coreclr | Path 3 | -------------|----------|---------|------------------------------------------|---------------------------|---------|------------- 4 | x86 | Windows | Release | 05afa4f81fdf671429b54467c64d65cde6b5fadc | [ 4.5.1 ] -> *4.5.22220.0 | *v1.0.4 | \bin\Win.x86\ 5 | x64 | Windows | Release | 05afa4f81fdf671429b54467c64d65cde6b5fadc | [ 4.5.1 ] -> *4.5.22220.0 | *v1.0.4 | \bin\Win.x64\ 6 | 7 | `* - The base of version, i.e. it can be different from official release` 8 | 9 | https://github.com/3F/coreclr 10 | 11 | -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/changelog.txt: -------------------------------------------------------------------------------- 1 | https://github.com/3F/coreclr 2 | - - - - - - - - - - - - - - - - 3 | 4 | # coreclr \ ILAsm 5 | 6 | [v4.5.1] 7 | 8 | * FIXED: Fixed using of cvtres (.res -> obj COFF-format) in mscorpe. 9 | Possible crash: https://github.com/3F/coreclr/issues/2 10 | Related Issue: https://github.com/3F/DllExport/issues/17 11 | 12 | * NEW: Implemented additional searching of the converters of resources: 13 | Environment PATH, local directory, and other additional from user path. 14 | Now it also can be wrapped like ` mytool.cmd -> cvtres.exe %* ` etc. 15 | 16 | * NEW: Added new /CVRES (/CVR) key to ilasm.exe 17 | `/CVRES= Set path to cvtres tool: /CVR=cvtres.exe /CVR=tool\cvtres.cmd /CVR=D:\tool\` 18 | 19 | * NOTE: based on 4.5.22220.0 / coreclr 1.0.4 20 | ^ ^ ^ ^ 21 | | | | |-- VER_FILEVERSIONREVISION 22 | | | |------- VER_FILEVERSIONBUILD 23 | | |---------- VER_FILEVERSIONMINOR 24 | |------------ VER_MAJORVERSION 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/coreclr.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/coreclr/coreclr.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/ilasm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/coreclr/ilasm.exe -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/ildasm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/coreclr/ildasm.exe -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/ildasmrc.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/coreclr/ildasmrc.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/mscordaccore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/coreclr/mscordaccore.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/coreclr/mscordbi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/coreclr/mscordbi.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/net.r_eg.DllExport.Configurator.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/net.r_eg.DllExport.Configurator.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/net.r_eg.DllExport.Wizard.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/net.r_eg.DllExport.Wizard.dll -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/net.r_eg.DllExport.Wizard.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | true 7 | 8 | 9 | 10 | 11 | 12 | .\ 13 | packages\DllExport 14 | tools\raw\lib\net20\DllExport.dll 15 | tools\net.r_eg.DllExport.targets 16 | Restore 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Default 25 | 26 | 27 | 28 | 29 | 36 | -1 37 | 38 | 39 | 52 | 53 | 54 | true 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/net.r_eg.DllExport.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | true 6 | 7 | 8 | 9 | $(MSBuildThisFileDirectory)..\ 10 | $(VsInstallRoot)\ 11 | $(DevEnvDir)\..\..\ 12 | $(DllExportVSRoot)Common7\IDE\ 13 | 14 | gcache\metalib\$(DllExportNamespace)\ 15 | tools\ 16 | 17 | 18 | $(DllExportRootPkg)$(DllExportLibPath) 19 | DllExportAttribute 20 | DllExport.dll 21 | $(DllExportLibFullPath)$(DllExportMetaLibName) 22 | $(DllExportRootPkg)$(DllExportToolsPath)coreclr\ 23 | 24 | 25 | $(DllExportNamespace).$(DllExportMetaLibAttr) 26 | $(DllExportMetaLibAttr) 27 | 28 | 29 | 30 | 31 | $(PlatformTarget) 32 | $(CpuType) 33 | $(DebugSymbols) 34 | false 35 | 45000 36 | $(KeyContainerName)$(AssemblyKeyContainerName) 37 | $(KeyOriginatorFile) 38 | $(MSBuildProjectDirectory) 39 | $(TargetPath) 40 | $(DllExportILAsmCustomPath);$(TargetedFrameworkDir);$(TargetFrameworkDirectory) 41 | $(DllExportVSRoot)VC\bin 42 | $(DllExportVSBin) 43 | $(TargetFrameworkVersion) 44 | $(DllExportILAsmCustomPath);$(TargetFrameworkSDKToolsDirectory) 45 | $(NoDllExportsForAnyCpu) 46 | true 47 | false 48 | 1 49 | false 50 | 51 | $(DllExportVSRoot)Common7\Tools\VsDevCmd.bat 52 | $(DllExportVSRoot)VC\vcvarsall.bat;$(DllExportVSRoot)VC\Auxiliary\Build\vcvarsall.bat 53 | 54 | 55 | 56 | 81 | 82 | 83 | true 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /packages/DllExport.1.6.1/tools/raw/lib/net20/DllExport.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Awbugl/XQCSharpSDK/c33190756628da9b36d541c529f640a76a3a9045/packages/DllExport.1.6.1/tools/raw/lib/net20/DllExport.dll -------------------------------------------------------------------------------- /packages/Fody.2.2.1.0/Content/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/Fody.2.2.1.0/Tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | $item = $project.ProjectItems | where-object {$_.Name -eq "FodyWeavers.xml"} 3 | $item.Properties.Item("BuildAction").Value = [int]0 -------------------------------------------------------------------------------- /packages/Fody.2.2.1.0/build/net452/Fody.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | $(NCrunchOriginalSolutionDir) 7 | 8 | 9 | 10 | 11 | $(SolutionDir) 12 | 13 | 14 | 15 | 16 | $(MSBuildProjectDirectory)..\..\..\ 17 | 18 | 19 | 20 | 21 | 22 | 23 | $(KeyOriginatorFile) 24 | 25 | 26 | 27 | 28 | $(AssemblyOriginatorKeyFile) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | $(ProjectDir)FodyWeavers.xml 39 | $(SignAssembly) 40 | $(MSBuildThisFileDirectory)..\..\ 41 | 42 | 45 | 52 | 53 | 69 | 70 | 73 | 74 | 75 | 76 | True 77 | 78 | 79 | 80 | 81 | 82 | 85 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /packages/Fody.2.2.1.0/build/netstandard1.2/Fody.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | $(NCrunchOriginalSolutionDir) 7 | 8 | 9 | 10 | 11 | $(SolutionDir) 12 | 13 | 14 | 15 | 16 | $(MSBuildProjectDirectory)..\..\..\ 17 | 18 | 19 | 20 | 21 | 22 | 23 | $(KeyOriginatorFile) 24 | 25 | 26 | 27 | 28 | $(AssemblyOriginatorKeyFile) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | $(ProjectDir)FodyWeavers.xml 39 | $(SignAssembly) 40 | $(MSBuildThisFileDirectory)..\..\ 41 | 42 | 45 | 52 | 53 | 69 | 70 | 73 | 74 | 75 | 76 | True 77 | 78 | 79 | 80 | 81 | 82 | 85 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /packages/Fody.2.2.1.0/build/portable-net+sl+win+wpa+wp/Fody.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | $(NCrunchOriginalSolutionDir) 7 | 8 | 9 | 10 | 11 | $(SolutionDir) 12 | 13 | 14 | 15 | 16 | $(MSBuildProjectDirectory)..\..\..\ 17 | 18 | 19 | 20 | 21 | 22 | 23 | $(KeyOriginatorFile) 24 | 25 | 26 | 27 | 28 | $(AssemblyOriginatorKeyFile) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | $(ProjectDir)FodyWeavers.xml 39 | $(SignAssembly) 40 | $(MSBuildThisFileDirectory)..\..\ 41 | 42 | 45 | 52 | 53 | 69 | 70 | 73 | 74 | 75 | 76 | True 77 | 78 | 79 | 80 | 81 | 82 | 85 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | --------------------------------------------------------------------------------