├── .gitignore ├── .gitattributes ├── TextTemplate.ico ├── obj └── Debug │ └── net5.0 │ ├── MeowIOTBot.AssemblyInfoInputs.cache │ ├── .NETCoreApp,Version=v5.0.AssemblyAttributes.cs │ ├── MeowIOTBot.GeneratedMSBuildEditorConfig.editorconfig │ └── MeowIOTBot.AssemblyInfo.cs ├── .vs └── MeowIOTBot │ ├── v16 │ └── .suo │ └── DesignTimeBuild │ └── .dtbcache.v2 ├── githubImgFolder ├── _com1.png ├── _com2.png ├── _com3.png ├── _com4.png ├── _com5.png ├── _com6.png ├── _com7.png ├── _gif1.gif ├── _gif2.gif ├── _gif3.gif ├── LogoLong.png ├── sendtest.png └── MainClassdg.jpg ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── feature-request-------.md │ └── bug-report---------.md └── workflows │ └── dotnet.yml ├── README.md ├── LICENSE ├── MeowIOTBot.sln ├── ExceptionCore.cs ├── ObjectEvent └── GeneralEventArgs.cs ├── Serverutil.cs ├── MeowIOTBot.csproj ├── QQ ├── LoginQQEvent.cs ├── QQAction.cs ├── QQEvent.cs ├── QQRecieveMessage.cs ├── QQSendMessage.cs └── QQFunc.cs ├── CODE_OF_CONDUCT.md ├── NetworkHelperGeneral ├── HttpHelper.cs └── PostHelper.cs ├── _Client ├── MeowClient.cs └── ClientX.cs └── MainClassdg.cd /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | bin/ 3 | obj/ 4 | .vs/ 5 | MeowIOTBotTest.sln 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /TextTemplate.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/TextTemplate.ico -------------------------------------------------------------------------------- /obj/Debug/net5.0/MeowIOTBot.AssemblyInfoInputs.cache: -------------------------------------------------------------------------------- 1 | dfce52238f6fd610cdc52d3dac8bf22e97d59faa 2 | -------------------------------------------------------------------------------- /.vs/MeowIOTBot/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/.vs/MeowIOTBot/v16/.suo -------------------------------------------------------------------------------- /githubImgFolder/_com1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_com1.png -------------------------------------------------------------------------------- /githubImgFolder/_com2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_com2.png -------------------------------------------------------------------------------- /githubImgFolder/_com3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_com3.png -------------------------------------------------------------------------------- /githubImgFolder/_com4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_com4.png -------------------------------------------------------------------------------- /githubImgFolder/_com5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_com5.png -------------------------------------------------------------------------------- /githubImgFolder/_com6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_com6.png -------------------------------------------------------------------------------- /githubImgFolder/_com7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_com7.png -------------------------------------------------------------------------------- /githubImgFolder/_gif1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_gif1.gif -------------------------------------------------------------------------------- /githubImgFolder/_gif2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_gif2.gif -------------------------------------------------------------------------------- /githubImgFolder/_gif3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/_gif3.gif -------------------------------------------------------------------------------- /githubImgFolder/LogoLong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/LogoLong.png -------------------------------------------------------------------------------- /githubImgFolder/sendtest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/sendtest.png -------------------------------------------------------------------------------- /githubImgFolder/MainClassdg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/githubImgFolder/MainClassdg.jpg -------------------------------------------------------------------------------- /.vs/MeowIOTBot/DesignTimeBuild/.dtbcache.v2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opq-osc/MeowIOTBot/HEAD/.vs/MeowIOTBot/DesignTimeBuild/.dtbcache.v2 -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # IDE1006: Naming Styles 4 | dotnet_diagnostic.IDE1006.severity = silent 5 | 6 | # CA1507: Use nameof to express symbol names 7 | dotnet_diagnostic.CA1507.severity = silent 8 | -------------------------------------------------------------------------------- /obj/Debug/net5.0/.NETCoreApp,Version=v5.0.AssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using System.Reflection; 4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v5.0", FrameworkDisplayName = "")] 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request-------.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request [功能要求] 3 | about: Suggest an idea for this project [您希望添加的功能] 4 | title: "[功能建议] : 当前使用版本 @ 时间" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | Describe the Feature * (描述您需要的功能) 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![如果你看到这行字说明您需要翻墙查看内容](https://github.com/DavidSciMeow/MeowIOTBot/blob/main/githubImgFolder/LogoLong.png)](test) 2 | 3 | 注:由于本喵已经转向`Mirai-C#`开发,本工具包故`不再维护`,您可以`申请权限对本库进行维护`,或者使用`其他社区产品` 4 | 注2:本喵及其推荐 `YukinoshitaBot.OPQ` 项目,其使用`注入`和`类MVC`结构实现Bot管理和控制,虽然不如本包开放,但是极具实验意义. 5 | 6 | ``` 7 | @{ 8 | DavidSciMeow,SDU,20220505 9 | } 10 | ``` 11 | -------------------------------------------------------------------------------- /obj/Debug/net5.0/MeowIOTBot.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.TargetFramework = net5.0 3 | build_property.TargetPlatformMinVersion = 4 | build_property.UsingMicrosoftNETSdkWeb = 5 | build_property.ProjectTypeGuids = 6 | build_property.PublishSingleFile = 7 | build_property.IncludeAllContentForSelfExtract = 8 | build_property._SupportedPlatformList = Android,iOS,Linux,macOS,Windows 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report---------.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report [错误运行报告] 3 | about: " -- Problems occur [问题]" 4 | title: "[错误报告] : 版本 @ 时间" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** (描述问题以及问题状态) 11 | 12 | **To Reproduce** (复现方案或造成原因) 13 | 14 | **Expected behavior** (您所期望的操作结果) 15 | 16 | **Screenshots** (错误截图) 17 | 18 | **Desktop (please complete the following information):** (您的设备型号) 19 | - OS(操作系统): [e.g. iOS] 20 | - Application Version(框架版本号): [e.g. 22] 21 | 22 | **Additional context** (其他留言) 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 DavidSciMeow 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. 22 | -------------------------------------------------------------------------------- /MeowIOTBot.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30717.126 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MeowIOTBot", "MeowIOTBot.csproj", "{3CD6E6DE-6285-4D2A-A4AF-5DDDCD92B3F4}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3CD6E6DE-6285-4D2A-A4AF-5DDDCD92B3F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3CD6E6DE-6285-4D2A-A4AF-5DDDCD92B3F4}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3CD6E6DE-6285-4D2A-A4AF-5DDDCD92B3F4}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3CD6E6DE-6285-4D2A-A4AF-5DDDCD92B3F4}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {6E8EC361-1632-4BAD-BD65-C35212562092} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ExceptionCore.cs: -------------------------------------------------------------------------------- 1 | namespace MeowIOTBot 2 | { 3 | /// 4 | /// 用于枚举错误类型 5 | /// for Enum the Exception Type 6 | /// 7 | public sealed class EC 8 | { 9 | /// 10 | /// 错误类型定义符 11 | /// 12 | public readonly static string E00 = "Json事件缺少 [EventMsg] ,无法初始化事件"; 13 | /// 14 | /// 错误类型定义符 15 | /// 16 | public readonly static string E01 = "Json事件缺少 [EventName] , 无法确定类型"; 17 | /// 18 | /// 错误类型定义符 19 | /// 20 | public readonly static string E02 = "Json事件缺少 [EventData] , 没有内部初始化"; 21 | /// 22 | /// 错误类型定义符 23 | /// 24 | public readonly static string E11 = "同意类型缺失,没有参数呈递"; 25 | /// 26 | /// 错误类型定义符 27 | /// 28 | public readonly static string E12 = "本消息类型无法回复,不含逻辑参数"; 29 | /// 30 | /// 错误类型定义符 31 | /// 32 | public readonly static string E13 = "图片转换失效,请检查传入的bitmap实例"; 33 | /// 34 | /// 错误类型定义符 35 | /// 36 | public readonly static string E14 = "图片转换失效,bitmap实例为空"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ObjectEvent/GeneralEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | 4 | namespace MeowIOTBot.ObjectEvent 5 | { 6 | /// 7 | /// 对象化事件 8 | /// Objective EventArgs 9 | /// 10 | public class ObjectEventArgs : EventArgs 11 | { 12 | /// 13 | /// 构造函数 14 | /// Constructor 15 | /// 16 | /// 17 | /// 服务端的原始数据 (需要Newtonsoft解析) 18 | /// Serveric raw data(which needs Newtonsoft Expeclict) 19 | /// 20 | public ObjectEventArgs(JObject raw) 21 | { 22 | Data = raw["CurrentPacket"]["Data"].ToObject(); 23 | CurrentQQ = raw["CurrentQQ"].ToObject(); 24 | WebConnId = raw["CurrentPacket"]["WebConnId"].ToString(); 25 | } 26 | /// 27 | /// 重写的服务端Data字段 28 | /// Rewrite Data from Server 29 | /// 30 | public JObject Data { get; } 31 | /// 32 | /// 重写的CurrentQQ字段 33 | /// Rewrite 'currentQQ' from server 34 | /// 35 | public long CurrentQQ { get; } 36 | /// 37 | /// 重写的WebConnId字段 38 | /// Rewrite 'WebConnId' from server 39 | /// 40 | public string WebConnId { get; } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /obj/Debug/net5.0/MeowIOTBot.AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | using System; 12 | using System.Reflection; 13 | 14 | [assembly: System.Reflection.AssemblyCompanyAttribute("Electronicute")] 15 | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 16 | [assembly: System.Reflection.AssemblyCopyrightAttribute("2020 @ Electronicute")] 17 | [assembly: System.Reflection.AssemblyDescriptionAttribute("var 5.4.0\r\n优化了进程监视器,更新类图")] 18 | [assembly: System.Reflection.AssemblyFileVersionAttribute("5.4.0.0")] 19 | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("5.4.0")] 20 | [assembly: System.Reflection.AssemblyProductAttribute("MeowIOTBot")] 21 | [assembly: System.Reflection.AssemblyTitleAttribute("MeowIOTBot")] 22 | [assembly: System.Reflection.AssemblyVersionAttribute("5.4.0.44")] 23 | [assembly: System.Reflection.AssemblyMetadataAttribute("RepositoryUrl", "https://github.com/DavidSciMeow/MeowIOTBot")] 24 | [assembly: System.Resources.NeutralResourcesLanguageAttribute("zh")] 25 | 26 | // Generated by the MSBuild WriteCodeFragment class. 27 | 28 | -------------------------------------------------------------------------------- /Serverutil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MeowIOTBot 8 | { 9 | /// 10 | /// 服务端日志标准 11 | /// 12 | public enum LogType 13 | { 14 | /// 15 | /// 无日志 16 | /// 17 | None = 0, 18 | /// 19 | /// 客户端信息流 20 | /// 21 | ClientMessage = 1, 22 | /// 23 | /// 客户端事件流 24 | /// 25 | ClientVerbose = 2, 26 | /// 27 | /// 服务端信息流 28 | /// 29 | ServerMessage = 3, 30 | /// 31 | /// 完整日志 32 | /// 33 | Verbose = 4 34 | } 35 | /// 36 | /// 服务端工具包 37 | /// 38 | public class ServerUtil 39 | { 40 | /// 41 | /// 服务器日志 42 | /// 43 | /// 记录 44 | /// 类型 45 | /// 前景色 46 | /// 背景色 47 | /// * 48 | public static int Log(string s, LogType l, ConsoleColor Fore = ConsoleColor.White, ConsoleColor Back = ConsoleColor.Black, int k = 0) 49 | { 50 | if ((int)Basex.MeowClient.logFlag >= (int)l) 51 | { 52 | Console.ForegroundColor = Fore; 53 | Console.BackgroundColor = Back; 54 | Console.WriteLine($"- [Meow] [{DateTime.Now}] - \n{s}"); 55 | Console.ResetColor(); 56 | } 57 | return k; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | name: dotnet 2 | #只在main上的操作会进行 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | #工作流任务列表 9 | jobs: 10 | Build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | #设置dotnet操作流环境 15 | - name: Setup .NET 16 | uses: actions/setup-dotnet@v1 17 | with: 18 | dotnet-version: 5.0.x 19 | #恢复库 20 | - name: Restore dependencies 21 | run: dotnet restore 22 | #构建 23 | - name: Build 24 | run: dotnet build --no-restore 25 | #任务2:测试 26 | - name: Test 27 | run: dotnet test --no-build --verbosity normal 28 | #任务2:发布Nuget 29 | Publish: 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v2 33 | #设置dotnet操作流环境 34 | - name: Setup .NET 35 | uses: actions/setup-dotnet@v1 36 | with: 37 | dotnet-version: 5.0.x 38 | #恢复库 39 | - name: Restore dependencies 40 | run: dotnet restore 41 | #构建 42 | - name: Build 43 | run: dotnet build --no-restore 44 | #任务2:测试 45 | - name: Test 46 | run: dotnet test --no-build --verbosity normal 47 | #任务3:发布nuget 48 | - name: Publish 49 | uses: brandedoutcast/publish-nuget@v2.5.2 50 | with: 51 | PROJECT_FILE_PATH: MeowIOTBot.csproj #确定发布项目名 52 | NUGET_KEY: ${{secrets.NUGET_API_KEY}} #使用专用key 53 | #GitRelease: 54 | #runs-on: ubuntu-latest 55 | #steps: 56 | #任务4:创建github release 57 | #- name: Create GitHub release 58 | #uses: marvinpinto/action-automatic-releases@latest 59 | #with: 60 | #repo_token: "${{ secrets.ACC_TOKEN }}" 61 | #automatic_release_tag: ${{ env.ReleaseVersion }} 62 | #title: ${{ env.ReleaseVersion }} 63 | #prerelease: false 64 | #files: | 65 | #artifacts/packages/* 66 | -------------------------------------------------------------------------------- /MeowIOTBot.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | true 6 | true 7 | DavidSciMeow 8 | Electronicute 9 | MeowIOTBot 10 | var 5.4.0 11 | 优化了进程监视器,更新类图 12 | 2020 @ Electronicute 13 | MIT 14 | https://github.com/DavidSciMeow/MeowIOTBot 15 | GitHub 16 | 17 | zh 18 | https://github.com/DavidSciMeow/MeowIOTBot 19 | false 20 | false 21 | Electronicute.pfx 22 | 5.4.0 23 | 5.4.0.44 24 | 5.4.0.0 25 | Electronicute.MeowIOTBot 26 | IOTQQBot, QQBot, Tencent, opqbot 27 | TextTemplate.ico 28 | 29 | 30 | 31 | C:\Users\David\source\repos\MeowIOTBot\MeowIOTBot.xml 32 | false 33 | Auto 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /QQ/LoginQQEvent.cs: -------------------------------------------------------------------------------- 1 | using MeowIOTBot.NetworkHelper; 2 | using System; 3 | using System.Drawing; 4 | using System.IO; 5 | 6 | namespace MeowIOTBot 7 | { 8 | /// 9 | /// 框架登录处理 10 | /// Interfaceable QQ Login 11 | /// 12 | public class LoginQQ 13 | { 14 | /// 15 | /// 登录接口 16 | /// Login Interface 17 | /// 18 | /// 19 | /// 打印时控制台的高度(建议50),过大可能导致分页 20 | /// console output selected height -by default is 50 (be aware if too large may cause to split-page) 21 | /// 22 | /// 23 | /// 打印时控制台的宽度(建议50),过大可能导致分页 24 | /// console output selected width -by default is 50 (be aware if too large may cause to split-page) 25 | /// 26 | public static async void Login(int imgHeight = 50, int imgWidth = 50) 27 | { 28 | string d = await PostHelper.PASA(PostHelper.UrlType.LoginQQ, ""); 29 | var st = d.IndexOf("base64,"); 30 | string base64 = d.Substring(st, d[st..].IndexOf("\"")).Replace("base64,",""); 31 | PrintQRCodeFromBase64(base64, imgHeight, imgWidth); 32 | } 33 | /// 34 | /// 打印QR码 35 | /// 36 | /// base64子串 37 | /// 高度 38 | /// 宽度 39 | private static void PrintQRCodeFromBase64(string base64img, int height, int width) 40 | { 41 | MemoryStream stream = new(Convert.FromBase64String(base64img)); 42 | Bitmap b = new(new Bitmap(stream), width, height); 43 | for (int x = 0; x < width; x++) 44 | { 45 | for (int y = 0; y < height; y++) 46 | { 47 | var d = b.GetPixel(x, y); 48 | if (d.GetBrightness() < (float)0.5) 49 | { 50 | Console.BackgroundColor = ConsoleColor.White; 51 | Console.Write(" "); 52 | Console.ResetColor(); 53 | } 54 | else 55 | { 56 | Console.BackgroundColor = ConsoleColor.Black; 57 | Console.Write(" "); 58 | Console.ResetColor(); 59 | } 60 | } 61 | Console.WriteLine(); 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at 1500294830@qq.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /NetworkHelperGeneral/HttpHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MeowIOTBot.NetworkHelper 8 | { 9 | /// 10 | /// 特征网络包发送类 11 | /// an Interface (actually class) for PostData to Server 12 | /// 13 | public class HttpHelper 14 | { 15 | /// 16 | /// 连接节点 17 | /// Backend Point 18 | /// 19 | public string Url; 20 | /// 21 | /// 内容默认模式 22 | /// ContentType 23 | /// 24 | public string contentType; 25 | /// 26 | /// Nginx 设置的头检测 27 | /// HeaderCheck for linux Nginx 28 | /// 29 | public WebHeaderCollection Header = null; 30 | /// 31 | /// 继承用空参构造 32 | /// empty-constructor for inherit 33 | /// 34 | public HttpHelper() { } 35 | /// 36 | /// 外源用构造 37 | /// constructor for Extern Usage 38 | /// 39 | /// 40 | /// 要连接的URL 41 | /// the url you wanna to get or post 42 | /// 43 | /// 44 | /// 内容格式 (多数是Json) 45 | /// a Type to specific the content Usage : mostly is "application/json" 46 | /// 47 | public HttpHelper(string url, string contentType) 48 | { 49 | Url = url; 50 | this.contentType = contentType; 51 | } 52 | /// 53 | /// 构造函数 54 | /// Constructor 55 | /// 56 | /// 57 | /// 连接节点 58 | /// Backend Point 59 | /// 60 | /// 61 | /// 内容格式 62 | /// Usually is Json 63 | /// 64 | /// 65 | /// UA识别头 66 | /// HeaderCheck for Linux Nginx 67 | /// 68 | public HttpHelper(string url, string contentType, WebHeaderCollection header = null) 69 | { 70 | Url = url; 71 | Header = header; 72 | this.contentType = contentType; 73 | } 74 | /// 75 | /// 使用连接获取操作 76 | /// using Connector to get 77 | /// 78 | /// 79 | /// 获得的字符 80 | /// Strings for Response 81 | /// 82 | public async Task HttpGet() 83 | { 84 | try 85 | { 86 | string retString = string.Empty; 87 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); 88 | request.Method = "GET"; 89 | request.ContentType = contentType; 90 | HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); //响应结果 91 | Stream myResponseStream = response.GetResponseStream(); 92 | StreamReader streamReader = new(myResponseStream); 93 | retString = streamReader.ReadToEnd(); 94 | streamReader.Close(); 95 | myResponseStream.Close(); 96 | return retString; 97 | } 98 | catch 99 | { 100 | throw; 101 | } 102 | } 103 | /// 104 | /// 使用连接发送数据 105 | /// to Send a Post Connection 106 | /// 107 | /// 108 | /// 要发送的数据 109 | /// Content which waiting to send a POST Action 110 | /// 111 | /// 112 | /// 操作返回的字符 113 | /// Action return string 114 | /// 115 | public async Task HttpPost(string Content) 116 | { 117 | try 118 | { 119 | string result; 120 | HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Url); 121 | req.Method = "POST"; 122 | req.ContentType = contentType; 123 | req.Headers = Header; 124 | byte[] data = Encoding.UTF8.GetBytes(Content);//把字符串转换为字节 125 | 126 | req.ContentLength = data.Length; //请求长度 127 | 128 | using (Stream reqStream = req.GetRequestStream()) //获取 129 | { 130 | reqStream.Write(data, 0, data.Length);//向当前流中写入字节 131 | reqStream.Close(); //关闭当前流 132 | } 133 | HttpWebResponse resp = (HttpWebResponse)await req.GetResponseAsync(); //响应结果 134 | Stream stream = resp.GetResponseStream(); 135 | //获取响应内容 136 | using (StreamReader reader = new(stream, Encoding.UTF8)) 137 | { 138 | result = reader.ReadToEnd(); 139 | } 140 | return result; 141 | } 142 | catch (Exception ex) 143 | { 144 | Console.WriteLine(ex.Message); 145 | return null; 146 | } 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /NetworkHelperGeneral/PostHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MeowIOTBot.NetworkHelper 8 | { 9 | /// 10 | /// 一个用于和IOT交流的PostHelper 11 | /// an IOT PostHelper for user delegate 12 | /// 13 | public class PostHelper 14 | { 15 | /// 16 | /// POST的URL地址 17 | /// for POST URL Position 18 | /// 19 | public static string CallerUrl { get; set; } 20 | /// 21 | /// 登录QQ 22 | /// Login QQ number 23 | /// 24 | public static string LoginQQ { get; set; } 25 | /// 26 | /// 超时设置(可以进行动态设置,默认是30s) 27 | /// setting for Timeout (*which COULD be dynamic and init with 30s) 28 | /// 29 | public static int Timeout { get; set; } = 30; 30 | /// 31 | /// 一个Nginx的Header识别标 32 | /// A nginx Header Surffix 33 | /// 34 | public static WebHeaderCollection Header { get; set; } 35 | /// 36 | /// 准备并且发送一个请求 37 | /// Prepare And Send Async (PASA) 38 | /// 39 | /// 40 | /// 要发送的"指令"类型 41 | /// the Command Type you want to Send 42 | /// 43 | /// 44 | /// 要发送的Json集 45 | /// 46 | /// 47 | public static async Task PASA(UrlType urlType, string Json) { 48 | try 49 | { 50 | var Url = urlType switch 51 | { 52 | UrlType.init => throw (new Exception("Initialization is done by Server!")), 53 | UrlType.ClusterInfo => $"{CallerUrl}/v1/ClusterInfo", 54 | UrlType.Announce => $"{CallerUrl}/v1/Group/Announce?qq={LoginQQ}", 55 | UrlType.LoginQQ => $"{CallerUrl}/v1/Login/GetQRcode", 56 | UrlType.__RefreshKeys => $"{CallerUrl}/v1/RefreshKeys?qq={LoginQQ}", 57 | UrlType.__Logs => $"{CallerUrl}/v1/Log", 58 | UrlType.ShutUpSingle => $"{CallerUrl}/v1/LuaApiCaller?qq={LoginQQ}&funcname=OidbSvc.0x570_8&timeout={Timeout}", 59 | UrlType.Tickles => $"{CallerUrl}/v1/LuaApiCaller?qq={LoginQQ}&funcname=OidbSvc.0xed3_1&timeout={Timeout}", 60 | UrlType.ShutUpEntirely => $"{CallerUrl}/v1/LuaApiCaller?qq={LoginQQ}&funcname=OidbSvc.0x89a_0&timeout={Timeout}", 61 | //UrlType.SendMsgV2 => $"{CallerUrl}/v2/LuaApiCaller?qq={LoginQQ}&funcname={urlType}&timeout={Timeout}", 62 | _ => $"{CallerUrl}/v1/LuaApiCaller?qq={LoginQQ}&funcname={urlType}&timeout={Timeout}", 63 | }; 64 | 65 | string result; 66 | HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Url); 67 | req.Method = "POST"; 68 | req.ContentType = "application/json"; 69 | req.Headers = Header??new WebHeaderCollection(); 70 | byte[] data = Encoding.UTF8.GetBytes(Json);//把字符串转换为字节 71 | 72 | req.ContentLength = data.Length; //请求长度 73 | 74 | using (Stream reqStream = req.GetRequestStream()) //获取 75 | { 76 | reqStream.Write(data, 0, data.Length);//向当前流中写入字节 77 | reqStream.Close(); //关闭当前流 78 | } 79 | HttpWebResponse resp = (HttpWebResponse)await req.GetResponseAsync(); //响应结果 80 | Stream stream = resp.GetResponseStream(); 81 | //获取响应内容 82 | using (StreamReader reader = new(stream, Encoding.UTF8)) 83 | { 84 | result = reader.ReadToEnd(); 85 | } 86 | return result; 87 | } 88 | catch (Exception ex) 89 | { 90 | Console.WriteLine(ex.Message); 91 | return null; 92 | } 93 | } 94 | /// 95 | /// 发送的类型(不断更新) 96 | /// an type that used to PostAction 97 | /// 98 | public enum UrlType 99 | { 100 | /// 101 | /// 全局日志 102 | /// 103 | __Logs, 104 | /// 105 | /// 刷新Key重新登录 106 | /// 107 | __RefreshKeys, 108 | /// 109 | /// 登录QQ 110 | /// get one QQ Login 111 | /// 112 | LoginQQ, 113 | /// 114 | /// 登出 115 | /// LogOut Some QQ 116 | /// 117 | LogOut, 118 | /// 119 | /// 集群信息 120 | /// get clusterinfo 121 | /// 122 | ClusterInfo, 123 | /// 124 | /// 发送群公告 125 | /// send Announce 126 | /// 127 | Announce, 128 | /// 129 | /// 自动初始化 (大多数时间服务器已经自动初始化了) 130 | /// initialization (Most of the time is Done by server backend) 131 | /// 132 | init, 133 | /// 134 | /// 发送信息(弃用) 135 | /// send Message which is already Obselete 136 | /// 137 | [Obsolete("已弃用", false)] 138 | SendMsg, 139 | /// 140 | /// 新的发送信息接口 141 | /// Version2 SendMsg 142 | /// 143 | SendMsgV2, 144 | /// 145 | /// 获取好友列表 146 | /// get FirendList 147 | /// 148 | GetQQUserList, 149 | /// 150 | /// 搜索QQ群 151 | /// search for QQGroup 152 | /// 153 | SearchGroup, 154 | /// 155 | /// 获取群列表 156 | /// Get Group List 157 | /// 158 | GetGroupList, 159 | /// 160 | /// 获取群成员列表 161 | /// get GroupUserList 162 | /// 163 | GetGroupUserList, 164 | /// 165 | /// 发送赞 166 | /// send QQZan to someone 167 | /// 168 | QQZan, 169 | /// 170 | /// 添加好友 171 | /// Add some QQUser 172 | /// 173 | AddQQUser, 174 | /// 175 | /// 撤回信息 176 | /// Revoke Message 177 | /// 178 | RevokeMsg, 179 | /// 180 | /// 禁言某人 181 | /// Shut somebody (Please note This COULD have othe affect) 182 | /// 183 | ShutUpSingle, 184 | /// 185 | /// 禁言整个群组 186 | /// Shut Whole Group 187 | /// 188 | ShutUpEntirely, 189 | /// 190 | /// 处理好友请求 191 | /// Dealwith Friend Request 192 | /// 193 | DealFriend, 194 | /// 195 | /// 处理群请求 196 | /// returnAnswerFromInvite 197 | /// 198 | AnswerInviteGroup, 199 | /// 200 | /// 更改群名片 201 | /// to Change GroupID 202 | /// 203 | ModifyGroupCard, 204 | /// 205 | /// 设置头衔 206 | /// set Title 207 | /// 208 | SetUniqueTitle, 209 | /// 210 | /// 获取任意用户信息 211 | /// getUserInfo 212 | /// 213 | GetUserInfo, 214 | /// 215 | /// 获取当前用户相关Cookie 216 | /// get User Cookies 217 | /// 218 | GetUserCook, 219 | /// 220 | /// 加群退群管理 221 | /// add in or leave Group Control 222 | /// 223 | GroupMgr, 224 | /// 225 | /// 戳一戳 226 | /// repersent the Tickle action 227 | /// 228 | Tickles 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /_Client/MeowClient.cs: -------------------------------------------------------------------------------- 1 | using MeowIOTBot.ObjectEvent; 2 | using Newtonsoft.Json.Linq; 3 | using Socket.Io.Client.Core.Model.SocketIo; 4 | using System; 5 | 6 | namespace MeowIOTBot.Basex 7 | { 8 | /// 9 | /// 代理的类 10 | /// DelegateLibrary 11 | /// 12 | /// 用法如下 (Usage) 13 | /// using var c = new MeowClient("url", "qq"); 14 | /// c.Connect(); 15 | /// c.OnServerAction += (s, e) =>{}; 16 | /// 17 | /// 18 | public class MeowClient : IDisposable 19 | { 20 | /// 21 | /// 日志记录标志 22 | /// decided if you want to Console.Write(log) 23 | /// this can be dynamically 24 | /// 25 | public static LogType logFlag { get; set; } 26 | /// 27 | /// socket标 28 | /// socket Client Variable 29 | /// 30 | public Socket.Io.Client.Core.SocketIoClient ss = new(); 31 | /// 32 | /// Url 33 | /// 34 | public string Url; 35 | /// 36 | /// 进程监视器 37 | /// 38 | public System.Timers.Timer MonitorTimer = new() 39 | { 40 | Interval = 10000,//10s 41 | AutoReset = true, 42 | }; 43 | /// 44 | /// 构造代理的类 45 | /// 46 | /// ws的连接Client位置 例如 ws://localhost:10000 47 | /// 是否打印日志 48 | /// 底层监视器回报的间隔(底层监视器将在第一次连接成功后一直回报到进程结束) 49 | /// 50 | public MeowClient(string url, LogType logflag, long MonitorInterval = 10000, bool _MonitorEnable = true) 51 | { 52 | logFlag = logflag; 53 | Url = url; 54 | MonitorTimer.Interval = MonitorInterval; 55 | MonitorTimer.Elapsed += (s, e) => 56 | { 57 | switch( ss.State switch 58 | { 59 | ReadyState.Open => ServerUtil.Log($"[Monitor : Serveric State Open]",LogType.Verbose, k: 0), 60 | ReadyState.Opening => ServerUtil.Log($"[Monitor : Serveric State Opening]",LogType.Verbose, k: 1), 61 | ReadyState.Paused => ServerUtil.Log($"[Monitor : Serveric State Paused]",LogType.Verbose, k: 2), 62 | ReadyState.Closing => ServerUtil.Log($"[Monitor : Serveric State Closing]",LogType.Verbose, k: 3), 63 | ReadyState.Closed => ServerUtil.Log($"[Monitor : Serveric State Closed]",LogType.Verbose, k: 4), 64 | _ => ServerUtil.Log($"[Monitor : Serveric State Err]",LogType.Verbose, k: 5), 65 | }) 66 | { 67 | case 0: _ServericOpen.Invoke(new(), new());break; 68 | case 2: _ServericPaused.Invoke(new(), new());break; 69 | case 4: _ServericClosed.Invoke(new(), new());break; 70 | default:break; 71 | } 72 | }; 73 | ss.Events.OnConnect.Subscribe(d => 74 | { 75 | ServerUtil.Log($"[Connected] {d}", LogType.None); 76 | }); 77 | ss.Events.OnOpen.Subscribe(d => 78 | { 79 | ServerUtil.Log($"[Open] {d}", LogType.ServerMessage); 80 | }); 81 | ss.Events.OnHandshake.Subscribe(d => 82 | { 83 | ServerUtil.Log($"[HandShake] SID:{d.Sid} PI:{d.PingInterval} PT:{d.PingTimeout}", LogType.Verbose); 84 | }); 85 | ss.Events.OnPong.Subscribe(d => 86 | { 87 | ServerUtil.Log($"[Pong] {d.Data}", LogType.Verbose); 88 | }); 89 | ss.Events.OnError.Subscribe(d => 90 | { 91 | ServerUtil.Log($"[Err] {d.Description}", LogType.ServerMessage); 92 | }); 93 | ss.Events.OnProbeError.Subscribe(d => 94 | { 95 | ServerUtil.Log($"[ProbeErr] {d.PingData} {d.PongData}", LogType.ServerMessage); 96 | }); 97 | ss.Events.OnPacket.Subscribe(d => 98 | { 99 | if (!string.IsNullOrEmpty(d.Data)) 100 | { 101 | ServerUtil.Log($"[Packet] {d.Data}", LogType.Verbose); 102 | try 103 | { 104 | var ja = JArray.Parse(d.Data); 105 | if ("OnGroupMsgs".Equals(ja[0].ToString())) 106 | { 107 | var x = new ObjectEventArgs(JObject.Parse(ja[1].ToString())); 108 | OnServerAction.Invoke(new object(), x); 109 | OnGroupMsgs.Invoke(new object(), x); 110 | } 111 | else if ("OnFriendMsgs".Equals(ja[0].ToString())) 112 | { 113 | var x = new ObjectEventArgs(JObject.Parse(ja[1].ToString())); 114 | OnServerAction.Invoke(new object(), x); 115 | OnFriendMsgs.Invoke(new object(), x); 116 | } 117 | else if ("OnEvents".Equals(ja[0].ToString())) 118 | { 119 | var x = new ObjectEventArgs(JObject.Parse(ja[1].ToString())); 120 | OnServerAction.Invoke(new object(), x); 121 | OnEventMsgs.Invoke(new object(), x); 122 | } 123 | } 124 | catch 125 | { 126 | 127 | } 128 | } 129 | else 130 | { 131 | ServerUtil.Log($"[Packet] [EmptyPacket / Maybe is serveric ping]", LogType.ServerMessage); 132 | } 133 | 134 | }); 135 | if (_MonitorEnable) 136 | { 137 | MonitorTimer.Start(); 138 | } 139 | _ServericOpen += (s, e) => { }; 140 | _ServericPaused += (s, e) => { }; 141 | _ServericClosed += (s, e) => { }; 142 | OnServerAction += (s, e) => { }; 143 | OnGroupMsgs += (s, e) => { }; 144 | OnFriendMsgs += (s, e) => { }; 145 | OnEventMsgs += (s, e) => { }; 146 | } 147 | 148 | /// 149 | /// 关闭连接 150 | /// normally dispose 151 | /// 152 | public void Dispose() 153 | { 154 | GC.SuppressFinalize(this); 155 | MonitorTimer.Stop(); 156 | MonitorTimer.Dispose(); 157 | try 158 | { 159 | if (ss != null) 160 | { 161 | ss = null; 162 | } 163 | } 164 | catch 165 | { 166 | ss = null; 167 | GC.Collect(); 168 | } 169 | } 170 | 171 | /// 172 | /// SocketIO 服务器回报 173 | /// 174 | /// $ 175 | /// * 176 | public delegate void EventHandler(object sender, EventArgs e); 177 | /// 178 | /// 服务器当前状态开 179 | /// 180 | public event EventHandler _ServericOpen; 181 | /// 182 | /// 服务器当前状态暂停 183 | /// 184 | public event EventHandler _ServericPaused; 185 | /// 186 | /// 服务器当前状态关 187 | /// 188 | public event EventHandler _ServericClosed; 189 | 190 | /// 191 | /// 服务器的总体事件集合委托 192 | /// On Server Message delegate 193 | /// 194 | /// 195 | /// 196 | public delegate void ObjectEventHandler(object sender, ObjectEventArgs e); 197 | /// 198 | /// 服务器的总体事件集合 (如果你重写这个事件,那么服务端的解析将可以由您自己决定) 199 | /// On Server Message (if you rewrite the Build Core will fail) 200 | /// 201 | public event ObjectEventHandler OnServerAction; 202 | /// 203 | /// 服务器群聊消息事件委托 204 | /// Serveric [OnGroup] Message Delegate 205 | /// 206 | /// 207 | /// 208 | public delegate void GroupMessageEventHandler(object sender, ObjectEventArgs e); 209 | /// 210 | /// 服务器群聊消息事件 (如果你重写这个事件,那么服务端的解析将可以由您自己决定) 211 | /// Serveric [OnGroup] Message Event (if you rewrite the Build Core will fail) 212 | /// 213 | public event GroupMessageEventHandler OnGroupMsgs; 214 | /// 215 | /// 服务器好友消息事件委托 216 | /// Serveric [OnFriend] Message Delegate 217 | /// 218 | /// 219 | /// 220 | public delegate void FriendMessageEventHandler(object sender, ObjectEventArgs e); 221 | /// 222 | /// 服务器好友消息事件 (如果你重写这个事件,那么服务端的解析将可以由您自己决定) 223 | /// Serveric [OnFriend] Message Event (if you rewrite the Build Core will fail) 224 | /// 225 | public event FriendMessageEventHandler OnFriendMsgs; 226 | /// 227 | /// 服务器事件消息事件委托 228 | /// Serveric [OnEvent] Message Delegate 229 | /// 230 | /// 231 | /// 232 | public delegate void EventMessageEventHandler(object sender, ObjectEventArgs e); 233 | /// 234 | /// 服务器事件消息事件 (如果你重写这个事件,那么服务端的解析将可以由您自己决定) 235 | /// Serveric [OnEvent] Message Event (if you rewrite the Build Core will fail) 236 | /// 237 | public event EventMessageEventHandler OnEventMsgs; 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /QQ/QQAction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Newtonsoft.Json; 4 | using MeowIOTBot.QQ.QQFunc; 5 | using static MeowIOTBot.NetworkHelper.PostHelper; 6 | using static MeowIOTBot.QQ.QQFunc.QQGroupList; 7 | using static MeowIOTBot.QQ.QQFunc.QQGroupUserList; 8 | using static MeowIOTBot.QQ.QQFunc.QQGroupRequest; 9 | using static MeowIOTBot.QQ.QQFunc.QQFriendList; 10 | using static MeowIOTBot.QQ.QQFunc.QQFriendRequest; 11 | 12 | 13 | namespace MeowIOTBot.QQ.QQAction 14 | { 15 | /// 16 | /// 本账号操作 17 | /// any parameter that in selfsponse 18 | /// 19 | public class Me 20 | { 21 | /// 22 | /// 获取在线账号的Cookie 23 | /// get the cookie of this Online(ed) QQ 24 | /// 25 | public static async Task GetUserCook() => JsonConvert.DeserializeObject(await PASA(UrlType.GetUserCook, "{\"Flag\":false}")); 26 | /// 27 | /// 赞某个人 28 | /// sent QQZan* 29 | /// 30 | /// 31 | /// 被赞人的QQ号 32 | /// QQ number for somebosy recieve Zan Action 33 | /// 34 | public static async Task ToZanSombody(long qid) => await PASA(UrlType.QQZan, $"{{\"UserID\":{qid}}}"); 35 | /// 36 | /// 戳一戳某个人 37 | /// sent QQ Tickle 38 | /// 39 | /// 40 | /// 被戳人的类型 好友为0 群友为1 41 | /// the Tickles-type as friend is 0 group is 1 42 | /// 43 | /// 44 | /// 好友的QQ号 45 | /// the friend's QQ number 46 | /// 47 | /// 48 | /// 如果戳群友,这里填入群号(默认不用管) 49 | /// as if you tickles the groupmember then this is Groupnumber 50 | /// 51 | /// 52 | public static async Task ToTickle(int type, long qid, long groupid=0) => await PASA(UrlType.Tickles, $"{{\"Type\":{type},\"UserID\":{qid},\"GroupID\":{groupid}}}"); 53 | /// 54 | /// 全局Log 55 | /// RoundLog 56 | /// 57 | /// - 58 | /// - 59 | /// 60 | public static async Task ServiceLog(int consoleLev = 8, int FileLevel = 3) => await PASA(UrlType.__Logs, $"{{\"ConsoleLevel\":{consoleLev},\"FileLevel\":{FileLevel}}}"); 61 | /// 62 | /// (查询任意一个QQ用户)获取一个QQPerson实例的边界操作 63 | /// is the operation that getPersondetailed Message 64 | /// 65 | /// 66 | /// QQ号 67 | /// Query QQ number 68 | /// 69 | /// 70 | public static async Task GetPerson(long qqid) => JsonConvert.DeserializeObject(await PASA(UrlType.GetUserInfo, $"{{\"UserID\":{qqid}}}")); 71 | } 72 | /// 73 | /// QQ群操作 74 | /// QQGroup Interve Operation 75 | /// 76 | public class Group 77 | { 78 | /// 79 | /// 设置群头衔(必须为群主) 80 | /// Set GroupTitle(must As a GroupLeader) 81 | /// 82 | /// 群号(QQGroupNumber) 83 | /// 用户QQ号(PersonQQNumber) 84 | /// 头衔名(最大六个字符) 85 | public static async Task __SetGUT(long GroupID,long UserID,string NewTitle) => await PASA(UrlType.SetUniqueTitle, $"{{\"GroupID\":{GroupID},\"UserID\":{UserID},\"NewTitle\":\"{NewTitle}\"}}"); 86 | /// 87 | /// 撤回群内信息 88 | /// Revoke Messsage from 89 | /// 90 | /// 群号(GroupID) 91 | /// 信息的序列号(SequenceNum) 92 | /// 信息的校验码(RandomrizeParam) 93 | /// 94 | public static async Task _RevokeGroupMessage(long GroupID,long MsgSeq,long MsgRandom) => await PASA(UrlType.RevokeMsg, $"{{\"GroupID\":{GroupID},\"MsgSeq\":{MsgSeq},\"MsgRandom\":{MsgRandom}}}"); 95 | /// 96 | /// 禁言某个人员 97 | /// shut Up somebody in group of... 98 | /// 99 | /// 群号 (GroupId) 100 | /// 被执行人QQ号 (execute user to..) 101 | /// 禁言时间[分钟] (Shutup for .. minute) 102 | /// 103 | public static async Task _ShutUpSingle(long GroupID,long ShutUpUserID,int Minute) => await PASA(UrlType.ShutUpSingle, $"{{\"GroupID\":{GroupID},\"ShutUpUserID\":{ShutUpUserID},\"ShutTime\":{Minute}}}"); 104 | /// 105 | /// 禁言全体群成员 106 | /// Shutup for entire Group 107 | /// 108 | /// 群号(GroupId) 109 | /// 110 | /// 是否开启禁言[关闭发送False] 111 | /// Send True as ShutUP enable,vise versa 112 | /// 113 | /// 114 | public static async Task _ShutUpAll(long GroupID, bool ON) 115 | { 116 | int k = ON ? 1 : 0; 117 | return await PASA(UrlType.ShutUpEntirely, $"{{\"GroupID\":{GroupID},\"Switch\":{k}}}"); 118 | } 119 | /// 120 | /// 更改群名片 121 | /// change the GroupCard 122 | /// 123 | /// 群号GroupNumber 124 | /// QQ号QQNumber 125 | /// 新的群名称 126 | /// 127 | public static async Task _ModifyNickCard(long qqgroup, long userid, string newName) => await PASA( 128 | UrlType.ModifyGroupCard, 129 | $"{{\"GroupID\":{qqgroup},\"UserID\":{userid},\"NewNick\":\"{newName}\"}}"); 130 | /// 131 | /// 获取一个QQGroupUserList对象 132 | /// get a QQGroupList Object 133 | /// 134 | /// 一个请求对象The QQ Group Request Object 135 | /// 返回一个标准的QQGroupUserList对象returns a standarded QQGroupList Object 136 | public static async Task> GetGroupUserList(long GroupId) 137 | { 138 | long LastUin = 0; 139 | List u = new(); 140 | while (true) 141 | { 142 | var k = await PASA( 143 | UrlType.GetGroupUserList, 144 | $"{{\"GroupUin\":{GroupId},\"LastUin\":{LastUin}}}" 145 | ); 146 | var d = JsonConvert.DeserializeObject(k); 147 | u.AddRange(d.MemberList.ToArray()); 148 | if (d.LastUin == 0) 149 | { 150 | break; 151 | } 152 | else 153 | { 154 | LastUin = d.LastUin; 155 | } 156 | } 157 | return u; 158 | } 159 | /// 160 | /// 获取所有群列表 161 | /// get-all Group list 162 | /// 163 | /// 164 | public static async Task> GetGroupList() 165 | { 166 | _GroupList u = new(); 167 | int index = 0; 168 | while (true) 169 | { 170 | var r = await GetGroupListOnIndex(index); 171 | r.TroopList.ForEach((k) => { u.Add(k); }); 172 | if (r.NextToken == 0 || r.NextToken == null) 173 | { 174 | break; 175 | } 176 | } 177 | return u.getInstance(); 178 | } 179 | /// 180 | /// 加群Joinin Group 181 | /// Addin Group 182 | /// 183 | /// 加入的群群号the Group Number 184 | /// 验证内容the identify content 185 | /// 186 | public static async Task AddIntoGroup(long GroupId, string Content) => await __GroupManage(1, GroupId, 0, Content); 187 | /// 188 | /// 退群Leave Group 189 | /// 190 | /// 加入的群群号the Group Number 191 | /// 验证内容the identify content 192 | /// 193 | public static async Task QuitGroup(long GroupId, string Content) => await __GroupManage(2, GroupId, 0, Content); 194 | /// 195 | /// 移除群员remove Group Member 196 | /// 197 | /// 加入的群群号the Group Number 198 | /// 验证内容the identify content 199 | /// 被移除者the one that will be execute 200 | /// 201 | public static async Task RemoveSomeBodyFrom(long GroupId, long QQPerson, string Content) => await __GroupManage(3, GroupId, QQPerson, Content); 202 | /// 203 | /// 拉人到.. 204 | /// inviteSomeone 205 | /// 206 | /// 加入的群群号 207 | /// the Group Number 208 | /// 209 | /// 验证内容 210 | /// the identify content 211 | /// 212 | /// 被拉人 213 | /// the one that you ingage in 214 | /// 215 | /// 216 | public static async Task InviteSomeBodyInto(long GroupId, long QQPerson, string Content) => await __GroupManage(8, GroupId, QQPerson, Content); 217 | } 218 | /// 219 | /// QQ好友相关操作 220 | /// QQFriend Interve Opeation 221 | /// 222 | public class Friend 223 | { 224 | /// 225 | /// 从QQ搜索加人 226 | /// Add Friend From QQSearch 227 | /// 228 | /// 要加的人QQ号the QQnumber that you want to become friend with 229 | /// 验证内容the specific content you want to send 230 | /// 231 | public static async Task AddFriendFromQQSearch(long AddUserUid, string Content) => await __FriendManage(2020, 0, AddUserUid, Content); 232 | /// 233 | /// 从QQ空间加人 234 | /// 235 | /// 要加的人QQ号the QQnumber that you want to become friend with 236 | /// 验证内容the specific content you want to send 237 | /// 238 | public static async Task AddFriendFromQQSpace(long AddUserUid, string Content) => await __FriendManage(2011, 0, AddUserUid, Content); 239 | /// 240 | /// 从群内加人 241 | /// 242 | /// 要加的人QQ号the QQnumber that you want to become friend with 243 | /// 验证内容the specific content you want to send 244 | /// 同在的群号the specific group that you two both in 245 | /// 246 | public static async Task AddFriendFromQQGroup(long AddUserUid, long fromGroupId, string Content) => await __FriendManage(2004, fromGroupId, AddUserUid, Content); 247 | /// 248 | /// 获取好友列表 249 | /// get the QQFriend List 250 | /// 251 | /// 252 | public static async Task> GetFriendList() 253 | { 254 | _FriendList u = new(); 255 | int index = 0; 256 | while (true) 257 | { 258 | var r = await GetListOnIndex(index); 259 | r.FriendList.ForEach((k) => { u.Add(k); }); 260 | if (r.Totoal_friend_count > index) 261 | { 262 | index = ((index + r.GetfriendCount) > r.Totoal_friend_count ? r.Totoal_friend_count : index += r.GetfriendCount); 263 | } 264 | else 265 | { 266 | break; 267 | } 268 | } 269 | return u.getInstance(); 270 | 271 | } 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /QQ/QQEvent.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using static MeowIOTBot.NetworkHelper.PostHelper; 3 | using System; 4 | using System.Threading.Tasks; 5 | 6 | namespace MeowIOTBot.QQ.QQEvent 7 | { 8 | /// 9 | /// 群通知大类 10 | /// 11 | public class ON_EVENT_GROUP_ADMINSYSNOTIFY 12 | { 13 | /// 14 | /// 15 | /// 16 | public long Seq; 17 | /// 18 | /// 19 | /// 20 | public long Type; 21 | /// 22 | /// 23 | /// 24 | public string MsgTypeStr; 25 | /// 26 | /// 27 | /// 28 | public long Who; 29 | /// 30 | /// 31 | /// 32 | public string WhoName; 33 | /// 34 | /// 35 | /// 36 | public string MsgStatusStr; 37 | /// 38 | /// 39 | /// 40 | public string Content; 41 | /// 42 | /// 43 | /// 44 | public string RefuseContent; 45 | /// 46 | /// 47 | /// 48 | public long Flag_7; 49 | /// 50 | /// 51 | /// 52 | public long Flag_8; 53 | /// 54 | /// 55 | /// 56 | public long GroupId; 57 | /// 58 | /// 59 | /// 60 | public string GroupName; 61 | /// 62 | /// 63 | /// 64 | public long ActionUin; 65 | /// 66 | /// 67 | /// 68 | public string ActionName; 69 | /// 70 | /// 71 | /// 72 | public string ActionGroupCard; 73 | /// 74 | /// 75 | /// 76 | public long Action; 77 | } 78 | /// 79 | /// 管理员变更事件 80 | /// 81 | public class ON_EVENT_GROUP_ADMIN 82 | { 83 | /// 84 | /// 标志,是否成为管理员 85 | /// 86 | public long Flag; 87 | /// 88 | /// 群号 89 | /// 90 | public long GroupID; 91 | /// 92 | /// 用户名 93 | /// 94 | public long UserID; 95 | } 96 | /// 97 | /// 群禁言事件 98 | /// 99 | public class ON_EVENT_GROUP_SHUT 100 | { 101 | /// 102 | /// 群名 103 | /// 104 | public long GroupID; 105 | /// 106 | /// 禁言时间(秒) 107 | /// 108 | public long ShutTime; 109 | /// 110 | /// 用户名 111 | /// 112 | public long UserID; 113 | } 114 | /// 115 | /// 群成员退出群聊事件 116 | /// 117 | public class ON_EVENT_GROUP_EXIT 118 | { 119 | /// 120 | /// 退出成员名 121 | /// 122 | public long UserID; 123 | } 124 | /// 125 | /// 主动退群成功事件 126 | /// 127 | public class ON_EVENT_GROUP_EXIT_SUCC 128 | { 129 | /// 130 | /// 退出的群 131 | /// 132 | public long GroupID; 133 | } 134 | /// 135 | /// 某人进群事件 136 | /// 137 | public class ON_EVENT_GROUP_JOIN 138 | { 139 | /// 140 | /// 被邀请人 141 | /// 142 | public long InviteUin; 143 | /// 144 | /// 用户ID 145 | /// 146 | public long UserID; 147 | /// 148 | /// 用户名 149 | /// 150 | public string UserName; 151 | } 152 | /// 153 | /// 邀请加群 154 | /// 155 | public class ON_EVENT_GROUP_ADMINSYSNOTIFY_INVITE_GROUP : ON_EVENT_GROUP_ADMINSYSNOTIFY 156 | { 157 | /// 158 | /// 构造 159 | /// 160 | /// 161 | public ON_EVENT_GROUP_ADMINSYSNOTIFY_INVITE_GROUP(ON_EVENT_GROUP_ADMINSYSNOTIFY x) 162 | { 163 | Seq = x.Seq; 164 | Type = x.Type; 165 | MsgTypeStr = x.MsgTypeStr; 166 | Who = x.Who; 167 | WhoName = x.WhoName; 168 | MsgStatusStr = x.MsgStatusStr; 169 | Content = x.Content; 170 | RefuseContent = x.RefuseContent; 171 | Flag_7 = x.Flag_7; 172 | Flag_8 = x.Flag_8; 173 | GroupId = x.GroupId; 174 | GroupName = x.GroupName; 175 | ActionUin = x.ActionUin; 176 | ActionName = x.ActionName; 177 | ActionGroupCard = x.ActionGroupCard; 178 | Action = x.Action; 179 | } 180 | /// 181 | /// 同意请求 182 | /// 183 | public async Task RequestAccept() 184 | { 185 | var k = this; 186 | k.Action = 11; 187 | return await PASA(UrlType.AnswerInviteGroup, Newtonsoft.Json.JsonConvert.SerializeObject(k)); 188 | } 189 | /// 190 | /// 拒绝请求 191 | /// 192 | public async Task RequestDenied() 193 | { 194 | var k = this; 195 | k.Action = 21; 196 | return await PASA(UrlType.AnswerInviteGroup, Newtonsoft.Json.JsonConvert.SerializeObject(k)); 197 | } 198 | /// 199 | /// 忽略请求 200 | /// 201 | public async Task RequestDismiss() 202 | { 203 | var k = this; 204 | k.Action = 14; 205 | return await PASA(UrlType.AnswerInviteGroup, Newtonsoft.Json.JsonConvert.SerializeObject(k)); 206 | } 207 | } 208 | /// 209 | /// 群成员撤回消息 210 | /// 211 | public class ON_EVENT_GROUP_REVOKE 212 | { 213 | /// 214 | /// 执行人 215 | /// 216 | public long AdminUserID; 217 | /// 218 | /// 执行群 219 | /// 220 | public long GroupID; 221 | /// 222 | /// 撤回消息的随机码 223 | /// 224 | public long MsgRandom; 225 | /// 226 | /// 撤回消息序号 227 | /// 228 | public long MsgSeq; 229 | /// 230 | /// 被执行人 231 | /// 232 | public long UserID; 233 | } 234 | /*------------------------------------------------------*/ 235 | /// 236 | /// 加好友事件 237 | /// 238 | public class ON_EVENT_FRIEND_ADD 239 | { 240 | /// 241 | /// QQ号 242 | /// 243 | public long UserID; 244 | /// 245 | /// 用户昵称 246 | /// 247 | public string UserNick; 248 | /// 249 | /// 来源类型 250 | /// 251 | public long FromType; 252 | /// 253 | /// 类型 254 | /// 255 | public long Type; 256 | /// 257 | /// 258 | /// 259 | public string MsgTypeStr; 260 | /// 261 | /// 262 | /// 263 | public long Field_3; 264 | /// 265 | /// 266 | /// 267 | public long Field_8; 268 | /// 269 | /// 验证信息 270 | /// 271 | public string Content; 272 | /// 273 | /// 群信息 274 | /// 275 | public string FromContent; 276 | /// 277 | /// 来源群号 278 | /// 279 | public long FromGroupId; 280 | /// 281 | /// 来源群名 282 | /// 283 | public string FromGroupName; 284 | /// 285 | /// 286 | /// 287 | public int Action; 288 | 289 | /// 290 | /// 同意请求 291 | /// 292 | public async Task RequestAccept() 293 | { 294 | var k = this; 295 | k.Action = 2; 296 | return await PASA(UrlType.DealFriend, Newtonsoft.Json.JsonConvert.SerializeObject(k)); 297 | } 298 | /// 299 | /// 拒绝请求 300 | /// 301 | public async Task RequestDenied() 302 | { 303 | var k = this; 304 | k.Action = 3; 305 | return await PASA(UrlType.DealFriend, Newtonsoft.Json.JsonConvert.SerializeObject(k)); 306 | } 307 | /// 308 | /// 忽略请求 309 | /// 310 | public async Task RequestDismiss() 311 | { 312 | var k = this; 313 | k.Action = 1; 314 | return await PASA(UrlType.DealFriend, Newtonsoft.Json.JsonConvert.SerializeObject(k)); 315 | } 316 | } 317 | /// 318 | /// 成为好友事件 319 | /// 320 | public class ON_EVENT_NOTIFY_PUSHADDFRD 321 | { 322 | /// 323 | /// 昵称 324 | /// 325 | public string NickName; 326 | /// 327 | /// 用户 328 | /// 329 | public long UserID; 330 | } 331 | /// 332 | /// 好友状态信息事件(被同意添加好友/被拒绝添加好友) 333 | /// 334 | public class ON_EVENT_FRIEND_ADD_STATUS 335 | { 336 | /// 337 | /// 昵称 338 | /// 339 | public string NickName; 340 | /// 341 | /// 类型 342 | /// 343 | public int Type; 344 | /// 345 | /// 类型状态 346 | /// 347 | public string TypeStatus; 348 | /// 349 | /// 用户QQ号 350 | /// 351 | public int UserID; 352 | } 353 | /// 354 | /// 删除好友事件 355 | /// 356 | public class ON_EVENT_FRIEND_DELETE 357 | { 358 | /// 359 | /// 用户QQ号 360 | /// 361 | public long UserID; 362 | } 363 | /// 364 | /// 事件类型枚举类 365 | /// EventType EnumClass 366 | /// 367 | public enum EventType 368 | { 369 | /// 370 | /// 还没识别的事件类型 371 | /// 372 | ON_EVENT_NULL_REF, 373 | /*--------------------------*/ 374 | /// 375 | /// 管理员设置事件 376 | /// 377 | ON_EVENT_GROUP_ADMINSYSNOTIFY, 378 | /// 379 | /// 管理员变更事件 380 | /// 381 | ON_EVENT_GROUP_ADMIN, 382 | /// 383 | /// 群禁言 384 | /// 385 | ON_EVENT_GROUP_SHUT, 386 | /// 387 | /// 群成员退出群聊事件 388 | /// 389 | ON_EVENT_GROUP_EXIT, 390 | /// 391 | /// 主动退群成功事件 392 | /// 393 | ON_EVENT_GROUP_EXIT_SUCC, 394 | /// 395 | /// 某人进群事件 396 | /// 397 | ON_EVENT_GROUP_JOIN, 398 | /// 399 | /// 某人邀你进群 400 | /// 401 | ON_EVENT_GROUP_ADMINSYSNOTIFY_INVITE_GROUP, 402 | /// 403 | /// 群成员撤回消息 404 | /// 405 | ON_EVENT_GROUP_REVOKE, 406 | /*-------------*/ 407 | /// 408 | /// 某人加你好友 409 | /// 410 | ON_EVENT_FRIEND_ADD, 411 | /// 412 | /// 某人不再是你的好友 413 | /// 414 | ON_EVENT_FRIEND_DELETE 415 | } 416 | /// 417 | /// 事件的摘要 418 | /// Event Hash 419 | /// 420 | public class EventMsg 421 | { 422 | /// 423 | /// 构造用 424 | /// 425 | /// 426 | public EventMsg(JObject jo) 427 | { 428 | if (jo.TryGetValue("EventMsg", out var EventMsg)) 429 | { 430 | var em = JObject.Parse(EventMsg.ToString()); 431 | em.TryGetValue("FromUin", out var FromUin); 432 | this.FromUser = FromUin?.ToObject() ?? 0; 433 | em.TryGetValue("ToUin", out var ToUin); 434 | this.ToUser = ToUin?.ToObject() ?? 0; 435 | em.TryGetValue("MsgType", out var MsgType); 436 | this.MsgType = MsgType?.ToString(); 437 | em.TryGetValue("MsgSeq", out var MsgSeq); 438 | this.MsgSeq = MsgSeq?.ToObject() ?? 0; 439 | em.TryGetValue("Content", out var Content); 440 | this.Content = Content?.ToString(); 441 | } 442 | else { throw new Exception(EC.E00); } 443 | } 444 | /// 445 | /// 其他数据(扩展类) 446 | /// eXtensionClass - for InnerData 447 | /// 448 | public object Data { get; } = null; 449 | /// 450 | /// 来源用户 451 | /// For The Msg From 452 | /// 453 | public long FromUser { get; } 454 | /// 455 | /// 接收用户 456 | /// For The Msg To 457 | /// 458 | public long ToUser { get; } 459 | /// 460 | /// 信息类型 461 | /// MsginnerType 462 | /// 463 | public string MsgType { get; } 464 | /// 465 | /// 消息序列号 466 | /// Msg Sequence 467 | /// 468 | public long MsgSeq { get; } 469 | /// 470 | /// 信息内容 471 | /// Msg Innerexcption 472 | /// 473 | public string Content { get; } 474 | } 475 | /// 476 | /// 继承用事件内部数据类 477 | /// for inherit classes (which is EventData-Typed) 478 | /// 479 | public class Event 480 | { 481 | /// 482 | /// 构造用 483 | /// 484 | /// 485 | public Event(JObject jo) 486 | { 487 | EMsg = new EventMsg(jo); 488 | if (jo.TryGetValue("EventName", out var EventName)) 489 | { 490 | var en = EventName.ToString(); 491 | this.EType = en switch 492 | { 493 | "ON_EVENT_GROUP_ADMIN" => EventType.ON_EVENT_GROUP_ADMIN, 494 | "ON_EVENT_GROUP_ADMINSYSNOTIFY" => EventType.ON_EVENT_GROUP_ADMINSYSNOTIFY, 495 | "ON_EVENT_GROUP_SHUT" => EventType.ON_EVENT_GROUP_SHUT, 496 | "ON_EVENT_GROUP_EXIT" => EventType.ON_EVENT_GROUP_EXIT, 497 | "ON_EVENT_GROUP_EXIT_SUCC" => EventType.ON_EVENT_GROUP_EXIT_SUCC, 498 | "ON_EVENT_GROUP_JOIN" => EventType.ON_EVENT_GROUP_JOIN, 499 | "ON_EVENT_FRIEND_ADD" => EventType.ON_EVENT_FRIEND_ADD, 500 | "ON_EVENT_GROUP_REVOKE" => EventType.ON_EVENT_GROUP_REVOKE, 501 | _ => EventType.ON_EVENT_NULL_REF 502 | }; 503 | } 504 | else { throw new Exception(EC.E01); } 505 | if (jo.TryGetValue("EventData", out var EventData)) 506 | { 507 | JObject jed = JObject.Parse(EventData.ToString()); 508 | this.Data = EventName.ToString() switch 509 | { 510 | "ON_EVENT_GROUP_ADMIN" => jed.ToObject(), 511 | "ON_EVENT_GROUP_ADMINSYSNOTIFY" => jed.ToObject(), 512 | "ON_EVENT_GROUP_SHUT" => jed.ToObject(), 513 | "ON_EVENT_GROUP_EXIT" => jed.ToObject(), 514 | "ON_EVENT_GROUP_EXIT_SUCC" => jed.ToObject(), 515 | "ON_EVENT_GROUP_JOIN" => jed.ToObject(), 516 | "ON_EVENT_FRIEND_ADD" => jed.ToObject(), 517 | "ON_EVENT_GROUP_REVOKE" => jed.ToObject(), 518 | _ => null 519 | }; 520 | } 521 | else { throw new Exception(EC.E02); } 522 | } 523 | /// 524 | /// 枚举类型(用于转换下面的InnerData) 525 | /// inner Class For Cast InnerData 526 | /// 527 | public EventType EType { get; } = EventType.ON_EVENT_NULL_REF; 528 | /// 529 | /// 事件的摘要信息 530 | /// Event Hash 531 | /// 532 | public EventMsg EMsg { get; } = null; 533 | /// 534 | /// 事件的内部转换信息 535 | /// inner DataCast -> Object 536 | /// 537 | public object Data { get; } 538 | } 539 | } 540 | -------------------------------------------------------------------------------- /QQ/QQRecieveMessage.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace MeowIOTBot.QQ.QQMessage.QQRecieveMessage 7 | { 8 | /// 9 | /// QQ信息的包装类 10 | /// QQ Message's Class 11 | /// 12 | public class QQRecieveMessage 13 | { 14 | /// 15 | /// 当前服务端登录的QQ 16 | /// Service login QQ 17 | /// 18 | public long CurrentQQ; 19 | /// 20 | /// IO类型 21 | /// IO inner type 22 | /// 23 | public MessageIOType IOType; 24 | /// 25 | /// 信息的IO附加参数 26 | /// Message IO Body Parameter 27 | /// 28 | public IOBody IOBody; 29 | /// 30 | /// 信息的公用属性类 31 | /// Message Public Properties 32 | /// 33 | public MsgProperty Property; 34 | /// 35 | /// 构造参数 36 | /// Constructor 37 | /// 38 | /// 39 | /// IO类型 40 | /// IO inner type 41 | /// 42 | /// 43 | /// 信息的IO附加参数 44 | /// Message IO Body Parameter 45 | /// 46 | /// 47 | /// 信息的公用属性类 48 | /// Message Public Properties 49 | /// 50 | /// 51 | /// 当前服务端登录的QQ 52 | /// Service login QQ 53 | /// 54 | public QQRecieveMessage(MessageIOType iOType, IOBody iOBody, MsgProperty property, long currentQQ) 55 | { 56 | IOType = iOType; 57 | IOBody = iOBody; 58 | Property = property; 59 | CurrentQQ = currentQQ; 60 | } 61 | } 62 | /// 63 | /// 信息的IO附加参数 64 | /// Message IO Body Parameter 65 | /// 66 | public class IOBody 67 | { 68 | /// 69 | /// 发信人 70 | /// sender QQ 71 | /// 72 | public long MsgFromQQ { get; } 73 | /// 74 | /// 收信人 75 | /// Reciever QQ 76 | /// 77 | public long MsgRecvQQ { get; } 78 | /// 79 | /// 发信人昵称 80 | /// Sender NickName 81 | /// 82 | public string NickName { get; } 83 | /// 84 | /// 群聊的群号 (可空类型) 85 | /// GroupChat's Group Number (as it can be Nullable) 86 | /// 87 | public long? FromGroupId { get; } 88 | /// 89 | /// 群聊的群名 (可空类型) 90 | /// GroupChat's Group Name (as it can be Nullable) 91 | /// 92 | public string FromGroupName { get; } 93 | /// 94 | /// 构造 95 | /// Constructor 96 | /// 97 | /// 98 | /// 发信人 99 | /// sender QQ 100 | /// 101 | /// 102 | /// 收信人 103 | /// Reciever QQ 104 | /// 105 | /// 106 | /// 发信人昵称 107 | /// Sender NickName 108 | /// 109 | /// 110 | /// 群聊的群号 (可空类型) 111 | /// GroupChat's Group Number (as it can be Nullable) 112 | /// 113 | /// 114 | /// 群聊的群名 (可空类型) 115 | /// GroupChat's Group Name (as it can be Nullable) 116 | /// 117 | public IOBody(long msgFromQQ, long msgRecvQQ, string nickName, long? fromGroupId, string fromGroupName) 118 | { 119 | MsgFromQQ = msgFromQQ; 120 | MsgRecvQQ = msgRecvQQ; 121 | NickName = nickName; 122 | FromGroupId = fromGroupId; 123 | FromGroupName = fromGroupName; 124 | } 125 | } 126 | /// 127 | /// 信息的公用属性类 128 | /// Message Public Properties 129 | /// 130 | public class MsgProperty 131 | { 132 | /// 133 | /// 附属的第二指令 134 | /// Parametered Second Command Value 135 | /// 136 | public string C2cCmd { get; } 137 | /// 138 | /// 消息的验证时间 139 | /// Message Sender Time 140 | /// 141 | public long? MsgTime { get; } 142 | /// 143 | /// 消息序列号 144 | /// Message Sequence Data 145 | /// 146 | public long? MsgSeq { get; } 147 | /// 148 | /// 消息的随机码 149 | /// Message Random Identify Data 150 | /// 151 | public long? MsgRandom { get; } 152 | /// 153 | /// 消息的UID 154 | /// Message Uid 155 | /// 156 | public long? MsgUid { get; } 157 | /// 158 | /// 红包信息 159 | /// Redbag Infomation string 160 | /// 161 | public string RedBagInfo { get; } 162 | /// 163 | /// 构造方法 164 | /// Constructor 165 | /// 166 | /// 167 | /// 附属的第二指令 168 | /// Parametered Second Command Value 169 | /// 170 | /// 171 | /// 消息序列号 172 | /// Message Sequence Data 173 | /// 174 | /// 175 | /// 消息的随机码 176 | /// Message Random Identify Data 177 | /// 178 | /// 179 | /// 消息的UID 180 | /// Message Uid 181 | /// 182 | /// 183 | /// 红包信息 184 | /// Redbag Infomation string 185 | /// 186 | /// 187 | /// 消息的验证时间 188 | /// Message Sender Time 189 | /// 190 | public MsgProperty(string c2cCmd, long? msgSeq, long? msgRandom, long? msgUid, string redBagInfo, long? msgTime) 191 | { 192 | C2cCmd = c2cCmd; 193 | MsgSeq = msgSeq; 194 | MsgRandom = msgRandom; 195 | MsgUid = msgUid; 196 | RedBagInfo = redBagInfo; 197 | MsgTime = msgTime; 198 | } 199 | } 200 | /// 201 | /// 消息类型 202 | /// MessageIOType 203 | /// 204 | public enum MessageIOType 205 | { 206 | /// 207 | /// 好友信息 208 | /// Friend Message 209 | /// 210 | Friend, 211 | /// 212 | /// 群信息 213 | /// Group Message 214 | /// 215 | Group, 216 | /// 217 | /// 临时信息 218 | /// Temp Session Message 219 | /// 220 | TempSession 221 | } 222 | 223 | /// 224 | /// 基础消息格式(抽象继承模式) 225 | /// Message Type * Abstract Inherit Mode 226 | /// 227 | public abstract class Message 228 | { 229 | /// 230 | /// 信息的基础内容 231 | /// Message Basic Content 232 | /// 233 | public JObject RawContent; 234 | /// 235 | /// 构造基础的信息模型 236 | /// Constructor 237 | /// 238 | /// 239 | /// 信息的基础内容 240 | /// Message Basic Content 241 | /// 242 | protected Message(string content) => RawContent = JObject.Parse(content); 243 | } 244 | /// 245 | /// 信息类型 : 文本信息 246 | /// Message Type : Text Message 247 | /// 248 | public class TextMsg : Message 249 | { 250 | /// 251 | /// 文本信息 252 | /// Text Message 253 | /// 254 | public string Content; 255 | /// 256 | /// 构造信息类型 : 文本信息 257 | /// Message Constructor Type : Text Message 258 | /// 259 | /// 260 | /// 信息的基础内容 261 | /// Message Basic Content 262 | /// 263 | public TextMsg(string content) : base($"{{\"Content\":\"{content}\"}}") => Content = content; 264 | } 265 | /// 266 | /// at类型的消息 * 仅群聊 267 | /// Type Of the message [@] * maybe only in Group Chat 268 | /// 269 | public class AtTextMsg : Message 270 | { 271 | /// 272 | /// 文本信息 273 | /// Text Message 274 | /// 275 | public string Content; 276 | /// 277 | /// 文本信息 278 | /// Text Message 279 | /// 280 | public string RemoveAtContent; 281 | /// 282 | /// 文本信息 283 | /// Text Message 284 | /// 285 | public string replyContent; 286 | /// 287 | /// 是否回复类型的At信息 288 | /// is reply at message 289 | /// 290 | public bool _isReplyAt; 291 | /// 292 | /// 回复类型At信息的被回复者 293 | /// indecated the reply message's UserId 294 | /// 295 | public long[] ReplyAtUserID; 296 | /// 297 | /// 回复类型At信息的顺序码 298 | /// indecated the reply message's Message Sequence 299 | /// 300 | public long ReplyMessageSeq; 301 | /// 302 | /// 被at的人 303 | /// the List of AtedQQ 304 | /// 305 | public List AtedQQ; 306 | /// 307 | /// 信息 308 | /// Info 309 | /// 310 | public class QQinfo 311 | { 312 | /// 313 | /// QQ昵称 314 | /// Nick 315 | /// 316 | public string QQNick; 317 | /// 318 | /// QQ号 319 | /// QQNumber 320 | /// 321 | public long QQUid; 322 | } 323 | /// 324 | /// 构造at类型的消息 * 仅群聊 325 | /// Type Of the message [@] * maybe only in Group Chat 326 | /// 327 | /// 328 | /// 文本信息 329 | /// Text Message 330 | /// 331 | public AtTextMsg(string content) : base(content) 332 | { 333 | var jo = JObject.Parse(content.Replace("\\\"", "\"")); 334 | jo.TryGetValue("UserExt", out var atedQQ); 335 | AtedQQ = atedQQ?.ToObject>(); 336 | if(AtedQQ != null) 337 | { 338 | StringBuilder sb = new(); 339 | List ls = new(); 340 | Content = jo["Content"].ToString(); 341 | foreach (var d in Content.Split(' ')[AtedQQ.Count..]) 342 | { 343 | for (int i = 0; i < ls.Count; i++) 344 | { 345 | if (d.Equals(ls[i].QQNick)) 346 | { 347 | ls[i] = null; 348 | break; 349 | } 350 | } 351 | sb.Append($"{d} "); 352 | } 353 | RemoveAtContent = sb.ToString(); 354 | } 355 | else 356 | { 357 | if ("[回复]".Equals(jo["Tips"]?.ToString())) 358 | { 359 | Content = jo["Content"].ToString(); 360 | replyContent = jo["SrcContent"].ToString(); 361 | ReplyAtUserID = jo["UserID"].ToObject(); 362 | ReplyMessageSeq = jo["MsgSeq"].ToObject(); 363 | } 364 | else 365 | { 366 | Console.WriteLine($"Message Unhandled -- {Content}"); 367 | } 368 | } 369 | } 370 | } 371 | /// 372 | /// 图片类信息 373 | /// Picture Message 374 | /// 375 | public class PicMsg : Message 376 | { 377 | /// 378 | /// 好友图片列表 379 | /// Private User Picture List Item 380 | /// 381 | public class Pic 382 | { 383 | /// 384 | /// 文件的标号 385 | /// File Identity of SnapPic 386 | /// 387 | public long? FileId; 388 | /// 389 | /// 文件的Md5 390 | /// File Md5 391 | /// 392 | public string FileMd5; 393 | /// 394 | /// 文件的大小 395 | /// File Size 396 | /// 397 | public long FileSize; 398 | /// 399 | /// 闪照的转发前置 400 | /// The Buffer Of SnapPic 401 | /// 402 | public string ForwordBuf; 403 | /// 404 | /// 闪图的转发序列号 405 | /// The Number identity of SnapPic 406 | /// 407 | public long ForwordField; 408 | /// 409 | /// 文件的路径 410 | /// File Path (relative) 411 | /// 412 | public string Path; 413 | /// 414 | /// 文件的URL 415 | /// file Url 416 | /// 417 | public string Url; 418 | /// 419 | /// 文件的提示符号 420 | /// File tips 421 | /// 422 | public string Tips; 423 | } 424 | /// 425 | /// 图片列表 426 | /// PicList 427 | /// 428 | public Pic[] PicList; 429 | /// 430 | /// At的QQ 431 | /// ated QQ number 432 | /// 433 | public int[] AtedQQ; 434 | /// 435 | /// 好友图片的内容 436 | /// Friend Pic Text Content 437 | /// 438 | public string Content; 439 | /// 440 | /// 用来判断是否为闪照 441 | /// the flag for determain weather or not is a SnapPic. 442 | /// 443 | public bool _isSnapPic; 444 | 445 | /// 446 | /// 构造好友图片 447 | /// construct a Content 448 | /// 449 | /// 450 | public PicMsg(string content) : base(content) 451 | { 452 | var jo = JObject.Parse(content.Replace("\\\"", "\"")); 453 | jo.TryGetValue("Content", out var _Content); 454 | this.Content = _Content?.ToString(); 455 | jo.TryGetValue("Tips", out var tips); 456 | _isSnapPic = tips.ToString().Contains("闪照"); 457 | if(_isSnapPic) 458 | { 459 | jo.TryGetValue("FileId", out var FileId); 460 | jo.TryGetValue("FileMd5", out var FileMd5); 461 | jo.TryGetValue("FileSize", out var FileSize); 462 | jo.TryGetValue("ForwordBuf", out var ForwordBuf); 463 | jo.TryGetValue("ForwordField", out var ForwordField); 464 | jo.TryGetValue("Url", out var Url); 465 | PicList = new Pic[] { 466 | new Pic { 467 | FileId = FileId?.ToObject(), 468 | FileMd5 = FileMd5.ToString(), 469 | FileSize = FileSize.ToObject(), 470 | ForwordBuf = ForwordBuf.ToString(), 471 | ForwordField = ForwordField.ToObject(), 472 | Url = Url.ToString() 473 | } 474 | }; 475 | } 476 | else{ 477 | jo.TryGetValue("GroupPic", out var _GroupPic); 478 | jo.TryGetValue("FriendPic", out var _FriendPic); 479 | if (_FriendPic != null){PicList = _FriendPic.ToObject();} 480 | else if (_GroupPic != null){PicList = _GroupPic.ToObject();} 481 | jo.TryGetValue("UserID", out var atuid); 482 | AtedQQ = atuid?.ToObject(); 483 | } 484 | } 485 | } 486 | /// 487 | /// 语音类信息 488 | /// Voice Message 489 | /// 490 | public class VoiceMsg : Message 491 | { 492 | /// 493 | /// 语音文件的URL 494 | /// 495 | public string url; 496 | /// 497 | /// 构造群聊语音 498 | /// 499 | /// 500 | public VoiceMsg(string content) : base(content) 501 | { 502 | var jo = JObject.Parse(content.Replace("\\\"", "\"")); 503 | jo.TryGetValue("Url", out var _Url); 504 | this.url = _Url?.ToString(); 505 | } 506 | } 507 | /// 508 | /// 视频类消息 509 | /// Video Message 510 | /// 511 | public class VideoMsg : Message 512 | { 513 | /// 514 | /// 内部的文字内容 515 | /// the content of text 516 | /// 517 | public string innerContent; 518 | /// 519 | /// 前置的发送buf字段 520 | /// the inner forward Buffer property 521 | /// 522 | public string ForwordBuf; 523 | /// 524 | /// 前置的发送字段 525 | /// the inner forward buffer field 526 | /// 527 | public long ForwordField; 528 | /// 529 | /// 视频的Md5码 530 | /// the SHAMd5 of video 531 | /// 532 | public string VideoMd5; 533 | /// 534 | /// 视频的大小(应该是单位Byte) 535 | /// the Size of Video (which is maybe using Byte) 536 | /// 537 | public long VideoSize; 538 | /// 539 | /// 视频的Url 540 | /// the URL of the Video 541 | /// 542 | public string VideoUrl; 543 | /// 544 | /// 构造一个视频信息 545 | /// Construct a video msg 546 | /// 547 | /// 548 | public VideoMsg(string content) : base(content) 549 | { 550 | var jo = JObject.Parse(content.Replace("\\\"", "\"")); 551 | jo.TryGetValue("Content", out var _Content); 552 | this.innerContent = _Content?.ToString(); 553 | jo.TryGetValue("ForwordBuf", out var _ForwordBuf); 554 | this.ForwordBuf = _ForwordBuf?.ToString(); 555 | jo.TryGetValue("ForwordField", out var _ForwordField); 556 | this.ForwordField = _ForwordField?.ToObject() ?? 0; 557 | jo.TryGetValue("VideoMd5", out var _VideoMd5); 558 | this.VideoMd5 = _VideoMd5?.ToString(); 559 | jo.TryGetValue("VideoSize", out var _VideoSize); 560 | this.VideoSize = _VideoSize?.ToObject() ?? 0; 561 | jo.TryGetValue("VideoUrl", out var _VideoUrl); 562 | this.VideoUrl = _VideoUrl?.ToString(); 563 | } 564 | } 565 | } 566 | -------------------------------------------------------------------------------- /QQ/QQSendMessage.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MeowIOTBot.QQ.QQMessage.QQSendMessage 11 | { 12 | /// 13 | /// 返回状态类 14 | /// 15 | public class SenderStatus 16 | { 17 | /// 18 | /// 原消息串 19 | /// 20 | public string MessageStr; 21 | /// 22 | /// 状态码 23 | /// 24 | public Sdstatus StatusCode; 25 | /// 26 | /// 构造 27 | /// 28 | /// 29 | public SenderStatus(JObject jo) 30 | { 31 | MessageStr = jo["Msg"]?.ToString(); 32 | StatusCode = (Sdstatus)(jo["Ret"]?.ToObject() ?? -1); 33 | } 34 | /// 35 | /// 中文输出错误类型 36 | /// 37 | /// 38 | /// 39 | public string ToString(bool CHS = false) 40 | { 41 | if (CHS) 42 | { 43 | return (int)StatusCode switch 44 | { 45 | -1 => "超时空串", 46 | 0 => "发送成功", 47 | 34 => "未知错误", 48 | 46 => "手动完成身份验证", 49 | 110 => "发送失败,你已被移出群聊", 50 | 120 => "你已被禁言", 51 | 241 => "发送频率过高", 52 | 299 => "超过群发言频率限制", 53 | _ => "其他错误" 54 | }; 55 | } 56 | else 57 | { 58 | return base.ToString(); 59 | } 60 | } 61 | } 62 | /// 63 | /// 可发送信息类接口设计 64 | /// 65 | public interface Sendable 66 | { 67 | /// 68 | /// 一个异步的发送信息方法 69 | /// 70 | /// 返回一个成功与否的字符串 71 | public Task Send(); 72 | /// 73 | /// 一个异步的发送信息方法 74 | /// 75 | /// 是否将服务端异常视作错误(默认否) 76 | /// 返回一个成功与否的类 77 | public Task Send(bool treatAsErr = false); 78 | } 79 | /// 80 | /// 可发送类的发送实现方案 81 | /// 82 | public abstract class SendableClass : Sendable 83 | { 84 | /// 85 | /// 一个异步的发送信息方法 86 | /// 87 | /// 返回一个成功与否的字符串 88 | public async Task Send() => 89 | await NetworkHelper.PostHelper.PASA( 90 | NetworkHelper.PostHelper.UrlType.SendMsgV2, 91 | JsonConvert.SerializeObject(this, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }) 92 | ); 93 | /// 94 | /// 一个异步的发送信息方法 95 | /// 96 | /// 是否将服务端异常视作错误(默认否) 97 | /// 返回一个成功与否的类 98 | public async Task Send(bool treatAsErr = false) 99 | { 100 | var ss = new SenderStatus(JObject.Parse(await Send())); 101 | if (treatAsErr && (ss.StatusCode != Sdstatus.OK)) 102 | { 103 | throw new Exception($"{ss.ToString(true)}::{ss.StatusCode}::{ss.MessageStr}"); 104 | } 105 | else 106 | { 107 | return ss; 108 | } 109 | } 110 | } 111 | /// 112 | /// 原信息 113 | /// 114 | public class MsgV2 : SendableClass 115 | { 116 | /// 117 | /// 发送到的位置 118 | /// 119 | public long ToUserUid; 120 | /// 121 | /// 接收人的类型 122 | /// 123 | public int SendToType; 124 | /// 125 | /// 信息的类型 126 | /// 127 | public string SendMsgType; 128 | /// 129 | /// 信息主体 130 | /// 131 | public string Content; 132 | /// 133 | /// 陌生人识别号 134 | /// 135 | public long GroupID; 136 | /// 137 | /// 构造一个原始信息类(内部解析) 138 | /// 139 | /// 发送到 140 | /// 收件人类型 141 | /// 信息类型 142 | /// 信息主体 143 | /// 陌生人识别号 144 | /// 是否atqq 数组qq号 (*暂时群组内不好用) 145 | /// 是否At全体 *取消上面的atqq数组 (*暂时群组内不好用) 146 | public MsgV2(long sendTo, MessageSendToType sendToType, MessageSendType sendMsgType, string content, 147 | long GroupId, List atqq = null, bool atAll = false) 148 | { 149 | ToUserUid = sendTo; 150 | SendToType = (int)sendToType; 151 | SendMsgType = sendMsgType.ToString(); 152 | Content = content; 153 | if (sendToType == MessageSendToType.Private) 154 | { 155 | GroupID = GroupId; 156 | } 157 | else if (sendToType == MessageSendToType.Group && (atqq != null || atAll)) 158 | { 159 | if (atAll == true) 160 | { 161 | Content = $"[ATALL()]{content}"; 162 | } 163 | else 164 | { 165 | StringBuilder sb = new(); 166 | sb.Append("[ATUSER("); 167 | bool x = false; 168 | foreach (var k in atqq) 169 | { 170 | if (x) { sb.Append(','); } 171 | sb.Append(k); 172 | x = true; 173 | } 174 | Content = $"{sb})]{content}"; 175 | } 176 | } 177 | } 178 | } 179 | /// 180 | /// 封装的文字信息 181 | /// 182 | public class MsgV2_TxtMsg : MsgV2 183 | { 184 | /// 185 | /// 文字信息 186 | /// 187 | /// 发送到 188 | /// 收件人类型 189 | /// 内容 190 | /// 陌生人识别号 191 | /// 是否atqq 数组qq号 (*暂时群组内不好用) 192 | /// 是否At全体 *取消上面的atqq数组 (*暂时群组内不好用) 193 | public MsgV2_TxtMsg(long sendTo, MessageSendToType sendToType, string content, long GroupId = 0, List atqq = null,bool atAll=false) 194 | : base(sendTo, sendToType, MessageSendType.TextMsg, content, GroupId, atqq, atAll) 195 | { } 196 | } 197 | /// 198 | /// 封装的图片信息 199 | /// 200 | public class MsgV2_PicMsg : MsgV2 201 | { 202 | /// 203 | /// 图像URL 204 | /// 205 | public string PicUrl; 206 | /// 207 | /// 图像地址(服务端) 208 | /// 209 | public string PicPath; 210 | /// 211 | /// 图像的Md5 212 | /// 213 | public string PicMd5s; 214 | /// 215 | /// 图像的Base64类 216 | /// 217 | public string PicBase64Buf; 218 | /// 219 | /// 总体图片构造类 220 | /// 221 | /// 发送到 222 | /// 信息类型 223 | /// 内容 224 | /// 图片URL 225 | /// 图片服务端路径 226 | /// 图片Md5 227 | /// 图片的Base64 228 | /// 陌生人识别号 229 | /// 是否atqq 数组qq号 (*暂时群组内不好用) 230 | /// 是否At全体 *取消上面的atqq数组 (*暂时群组内不好用) 231 | public MsgV2_PicMsg(long sendTo, MessageSendToType sendToType, string content = null, 232 | string picUrl = null, string picPath = null, string picMd5s = null, string picBase64Buf = null, 233 | long GroupId = 0, List atqq = null, bool atAll = false) 234 | : base(sendTo, sendToType, MessageSendType.PicMsg, content, GroupId, atqq, atAll) 235 | { 236 | PicUrl = picUrl; 237 | PicPath = picPath; 238 | PicMd5s = picMd5s; 239 | PicBase64Buf = picBase64Buf; 240 | } 241 | /// 242 | /// 重写的直接发送bitmap的图片构造 243 | /// 244 | /// 发送到 245 | /// 信息类型 246 | /// 内容 247 | /// 一个将要使用Base64发送的Bitmap实例 248 | /// 陌生人识别号 249 | /// 是否atqq 数组qq号 (*暂时群组内不好用) 250 | /// 是否At全体 *取消上面的atqq数组 (*暂时群组内不好用) 251 | public MsgV2_PicMsg(long sendTo, MessageSendToType sendToType, Bitmap b, string content = null, 252 | long GroupId = 0, List atqq = null, bool atAll = false) 253 | : base(sendTo, sendToType, MessageSendType.PicMsg, content, GroupId, atqq, atAll) 254 | { 255 | if (b != null) 256 | { 257 | try 258 | { 259 | using MemoryStream ms = new(); 260 | b.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 261 | byte[] arr = new byte[ms.Length]; 262 | ms.Position = 0; 263 | ms.Read(arr, 0, (int)ms.Length); 264 | ms.Close(); 265 | PicBase64Buf = Convert.ToBase64String(arr); 266 | } 267 | catch (Exception ex) 268 | { 269 | throw new Exception($"{EC.E13}:{ex.Message}"); 270 | } 271 | } 272 | else 273 | { 274 | throw new Exception(EC.E14); 275 | } 276 | } 277 | } 278 | /// 279 | /// 封装的语音信息 280 | /// 281 | public class MsgV2_VocMsg : MsgV2 282 | { 283 | /// 284 | /// 语音的URL 285 | /// 286 | public string VoiceUrl; 287 | /// 288 | /// 语音的路径 289 | /// 290 | public string VoicePath; 291 | /// 292 | /// 语音信息 293 | /// 294 | /// 发送到 295 | /// 接收人类型 296 | /// 语音URL 297 | /// 语音文件服务端路径 298 | /// 陌生人识别号 299 | public MsgV2_VocMsg(long sendTo, MessageSendToType sendToType, 300 | string voiceUrl = null, string voicePath = null, 301 | long GroupId = 0) 302 | : base(sendTo, sendToType, MessageSendType.VoiceMsg, null, GroupId, null) 303 | { 304 | VoiceUrl = voiceUrl; 305 | VoicePath = voicePath; 306 | } 307 | } 308 | /// 309 | /// 封装的转发信息 310 | /// 311 | public class MsgV2_FwdMsg : MsgV2 312 | { 313 | /// 314 | /// 转发存档列 315 | /// 316 | public string ForwordBuf; 317 | /// 318 | /// 转发区 319 | /// 320 | public string ForwordField; 321 | /// 322 | /// 转发信息的多定义 323 | /// 324 | /// 发送到 325 | /// 信息类型 326 | /// 框架生成的参数 327 | /// 框架生成的参数 328 | /// 群号 329 | /// 是否atqq 数组qq号 (*暂时群组内不好用) 330 | /// 是否At全体 *取消上面的atqq数组 (*暂时群组内不好用) 331 | public MsgV2_FwdMsg(long sendTo, MessageSendToType sendToType, 332 | string forwordBuf, string forwordField, 333 | long GroupId = 0, List atqq = null, bool atAll = false) 334 | : base(sendTo, sendToType, MessageSendType.ForwordMsg, null, GroupId, atqq, atAll) 335 | { 336 | ForwordBuf = forwordBuf; 337 | ForwordField = forwordField; 338 | } 339 | } 340 | /// 341 | /// 封装的回复信息(仅群聊回复) 342 | /// 343 | public class MsgV2_RplMsg : MsgV2 344 | { 345 | /// 346 | /// 回复信息内容 347 | /// 348 | public replayInfo ReplayInfo; 349 | /// 350 | /// 回复内容的定义类(内部类) 351 | /// 352 | public class replayInfo 353 | { 354 | /// 355 | /// 消息序列号 356 | /// 357 | public long MsgSeq; 358 | /// 359 | /// 消息事件 360 | /// 361 | public long MsgTime; 362 | /// 363 | /// 用户ID 364 | /// 365 | public long UserID; 366 | /// 367 | /// 发送的信息 368 | /// 369 | public string RawContent; 370 | /// 371 | /// 构造一个回复内容 372 | /// 373 | /// 消息序列号 374 | /// 消息的随机码 375 | /// 要回复信息的发送者 376 | /// 内容 377 | public replayInfo(long msgSeq, long msgTime, long userID, string rawContent) 378 | { 379 | MsgSeq = msgSeq; 380 | MsgTime = msgTime; 381 | UserID = userID; 382 | RawContent = rawContent; 383 | } 384 | } 385 | /// 386 | /// 回复信息 I 387 | /// 388 | /// 发送到 389 | /// 一个回复信息内容对象 390 | public MsgV2_RplMsg(long sendTo, replayInfo replayInfo) 391 | : base(sendTo, MessageSendToType.Group, MessageSendType.ReplayMsg, null, 0, null) 392 | { 393 | ReplayInfo = replayInfo; 394 | } 395 | /// 396 | /// 回复信息 II 397 | /// 398 | /// 发送到 399 | /// 消息序列号 400 | /// 消息时间 401 | /// 用户ID 402 | /// 内容 403 | public MsgV2_RplMsg(long sendTo, long msgSeq, long msgTime, long userId, string rawContent) 404 | : base(sendTo, MessageSendToType.Group, MessageSendType.ReplayMsg, null, 0, null) 405 | { 406 | ReplayInfo = new replayInfo(msgSeq, msgTime, userId, rawContent); 407 | } 408 | } 409 | /// 410 | /// 封装的Json信息 411 | /// 412 | public class MsgV2_JsnMsg : MsgV2 413 | { 414 | /// 415 | /// Json信息 416 | /// 417 | /// 发送到 418 | /// 接收人类型 419 | /// Json串 420 | /// 陌生人识别号 421 | /// 是否atqq 数组qq号 (*暂时群组内不好用) 422 | /// 是否At全体 *取消上面的atqq数组 (*暂时群组内不好用) 423 | public MsgV2_JsnMsg(long sendTo, MessageSendToType sendToType, string JsonContent, 424 | long GroupId = 0, List atqq = null, bool atAll = false) 425 | : base(sendTo, sendToType, MessageSendType.JsonMsg, JsonContent, GroupId, atqq, atAll) 426 | { } 427 | } 428 | /// 429 | /// 封装的Xml信息 430 | /// 431 | public class MsgV2_XmlMsg : MsgV2 432 | { 433 | /// 434 | /// XML信息 435 | /// 436 | /// 发送到 437 | /// 接收人类型 438 | /// XML流 439 | /// 陌生人识别号 440 | /// 是否atqq 数组qq号 (*暂时群组内不好用) 441 | /// 是否At全体 *取消上面的atqq数组 (*暂时群组内不好用) 442 | public MsgV2_XmlMsg(long sendTo, MessageSendToType sendToType, string XmlContent, 443 | long GroupId = 0, List atqq = null, bool atAll = false) 444 | : base(sendTo, sendToType, MessageSendType.XmlMsg, XmlContent, GroupId, atqq, atAll) 445 | { } 446 | } 447 | /// 448 | /// 封装的上传群文件方法 449 | /// 450 | public class MsgV2_UploadFile : SendableClass 451 | { 452 | /// 453 | /// 发送到的位置 454 | /// 455 | public long ToUserUid; 456 | /// 457 | /// 信息的类型 458 | /// 459 | public string SendMsgType; 460 | /// 461 | /// 文件路径 462 | /// 463 | public string FilePath; 464 | /// 465 | /// 文件URL 466 | /// 467 | public string FileUrl; 468 | /// 469 | /// 文件的Base64 470 | /// 471 | public string FileBase64; 472 | /// 473 | /// 文件名 474 | /// 475 | public string FileName; 476 | /// 477 | /// 是否通知 478 | /// 479 | public bool Notify; 480 | /// 481 | /// 构造一个发送群文件的方法 482 | /// 483 | /// 发送到(群号) 484 | /// 文件名 485 | /// 文件服务器路径 486 | /// 文件URL(网络) 487 | /// 文件Base64 488 | /// 是否通知(默认否) 489 | public MsgV2_UploadFile(long toUserUid, string fileName, 490 | string filePath=null, string fileUrl=null, string fileBase64=null, bool notify = true) 491 | { 492 | ToUserUid = toUserUid; 493 | SendMsgType = "UploadGroupFile"; 494 | FilePath = filePath; 495 | FileUrl = fileUrl; 496 | FileBase64 = fileBase64; 497 | FileName = fileName; 498 | Notify = notify; 499 | } 500 | } 501 | 502 | /// 503 | /// 枚举的发送类别 504 | /// 505 | public enum MessageSendToType 506 | { 507 | /// 508 | /// 好友 509 | /// 510 | Friend = 1, 511 | /// 512 | /// 群 513 | /// 514 | Group = 2, 515 | /// 516 | /// 私聊 517 | /// 518 | Private = 3, 519 | } 520 | /// 521 | /// 枚举的发送信息类 522 | /// 523 | public enum MessageSendType 524 | { 525 | /// 526 | /// 文本信息 527 | /// 528 | TextMsg, 529 | /// 530 | /// JSON信息 531 | /// 532 | JsonMsg, 533 | /// 534 | /// XML信息 535 | /// 536 | XmlMsg, 537 | /// 538 | /// 回复信息 539 | /// 540 | ReplayMsg, 541 | /// 542 | /// 特效信息 543 | /// 544 | TeXiaoTextMsg, 545 | /// 546 | /// 图片信息 547 | /// 548 | PicMsg, 549 | /// 550 | /// 语音信息 551 | /// 552 | VoiceMsg, 553 | /// 554 | /// ??? 555 | /// 556 | PhoneMsg, 557 | /// 558 | /// 转发信息 559 | /// 560 | ForwordMsg, 561 | /// 562 | /// 上传群文件 563 | /// 564 | UploadGroupFile 565 | } 566 | /// 567 | /// 枚举的发送返回逻辑 568 | /// 569 | public enum Sdstatus 570 | { 571 | /// 572 | /// 空串 573 | /// 574 | NULLREF = -1, 575 | /// 576 | /// 发送成功 577 | /// 578 | OK = 0, 579 | /// 580 | /// 未知错误 581 | /// 582 | err_STB = 34, 583 | /// 584 | /// 手动完成身份验证 585 | /// 586 | err_Auth = 46, 587 | /// 588 | /// 发送失败,你已被移出群聊 589 | /// 590 | err_GroupOut = 110, 591 | /// 592 | /// 你已被禁言 593 | /// 594 | err_Shut = 120, 595 | /// 596 | /// 发送频率过高 597 | /// 598 | err_Freq = 241, 599 | /// 600 | /// 超过群发言频率限制 601 | /// 602 | err_GroupFreq = 299 603 | } 604 | } 605 | -------------------------------------------------------------------------------- /QQ/QQFunc.cs: -------------------------------------------------------------------------------- 1 | using MeowIOTBot.NetworkHelper; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | using static MeowIOTBot.NetworkHelper.PostHelper; 6 | 7 | namespace MeowIOTBot.QQ.QQFunc 8 | { 9 | /// 10 | /// 用户的Cookie[字段未识别用途,保留] 11 | /// User's Cookies the Parameter is not in instance for usage 12 | /// 13 | public class QQCookie 14 | { 15 | /// 16 | /// 17 | /// 18 | public string ClientKey { get; set; } 19 | /// 20 | /// 21 | /// 22 | public string Cookies { get; set; } 23 | /// 24 | /// 25 | /// 26 | public string Gtk { get; set; } 27 | /// 28 | /// 29 | /// 30 | public string Gtk32 { get; set; } 31 | /// 32 | /// 33 | /// 34 | public Pskey PSkey { get; set; } 35 | /// 36 | /// 37 | /// 38 | public string Skey { get; set; } 39 | /// 40 | /// Inner Class for cookie.// 41 | /// 42 | public class Pskey 43 | { 44 | /// 45 | /// 46 | /// 47 | public string connect { get; set; } 48 | /// 49 | /// 50 | /// 51 | public string docs { get; set; } 52 | /// 53 | /// 54 | /// 55 | public string docx { get; set; } 56 | /// 57 | /// 58 | /// 59 | public string game { get; set; } 60 | /// 61 | /// 62 | /// 63 | public string gamecenter { get; set; } 64 | /// 65 | /// 66 | /// 67 | public string imgcache { get; set; } 68 | /// 69 | /// 70 | /// 71 | public string mtencentcom { get; set; } 72 | /// 73 | /// 74 | /// 75 | public string mail { get; set; } 76 | /// 77 | /// 78 | /// 79 | public string mma { get; set; } 80 | /// 81 | /// 82 | /// 83 | public string now { get; set; } 84 | /// 85 | /// 86 | /// 87 | public string office { get; set; } 88 | /// 89 | /// 90 | /// 91 | public string openmobile { get; set; } 92 | /// 93 | /// 94 | /// 95 | public string qqweb { get; set; } 96 | /// 97 | /// 98 | /// 99 | public string qun { get; set; } 100 | /// 101 | /// 102 | /// 103 | public string qzone { get; set; } 104 | /// 105 | /// 106 | /// 107 | public string qzonecom { get; set; } 108 | /// 109 | /// 110 | /// 111 | public string tenpaycom { get; set; } 112 | /// 113 | /// 114 | /// 115 | public string ti { get; set; } 116 | /// 117 | /// 118 | /// 119 | public string vip { get; set; } 120 | /// 121 | /// 122 | /// 123 | public string weishi { get; set; } 124 | } 125 | } 126 | /// 127 | /// QQ用户 128 | /// 129 | public class QQPerson 130 | { 131 | /// 132 | /// 代码 133 | /// Code parameter 134 | /// 135 | public int code; 136 | /// 137 | /// 存储区 138 | /// it's which the DataStores 139 | /// 140 | public datax data; 141 | /// 142 | /// 储存用的类 143 | /// the Class that holds the Data 144 | /// 145 | public class datax 146 | { 147 | /// 148 | /// 头像地址 149 | /// the avator url 150 | /// 151 | public string avatarUrl; 152 | /// 153 | /// 头像bitmapHash 154 | /// avator Bitmap Hash 155 | /// 156 | public string bitmap; 157 | /// 158 | /// 保留字段 159 | /// some unidentify parameter 160 | /// 161 | public int commfrd; 162 | /// 163 | /// 朋友状态 164 | /// a statues that indecate friendship-status 165 | /// 166 | public int friendship; 167 | /// 168 | /// 所在地 169 | /// a parameter that indecate where its from(s) 170 | /// 171 | public string from; 172 | /// 173 | /// 性别 174 | /// Friend Gender 175 | /// 176 | public int gender; 177 | /// 178 | /// 活跃值 179 | /// it's a value that indecate your friends QQ using frequency 180 | /// 181 | public long intimacyScore; 182 | /// 183 | /// 是否为朋友 184 | /// it's a parameter that if you two is friend 185 | /// 186 | public int isFriend; 187 | /// 188 | /// -- 189 | /// 190 | public string logolabel; 191 | /// 192 | /// 昵称 193 | /// a parameter that shows your friend nickname 194 | /// 195 | public string nickname; 196 | /// 197 | /// 腾讯会员等级状态 198 | /// is a parameter shows that your friend is a VIP 199 | /// 200 | public int qqvip; 201 | /// 202 | /// 是否开通QQ空间 203 | /// is a parameter that indecate is your friend have QZone Opened 204 | /// 205 | public int qzone; 206 | /// 207 | /// 真名 208 | /// it's a parameter that indecate your friend's Realname 209 | /// 210 | public string realname; 211 | /// 212 | /// 其他名 213 | /// it's a parameter that indecate is you friend is having some other nick name 214 | /// 215 | public string smartname; 216 | /// 217 | /// QQ号 218 | /// user QQ number 219 | /// 220 | public long uin; 221 | } 222 | /// 223 | /// 默认行为 224 | /// in progress default function place 225 | /// 226 | public int @default; 227 | /// 228 | /// 返回的查询信息 229 | /// the result of query 230 | /// 231 | public string message; 232 | /// 233 | /// 子串码 234 | /// the next gen of query code 235 | /// 236 | public int subcode; 237 | } 238 | /// 239 | /// 好友列表 240 | /// get QQFriendList 241 | /// 242 | public class QQFriendList 243 | { 244 | /// 245 | /// QQ好友类 246 | /// this is a class that indecate your QQ friend 247 | /// 248 | public class QQFriend 249 | { 250 | /// 251 | /// 好友QQ号 252 | /// QQ number 253 | /// 254 | public long FriendUin; 255 | /// 256 | /// 是否含有备注 257 | /// if you get this Friend Remarked 258 | /// 259 | public bool IsRemark; 260 | /// 261 | /// 好友昵称 262 | /// your friends nickname 263 | /// 264 | public string NickName; 265 | /// 266 | /// 在线字符串 267 | /// this is a string that your friend that Online choose 268 | /// 269 | public string OnlineStr; 270 | /// 271 | /// 昵称 272 | /// this is the remark that you may give to your 273 | /// 274 | public string Remark; 275 | /// 276 | /// 状态 277 | /// status 278 | /// 279 | public int status; 280 | } 281 | /// 282 | /// 总好友数 283 | /// the full count of your friend 284 | /// 285 | public int Friend_count; 286 | /// 287 | /// 被调用好友数 288 | /// the sequence that your Indecator have 289 | /// 290 | public List FriendList; 291 | /// 292 | /// 获取好友数 293 | /// the friend that is using to get 294 | /// 295 | public int GetfriendCount; 296 | /// 297 | /// 列表读取 298 | /// List Start Index 299 | /// 300 | public int StartIndex; 301 | /// 302 | /// 好友总数 303 | /// Total Friend Count 304 | /// 305 | public int Totoal_friend_count; 306 | /// 307 | /// 内部保存的SET集 308 | /// the Set of all indecator 309 | /// 310 | public class _FriendList 311 | { 312 | private readonly List q = new(); 313 | /// 314 | /// 添加集方法 315 | /// Set Insert Function 316 | /// 317 | /// 项目 318 | /// 319 | public bool Add(QQFriend n) 320 | { 321 | if (q.Exists((QQFriend k) => k.FriendUin == n.FriendUin)) 322 | { 323 | return false; 324 | } 325 | else 326 | { 327 | q.Add(n); 328 | return true; 329 | } 330 | } 331 | /// 332 | /// 获取集 333 | /// get Set 334 | /// 335 | /// 336 | public List getInstance() => q; 337 | } 338 | 339 | /// 340 | /// 获取列表的部分集合 341 | /// get partial list of indecator SETs 342 | /// 343 | /// 344 | /// 345 | public static async Task GetListOnIndex(int Index) => JsonConvert.DeserializeObject(await PASA(UrlType.GetQQUserList, $"{{\"StartIndex\":{Index}}}")); 346 | } 347 | /// 348 | /// QQ好友请求(管理类)方法 349 | /// QQ Friend Request Response Method 350 | /// 351 | public class QQFriendRequest 352 | { 353 | /// 354 | /// 加好友总方法 355 | /// Add Friend Method Set 356 | /// 357 | /// 358 | /// 2011 空间 2020 QQ搜索 2004 群组 2005 讨论组 359 | /// 2011:Qzone 2020:QQSearch 2004:FromSpecificGroup 2005:FromDiscussGroup 360 | /// 361 | /// 362 | /// 来源为2004时需要添加 363 | /// the Group you both in, which is needed for Type 2004 364 | /// 365 | /// 366 | /// 内容 367 | /// the content that you want to present 368 | /// 369 | /// 370 | /// 要添加的用户 371 | /// the User that you want to install with 372 | /// 373 | /// 374 | public static async Task __FriendManage(int AddFromSource, long FromGroupID, long AddUserUid, string Content) => 375 | await PASA( 376 | UrlType.AddQQUser, 377 | $"{{\"AddUserUid\":{AddUserUid}," + 378 | $"\"Content\":\"{Content}\"," + 379 | $"\"AddFromSource\":{AddFromSource}," + 380 | $"\"FromGroupID\":{FromGroupID}}}" 381 | ); 382 | } 383 | /// 384 | /// 群成员列表 385 | /// QQ GroupMember List 386 | /// 387 | public class QQGroupUserList 388 | { 389 | /// 390 | /// 列对象 391 | /// the counter object int 392 | /// 393 | public int Count { get; set; } 394 | /// 395 | /// 群号 396 | /// the GroupNumber 397 | /// 398 | public long GroupUin { get; set; } 399 | /// 400 | /// 保留 401 | /// the Programme running need this parameter to check 402 | /// 403 | public int LastUin { get; set; } 404 | /// 405 | /// 群成员列表 406 | /// GroupMember List 407 | /// 408 | public List MemberList { get; set; } 409 | /// 410 | /// QQ群成员 411 | /// the Group member Class 412 | /// 413 | public class QQGroupUser 414 | { 415 | /// 416 | /// 年龄 417 | /// Age 418 | /// 419 | public int Age; 420 | /// 421 | /// 未知属性 422 | /// some undefined code 423 | /// 424 | public int FaceId; 425 | /// 426 | /// 性别 427 | /// gender 428 | /// 429 | public int Gender; 430 | /// 431 | /// 群昵称 432 | /// his group nickname 433 | /// 434 | public string GroupCard; 435 | /// 436 | /// 加入群时间 437 | /// the Time that join in Group 438 | /// 439 | public long JoinGroupTime; 440 | /// 441 | /// 展示的群成员邮箱 442 | /// The Email it choose 443 | /// 444 | public string MemberEmail; 445 | /// 446 | /// 群成员QQ号 447 | /// the QQ number that Member have 448 | /// 449 | public long MemberUin; 450 | /// 451 | /// 群成员昵称 452 | /// the nickname of the specific (QQNickName) 453 | /// 454 | public string NickName; 455 | /// 456 | /// -- 457 | /// -- 458 | /// 459 | public int RankDes; 460 | /// 461 | /// 我的群成员备注 462 | /// the Group Remark 463 | /// 464 | public string Remark; 465 | /// 466 | /// 群成员最后一次发言时间 467 | /// the last time he talkin 468 | /// 469 | public int SpeakTime; 470 | /// 471 | /// 群成员当前状态 10在线 | 20隐身 472 | /// the Status the Mebemer [int] for 10 is online and 20 is offline 473 | /// 474 | public int Status; 475 | /// 476 | /// 是否群管理员 0F/1T 477 | /// a parameter indecate this memeber is GroupAdministrator 478 | /// 479 | public int GroupAdmin; 480 | } 481 | } 482 | /// 483 | /// 群列表 484 | /// Group List class 485 | /// 486 | public class QQGroupList 487 | { 488 | /// 489 | /// 群总数 490 | /// the Total Count of QQGroup 491 | /// 492 | public int Count; 493 | /// 494 | /// 拉取列表的下一个操作验证 495 | /// the next gen of the Programme 496 | /// 497 | public int? NextToken; 498 | /// 499 | /// 拉取的部分群列表 500 | /// converted QQGroupList 501 | /// 502 | public List TroopList; 503 | /// 504 | /// QQ群的操作列表 505 | /// Group Class 506 | /// 507 | public class QQGroup 508 | { 509 | /// 510 | /// 群号 511 | /// Group Number 512 | /// 513 | public long GroupId; 514 | /// 515 | /// 群成员数 516 | /// Group Member Count 517 | /// 518 | public int GroupMemberCount; 519 | /// 520 | /// 群名 521 | /// Group Name 522 | /// 523 | public string GroupName; 524 | /// 525 | /// 群公告(获取最近一条置顶) 526 | /// the Most Recently GroupAnnounce 527 | /// 528 | public string GroupNotice; 529 | /// 530 | /// 群主 531 | /// the Group Owner 532 | /// 533 | public long GroupOwner; 534 | /// 535 | /// 群总成员数 536 | /// Group Memeber Total Count 537 | /// 538 | public int GroupTotalCount; 539 | } 540 | /// 541 | /// 内套的群列表 542 | /// Inner class of Group List 543 | /// 544 | public class _GroupList 545 | { 546 | /// 547 | /// 私有的群列表 548 | /// 549 | private readonly List q = new(); 550 | /// 551 | /// 重构的对比添加 552 | /// 553 | /// 项 554 | /// 555 | public bool Add(QQGroup n) 556 | { 557 | if (q.Exists((QQGroup k) => k.GroupId == n.GroupId)) 558 | { 559 | return false; 560 | } 561 | else 562 | { 563 | q.Add(n); 564 | return true; 565 | } 566 | } 567 | /// 568 | /// 获取群列表 569 | /// 570 | /// 571 | public List getInstance() => q; 572 | } 573 | /// 574 | /// 拉取群列表 575 | /// the Group List 576 | /// 577 | /// 578 | /// 索引号 579 | /// Index number 580 | /// 581 | /// 582 | public static async Task GetGroupListOnIndex(int nt) => 583 | JsonConvert.DeserializeObject( 584 | await PASA( 585 | UrlType.GetGroupList, 586 | $"{{\"NextToken\":{nt}}}") 587 | ); 588 | } 589 | /// 590 | /// QQ群请求(管理类)方法 591 | /// QQGroup Manager Method 592 | /// 593 | public class QQGroupRequest 594 | { 595 | /// 596 | /// 总方法 597 | /// General Method 598 | /// 599 | /// 600 | /// 8拉人 1加入 2退出 3移出 601 | /// for [int] 8:invite 1:joinin 2:leave 3:remove-someone 602 | /// 603 | /// 604 | /// 群号 605 | /// GroupNumber 606 | /// 607 | /// 608 | /// QQ用户ID *加入退出不用写* 609 | /// the QQ number (*for enter and quit please leave this blanked) 610 | /// 611 | /// 612 | /// 内容 613 | /// the Content 614 | /// 615 | public static async Task __GroupManage(int ActionType, long GroupID, long ActionUserID, string Content) => await 616 | PostHelper.PASA( 617 | PostHelper.UrlType.GroupMgr, 618 | $"{{\"ActionType\":{ActionType},\"GroupID\":{GroupID}," + 619 | $"\"ActionUserID\":{ActionUserID},\"Content\":\"{Content}\"}}" 620 | ); 621 | } 622 | } 623 | 624 | 625 | -------------------------------------------------------------------------------- /MainClassdg.cd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | _Client\ClientX.cs 12 | 13 | 14 | 15 | 16 | _Client\ClientX.cs 17 | 18 | 19 | 20 | 21 | _Client\ClientX.cs 22 | 23 | 24 | 25 | 26 | _Client\ClientX.cs 27 | 28 | 29 | 30 | 31 | _Client\ClientX.cs 32 | 33 | 34 | 35 | 36 | _Client\ClientX.cs 37 | 38 | 39 | 40 | 41 | _Client\ClientX.cs 42 | 43 | 44 | 45 | 46 | _Client\ClientX.cs 47 | 48 | 49 | 50 | 51 | _Client\ClientX.cs 52 | 53 | 54 | 55 | 56 | _Client\ClientX.cs 57 | 58 | 59 | 60 | 61 | _Client\ClientX.cs 62 | 63 | 64 | 65 | 66 | _Client\ClientX.cs 67 | 68 | 69 | 70 | 71 | _Client\ClientX.cs 72 | 73 | 74 | 75 | 76 | _Client\ClientX.cs 77 | 78 | 79 | 80 | 81 | _Client\ClientX.cs 82 | 83 | 84 | 85 | 86 | _Client\ClientX.cs 87 | 88 | 89 | 90 | 91 | _Client\ClientX.cs 92 | 93 | 94 | 95 | 96 | _Client\ClientX.cs 97 | 98 | 99 | 100 | 101 | _Client\ClientX.cs 102 | 103 | 104 | 105 | 106 | _Client\ClientX.cs 107 | 108 | 109 | 110 | 111 | _Client\ClientX.cs 112 | 113 | 114 | 115 | 116 | _Client\ClientX.cs 117 | 118 | 119 | 120 | 121 | _Client\ClientX.cs 122 | 123 | 124 | 125 | 126 | BABgQAoEAAGAAJIAAAABAOAAAAQgAAQAAAAABIEgQEE= 127 | _Client\ClientX.cs 128 | 129 | 130 | 131 | 132 | 133 | AAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAQAAAAAAA= 134 | QQ\LoginQQEvent.cs 135 | 136 | 137 | 138 | 139 | 140 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAQAAAAAAAAAAA= 141 | ExceptionCore.cs 142 | 143 | 144 | 145 | 146 | 147 | AAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAA= 148 | Serverutil.cs 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | _Client\MeowClient.cs 160 | 161 | 162 | 163 | 164 | _Client\MeowClient.cs 165 | 166 | 167 | 168 | 169 | _Client\MeowClient.cs 170 | 171 | 172 | 173 | 174 | _Client\MeowClient.cs 175 | 176 | 177 | 178 | 179 | _Client\MeowClient.cs 180 | 181 | 182 | 183 | 184 | QAAAAEIAQCAAAUAAIAAAAAAAAAAAgAAQCAAAAAAAgAA= 185 | _Client\MeowClient.cs 186 | 187 | 188 | 189 | 190 | 191 | 192 | BAAAAAAAAAAAAIAAAAAAAAAAAAAAAJAACAAAAAAAAAA= 193 | NetworkHelperGeneral\HttpHelper.cs 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | NetworkHelperGeneral\PostHelper.cs 205 | 206 | 207 | 208 | 209 | BAAAAAAAAAEAAAAAAAAAAAQAAAAgAAIAAAAAAAAAAAA= 210 | NetworkHelperGeneral\PostHelper.cs 211 | 212 | 213 | 214 | 215 | 216 | AAAAIAAAAAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAA= 217 | ObjectEvent\GeneralEventArgs.cs 218 | 219 | 220 | 221 | 222 | 223 | AAAAAAAAAAAAAAAAIAAAAACAAAAAIAAAAAABAAAAAgA= 224 | QQ\QQAction.cs 225 | 226 | 227 | 228 | 229 | 230 | ABAQAAgAAEAAAAACAAAAAAAAAIAAAAgAhAAAAABAAAA= 231 | QQ\QQAction.cs 232 | 233 | 234 | 235 | 236 | 237 | AAAAAAQAAAAAAAAAAAAAAAAgAAgAAAAAAAAAAAAEAAA= 238 | QQ\QQAction.cs 239 | 240 | 241 | 242 | 243 | 244 | AEAACAAEAgAABCAAAAAAAAQIgAAAAAAAAQAMAQAAAAU= 245 | QQ\QQEvent.cs 246 | 247 | 248 | 249 | 250 | 251 | AAQAAAAAAAAAAAAAAAAAAAiAAAAAAAAAAAAAAAAAAAA= 252 | QQ\QQEvent.cs 253 | 254 | 255 | 256 | 257 | 258 | AAQAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAACAAAAA= 259 | QQ\QQEvent.cs 260 | 261 | 262 | 263 | 264 | 265 | AAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAA= 266 | QQ\QQEvent.cs 267 | 268 | 269 | 270 | 271 | 272 | AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 273 | QQ\QQEvent.cs 274 | 275 | 276 | 277 | 278 | 279 | AAAAAAQAAAAAAAAAAAAAAAgAAAAAAAAAAQAAAAAAAAA= 280 | QQ\QQEvent.cs 281 | 282 | 283 | 284 | 285 | 286 | AAACAAAAAAAAAAAAQAAAAAAAAAAAAAAAEAAAAAAAAAA= 287 | QQ\QQEvent.cs 288 | 289 | 290 | 291 | 292 | 293 | AAQAAAAAQAAAAAAAQAAAAAgAAAAIAAAAAAAAAAAAAAA= 294 | QQ\QQEvent.cs 295 | 296 | 297 | 298 | 299 | 300 | EAACAAAAAgABQAAAUAAIAAwAgAAAAAAAEQAAAAAAAIQ= 301 | QQ\QQEvent.cs 302 | 303 | 304 | 305 | 306 | 307 | AAAAAAAAAAAAAAAAAAAAAAgAAAAAAAEAAAAAAAAAAAA= 308 | QQ\QQEvent.cs 309 | 310 | 311 | 312 | 313 | 314 | AAAAAAAAAAAAAAAAACAAAAgAAAAAAAEAAQAAAAAAAAA= 315 | QQ\QQEvent.cs 316 | 317 | 318 | 319 | 320 | 321 | AAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAA= 322 | QQ\QQEvent.cs 323 | 324 | 325 | 326 | 327 | 328 | AAAAAAAgAgAAAAAAQAAAAAAAAAAQABAAAAAAACAAAAA= 329 | QQ\QQEvent.cs 330 | 331 | 332 | 333 | 334 | 335 | AIAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAAAAAAAAAAAA= 336 | QQ\QQEvent.cs 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | QQ\QQFunc.cs 348 | 349 | 350 | 351 | 352 | AQAAAAAABAAAAAAAAAAAAAAAAAgAAgAAAAAIAAAIAAA= 353 | QQ\QQFunc.cs 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | QQ\QQFunc.cs 365 | 366 | 367 | 368 | 369 | AAAAAAAAAAAAAAAAAAAAAAAgIAAAACAAAAAQAAAAACA= 370 | QQ\QQFunc.cs 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | QQ\QQFunc.cs 382 | 383 | 384 | 385 | 386 | QQ\QQFunc.cs 387 | 388 | 389 | 390 | 391 | AAAABAAAAAAAAAAAAAAAAACABAAAAIEAAAAAgAAAAAA= 392 | QQ\QQFunc.cs 393 | 394 | 395 | 396 | 397 | 398 | AAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAA= 399 | QQ\QQFunc.cs 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | QQ\QQFunc.cs 411 | 412 | 413 | 414 | 415 | AAAAAAAAAAAAACAAAAAAAARAAAAAAAAAAAAAAQAAAAA= 416 | QQ\QQFunc.cs 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | QQ\QQFunc.cs 428 | 429 | 430 | 431 | 432 | QQ\QQFunc.cs 433 | 434 | 435 | 436 | 437 | IAIAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAgAAAAA= 438 | QQ\QQFunc.cs 439 | 440 | 441 | 442 | 443 | 444 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQA= 445 | QQ\QQFunc.cs 446 | 447 | 448 | 449 | 450 | 451 | AAAAAAAAgAAAEAAAAAAAAAAAgAAAAAAAAAAAAQAAAAA= 452 | QQ\QQRecieveMessage.cs 453 | 454 | 455 | 456 | 457 | 458 | AAAQAAAAAAAAAEAAAAAIAAQAAAAAAAEAAAAAAAAAAAA= 459 | QQ\QQRecieveMessage.cs 460 | 461 | 462 | 463 | 464 | 465 | AAAAAAAAQAAAAAABRAAAAAAAAAAAAAAAAAAAAgAAEAA= 466 | QQ\QQRecieveMessage.cs 467 | 468 | 469 | 470 | 471 | 472 | QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 473 | QQ\QQRecieveMessage.cs 474 | 475 | 476 | 477 | 478 | 479 | AAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 480 | QQ\QQRecieveMessage.cs 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | QQ\QQRecieveMessage.cs 492 | 493 | 494 | 495 | 496 | AAAAAAEAAgAAAAAAAAAAAAAAAAAAAAAAAAAQIBBAAAA= 497 | QQ\QQRecieveMessage.cs 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | QQ\QQRecieveMessage.cs 509 | 510 | 511 | 512 | 513 | AAAAAEEAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 514 | QQ\QQRecieveMessage.cs 515 | 516 | 517 | 518 | 519 | 520 | AAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAA= 521 | QQ\QQRecieveMessage.cs 522 | 523 | 524 | 525 | 526 | 527 | AAAAAAAAAgAAAAAAAAAAAAAAAAABAAACAAAAEAEAAAA= 528 | QQ\QQRecieveMessage.cs 529 | 530 | 531 | 532 | 533 | 534 | AAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAIAAAAAAAAAA= 535 | QQ\QQSendMessage.cs 536 | 537 | 538 | 539 | 540 | 541 | AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA= 542 | QQ\QQSendMessage.cs 543 | 544 | 545 | 546 | 547 | 548 | 549 | AAwAAAAAAgAAAAAAEAAAAAAAAAAAAAAAAAACAAAAAAA= 550 | QQ\QQSendMessage.cs 551 | 552 | 553 | 554 | 555 | 556 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 557 | QQ\QQSendMessage.cs 558 | 559 | 560 | 561 | 562 | 563 | AAAAAAAAQAAAAAAAAABIAAAAAAAAAAAAAEAAAAAAAAA= 564 | QQ\QQSendMessage.cs 565 | 566 | 567 | 568 | 569 | 570 | AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACAAAA= 571 | QQ\QQSendMessage.cs 572 | 573 | 574 | 575 | 576 | 577 | AAAAAAAAAAAAAAAAAAAAAAAAAAABAAACAAAAAAAAAAA= 578 | QQ\QQSendMessage.cs 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | QQ\QQSendMessage.cs 590 | 591 | 592 | 593 | 594 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE= 595 | QQ\QQSendMessage.cs 596 | 597 | 598 | 599 | 600 | 601 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 602 | QQ\QQSendMessage.cs 603 | 604 | 605 | 606 | 607 | 608 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 609 | QQ\QQSendMessage.cs 610 | 611 | 612 | 613 | 614 | 615 | AAgAAAAAAAAAAAAAgAAAAQAAAAAAAABAAABCAABAAAA= 616 | QQ\QQSendMessage.cs 617 | 618 | 619 | 620 | 621 | 622 | AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA= 623 | QQ\QQSendMessage.cs 624 | 625 | 626 | 627 | 628 | 629 | CAAAAAAAAAAAAAAADAAkAAIAAAIAAQAEAgAAAAEAAAA= 630 | QQ\QQEvent.cs 631 | 632 | 633 | 634 | 635 | 636 | AAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAgCAAAAAAAAAA= 637 | QQ\QQRecieveMessage.cs 638 | 639 | 640 | 641 | 642 | 643 | AAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAACAAAAAAAAAA= 644 | QQ\QQSendMessage.cs 645 | 646 | 647 | 648 | 649 | 650 | ACAAgEAQAAAAIAAAAAIAAAAAAQAAAAAAAAAAAAAAKCA= 651 | QQ\QQSendMessage.cs 652 | 653 | 654 | 655 | 656 | 657 | AAAAAAAAAgAAAAAEAAAAAAAIAAACAAAEAAABAACAAAQ= 658 | QQ\QQSendMessage.cs 659 | 660 | 661 | 662 | 663 | 664 | ACAAAAEAAIAAAAAAAAAAAAAAAAIAAAAAAAAAAAEAAAA= 665 | Serverutil.cs 666 | 667 | 668 | 669 | -------------------------------------------------------------------------------- /_Client/ClientX.cs: -------------------------------------------------------------------------------- 1 | using MeowIOTBot.Basex; 2 | using System; 3 | using MeowIOTBot.QQ.QQMessage.QQRecieveMessage; 4 | using MeowIOTBot.QQ.QQEvent; 5 | using Newtonsoft.Json.Linq; 6 | 7 | namespace MeowIOTBot 8 | { 9 | /// 10 | /// 完全代理的IOT端 11 | /// Full stack delegated IOT Backend 12 | /// 用法如下 (Usage as below) 13 | /// 14 | /// using var recv = MeowIOTClient.Connect("url", "qq"); 15 | /// recv._(delegate event) += (s, e) =>{}; 16 | /// 17 | /// 18 | public class MeowIOTClient : MeowClient 19 | { 20 | /// 21 | /// 一个自枚举的多功能解释端 22 | /// 23 | /// ws的连接Client位置 例如 ws://localhost:10000 24 | /// 是否打印日志 25 | /// 监视器循环时间 26 | /// 是否启用监视器(默认启动) 27 | public MeowIOTClient(string url, LogType logflag, long monitortime=10000, bool monitorenable=true) 28 | : base(url, logflag, monitortime, monitorenable) 29 | { 30 | OnServerAction += SocketNullDelegate; 31 | OnGroupMsgs += Meow_OnGroupMsgs; 32 | OnEventMsgs += Meow_OnEventMsgs; 33 | OnFriendMsgs += Meow_OnFriendMsgs; 34 | _FriendTextMsgRecieve += SocketNullDelegate; 35 | _FriendPicMsgRecieve += SocketNullDelegate; 36 | _FriendVocMsgRecieve += SocketNullDelegate; 37 | _FriendVidMsgRecieve += SocketNullDelegate; 38 | _GroupAtTextMsgRecieve += SocketNullDelegate; 39 | _GroupAtPicMsgRecieve += SocketNullDelegate; 40 | _GroupPicMsgRecieve += SocketNullDelegate; 41 | _GroupTextMsgRecieve += SocketNullDelegate; 42 | _GroupVocMsgRecieve += SocketNullDelegate; 43 | _GroupVidMsgRecieve += SocketNullDelegate; 44 | __ON_EVENT_GROUP_ADMIN += SocketNullDelegate; 45 | __ON_EVENT_GROUP_ADMINSYSNOTIFY += SocketNullDelegate; 46 | __ON_EVENT_GROUP_EXIT += SocketNullDelegate; 47 | __ON_EVENT_GROUP_EXIT_SUCC += SocketNullDelegate; 48 | __ON_EVENT_GROUP_INVITE += SocketNullDelegate; 49 | __ON_EVENT_GROUP_JOIN += SocketNullDelegate; 50 | __ON_EVENT_GROUP_REVOKE += SocketNullDelegate; 51 | __ON_EVENT_GROUP_SHUT += SocketNullDelegate; 52 | __ON_EVENT_FRIEND_ADD += SocketNullDelegate; 53 | __ON_EVENT_FRIEND_ADD_STATUS += SocketNullDelegate; 54 | __ON_EVENT_FRIEND_DELETE += SocketNullDelegate; 55 | __ON_EVENT_FRIEND_PUSHADDFRD += SocketNullDelegate; 56 | __ON_UNMOUNT_EVENT += SocketNullDelegate; 57 | } 58 | /// 59 | /// 连接后端 60 | /// 61 | public async System.Threading.Tasks.Task Connect() 62 | { 63 | await ss.OpenAsync(new(Url)); 64 | return this; 65 | } 66 | /// 67 | /// 断开后端 68 | /// 69 | /// 70 | public async System.Threading.Tasks.Task DisConnect() 71 | { 72 | await ss.CloseAsync(); 73 | return this; 74 | } 75 | /// 76 | /// 重连后端 77 | /// 78 | /// 79 | public async System.Threading.Tasks.Task ReConnect() 80 | { 81 | await ss.CloseAsync(); 82 | await ss.OpenAsync(new(Url)); 83 | return this; 84 | } 85 | 86 | #region 自动事件处理 -- Event Trigger -- 87 | private void SocketNullDelegate(object sender, object e) { } 88 | private void Meow_OnFriendMsgs(object sender, ObjectEvent.ObjectEventArgs e) 89 | { 90 | #region 私聊报头 -- Private Info Head -- 91 | var prop = new QQRecieveMessage( 92 | MessageIOType.Friend, 93 | new IOBody( 94 | e.Data["FromUin"].ToObject(), 95 | e.Data["ToUin"].ToObject(), 96 | null, 97 | null, 98 | null 99 | ), 100 | new MsgProperty( 101 | null, 102 | e.Data["MsgSeq"].ToObject(), 103 | null, 104 | null, 105 | e.Data["RedBaginfo"].ToString(), 106 | null 107 | ), 108 | e.CurrentQQ 109 | ); 110 | #endregion 111 | //文本 112 | var content = e.Data["Content"].ToString(); 113 | //触发对应操作信息 114 | switch (e.Data["MsgType"].ToString()) 115 | { 116 | case "TextMsg": 117 | { 118 | var msg = new TextMsg(content); 119 | _FriendTextMsgRecieve.Invoke(prop, msg); 120 | ServerUtil.Log($"好友文本信息 [{prop.IOBody.MsgFromQQ}->{prop.IOBody.MsgRecvQQ}] \n" + 121 | $"内容:{msg.Content}", LogType.ClientMessage, ConsoleColor.Magenta); 122 | } 123 | break; 124 | case "PicMsg": 125 | { 126 | var msg = new PicMsg(content); 127 | _FriendPicMsgRecieve.Invoke(prop, msg); 128 | if (msg._isSnapPic) 129 | { 130 | ServerUtil.Log($"好友闪照信息 [{prop.IOBody.MsgFromQQ}->{prop.IOBody.MsgRecvQQ}]", LogType.ClientMessage, ConsoleColor.Yellow); 131 | } 132 | else 133 | { 134 | ServerUtil.Log($"好友图片信息 [{prop.IOBody.MsgFromQQ}->{prop.IOBody.MsgRecvQQ}] \n" + 135 | $"内容:{msg.Content} | 图片共 {msg.PicList.Length} 张", LogType.ClientMessage, ConsoleColor.Yellow); 136 | } 137 | 138 | } 139 | break; 140 | case "VoiceMsg": 141 | { 142 | var msg = new VoiceMsg(content); 143 | _FriendVocMsgRecieve.Invoke(prop, msg); 144 | ServerUtil.Log($"好友语音信息 [{prop.IOBody.MsgFromQQ}->{prop.IOBody.MsgRecvQQ}]" 145 | , LogType.ClientMessage, ConsoleColor.DarkMagenta); 146 | } 147 | break; 148 | case "VideoMsg": 149 | { 150 | var msg = new VideoMsg(content); 151 | _FriendVidMsgRecieve.Invoke(prop, msg); 152 | ServerUtil.Log($"好友视频信息 [{prop.IOBody.MsgFromQQ}->{prop.IOBody.MsgRecvQQ}]" 153 | , LogType.ClientMessage, ConsoleColor.Green); 154 | } 155 | break; 156 | }; 157 | } 158 | private void Meow_OnGroupMsgs(object sender, ObjectEvent.ObjectEventArgs e) 159 | { 160 | #region 群聊报头 -- Group Info Head -- 161 | var prop = new QQRecieveMessage( 162 | MessageIOType.Friend, 163 | new IOBody( 164 | e.Data["FromUserId"].ToObject(), 165 | 0, 166 | e.Data["FromNickName"].ToString(), 167 | e.Data["FromGroupId"].ToObject(), 168 | e.Data["FromGroupName"].ToString() 169 | ), 170 | new MsgProperty( 171 | null, 172 | e.Data["MsgSeq"].ToObject(), 173 | e.Data["MsgRandom"].ToObject(), 174 | null, 175 | e.Data["RedBaginfo"].ToString(), 176 | e.Data["MsgTime"].ToObject() 177 | ), 178 | e.CurrentQQ 179 | ); 180 | #endregion 181 | //文本 182 | var content = e.Data["Content"].ToString(); 183 | //触发对应操作信息 184 | switch (e.Data["MsgType"].ToString()) 185 | { 186 | case "TextMsg": 187 | { 188 | var msg = new TextMsg(content); 189 | _GroupTextMsgRecieve.Invoke(prop, msg); 190 | ServerUtil.Log($"群文本信息 [{prop.IOBody.MsgFromQQ}] " + 191 | $"在群聊 [{prop.IOBody.FromGroupId} :: {prop.IOBody.FromGroupName}] \n" + 192 | $"内容:{msg.Content}", LogType.ClientMessage, ConsoleColor.Magenta); 193 | } 194 | break; 195 | case "AtMsg": 196 | { 197 | var msg = new AtTextMsg(content); 198 | _GroupAtTextMsgRecieve.Invoke(prop, msg); 199 | ServerUtil.Log($"群At文本信息 [{prop.IOBody.MsgFromQQ}] " + 200 | $"在群聊 [{prop.IOBody.FromGroupId} :: {prop.IOBody.FromGroupName}] \n" + 201 | $"内容:{msg.Content}", LogType.ClientMessage, ConsoleColor.Magenta, ConsoleColor.Cyan); 202 | } 203 | break; 204 | case "PicMsg": 205 | { 206 | var msg = new PicMsg(content); 207 | var d = "图片"; 208 | if (msg.AtedQQ != null) 209 | { 210 | _GroupAtPicMsgRecieve.Invoke(prop, msg); 211 | d = "At图片"; 212 | } 213 | if (msg._isSnapPic) 214 | { 215 | d = "闪照"; 216 | } 217 | _GroupPicMsgRecieve.Invoke(prop, msg); 218 | ServerUtil.Log($"群{d} [{prop.IOBody.MsgFromQQ}] " + 219 | $"在群聊 [{prop.IOBody.FromGroupId} :: {prop.IOBody.FromGroupName}] \n" + 220 | $"内容:{msg.Content} | 图片共 {msg.PicList.Length} 张", LogType.ClientMessage, ConsoleColor.Yellow); 221 | } 222 | break; 223 | case "VoiceMsg": 224 | { 225 | var msg = new VoiceMsg(content); 226 | _GroupVocMsgRecieve.Invoke(prop, msg); 227 | ServerUtil.Log($"群语音信息 [{prop.IOBody.MsgFromQQ}] " + 228 | $"在群聊 [{prop.IOBody.FromGroupId} :: {prop.IOBody.FromGroupName}]" 229 | , LogType.ClientMessage, ConsoleColor.DarkMagenta); 230 | } 231 | break; 232 | case "VideoMsg": 233 | { 234 | var msg = new VideoMsg(content); 235 | _GroupVidMsgRecieve.Invoke(prop, msg); 236 | ServerUtil.Log($"群视频信息 [{prop.IOBody.MsgFromQQ}] " + 237 | $"在群聊 [{prop.IOBody.FromGroupId} :: {prop.IOBody.FromGroupName}]" 238 | , LogType.ClientMessage, ConsoleColor.Green); 239 | } 240 | break; 241 | }; 242 | } 243 | private void Meow_OnEventMsgs(object sender, ObjectEvent.ObjectEventArgs e) 244 | { 245 | var d = new Event(e.Data); 246 | switch (d.EType.ToString()) 247 | { 248 | case "ON_EVENT_GROUP_ADMIN": 249 | { 250 | var x = (ON_EVENT_GROUP_ADMIN)d.Data; 251 | __ON_EVENT_GROUP_ADMIN.Invoke(d.EMsg, x); 252 | ServerUtil.Log($"[*群管理员变更*] 群{x.GroupID}的{x.UserID}{(x.Flag == 0 ? "不再是管理员了" : "成为管理员")}", LogType.ClientVerbose); 253 | } 254 | break; 255 | case "ON_EVENT_GROUP_SHUT": 256 | { 257 | var x = (ON_EVENT_GROUP_SHUT)d.Data; 258 | __ON_EVENT_GROUP_SHUT.Invoke(d.EMsg, x); 259 | ServerUtil.Log($"[*群禁言*] 群{x.GroupID}的{(x.UserID == 0 ? "全体" : x.UserID)}被{(x.ShutTime == 0 ? "解除禁言" : $"禁言{x.ShutTime}分钟")}", LogType.ClientVerbose); 260 | } 261 | break; 262 | case "ON_EVENT_GROUP_ADMINSYSNOTIFY": 263 | { 264 | var x = (ON_EVENT_GROUP_ADMINSYSNOTIFY)d.Data; 265 | __ON_EVENT_GROUP_ADMINSYSNOTIFY.Invoke(d.EMsg, x); 266 | switch (d.EMsg.Content switch 267 | { 268 | "退群消息" => EventType.ON_EVENT_GROUP_EXIT, 269 | "邀请加群" => EventType.ON_EVENT_GROUP_ADMINSYSNOTIFY_INVITE_GROUP, 270 | _ => EventType.ON_EVENT_GROUP_ADMINSYSNOTIFY 271 | }) 272 | { 273 | case EventType.ON_EVENT_GROUP_ADMINSYSNOTIFY_INVITE_GROUP: 274 | __ON_EVENT_GROUP_INVITE.Invoke(d.EMsg, new ON_EVENT_GROUP_ADMINSYSNOTIFY_INVITE_GROUP(x)); 275 | break; 276 | } 277 | ServerUtil.Log($"[*{x.MsgTypeStr}*] {x.Who}-->{x.GroupId}::{x.MsgStatusStr}", LogType.ClientVerbose); 278 | } 279 | break; 280 | case "ON_EVENT_GROUP_EXIT": 281 | { 282 | var x = (ON_EVENT_GROUP_EXIT)d.Data; 283 | __ON_EVENT_GROUP_EXIT.Invoke(d.EMsg, x); 284 | ServerUtil.Log($"[*群成员退出*] 群{d.EMsg.FromUser}的{x.UserID}用户退出了群聊", LogType.ClientVerbose); 285 | } 286 | break; 287 | case "ON_EVENT_GROUP_EXIT_SUCC": 288 | { 289 | var x = (ON_EVENT_GROUP_EXIT_SUCC)d.Data; 290 | __ON_EVENT_GROUP_EXIT_SUCC.Invoke(d.EMsg, x); 291 | ServerUtil.Log($"[*群主动退出*] 你主动退出了群号为{x.GroupID}的群聊", LogType.ClientVerbose); 292 | } 293 | break; 294 | case "ON_EVENT_GROUP_JOIN": 295 | { 296 | var x = (ON_EVENT_GROUP_JOIN)d.Data; 297 | __ON_EVENT_GROUP_JOIN.Invoke(d.EMsg, x); 298 | ServerUtil.Log($"[*群成员加入*] {x.UserID}加入了{d.EMsg.FromUser}群", LogType.ClientVerbose); 299 | } 300 | break; 301 | /*----------------------------------------------------------*/ 302 | case "ON_EVENT_FRIEND_ADD": 303 | { 304 | var x = (ON_EVENT_FRIEND_ADD)d.Data; 305 | __ON_EVENT_FRIEND_ADD.Invoke(d.EMsg, x); 306 | ServerUtil.Log($"[*好友添加申请*] {x.UserID}申请成为你的好友", LogType.ClientVerbose); 307 | } 308 | break; 309 | case "ON_EVENT_NOTIFY_PUSHADDFRD": 310 | { 311 | var x = (ON_EVENT_NOTIFY_PUSHADDFRD)d.Data; 312 | __ON_EVENT_FRIEND_PUSHADDFRD.Invoke(d.EMsg, x); 313 | ServerUtil.Log($"[*好友添加成功*] {x.UserID}已经成为你的好友", LogType.ClientVerbose); 314 | } 315 | break; 316 | case "ON_EVENT_FRIEND_ADD_STATUS": 317 | { 318 | var x = (ON_EVENT_FRIEND_ADD_STATUS)d.Data; 319 | __ON_EVENT_FRIEND_ADD_STATUS.Invoke(d.EMsg, x); 320 | ServerUtil.Log($"[*好友添加状态*] {x.UserID}{x.TypeStatus}", LogType.ClientVerbose); 321 | } 322 | break; 323 | case "ON_EVENT_FRIEND_DELETE": 324 | { 325 | var x = (ON_EVENT_FRIEND_DELETE)d.Data; 326 | __ON_EVENT_FRIEND_DELETE.Invoke(d.EMsg, x); 327 | ServerUtil.Log($"[*解除好友*] {x.UserID}不再是你的好友了", LogType.ClientVerbose); 328 | } 329 | break; 330 | case "ON_EVENT_GROUP_REVOKE": 331 | { 332 | var x = (ON_EVENT_GROUP_REVOKE)d.Data; 333 | __ON_EVENT_GROUP_REVOKE.Invoke(d.EMsg, x); 334 | ServerUtil.Log($"[*群成员撤回信息*] 在群{x.GroupID},{x.AdminUserID}撤回了{x.UserID}的信息", LogType.ClientVerbose); 335 | } 336 | break; 337 | default: 338 | { 339 | __ON_UNMOUNT_EVENT.Invoke(null, e.Data); 340 | ServerUtil.Log($"[*未解析事件*] 事件源Json:\n{e.Data}", LogType.ClientVerbose); 341 | } 342 | break; 343 | } 344 | } 345 | #endregion 346 | #region 触发好友消息事件区域 -- Event Trigger -- 347 | /// 348 | /// 好友消息事件 : 文本 349 | /// Serveric [OnFriend : Text] Message Event 350 | /// 351 | /// 报文头 352 | /// 报文体 353 | public delegate void EventFriendTextMessageEventHandler(QQRecieveMessage sender, TextMsg e); 354 | /// 355 | /// 好友消息事件 : 图片大类 356 | /// Serveric [OnFriend : Pic] Message Event 357 | /// 358 | /// 报文头 359 | /// 报文体 360 | public delegate void EventFriendPicMessageEventHandler(QQRecieveMessage sender, PicMsg e); 361 | /// 362 | /// 好友消息事件 : 语音大类 363 | /// Serveric [OnFriend : Voc] Message Event 364 | /// 365 | /// 报文头 366 | /// 报文体 367 | public delegate void EventFriendVocMessageEventHandler(QQRecieveMessage sender, VoiceMsg e); 368 | /// 369 | /// 好友消息事件 : 视频大类 370 | /// Serveric [OnFriend : Vid] Message Event 371 | /// 372 | /// 报文头 373 | /// 报文体 374 | public delegate void EventFriendVidMessageEventHandler(QQRecieveMessage sender, VideoMsg e); 375 | /*-----------------------------------------------------------------------*/ 376 | /// 377 | /// 好友消息事件 : 文本 378 | /// Serveric [OnFriend : Text] Message Event 379 | /// 380 | public event EventFriendTextMessageEventHandler _FriendTextMsgRecieve; 381 | /// 382 | /// 好友消息事件 : 图片大类 383 | /// Serveric [OnFriend : Pic] Message Event 384 | /// 385 | public event EventFriendPicMessageEventHandler _FriendPicMsgRecieve; 386 | /// 387 | /// 好友消息事件 : 语音大类 388 | /// Serveric [OnFriend : Voc] Message Event 389 | /// 390 | public event EventFriendVocMessageEventHandler _FriendVocMsgRecieve; 391 | /// 392 | /// 好友消息事件 : 视频大类 393 | /// Serveric [OnFriend : Vid] Message Event 394 | /// 395 | public event EventFriendVidMessageEventHandler _FriendVidMsgRecieve; 396 | #endregion 397 | #region 触发群消息事件区域 -- Event Trigger -- 398 | /// 399 | /// 群消息委托 : 文本大类 400 | /// Serveric [OnGroup : AtText] Message Event 401 | /// 402 | /// 报文头 403 | /// 报文体 404 | public delegate void EventGroupAtTextMessageEventHandler(QQRecieveMessage sender, AtTextMsg e); 405 | /// 406 | /// 群消息委托 : 文本大类 407 | /// Serveric [OnGroup : Text] Message Event 408 | /// 409 | /// 报文头 410 | /// 报文体 411 | public delegate void EventGroupTextMessageEventHandler(QQRecieveMessage sender, TextMsg e); 412 | /// 413 | /// 群消息事件 : 图片大类 414 | /// Serveric [OnGroup : Pic] Message Event 415 | /// 416 | /// 报文头 417 | /// 报文体 418 | public delegate void EventGroupPicMessageEventHandler(QQRecieveMessage sender, PicMsg e); 419 | /// 420 | /// 群消息事件 : 图片大类 421 | /// Serveric [OnGroup : AtPic] Message Event 422 | /// 423 | /// 报文头 424 | /// 报文体 425 | public delegate void EventGroupAtPicMessageEventHandler(QQRecieveMessage sender, PicMsg e); 426 | /// 427 | /// 群消息事件 : 语音大类 428 | /// Serveric [OnGroup : Voc] Message Event 429 | /// 430 | /// 报文头 431 | /// 报文体 432 | public delegate void EventGroupVocMessageEventHandler(QQRecieveMessage sender, VoiceMsg e); 433 | /// 434 | /// 群消息事件 : 视频大类 435 | /// Serveric [OnGroup : Vid] Message Event 436 | /// 437 | /// 报文头 438 | /// 报文体 439 | public delegate void EventGroupVidMessageEventHandler(QQRecieveMessage sender, VideoMsg e); 440 | /*-----------------------------------------------------------------------*/ 441 | /// 442 | /// 群消息委托 : 文本大类 443 | /// Serveric [OnGroup : AtText] Message Event 444 | /// 445 | public event EventGroupAtTextMessageEventHandler _GroupAtTextMsgRecieve; 446 | /// 447 | /// 群消息委托 : 文本大类 448 | /// Serveric [OnGroup : Text] Message Event 449 | /// 450 | public event EventGroupTextMessageEventHandler _GroupTextMsgRecieve; 451 | /// 452 | /// 群消息事件 : 图片大类 453 | /// Serveric [OnGroup : Pic] Message Event 454 | /// 455 | public event EventGroupPicMessageEventHandler _GroupPicMsgRecieve; 456 | /// 457 | /// 群消息事件 : 图片大类 458 | /// Serveric [OnGroup : AtPic] Message Event 459 | /// 460 | public event EventGroupAtPicMessageEventHandler _GroupAtPicMsgRecieve; 461 | /// 462 | /// 群消息事件 : 语音大类 463 | /// Serveric [OnGroup : Voc] Message Event 464 | /// 465 | public event EventGroupVocMessageEventHandler _GroupVocMsgRecieve; 466 | /// 467 | /// 群消息事件 : 视频大类 468 | /// Serveric [OnGroup : Vid] Message Event 469 | /// 470 | public event EventGroupVidMessageEventHandler _GroupVidMsgRecieve; 471 | #endregion 472 | #region 触发事件代理区域 -- Event Trigger -- 473 | /// 474 | /// 管理员变更事件 475 | /// GroupAdminChangeEvent 476 | /// 477 | /// 报文头 478 | /// 报文体 479 | public delegate void Event_ON_EVENT_GROUP_ADMIN_EventHandler(EventMsg sender, ON_EVENT_GROUP_ADMIN e); 480 | /// 481 | /// 群禁言事件 482 | /// GroupShut-upEvent 483 | /// 484 | /// 报文头 485 | /// 报文体 486 | public delegate void Event_ON_EVENT_GROUP_SHUT_EventHandler(EventMsg sender, ON_EVENT_GROUP_SHUT e); 487 | /// 488 | /// 群操作相关事件 (一层解析) 489 | /// *FirstLayerOf*GroupAdministratorEvent 490 | /// 491 | /// 报文头 492 | /// 报文体 493 | public delegate void Event_ON_EVENT_GROUP_EXIT_EventHandler(EventMsg sender, ON_EVENT_GROUP_EXIT e); 494 | /// 495 | /// 退群相关事件 496 | /// Someone Exit the Group 497 | /// 498 | /// 报文头 499 | /// 报文体 500 | public delegate void Event_ON_EVENT_GROUP_EXIT_SUCC_EventHandler(EventMsg sender, ON_EVENT_GROUP_EXIT_SUCC e); 501 | /// 502 | /// 主动退群成功事件 503 | /// SelfExitEvent 504 | /// 505 | /// 报文头 506 | /// 报文体 507 | public delegate void Event_ON_EVENT_GROUP_JOIN_EventHandler(EventMsg sender, ON_EVENT_GROUP_JOIN e); 508 | /// 509 | /// 加群事件 510 | /// Join Group Event 511 | /// 512 | /// 报文头 513 | /// 报文体 514 | public delegate void Event_ON_EVENT_GROUP_ADMIN_SYSNOTIFY_EventHandler(EventMsg sender, ON_EVENT_GROUP_ADMINSYSNOTIFY e); 515 | /// 516 | /// 邀请加群事件 517 | /// Invite into group Event 518 | /// 519 | /// 报文头 520 | /// 报文体 521 | public delegate void Event_ON_EVENT_GROUP_INVITE_EventHandler(EventMsg sender, ON_EVENT_GROUP_ADMINSYSNOTIFY_INVITE_GROUP e); 522 | /// 523 | /// 群成员撤回信息事件 524 | /// Event for revoke message in group 525 | /// 526 | /// 报文头 527 | /// 报文体 528 | public delegate void Event_ON_EVENT_GROUP_REVOKE_EventHandler(EventMsg sender, ON_EVENT_GROUP_REVOKE e); 529 | /// 530 | /// 加好友事件 531 | /// Add Friend Event 532 | /// 533 | /// 报文头 534 | /// 报文体 535 | public delegate void Event_ON_EVENT_FRIEND_ADD_EventHandler(EventMsg sender, ON_EVENT_FRIEND_ADD e); 536 | /// 537 | /// 删除好友事件 538 | /// Friend Delete Event 539 | /// 540 | /// 报文头 541 | /// 报文体 542 | public delegate void Event_ON_EVENT_FRIEND_DELETE_EventHandler(EventMsg sender, ON_EVENT_FRIEND_DELETE e); 543 | /// 544 | /// 成为好友事件 545 | /// Become Friend Event 546 | /// 547 | /// 报文头 548 | /// 报文体 549 | public delegate void Event_ON_EVENT_NOTIFY_PUSHADDFRD_EventHandler(EventMsg sender, ON_EVENT_NOTIFY_PUSHADDFRD e); 550 | /// 551 | /// 好友状态事件 552 | /// Friend Status Event 553 | /// 554 | /// 报文头 555 | /// 报文体 556 | public delegate void Event_ON_EVENT_FRIEND_ADD_STATUS_EventHandler(EventMsg sender, ON_EVENT_FRIEND_ADD_STATUS e); 557 | /// 558 | /// 未识别事件 559 | /// Unknown Event 560 | /// 561 | /// 报文头 562 | /// 报文体 563 | public delegate void Event_ON_EVENT_EventHandler(EventMsg sender, JObject e); 564 | /*-----------------------------------------------------------------------*/ 565 | /// 566 | /// 管理员变更事件 567 | /// GroupAdminChangeEvent 568 | /// 569 | public event Event_ON_EVENT_GROUP_ADMIN_EventHandler __ON_EVENT_GROUP_ADMIN; 570 | /// 571 | /// 群禁言事件 572 | /// GroupShut-upEvent 573 | /// 574 | public event Event_ON_EVENT_GROUP_SHUT_EventHandler __ON_EVENT_GROUP_SHUT; 575 | /// 576 | /// 群操作相关事件 (一层解析) 577 | /// *FirstLayerOf*GroupAdministratorEvent 578 | /// 579 | public event Event_ON_EVENT_GROUP_ADMIN_SYSNOTIFY_EventHandler __ON_EVENT_GROUP_ADMINSYSNOTIFY; 580 | /// 581 | /// 退群相关事件 582 | /// Someone Exit the Group 583 | /// 584 | public event Event_ON_EVENT_GROUP_EXIT_EventHandler __ON_EVENT_GROUP_EXIT; 585 | /// 586 | /// 主动退群成功事件 587 | /// SelfExitEvent 588 | /// 589 | public event Event_ON_EVENT_GROUP_EXIT_SUCC_EventHandler __ON_EVENT_GROUP_EXIT_SUCC; 590 | /// 591 | /// 加群事件 592 | /// Join Group Event 593 | /// 594 | public event Event_ON_EVENT_GROUP_JOIN_EventHandler __ON_EVENT_GROUP_JOIN; 595 | /// 596 | /// 邀请加群事件 597 | /// Invite into group Event 598 | /// 599 | public event Event_ON_EVENT_GROUP_INVITE_EventHandler __ON_EVENT_GROUP_INVITE; 600 | /// 601 | /// 群成员撤回信息事件 602 | /// Event for revoke message in group 603 | /// 604 | public event Event_ON_EVENT_GROUP_REVOKE_EventHandler __ON_EVENT_GROUP_REVOKE; 605 | 606 | /// 607 | /// 加好友事件 608 | /// Add Friend Event 609 | /// 610 | public event Event_ON_EVENT_FRIEND_ADD_EventHandler __ON_EVENT_FRIEND_ADD; 611 | /// 612 | /// 删除好友事件 613 | /// Friend Delete Event 614 | /// 615 | public event Event_ON_EVENT_FRIEND_DELETE_EventHandler __ON_EVENT_FRIEND_DELETE; 616 | /// 617 | /// 成为好友事件 618 | /// Become Friend Event 619 | /// 620 | public event Event_ON_EVENT_NOTIFY_PUSHADDFRD_EventHandler __ON_EVENT_FRIEND_PUSHADDFRD; 621 | /// 622 | /// 好友状态事件 623 | /// Friend Status Event 624 | /// 625 | public event Event_ON_EVENT_FRIEND_ADD_STATUS_EventHandler __ON_EVENT_FRIEND_ADD_STATUS; 626 | 627 | /// 628 | /// 未识别事件 629 | /// Unknown Event 630 | /// 631 | public event Event_ON_EVENT_EventHandler __ON_UNMOUNT_EVENT; 632 | #endregion 633 | } 634 | } 635 | --------------------------------------------------------------------------------