From 00e86ffa2aff8e55cbe0d337bf75e55ca6d2578d Mon Sep 17 00:00:00 2001 From: yiyun Date: Sat, 14 Jan 2023 15:02:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(qqbothub.web,konataapp,konataplugin):=20?= =?UTF-8?q?=E6=8F=90=E5=8F=96=20Konata=20=E7=9B=B8=E5=85=B3=E5=88=9D?= =?UTF-8?q?=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- QQBotHub.sln | 14 +- .../Controllers/HomeController.cs | 526 +++++++++++++----- plugins/KonataPlugin/DbContext.cs | 6 +- .../KonataPlugin}/IPlugins/IQQBotPlugin.cs | 2 +- .../KonataPlugin/IPlugins/IQQChannelPlugin.cs | 32 -- plugins/KonataPlugin/KonataBotStore.cs | 111 +++- plugins/KonataPlugin/KonataPlugin.cs | 10 +- plugins/KonataPlugin/KonataPlugin.csproj | 4 +- plugins/KonataPlugin/Models/QABox.cs | 2 +- plugins/KonataPlugin/README.md | 16 +- .../RequestModels/LoginRequestModel.cs | 2 +- .../SubmitCaptchaRequestModel.cs | 2 +- .../ResponseModels/BaseResponseModel.cs | 2 +- .../ResponseModels/InfoResponseDataModel.cs | 2 +- plugins/KonataPlugin/SettingsModel.cs | 35 +- plugins/KonataPlugin/Utils/DateTimeUtil.cs | 2 +- plugins/KonataPlugin/Utils/EnvUtil.cs | 2 +- plugins/KonataPlugin/Utils/HttpUtil.cs | 342 ++++++++++++ plugins/KonataPlugin/Utils/JsonUtil.cs | 28 + plugins/KonataPlugin/Utils/LogUtil.cs | 4 +- plugins/KonataPlugin/Utils/Md5Util.cs | 103 ++++ .../KonataPlugin}/Utils/SettingsUtil.cs | 24 +- plugins/KonataPlugin/settings.json | 23 +- plugins/KonataPlugin/wwwroot/index.html | 207 ++++++- .../wwwroot/libs/mdui/css/mdui.css | 0 .../wwwroot/libs/mdui/css/mdui.css.map | 0 .../wwwroot/libs/mdui/css/mdui.min.css | 0 .../wwwroot/libs/mdui/css/mdui.min.css.map | 0 .../libs/mdui/fonts/roboto/LICENSE.txt | 0 .../libs/mdui/fonts/roboto/Roboto-Black.woff | Bin .../libs/mdui/fonts/roboto/Roboto-Black.woff2 | Bin .../mdui/fonts/roboto/Roboto-BlackItalic.woff | Bin .../fonts/roboto/Roboto-BlackItalic.woff2 | Bin .../libs/mdui/fonts/roboto/Roboto-Bold.woff | Bin .../libs/mdui/fonts/roboto/Roboto-Bold.woff2 | Bin .../mdui/fonts/roboto/Roboto-BoldItalic.woff | Bin .../mdui/fonts/roboto/Roboto-BoldItalic.woff2 | Bin .../libs/mdui/fonts/roboto/Roboto-Light.woff | Bin .../libs/mdui/fonts/roboto/Roboto-Light.woff2 | Bin .../mdui/fonts/roboto/Roboto-LightItalic.woff | Bin .../fonts/roboto/Roboto-LightItalic.woff2 | Bin .../libs/mdui/fonts/roboto/Roboto-Medium.woff | Bin .../mdui/fonts/roboto/Roboto-Medium.woff2 | Bin .../fonts/roboto/Roboto-MediumItalic.woff | Bin .../fonts/roboto/Roboto-MediumItalic.woff2 | Bin .../mdui/fonts/roboto/Roboto-Regular.woff | Bin .../mdui/fonts/roboto/Roboto-Regular.woff2 | Bin .../fonts/roboto/Roboto-RegularItalic.woff | Bin .../fonts/roboto/Roboto-RegularItalic.woff2 | Bin .../libs/mdui/fonts/roboto/Roboto-Thin.woff | Bin .../libs/mdui/fonts/roboto/Roboto-Thin.woff2 | Bin .../mdui/fonts/roboto/Roboto-ThinItalic.woff | Bin .../mdui/fonts/roboto/Roboto-ThinItalic.woff2 | Bin .../mdui/icons/material-icons/LICENSE.txt | 0 .../MaterialIcons-Regular.ijmap | 0 .../material-icons/MaterialIcons-Regular.woff | Bin .../MaterialIcons-Regular.woff2 | Bin .../wwwroot/libs/mdui/js/mdui.esm.js | 0 .../wwwroot/libs/mdui/js/mdui.esm.js.map | 0 .../wwwroot/libs/mdui/js/mdui.js | 0 .../wwwroot/libs/mdui/js/mdui.js.map | 0 .../wwwroot/libs/mdui/js/mdui.min.js | 0 .../wwwroot/libs/mdui/js/mdui.min.js.map | 0 src/QQBotHub.Sdk/QQBotHub.Sdk.csproj | 6 +- src/QQBotHub.Sdk/QQBotStore.cs | 106 ---- src/QQBotHub.Sdk/Utils/SettingsUtil.cs | 51 ++ .../Controllers/HomeController.cs | 453 +-------------- src/QQBotHub.Web/Program.cs | 4 - src/QQBotHub.Web/QQBotHub.Web.csproj | 7 +- .../ResponseModels/BaseResponseModel.cs | 15 - src/QQBotHub.Web/SettingsModel.cs | 13 - src/QQBotHub.Web/Utils/LogUtil.cs | 45 -- src/QQBotHub.Web/wwwroot/css/main.css | 9 - src/QQBotHub.Web/wwwroot/index.html | 207 ------- .../KonataApp.csproj} | 0 test/{ConsoleApp => KonataApp}/Program.cs | 2 +- 76 files changed, 1272 insertions(+), 1147 deletions(-) rename {src/QQBotHub.Sdk => plugins/KonataPlugin}/IPlugins/IQQBotPlugin.cs (95%) delete mode 100644 plugins/KonataPlugin/IPlugins/IQQChannelPlugin.cs rename {src/QQBotHub.Web => plugins/KonataPlugin}/RequestModels/LoginRequestModel.cs (85%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/RequestModels/SubmitCaptchaRequestModel.cs (72%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/ResponseModels/InfoResponseDataModel.cs (89%) create mode 100644 plugins/KonataPlugin/Utils/HttpUtil.cs create mode 100644 plugins/KonataPlugin/Utils/JsonUtil.cs create mode 100644 plugins/KonataPlugin/Utils/Md5Util.cs rename {src/QQBotHub.Web => plugins/KonataPlugin}/Utils/SettingsUtil.cs (53%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/css/mdui.css (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/css/mdui.css.map (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/css/mdui.min.css (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/css/mdui.min.css.map (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/LICENSE.txt (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/icons/material-icons/LICENSE.txt (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.ijmap (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff2 (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/js/mdui.esm.js (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/js/mdui.esm.js.map (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/js/mdui.js (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/js/mdui.js.map (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/js/mdui.min.js (100%) rename {src/QQBotHub.Web => plugins/KonataPlugin}/wwwroot/libs/mdui/js/mdui.min.js.map (100%) delete mode 100644 src/QQBotHub.Sdk/QQBotStore.cs create mode 100644 src/QQBotHub.Sdk/Utils/SettingsUtil.cs delete mode 100644 src/QQBotHub.Web/ResponseModels/BaseResponseModel.cs delete mode 100644 src/QQBotHub.Web/SettingsModel.cs delete mode 100644 src/QQBotHub.Web/Utils/LogUtil.cs delete mode 100644 src/QQBotHub.Web/wwwroot/css/main.css delete mode 100644 src/QQBotHub.Web/wwwroot/index.html rename test/{ConsoleApp/ConsoleApp.csproj => KonataApp/KonataApp.csproj} (100%) rename test/{ConsoleApp => KonataApp}/Program.cs (98%) diff --git a/QQBotHub.sln b/QQBotHub.sln index 1ba6a2108..400eeac33 100644 --- a/QQBotHub.sln +++ b/QQBotHub.sln @@ -15,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QQHelloWorldPlugin", "plugi EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F5C1CDD2-053C-4C8E-8192-7A97477CFC44}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "test\ConsoleApp\ConsoleApp.csproj", "{DD974327-3D52-447A-9652-62811800140D}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QQStatPlugin", "plugins\QQStatPlugin\QQStatPlugin.csproj", "{D4A8C051-C14E-4123-AF20-794A98FD3662}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QQBotHub.Sdk", "src\QQBotHub.Sdk\QQBotHub.Sdk.csproj", "{56C78578-C690-4013-8AB6-1ED28770C2B1}" @@ -45,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MoLi4QQChannelPlugin", "plu EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KonataPlugin", "plugins\KonataPlugin\KonataPlugin.csproj", "{841E5EB5-D8A6-48A7-93E4-55938139B574}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KonataApp", "test\KonataApp\KonataApp.csproj", "{31D39F7C-C5E1-4349-9DA1-95E984AC6372}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -63,10 +63,6 @@ Global {6243DEEC-C677-412E-955D-BD18E02EB6E3}.Debug|Any CPU.Build.0 = Debug|Any CPU {6243DEEC-C677-412E-955D-BD18E02EB6E3}.Release|Any CPU.ActiveCfg = Release|Any CPU {6243DEEC-C677-412E-955D-BD18E02EB6E3}.Release|Any CPU.Build.0 = Release|Any CPU - {DD974327-3D52-447A-9652-62811800140D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DD974327-3D52-447A-9652-62811800140D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DD974327-3D52-447A-9652-62811800140D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DD974327-3D52-447A-9652-62811800140D}.Release|Any CPU.Build.0 = Release|Any CPU {D4A8C051-C14E-4123-AF20-794A98FD3662}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D4A8C051-C14E-4123-AF20-794A98FD3662}.Debug|Any CPU.Build.0 = Debug|Any CPU {D4A8C051-C14E-4123-AF20-794A98FD3662}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -123,6 +119,10 @@ Global {841E5EB5-D8A6-48A7-93E4-55938139B574}.Debug|Any CPU.Build.0 = Debug|Any CPU {841E5EB5-D8A6-48A7-93E4-55938139B574}.Release|Any CPU.ActiveCfg = Release|Any CPU {841E5EB5-D8A6-48A7-93E4-55938139B574}.Release|Any CPU.Build.0 = Release|Any CPU + {31D39F7C-C5E1-4349-9DA1-95E984AC6372}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {31D39F7C-C5E1-4349-9DA1-95E984AC6372}.Debug|Any CPU.Build.0 = Debug|Any CPU + {31D39F7C-C5E1-4349-9DA1-95E984AC6372}.Release|Any CPU.ActiveCfg = Release|Any CPU + {31D39F7C-C5E1-4349-9DA1-95E984AC6372}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -130,7 +130,6 @@ Global GlobalSection(NestedProjects) = preSolution {30B29087-4E84-4C67-BE3A-1CA8AB47B416} = {BDFD03E4-0A99-49A3-95A7-F7132EC4FF00} {6243DEEC-C677-412E-955D-BD18E02EB6E3} = {4B4BFBBE-8CE4-453C-B05A-EAFE933B79C9} - {DD974327-3D52-447A-9652-62811800140D} = {F5C1CDD2-053C-4C8E-8192-7A97477CFC44} {D4A8C051-C14E-4123-AF20-794A98FD3662} = {4B4BFBBE-8CE4-453C-B05A-EAFE933B79C9} {56C78578-C690-4013-8AB6-1ED28770C2B1} = {BDFD03E4-0A99-49A3-95A7-F7132EC4FF00} {F6087CC7-5239-42E3-92D6-51F25F6E3EE8} = {4B4BFBBE-8CE4-453C-B05A-EAFE933B79C9} @@ -145,6 +144,7 @@ Global {8BEB0C54-7117-4025-8042-4D947E6E45F2} = {4B4BFBBE-8CE4-453C-B05A-EAFE933B79C9} {0DCFB20E-CFE2-4927-BC71-47FC2C2371A8} = {4B4BFBBE-8CE4-453C-B05A-EAFE933B79C9} {841E5EB5-D8A6-48A7-93E4-55938139B574} = {4B4BFBBE-8CE4-453C-B05A-EAFE933B79C9} + {31D39F7C-C5E1-4349-9DA1-95E984AC6372} = {F5C1CDD2-053C-4C8E-8192-7A97477CFC44} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3F1D77E3-11F8-4B5B-BEED-EE2816D57A86} diff --git a/plugins/KonataPlugin/Controllers/HomeController.cs b/plugins/KonataPlugin/Controllers/HomeController.cs index 5f22e5b91..f5c34da51 100644 --- a/plugins/KonataPlugin/Controllers/HomeController.cs +++ b/plugins/KonataPlugin/Controllers/HomeController.cs @@ -7,12 +7,16 @@ using Microsoft.AspNetCore.Mvc; using PluginCore; using PluginCore.Interfaces; -using QQChannelFramework.Api; -using QQChannelFramework.Expansions.Bot; -using QQChannelPlugin.IPlugins; -using QQChannelPlugin.Utils; - -namespace QQChannelPlugin.Controllers +using KonataPlugin.Utils; +using KonataPlugin.ResponseModels; +using KonataPlugin.RequestModels; +using Konata.Core.Common; +using Konata.Core.Interfaces; +using static Konata.Core.Events.Model.CaptchaEvent; +using PluginCore.IPlugins; +using Konata.Core.Interfaces.Api; + +namespace KonataPlugin.Controllers { /// /// 其实也可以不写这个, 直接访问 Plugins/ZhiDaoPlugin/index.html @@ -22,7 +26,8 @@ namespace QQChannelPlugin.Controllers /// 若 wwwroot 下有其它需要访问的文件, 如何 css, js, 而你又不想每次新增 action 指定返回, 则 Route 必须 Plugins/{PluginId}, /// 这样访问 Plugins/HelloWorldPlugin/css/main.css 就会访问到你插件下的 wwwroot/css/main.css /// - [Route($"Plugins/{nameof(QQChannelPlugin)}")] + [Route($"Plugins/{nameof(KonataPlugin)}")] + [Authorize("PluginCore.Admin")] public class HomeController : Controller { #region Fields @@ -49,212 +54,443 @@ public HomeController(IPluginFinder pluginFinder) } #endregion - public async Task Get() + + #region Actions + + [Route("")] + [HttpGet] + public async Task Index() { - string indexFilePath = System.IO.Path.Combine(PluginPathProvider.PluginWwwRootDir(nameof(QQChannelPlugin)), "index.html"); + string indexFilePath = System.IO.Path.Combine(PluginPathProvider.PluginWwwRootDir(nameof(KonataPlugin)), "index.html"); return PhysicalFile(indexFilePath, "text/html"); } - /// - /// 将所有 settings.json 中的 bot 尝试登录 - /// - /// - [Route(nameof(Login))] - [Authorize("PluginCore.Admin")] - public async Task Login() + + [HttpGet] + [Route(nameof(Uin))] + public async Task Uin() { - SettingsModel settingsModel = PluginCore.PluginSettingsModelFactory.Create(nameof(QQChannelPlugin)); - // 确保以前的都取消 - #region 确保以前的都取消 - foreach (var item in QQChannelBotStore.Bots) + BaseResponseModel responseModel = new BaseResponseModel(); + try { - try + var settings = Utils.SettingsUtil.Get(nameof(KonataPlugin)); + string uin = settings?.Uin ?? ""; + if (!string.IsNullOrEmpty(KonataBotStore.Bot?.Uin.ToString())) { - await item.ChannelBot.OfflineAsync(); - await item.ChannelBot.CloseAsync(); - item.ChannelBot = null; - item.OpenApiAccessInfo = new OpenApiAccessInfo(); - item.QQChannelApi = null; + uin = KonataBotStore.Bot?.Uin.ToString() ?? uin; } - catch (Exception ex) - { - } + responseModel.Code = 1; + responseModel.Message = "获取成功"; + responseModel.Data = uin; } - QQChannelBotStore.Bots.Clear(); - - #endregion - foreach (var botConfig in settingsModel.Bots) + catch (Exception ex) { - ChannelBotItem(botConfig, settingsModel); + responseModel.Code = -1; + responseModel.Message = "获取失败"; + responseModel.Data = ex.ToString(); } - // TODO: 暂时这么做, 以后优化界面 - return Content("尝试登录 设置 里的 QQ频道机器人中, 请耐性等待! 注意查看控制台!"); + return await Task.FromResult(responseModel); } - private async void ChannelBotItem(SettingsModel.BotDevItemModel botConfig, SettingsModel settings) + /// + /// 登录后,定时访问此api, 获取验证等信息 + /// + /// + [HttpGet] + [Route(nameof(Info))] + public async Task Info() { - // https://www.yuque.com/chianne1025/mybot/otkzzg + BaseResponseModel responseModel = new BaseResponseModel(); + InfoResponseDataModel dataModel = new InfoResponseDataModel(); - // 声明鉴权信息 - OpenApiAccessInfo openApiAccessInfo = new OpenApiAccessInfo(); - openApiAccessInfo.BotAppId = botConfig.BotAppId; - openApiAccessInfo.BotToken = botConfig.BotToken; - openApiAccessInfo.BotSecret = botConfig.BotSecret; + if (KonataBotStore.Bot == null) + { + // 未点击登录过 + responseModel.Code = 1; + responseModel.Message = "未登录"; + + dataModel.CaptchaTip = ""; + dataModel.IsOnline = false; + dataModel.CaptchaType = ""; + dataModel.CaptchaUpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); - // 使用QQChannelApi获取相应的Api接口 - // 鉴权信息在实例化时传入 - QQChannelApi qChannelApi = new(openApiAccessInfo); + responseModel.Data = dataModel; - // 指定Api请求使用Bot身份 - qChannelApi.UseBotIdentity(); + return responseModel; + } - if (botConfig.UseSandBoxMode) + //if (QQBotStore.Bot.IsOnline()) + if (CaptchaStore.IsOnline) { - // 指定Api通道模式为沙盒模式 (测试时使用) - qChannelApi.UseSandBoxMode(); + responseModel.Code = 2; + responseModel.Message = "已处于登录状态, 无需验证"; + + dataModel.CaptchaTip = ""; + dataModel.IsOnline = true; + dataModel.CaptchaType = ""; + dataModel.CaptchaUpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + + responseModel.Data = dataModel; + + return responseModel; } - else + + // 已经点击登录过一次 + responseModel.Code = 3; + responseModel.Message = "需要验证"; + switch (CaptchaStore.CaptchaType) { - // 不指定的情况下默认是正式模式 - //qChannelApi.UseReleaseMode(); + case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Sms: + dataModel.CaptchaType = "短信验证"; + break; + case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Slider: + dataModel.CaptchaType = "滑块验证"; + break; + case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Unknown: + dataModel.CaptchaType = "未知验证"; + break; + default: + dataModel.CaptchaType = "未知验证-不匹配的验证类型"; + break; } + dataModel.IsOnline = false; + dataModel.CaptchaTip = CaptchaStore.CaptchaTip; + dataModel.CaptchaUpdateTime = CaptchaStore.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss"); - // 实例化一个 ChannelBot,该类是一个容易理解且简单的类 - // 帮助你快速实现一个利于理解学习与开发的机器人原型 - // 将鉴权信息 (openApiAccessInfo) 传入构造函数 - ChannelBot channelBot = new(qChannelApi); - // 注册接受@机器人消息时间,否则无法收到消息 - channelBot.RegisterAtMessageEvent(); + responseModel.Data = dataModel; - #region 事件 + return await Task.FromResult(responseModel); + } - // 为链接官方平台成功事件绑定一个回调函数 - channelBot.OnConnected += () => + /// + /// 提交验证信息 + /// + /// + /// + [HttpPost] + [Route(nameof(SubmitCaptcha))] + public async Task SubmitCaptcha([FromBody] SubmitCaptchaRequestModel requestModel) + { + BaseResponseModel responseModel = new BaseResponseModel(); + string captcha = requestModel.Captcha; + if (string.IsNullOrEmpty(captcha)) { - Utils.LogUtil.Info($"{openApiAccessInfo.BotAppId} 连接成功"); + responseModel.Code = -1; + responseModel.Message = "captcha 不能为空"; - var plugins = _pluginFinder.EnablePlugins().ToList(); - Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); - foreach (var plugin in plugins) + return responseModel; + } + bool isSuccessCaptcha = false; + try + { + switch (CaptchaStore.CaptchaType) { - Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); - - plugin.OnConnected(openApiAccessInfo.BotAppId); + case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Sms: + isSuccessCaptcha = KonataBotStore.Bot.SubmitSmsCode(captcha); + break; + case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Slider: + isSuccessCaptcha = KonataBotStore.Bot.SubmitSliderTicket(captcha); + break; + case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Unknown: + break; + default: + break; } - }; - // 为鉴权成功事件绑定一个回调函数 - channelBot.AuthenticationSuccess += () => + responseModel.Code = 1; + responseModel.Message = $"{(isSuccessCaptcha ? "验证通过" : "验证失败, 请重新验证")}"; + } + catch (System.Exception ex) { - Utils.LogUtil.Info($"{openApiAccessInfo.BotAppId} 机器人已上线"); + responseModel.Code = -3; + responseModel.Message = "提交验证失败"; + responseModel.Data = ex.ToString(); - var plugins = _pluginFinder.EnablePlugins().ToList(); - Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); - foreach (var plugin in plugins) + Utils.LogUtil.Exception(ex); + } + + return await Task.FromResult(responseModel); + } + + [HttpPost] + [Route(nameof(Login))] + public async Task Login(LoginRequestModel requestModel) + { + BaseResponseModel responseModel = new BaseResponseModel(); + try + { + var oldSettings = Utils.SettingsUtil.Get(nameof(KonataPlugin)); + SettingsModel newSettings = new SettingsModel(); + newSettings.UseDemoModel = oldSettings.UseDemoModel; + newSettings.AdminQQ = oldSettings.AdminQQ; + if (requestModel.LoginType == "password") + { + newSettings = new SettingsModel + { + Uin = requestModel.Uin, + Password = requestModel.Password, + }; + if (string.IsNullOrEmpty(requestModel.Password?.Trim())) + { + newSettings.Password = oldSettings.Password; + } + + InitQQBot(botKeyStore: new BotKeyStore(uin: newSettings.Uin, password: newSettings.Password)); + + Utils.SettingsUtil.Set(nameof(KonataPlugin), newSettings); + } + else if (requestModel.LoginType == "config") { - Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); + newSettings = new SettingsModel(); + if (!string.IsNullOrEmpty(requestModel.BotKeyStore?.Trim())) + { + try + { + newSettings.BotKeyStore = JsonUtil.JsonStr2Obj(requestModel.BotKeyStore.Trim()); + } + catch (Exception ex) + { + Console.WriteLine("requestModel.BotKeyStore 转换失败:"); + Console.WriteLine(ex.ToString()); + } + } + + if (string.IsNullOrEmpty(requestModel.BotKeyStore?.Trim())) + { + newSettings.BotKeyStore = oldSettings.BotKeyStore; + } + + InitQQBot(botKeyStore: newSettings.BotKeyStore); + + Utils.SettingsUtil.Set(nameof(KonataPlugin), newSettings); + } + else + { + responseModel.Code = -2; + responseModel.Message = "未知登录方式"; - plugin.AuthenticationSuccess(openApiAccessInfo.BotAppId); + return await Task.FromResult(responseModel); } - }; - // 为机器人出现异常事件绑定一个回调函数 - channelBot.OnError += (ex) => + Task taskLogin = KonataBotStore.Bot.Login(); + + responseModel.Code = 1; + responseModel.Message = "提交登录成功"; + } + catch (Exception ex) { - Utils.LogUtil.Info($"{openApiAccessInfo.BotAppId} 机器人出现错误 -> {ex.Message}"); + responseModel.Code = -1; + responseModel.Message = "提交登录失败"; + responseModel.Data = ex.ToString(); + } - var plugins = _pluginFinder.EnablePlugins().ToList(); - Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); - foreach (var plugin in plugins) - { - Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); + return await Task.FromResult(responseModel); + } - plugin.OnError(openApiAccessInfo.BotAppId, ex); - } - }; + [HttpPost] + [Route(nameof(Logout))] + public async Task Logout() + { + BaseResponseModel responseModel = new BaseResponseModel(); + try + { + Task taskLogout = KonataBotStore.Bot.Logout(); - // 为接收到@机器人事件绑定一个回调函数 - // message 为收到的消息内容 - channelBot.ReceivedAtMessage += async (message) => + responseModel.Code = 1; + responseModel.Message = "提交退出成功"; + } + catch (Exception ex) { - Utils.LogUtil.Info($"{openApiAccessInfo.BotAppId} 机器人收到消息 -> {message.Content}"); + responseModel.Code = -1; + responseModel.Message = "提交退出失败"; + responseModel.Data = ex.ToString(); + } - var plugins = _pluginFinder.EnablePlugins().ToList(); - Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); - foreach (var plugin in plugins) - { - Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); + return await Task.FromResult(responseModel); + } - plugin.ReceivedAtMessage(openApiAccessInfo.BotAppId, message, qChannelApi); - } + #endregion - if (botConfig.UseDemoModel) - { - // 使用QQChannelApi异步回复一个与用户发送一样的消息内容 - // 发送消息时,如果机器人中的一些能力未联系官方开通,会导致发送失败,或者发送成功但需要等待官方人工审核 - // 发送失败或需要等待官方审核时会抛出异常,请注意捕获 - await qChannelApi - .GetMessageApi() - .SendTextMessageAsync(message.ChannelId, $"收到消息啦!您发送的消息为 -> {message.Content}", message.Id); - } - }; + #region Helpers - channelBot.ReceivedDirectMessage += async (message) => + [NonAction] + public void InitQQBot(BotKeyStore botKeyStore) + { + #region Bot + + // Create a bot instance + #region 准备数据 + // 优先从 环境变量 中获取 + BotConfig botConfig = BotConfig.Default(); + string botConfigJsonStr = EnvUtil.GetEnv("BOT_CONFIG"); + if (!string.IsNullOrEmpty(botConfigJsonStr)) { - Utils.LogUtil.Info($"{openApiAccessInfo.BotAppId} 机器人收到消息 -> {message.Content}"); + botConfig = JsonUtil.JsonStr2Obj(botConfigJsonStr); + } - var plugins = _pluginFinder.EnablePlugins().ToList(); - Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); - foreach (var plugin in plugins) - { - Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); + BotDevice botDevice = BotDevice.Default(); + string botDeviceJsonStr = EnvUtil.GetEnv("BOT_DEVICE"); + if (!string.IsNullOrEmpty(botDeviceJsonStr)) + { + botDevice = JsonUtil.JsonStr2Obj(botDeviceJsonStr); + } - plugin.ReceivedDirectMessage(openApiAccessInfo.BotAppId, message, qChannelApi); - } - }; + string botKeyStoreJsonStr = EnvUtil.GetEnv("BOT_KEYSTORE"); + if (!string.IsNullOrEmpty(botKeyStoreJsonStr)) + { + botKeyStore = JsonUtil.JsonStr2Obj(botKeyStoreJsonStr); + } + #endregion - // 仅私域机器人可用, 在频道内无需 at - channelBot.ReceivedUserMessage += async (message) => + var bot = BotFather.Create(botConfig, botDevice, botKeyStore); { - Utils.LogUtil.Info($"{openApiAccessInfo.BotAppId} 机器人收到消息 -> {message.Content}"); + // Print the log + bot.OnLog += (s, e) => + { + //#if DEBUG + // Utils.LogUtil.Info(e.EventMessage); + //#endif + if (_debug) + { + Utils.LogUtil.Info(e.EventMessage); + } + }; + + // Handle the captcha + bot.OnCaptcha += (s, e) => + { + Utils.LogUtil.Info("QQ 登录验证:"); + CaptchaStore.UpdateTime = DateTime.Now; + CaptchaStore.CaptchaType = e.Type; + if (e.Type == CaptchaType.Slider) + { + Utils.LogUtil.Info(e.SliderUrl); + //((Bot)s).SubmitSliderTicket(Console.ReadLine()); + CaptchaStore.CaptchaTip = $"{e.SliderUrl}"; + } + else if (e.Type == CaptchaType.Sms) + { + Utils.LogUtil.Info(e.Phone); + //((Bot)s).SubmitSmsCode(Console.ReadLine()); + CaptchaStore.CaptchaTip = $"{e.Phone}"; + } + }; + + // Handle messages from group + bot.OnGroupMessage += (s, e) => + { + Utils.LogUtil.Info($"群消息: {DateTime.Now.ToString()}: {e.Message.Chain?.FirstOrDefault()?.ToString() ?? ""}"); + + var plugins = _pluginFinder.EnablePlugins().ToList(); + Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); + foreach (var plugin in plugins) + { + Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); + if (e.Message.Sender.Uin != s.Uin) + { + // 排除机器人自己 + plugin.OnGroupMessage((s, e), e.Message.Chain?.FirstOrDefault()?.ToString() ?? "", e.GroupName, e.GroupUin, e.MemberUin); + } + } + }; + + // Handle messages from friend + bot.OnFriendMessage += (s, e) => + { + Utils.LogUtil.Info($"好友消息: {DateTime.Now.ToString()}: {e.Message.Chain?.FirstOrDefault()?.ToString() ?? ""}"); + + // 在获取插件这步正常, 没有触发 bot.OnFriendMessage + var plugins = _pluginFinder.EnablePlugins().ToList(); + Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); + //Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件: {e.Message.Chain?.FirstOrDefault()?.ToString() ?? ""}"); + foreach (var plugin in plugins) + { + Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); + if (e.Message.Sender.Uin != s.Uin) + { + // 排除机器人自己 + plugin.OnFriendMessage((s, e), e.Message.Chain?.FirstOrDefault()?.ToString() ?? "", e.FriendUin); + } + } + }; + + bot.OnBotOnline += (s, e) => + { + Utils.LogUtil.Info($"{s.Name} 上线"); + + CaptchaStore.IsOnline = true; + + var plugins = _pluginFinder.EnablePlugins(); + foreach (var plugin in plugins) + { + plugin.OnBotOnline((s, e), s.Name, s.Uin); + } + }; - var plugins = _pluginFinder.EnablePlugins().ToList(); - Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); - foreach (var plugin in plugins) + bot.OnBotOffline += (s, e) => { - Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); + Utils.LogUtil.Info($"{s.Name} 离线"); - plugin.ReceivedUserMessage(openApiAccessInfo.BotAppId, message, qChannelApi); - } - }; + CaptchaStore.IsOnline = false; + + var plugins = _pluginFinder.EnablePlugins(); + foreach (var plugin in plugins) + { + plugin.OnBotOffline((s, e), s.Name, s.Uin); + } + }; + // ... More handlers + } + + // Do login + //Task loginTask = bot.Login(); + + // 下方操作会阻塞, 并且是阻塞到过登录验证 + //if (!bot.Login().Result) + //{ + // Utils.LogUtil.Info($"{nameof(QQBotPlugin)} 启用后 QQ 自动登录失败"); + // return base.AfterEnable(); + //} + //else + //{ + // Utils.LogUtil.Info($"{nameof(QQBotPlugin)} 启用后 QQ 自动登录成功"); + //} #endregion - // 保存起来 - QQChannelBotStore.Bots.Add(new QQChannelBotStore.BotItemModel() - { - OpenApiAccessInfo = openApiAccessInfo, - QQChannelApi = qChannelApi, - ChannelBot = channelBot, - }); - - // TODO: 可能放在这里上线不合适 - // 完成以上配置后将机器人上线 - await channelBot.OnlineAsync(); + // 登录成功, 保存起来 + KonataBotStore.Bot = bot; } + #endregion + [Route(nameof(Download))] - [Authorize("PluginCore.Admin")] public async Task Download() { string dbFilePath = DbContext.DbFilePath; var fileStream = System.IO.File.OpenRead(dbFilePath); //System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(); - return File(fileStream: fileStream, contentType: "application/x-sqlite3", fileDownloadName: $"{nameof(QQChannelPlugin)}.sqlite", enableRangeProcessing: true); + return File(fileStream: fileStream, contentType: "application/x-sqlite3", fileDownloadName: $"{nameof(KonataPlugin)}.sqlite", enableRangeProcessing: true); } } + + #region More + + public static class CaptchaStore + { + public static Konata.Core.Events.Model.CaptchaEvent.CaptchaType CaptchaType { get; set; } + + public static string CaptchaTip { get; set; } + + public static DateTime UpdateTime { get; set; } + + public static bool IsOnline { get; set; } + } + + #endregion + } diff --git a/plugins/KonataPlugin/DbContext.cs b/plugins/KonataPlugin/DbContext.cs index f3f8f8003..fe3eeaded 100644 --- a/plugins/KonataPlugin/DbContext.cs +++ b/plugins/KonataPlugin/DbContext.cs @@ -1,6 +1,6 @@ using Dapper; using PluginCore; -using QQChannelPlugin.Models; +using KonataPlugin.Models; using System; using System.Collections.Generic; using System.Data; @@ -10,7 +10,7 @@ using System.Text; using System.Threading.Tasks; -namespace QQChannelPlugin +namespace KonataPlugin { public class DbContext { @@ -18,7 +18,7 @@ public static string DbFilePath { get { - string dbFilePath = Path.Combine(PluginPathProvider.PluginsRootPath(), nameof(QQChannelPlugin), $"{nameof(QQChannelPlugin)}.sqlite"); + string dbFilePath = Path.Combine(PluginPathProvider.PluginsRootPath(), nameof(KonataPlugin), $"{nameof(KonataPlugin)}.sqlite"); return dbFilePath; } diff --git a/src/QQBotHub.Sdk/IPlugins/IQQBotPlugin.cs b/plugins/KonataPlugin/IPlugins/IQQBotPlugin.cs similarity index 95% rename from src/QQBotHub.Sdk/IPlugins/IQQBotPlugin.cs rename to plugins/KonataPlugin/IPlugins/IQQBotPlugin.cs index 183bea88f..8ff980faf 100644 --- a/src/QQBotHub.Sdk/IPlugins/IQQBotPlugin.cs +++ b/plugins/KonataPlugin/IPlugins/IQQBotPlugin.cs @@ -1,7 +1,7 @@ using Konata.Core; using PluginCore.IPlugins; -namespace QQBotHub.Sdk.IPlugins +namespace PluginCore.IPlugins { public interface IQQBotPlugin : IPlugin { diff --git a/plugins/KonataPlugin/IPlugins/IQQChannelPlugin.cs b/plugins/KonataPlugin/IPlugins/IQQChannelPlugin.cs deleted file mode 100644 index 0d7cd251f..000000000 --- a/plugins/KonataPlugin/IPlugins/IQQChannelPlugin.cs +++ /dev/null @@ -1,32 +0,0 @@ -using PluginCore.IPlugins; -using QQChannelFramework.Api; -using QQChannelFramework.Models.MessageModels; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace QQChannelPlugin.IPlugins -{ - public interface IQQChannelPlugin : IPlugin - { - void OnConnected(string botAppId); - - void AuthenticationSuccess(string botAppId); - - void OnError(string botAppId, Exception ex); - - /// - /// 注意: message.Content 中包含 <@!1094789961239705377> 其中 1094789961239705377 为@的人 - /// - /// - /// - /// - void ReceivedAtMessage(string botAppId, Message message, QQChannelApi qChannelApi); - - void ReceivedDirectMessage(string botAppId, Message message, QQChannelApi qChannelApi); - - void ReceivedUserMessage(string botAppId, Message message, QQChannelApi qChannelApi); - } -} diff --git a/plugins/KonataPlugin/KonataBotStore.cs b/plugins/KonataPlugin/KonataBotStore.cs index 3bd2ea0d9..11612e462 100644 --- a/plugins/KonataPlugin/KonataBotStore.cs +++ b/plugins/KonataPlugin/KonataBotStore.cs @@ -1,29 +1,108 @@ -using System; +using Konata.Core; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using QQChannelFramework.Api; -using QQChannelFramework.Expansions.Bot; -namespace QQChannelPlugin +namespace KonataPlugin { - public static class QQChannelBotStore + public static class KonataBotStore { - public static List Bots { get; set; } + public static Bot Bot { get; set; } - static QQChannelBotStore() - { - Bots = new List(); - } - public sealed class BotItemModel - { - public OpenApiAccessInfo OpenApiAccessInfo { get; set; } - public QQChannelApi QQChannelApi { get; set; } + #region 废弃 + //public static class StoreUtil + //{ + // public static T Get(string fileName, T defaultObj) + // { + // T rtnObj = defaultObj; + // string configDir = Path.Combine(Directory.GetCurrentDirectory(), "App_Data"); + // if (!Directory.Exists(configDir)) + // { + // Directory.CreateDirectory(configDir); + // } + // string filePath = Path.Combine(configDir, fileName); + // if (!File.Exists(filePath)) + // { + // string jsonStr = Utils.JsonUtil.Obj2JsonStr(rtnObj); + // File.WriteAllText(path: filePath, contents: jsonStr, encoding: System.Text.Encoding.UTF8); + // } + // else + // { + // string jsonStr = File.ReadAllText(path: filePath, encoding: System.Text.Encoding.UTF8); + // rtnObj = Utils.JsonUtil.JsonStr2Obj(jsonStr); + // } - public ChannelBot ChannelBot { get; set; } - } + // return rtnObj; + // } + + // public static void Set(T obj, string fileName) + // { + // string configDir = Path.Combine(Directory.GetCurrentDirectory(), "App_Data"); + // if (!Directory.Exists(configDir)) + // { + // Directory.CreateDirectory(configDir); + // } + // string filePath = Path.Combine(configDir, fileName); + // string jsonStr = Utils.JsonUtil.Obj2JsonStr(obj); + // File.WriteAllText(path: filePath, contents: jsonStr, encoding: System.Text.Encoding.UTF8); + // } + + //} + + //public static BotConfig BotConfig + //{ + // get + // { + // BotConfig botConfig = BotConfig.Default(); + // botConfig = StoreUtil.Get("config.json", botConfig); + + // return botConfig; + // } + // set + // { + // BotConfig botConfig = value; + // StoreUtil.Set(botConfig, "config.json"); + // } + //} + + //public static BotDevice BotDevice + //{ + // get + // { + // BotDevice botDevice = BotDevice.Default(); + // botDevice = StoreUtil.Get("device.json", botDevice); + + // return botDevice; + // } + // set + // { + // BotDevice botDevice = value; + // StoreUtil.Set(botDevice, "device.json"); + // } + //} + + //public static BotKeyStore BotKeyStore + //{ + // get + // { + // SettingsModel settingsModel = Utils.SettingsUtil.Get(); + // string account = settingsModel.QQ; + // string password = settingsModel.Password; + // BotKeyStore botKeyStore = new BotKeyStore(uin: account, password: password); + // botKeyStore = StoreUtil.Get("keystore.json", botKeyStore); + + // return botKeyStore; + // } + // set + // { + // BotKeyStore botKeyStore = value; + // StoreUtil.Set(botKeyStore, "keystore.json"); + // } + //} + #endregion } } diff --git a/plugins/KonataPlugin/KonataPlugin.cs b/plugins/KonataPlugin/KonataPlugin.cs index 0bcf9d081..dee1f5c31 100644 --- a/plugins/KonataPlugin/KonataPlugin.cs +++ b/plugins/KonataPlugin/KonataPlugin.cs @@ -3,24 +3,24 @@ using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using PluginCore.IPlugins; -using QQChannelPlugin.Utils; +using KonataPlugin.Utils; using System.Text; using System.Collections.Generic; using System.Linq; -namespace QQChannelPlugin +namespace KonataPlugin { - public class QQChannelPlugin : BasePlugin + public class KonataPlugin : BasePlugin { public override (bool IsSuccess, string Message) AfterEnable() { - Console.WriteLine($"{nameof(QQChannelPlugin)}: {nameof(AfterEnable)}"); + Console.WriteLine($"{nameof(KonataPlugin)}: {nameof(AfterEnable)}"); return base.AfterEnable(); } public override (bool IsSuccess, string Message) BeforeDisable() { - Console.WriteLine($"{nameof(QQChannelPlugin)}: {nameof(BeforeDisable)}"); + Console.WriteLine($"{nameof(KonataPlugin)}: {nameof(BeforeDisable)}"); return base.BeforeDisable(); } diff --git a/plugins/KonataPlugin/KonataPlugin.csproj b/plugins/KonataPlugin/KonataPlugin.csproj index 176026f22..b4a30d12e 100644 --- a/plugins/KonataPlugin/KonataPlugin.csproj +++ b/plugins/KonataPlugin/KonataPlugin.csproj @@ -13,7 +13,7 @@ runtime --> - + runtime @@ -38,6 +38,8 @@ Always + true + PreserveNewest Always diff --git a/plugins/KonataPlugin/Models/QABox.cs b/plugins/KonataPlugin/Models/QABox.cs index 95bcece56..6633090cc 100644 --- a/plugins/KonataPlugin/Models/QABox.cs +++ b/plugins/KonataPlugin/Models/QABox.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace QQChannelPlugin.Models +namespace KonataPlugin.Models { /// /// 某人发消息 diff --git a/plugins/KonataPlugin/README.md b/plugins/KonataPlugin/README.md index 15df55e70..f3d610614 100644 --- a/plugins/KonataPlugin/README.md +++ b/plugins/KonataPlugin/README.md @@ -3,33 +3,33 @@ ## 介绍 -> 本项目为 QQ频道 基础插件, 可通过依赖本插件开发相关插件 +> 本项目为 QQ 基础插件, 可通过依赖本插件开发相关插件, +> 注意: 依赖本插件开发相关插件, 插件将感染 `GPL-3.0 license` ```json -"UseSandBoxMode": true, "UseDemoModel": true ``` -> 当开启 `UseDemoModel` 时, 可在机器人加入的频道内 `@机器人` , 它会自动回复, 此项功能用于测试 +> 当开启 `UseDemoModel` 时, 可在机器人加入的群内 `@机器人` , 它会自动回复, 此项功能用于测试 ## 登录 -- [点击访问即可尝试登录, 注意查看控制台信息](/Plugins/QQChannelPlugin/Login) +- [前往登录](/Plugins/KonataPlugin) ## 下载数据库 -> 所有数据保存到数据库 **QQChannelPlugin.sqlite** 中 +> 所有数据保存到数据库 **KonataPlugin.sqlite** 中 -- [下载数据库 (QQChannelPlugin.sqlite)](/Plugins/QQChannelPlugin/Download) +- [下载数据库 (KonataPlugin.sqlite)](/Plugins/KonataPlugin/Download) ## 相关 -> 项目地址: [https://github.com/yiyungent/QQBotHub/tree/main/plugins/QQChannelPlugin](https://github.com/yiyungent/QQBotHub/tree/main/plugins/QQChannelPlugin) -> 本项目基于 [Chianne1025/QQChannelFramework: MyBot - QQ频道机器人开发框架(C#)](https://github.com/Chianne1025/QQChannelFramework) +> 项目地址: [https://github.com/yiyungent/QQBotHub/tree/main/plugins/KonataPlugin](https://github.com/yiyungent/QQBotHub/tree/main/plugins/KonataPlugin) +> 本项目基于 [KonataDev/Konata.Core: QQ(Android) protocol core implemented with pure C#.](https://github.com/KonataDev/Konata.Core) diff --git a/src/QQBotHub.Web/RequestModels/LoginRequestModel.cs b/plugins/KonataPlugin/RequestModels/LoginRequestModel.cs similarity index 85% rename from src/QQBotHub.Web/RequestModels/LoginRequestModel.cs rename to plugins/KonataPlugin/RequestModels/LoginRequestModel.cs index c7dc218c0..a5fab3191 100644 --- a/src/QQBotHub.Web/RequestModels/LoginRequestModel.cs +++ b/plugins/KonataPlugin/RequestModels/LoginRequestModel.cs @@ -1,4 +1,4 @@ -namespace QQBotHub.Web.RequestModels +namespace KonataPlugin.RequestModels { public class LoginRequestModel { diff --git a/src/QQBotHub.Web/RequestModels/SubmitCaptchaRequestModel.cs b/plugins/KonataPlugin/RequestModels/SubmitCaptchaRequestModel.cs similarity index 72% rename from src/QQBotHub.Web/RequestModels/SubmitCaptchaRequestModel.cs rename to plugins/KonataPlugin/RequestModels/SubmitCaptchaRequestModel.cs index 70bb99626..f8e1d9aad 100644 --- a/src/QQBotHub.Web/RequestModels/SubmitCaptchaRequestModel.cs +++ b/plugins/KonataPlugin/RequestModels/SubmitCaptchaRequestModel.cs @@ -1,4 +1,4 @@ -namespace QQBotHub.Web.RequestModels +namespace KonataPlugin.RequestModels { public class SubmitCaptchaRequestModel { diff --git a/plugins/KonataPlugin/ResponseModels/BaseResponseModel.cs b/plugins/KonataPlugin/ResponseModels/BaseResponseModel.cs index c9802f2df..42cc8e52a 100644 --- a/plugins/KonataPlugin/ResponseModels/BaseResponseModel.cs +++ b/plugins/KonataPlugin/ResponseModels/BaseResponseModel.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace QQChannelPlugin.ResponseModels +namespace KonataPlugin.ResponseModels { public class BaseResponseModel { diff --git a/src/QQBotHub.Web/ResponseModels/InfoResponseDataModel.cs b/plugins/KonataPlugin/ResponseModels/InfoResponseDataModel.cs similarity index 89% rename from src/QQBotHub.Web/ResponseModels/InfoResponseDataModel.cs rename to plugins/KonataPlugin/ResponseModels/InfoResponseDataModel.cs index 6b19d2af1..803d17708 100644 --- a/src/QQBotHub.Web/ResponseModels/InfoResponseDataModel.cs +++ b/plugins/KonataPlugin/ResponseModels/InfoResponseDataModel.cs @@ -1,4 +1,4 @@ -namespace QQBotHub.Web.ResponseModels +namespace KonataPlugin.ResponseModels { public class InfoResponseDataModel { diff --git a/plugins/KonataPlugin/SettingsModel.cs b/plugins/KonataPlugin/SettingsModel.cs index debce0cae..fc9df6bb9 100644 --- a/plugins/KonataPlugin/SettingsModel.cs +++ b/plugins/KonataPlugin/SettingsModel.cs @@ -2,42 +2,23 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; +using Konata.Core.Common; using PluginCore.Models; -namespace QQChannelPlugin +namespace KonataPlugin { public class SettingsModel : PluginSettingsModel { - public List Bots { get; set; } + // 使用 = "" , 确保不被 json 化为 null + public string Uin { get; set; } = ""; - public sealed class BotDevItemModel - { - /// - /// 平台 BotAppId - /// - public string BotAppId { get; set; } + public string Password { get; set; } = ""; - /// - /// 平台 BotToken - /// - public string BotToken { get; set; } + public bool UseDemoModel { get; set; } = false; - /// - /// 平台 BotSecret - /// - public string BotSecret { get; set; } + public string AdminQQ { get; set; } = ""; - /// - /// 指定Api通道模式为沙盒模式 (测试时使用) - /// 不指定的情况下默认是正式模式 - /// - public bool UseSandBoxMode { get; set; } - - /// - /// 使用 演示 模式, 方便测试/体验 - /// - public bool UseDemoModel { get; set; } - } + public BotKeyStore BotKeyStore { get; set; } } } diff --git a/plugins/KonataPlugin/Utils/DateTimeUtil.cs b/plugins/KonataPlugin/Utils/DateTimeUtil.cs index 41aba55b7..915cc6c89 100644 --- a/plugins/KonataPlugin/Utils/DateTimeUtil.cs +++ b/plugins/KonataPlugin/Utils/DateTimeUtil.cs @@ -1,6 +1,6 @@ using System; -namespace QQChannelPlugin.Utils +namespace KonataPlugin.Utils { /// /// JavaScript时间戳:是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总毫秒数。(13 位数字) diff --git a/plugins/KonataPlugin/Utils/EnvUtil.cs b/plugins/KonataPlugin/Utils/EnvUtil.cs index f27bcae07..e9af270c4 100644 --- a/plugins/KonataPlugin/Utils/EnvUtil.cs +++ b/plugins/KonataPlugin/Utils/EnvUtil.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace QQChannelPlugin.Utils +namespace KonataPlugin.Utils { public class EnvUtil { diff --git a/plugins/KonataPlugin/Utils/HttpUtil.cs b/plugins/KonataPlugin/Utils/HttpUtil.cs new file mode 100644 index 000000000..6343af87f --- /dev/null +++ b/plugins/KonataPlugin/Utils/HttpUtil.cs @@ -0,0 +1,342 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace KonataPlugin.Utils +{ + public class HttpUtil + { + #region Http Get + /// + /// HTTP Get请求 + /// + /// 请求目标URL + /// + /// + /// + /// + /// 返回请求回复字符串 + public static string HttpGet(string url, StringBuilder responseHeadersSb = null, string[] headers = null, WebProxy proxy = null) + { + string rtResult = string.Empty; + try + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = "GET"; + request.KeepAlive = false; + + if (headers != null) + { + foreach (string header in headers) + { + string[] temp = header.Split(new string[] { ": " }, StringSplitOptions.RemoveEmptyEntries); + if (temp[0].Equals("Referer", StringComparison.InvariantCultureIgnoreCase)) + { + request.Referer = temp[1]; + } + else if (temp[0].Equals("User-Agent", StringComparison.InvariantCultureIgnoreCase)) + { + request.UserAgent = temp[1]; + } + else if (temp[0].Equals("Accept", StringComparison.InvariantCultureIgnoreCase)) + { + request.Accept = temp[1]; + } + else if (temp[0].Equals("Connection", StringComparison.InvariantCultureIgnoreCase) && temp[1].Equals("keep-alive", StringComparison.InvariantCultureIgnoreCase)) + { + request.KeepAlive = true; + } + else if (temp[0].Equals("Connection", StringComparison.InvariantCultureIgnoreCase)) + { + request.KeepAlive = false; + } + else if (temp[0].Equals("Content-Type", StringComparison.InvariantCultureIgnoreCase)) + { + request.ContentType = temp[1]; + } + else + { + request.Headers.Add(header); + } + } + } + if (proxy != null) + { + request.Proxy = proxy; + } + request.Timeout = 10000; + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + if (responseHeadersSb != null) + { + foreach (string name in response.Headers.AllKeys) + { + responseHeadersSb.AppendLine(name + ": " + response.Headers[name]); + } + } + Stream responseStream = response.GetResponseStream(); + //如果http头中接受gzip的话,这里就要判断是否为有压缩,有的话,直接解压缩即可 + if (response.Headers["Content-Encoding"] != null && response.Headers["Content-Encoding"].ToLower().Contains("gzip")) + { + responseStream = new GZipStream(responseStream, CompressionMode.Decompress); + } + using (StreamReader sReader = new StreamReader(responseStream, System.Text.Encoding.UTF8)) + { + rtResult = sReader.ReadToEnd(); + } + responseStream.Close(); + } + catch (Exception ex) + { + throw ex; + } + + return rtResult; + } + #endregion + + #region Http Post + public static string HttpPost(string url, string postDataStr = "", StringBuilder responseHeadersSb = null, string[] headers = null, WebProxy proxy = null) + { + string rtResult = string.Empty; + try + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = "POST"; + request.KeepAlive = false; + if (headers != null) + { + foreach (string header in headers) + { + string[] temp = header.Split(new string[] { ": " }, StringSplitOptions.RemoveEmptyEntries); + if (temp[0].Equals("Referer", StringComparison.InvariantCultureIgnoreCase)) + { + request.Referer = temp[1]; + } + else if (temp[0].Equals("User-Agent", StringComparison.InvariantCultureIgnoreCase)) + { + request.UserAgent = temp[1]; + } + else if (temp[0].Equals("Accept", StringComparison.InvariantCultureIgnoreCase)) + { + request.Accept = temp[1]; + } + else if (temp[0].Equals("Connection", StringComparison.InvariantCultureIgnoreCase) && temp[1].Equals("keep-alive", StringComparison.InvariantCultureIgnoreCase)) + { + request.KeepAlive = true; + } + else if (temp[0].Equals("Connection", StringComparison.InvariantCultureIgnoreCase)) + { + request.KeepAlive = false; + } + else if (temp[0].Equals("Content-Type", StringComparison.InvariantCultureIgnoreCase)) + { + request.ContentType = temp[1]; + } + else + { + request.Headers.Add(header); + } + } + } + if (proxy != null) + { + request.Proxy = proxy; + } + request.Timeout = 10000; + byte[] postBytes = Encoding.UTF8.GetBytes(postDataStr); + request.ContentLength = postBytes.Length; + // 写 content-body 一定要在属性设置之后 + Stream requestStream = request.GetRequestStream(); + requestStream.Write(postBytes, 0, postBytes.Length); + requestStream.Close(); + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + if (responseHeadersSb != null) + { + foreach (string name in response.Headers.AllKeys) + { + responseHeadersSb.AppendLine(name + ": " + response.Headers[name]); + } + } + Stream responseStream = response.GetResponseStream(); + //如果http头中接受gzip的话,这里就要判断是否为有压缩,有的话,直接解压缩即可 + if (response.Headers["Content-Encoding"] != null && response.Headers["Content-Encoding"].ToLower().Contains("gzip")) + { + responseStream = new GZipStream(responseStream, CompressionMode.Decompress); + } + using (StreamReader sReader = new StreamReader(responseStream, System.Text.Encoding.UTF8)) + { + rtResult = sReader.ReadToEnd(); + } + responseStream.Close(); + } + catch (Exception ex) + { + throw ex; + } + + return rtResult; + } + #endregion + + #region HTTP下载文件 + /// + /// HTTP 下载文件 + /// + public static string HttpDownloadFile(string url, string filePath) + { + // 设置参数 + HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; + //发送请求并获取相应回应数据 + HttpWebResponse response = request.GetResponse() as HttpWebResponse; + //直到request.GetResponse()程序才开始向目标网页发送Post请求 + Stream responseStream = response.GetResponseStream(); + //创建本地文件写入流 + Stream stream = new FileStream(filePath, FileMode.Create); + byte[] bArr = new byte[1024]; + int size = responseStream.Read(bArr, 0, (int)bArr.Length); + while (size > 0) + { + stream.Write(bArr, 0, size); + size = responseStream.Read(bArr, 0, (int)bArr.Length); + } + stream.Close(); + responseStream.Close(); + + return filePath; + } + #endregion + + + #region HTTP上传文件 + public static async Task UploadFileAsync(string url, string filePath, Dictionary formDataPairs = null, string cookieValue = null) + { + string fileName = Path.GetFileName(filePath); + using (var client = new HttpClient()) + { + //using (var content = new MultipartFormDataContent("Upload----" + DateTime.Now.Ticks.ToString("x"))) + using (var content = new MultipartFormDataContent()) + { + // TODO: 一口气读出,一口气发送 + var upfilebytes = File.ReadAllBytes(filePath); + var ms = new MemoryStream(upfilebytes); + + if (formDataPairs != null) + { + foreach (var item in formDataPairs) + { + // 添加字符串参数,参数名: item.Key, 参数值: item.Value + content.Add(new StringContent(item.Value), item.Key); + } + } + + // 添加文件参数,参数名为file,文件名为 fileName + content.Add(new StreamContent(ms), "file", fileName); + + if (cookieValue != null) + { + // Cookie: JSESSIONID=1A51768683B2FBAEB5B066992A229A13 + content.Headers.Add("Cookie", cookieValue); + } + + + using (var httpResponseMessage = await client.PostAsync(url, content)) + { + var responseContent = ""; + if (httpResponseMessage.IsSuccessStatusCode) + { + responseContent = await httpResponseMessage.Content.ReadAsStringAsync(); + } + return responseContent; + } + } + } + } + #endregion + + + public static async Task<(string response, string cookie)> LoginSessionAsync(string url, string userName, string password) + { + (string response, string cookie) rtn = (null, null); + // 通过设置handler.UseCookies=true(默认为true),默认的会自己带上cookies (请求登录后,获取 Set-Cookie) + var handler = new HttpClientHandler() { UseCookies = true }; + using (var client = new HttpClient(handler)) + { + client.DefaultRequestHeaders.Add("Connection", "Keep-Alive"); + client.DefaultRequestHeaders.Add("Keep-Alive", "timeout=900"); + var content = new FormUrlEncodedContent(new[] + { + new KeyValuePair("userName", userName), + new KeyValuePair("password", password), + }); + + using (var httpResponseMessage = await client.PostAsync(url, content)) + { + var responseContent = ""; + if (httpResponseMessage.IsSuccessStatusCode) + { + // Set-Cookie: JSESSIONID=F839F04109B851F5C86F6657C756A484; Path=/; HttpOnly + // 获取 Set-Cookie + if (httpResponseMessage.Headers.TryGetValues("Set-Cookie", out IEnumerable cookies)) + { + rtn.cookie = cookies?.Where(m => m.StartsWith("JSESSIONID="))?.FirstOrDefault(); + // TODO: 不确定, 末尾有没有 ; + rtn.cookie = rtn.cookie.Substring("JSESSIONID=".Length); + } + + + responseContent = await httpResponseMessage.Content.ReadAsStringAsync(); + rtn.response = responseContent; + } + + return rtn; + } + }; + } + + public static async Task<(string response, string token)> LoginBearerTokenAsync(string url, string userName, string password) + { + (string response, string token) rtn = (null, null); + // 通过设置handler.UseCookies=true(默认为true),默认的会自己带上cookies (请求登录后,获取 Set-Cookie) + var handler = new HttpClientHandler() { UseCookies = true }; + using (var client = new HttpClient(handler)) + { + client.DefaultRequestHeaders.Add("Connection", "Keep-Alive"); + client.DefaultRequestHeaders.Add("Keep-Alive", "timeout=900"); + var content = new FormUrlEncodedContent(new[] + { + new KeyValuePair("userName", userName), + new KeyValuePair("password", password), + }); + + using (var httpResponseMessage = await client.PostAsync(url, content)) + { + var responseContent = ""; + if (httpResponseMessage.IsSuccessStatusCode) + { + // Authorization: Bearer xxxxxx + // 获取 token + if (httpResponseMessage.Headers.TryGetValues("Authorization", out IEnumerable authorizationItems)) + { + rtn.token = authorizationItems.First(); + rtn.token = rtn.token.Substring("Bearer ".Length); + } + + responseContent = await httpResponseMessage.Content.ReadAsStringAsync(); + rtn.response = responseContent; + } + + return rtn; + } + }; + } + + } +} diff --git a/plugins/KonataPlugin/Utils/JsonUtil.cs b/plugins/KonataPlugin/Utils/JsonUtil.cs new file mode 100644 index 000000000..fca775858 --- /dev/null +++ b/plugins/KonataPlugin/Utils/JsonUtil.cs @@ -0,0 +1,28 @@ +//using Newtonsoft.Json; +using System.Text.Json; + +namespace KonataPlugin.Utils +{ + public class JsonUtil + { + + #region JsonStr2Obj + public static T JsonStr2Obj(string jsonStr) + { + //return JsonConvert.DeserializeObject(jsonStr); + return JsonSerializer.Deserialize + (jsonStr); + } + #endregion + + #region Obj2JsonStr + public static string Obj2JsonStr(object jsonObj) + { + //return JsonConvert.SerializeObject(jsonObj); + return JsonSerializer.Serialize(jsonObj, + new JsonSerializerOptions { WriteIndented = true }); + } + #endregion + + } +} diff --git a/plugins/KonataPlugin/Utils/LogUtil.cs b/plugins/KonataPlugin/Utils/LogUtil.cs index 1e36bf60a..a0258ce4f 100644 --- a/plugins/KonataPlugin/Utils/LogUtil.cs +++ b/plugins/KonataPlugin/Utils/LogUtil.cs @@ -4,11 +4,11 @@ using System.Text; using System.Linq; -namespace QQChannelPlugin.Utils +namespace KonataPlugin.Utils { public class LogUtil { - public const string Sign = nameof(QQChannelPlugin); + public const string Sign = nameof(KonataPlugin); public static void Info(string message) { diff --git a/plugins/KonataPlugin/Utils/Md5Util.cs b/plugins/KonataPlugin/Utils/Md5Util.cs new file mode 100644 index 000000000..31b234582 --- /dev/null +++ b/plugins/KonataPlugin/Utils/Md5Util.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; + +namespace KonataPlugin.Utils +{ + public class Md5Util + { + public static string Md5(string str) + { + try + { + MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); + byte[] bytValue, bytHash; + bytValue = System.Text.Encoding.UTF8.GetBytes(str); + bytHash = md5.ComputeHash(bytValue); + md5.Clear(); + string sTemp = ""; + for (int i = 0; i < bytHash.Length; i++) + { + sTemp += bytHash[i].ToString("X").PadLeft(2, '0'); + } + str = sTemp.ToLower(); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + + return str; + } + + #region MD5加密 + /// + /// 16位MD5加密 + /// + /// + /// + public static string MD5Encrypt16(string str) + { + var md5 = new MD5CryptoServiceProvider(); + string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(str)), 4, 8); + t2 = t2.Replace("-", ""); + return t2; + } + + /// + /// 16位MD5加密 + /// + /// + /// + /// + public static byte[] MD5Encrypt16(string str, bool flag) + { + //获取加密服务 + MD5CryptoServiceProvider md5CSP = new MD5CryptoServiceProvider(); + //获取要加密的字段,并转化为Byte[]数组 + byte[] testEncrypt = System.Text.Encoding.UTF8.GetBytes(str); + //加密Byte[]数组 + byte[] resultEncrypt = md5CSP.ComputeHash(testEncrypt); + + return resultEncrypt; + } + /// + /// 32位MD5加密 + /// + /// + /// + public static string MD5Encrypt32(string str) + { + string cl = str; + string pwd = ""; + MD5 md5 = MD5.Create(); //实例化一个md5对像 + // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择  + byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl)); + // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得 + for (int i = 0; i < s.Length; i++) + { + // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母 + // X 表示大写, x 表示小写, X2和x2表示不省略首位为0的十六进制数 + pwd = pwd + s[i].ToString("x2"); + } + return pwd; + } + /// + /// 64位MD5加密 + /// + /// + /// + public static string MD5Encrypt64(string str) + { + string cl = str; + //string pwd = ""; + MD5 md5 = MD5.Create(); //实例化一个md5对像 + // 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择  + byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl)); + return Convert.ToBase64String(s); + } + #endregion + + } +} diff --git a/src/QQBotHub.Web/Utils/SettingsUtil.cs b/plugins/KonataPlugin/Utils/SettingsUtil.cs similarity index 53% rename from src/QQBotHub.Web/Utils/SettingsUtil.cs rename to plugins/KonataPlugin/Utils/SettingsUtil.cs index 7a0d3dd24..2a7032d45 100644 --- a/src/QQBotHub.Web/Utils/SettingsUtil.cs +++ b/plugins/KonataPlugin/Utils/SettingsUtil.cs @@ -1,22 +1,25 @@ -using QQBotHub.Sdk.Utils; + -namespace QQBotHub.Web.Utils +using System.IO; + +namespace KonataPlugin.Utils { public class SettingsUtil { - - public static void EnsureExist() + public static void EnsureExist(string pluginId) { - string filePath = Path.Combine(Directory.GetCurrentDirectory(), "settings.json"); + string pluginDir = Path.Combine(PluginCore.PluginPathProvider.PluginsRootPath(), pluginId); + string filePath = Path.Combine(pluginDir, "settings.json"); if (!File.Exists(filePath)) { - Set(new SettingsModel()); + Set(pluginId, new SettingsModel()); } } - public static SettingsModel Get() + public static SettingsModel Get(string pluginId) { - string filePath = Path.Combine(Directory.GetCurrentDirectory(), "settings.json"); + string pluginDir = Path.Combine(PluginCore.PluginPathProvider.PluginsRootPath(), pluginId); + string filePath = Path.Combine(pluginDir, "settings.json"); if (!File.Exists(filePath)) { SettingsModel jsonModel = new SettingsModel(); @@ -34,9 +37,10 @@ public static SettingsModel Get() } } - public static void Set(SettingsModel settingsModel) + public static void Set(string pluginId, SettingsModel settingsModel) { - string filePath = Path.Combine(Directory.GetCurrentDirectory(), "settings.json"); + string pluginDir = Path.Combine(PluginCore.PluginPathProvider.PluginsRootPath(), pluginId); + string filePath = Path.Combine(pluginDir, "settings.json"); string jsonStr = JsonUtil.Obj2JsonStr(settingsModel); File.WriteAllText(path: filePath, contents: jsonStr, encoding: System.Text.Encoding.UTF8); } diff --git a/plugins/KonataPlugin/settings.json b/plugins/KonataPlugin/settings.json index 9c2d374f1..22722013e 100644 --- a/plugins/KonataPlugin/settings.json +++ b/plugins/KonataPlugin/settings.json @@ -1,18 +1,7 @@ -{ - "Bots": [ - { - "BotAppId": "", - "BotToken": "", - "BotSecret": "", - "UseSandBoxMode": true, - "UseDemoModel": true - }, - { - "BotAppId": "", - "BotToken": "", - "BotSecret": "", - "UseSandBoxMode": true, - "UseDemoModel": true - } - ] +{ + "Uin": "", + "Password": "", + "UseDemoModel": false, + "AdminQQ": "", + "BotKeyStore": null } \ No newline at end of file diff --git a/plugins/KonataPlugin/wwwroot/index.html b/plugins/KonataPlugin/wwwroot/index.html index d7df8a20a..fd6cfec7a 100644 --- a/plugins/KonataPlugin/wwwroot/index.html +++ b/plugins/KonataPlugin/wwwroot/index.html @@ -2,17 +2,206 @@ - - QQChannelPlugin - - + + KonataPlugin + + -
-

QQChannelPlugin!

-

插件的前端文件应当放在 wwwroot 文件夹下

-

暂时还没有做前端界面!!!

-
+
+

KonataPlugin

+
+ +
+ + + +
+
+
+ +
加载中...
+
+ +
+
+
+ + + + +
+
+
+
+ + +
+
+ + +
+ +
+ + \ No newline at end of file diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/css/mdui.css b/plugins/KonataPlugin/wwwroot/libs/mdui/css/mdui.css similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/css/mdui.css rename to plugins/KonataPlugin/wwwroot/libs/mdui/css/mdui.css diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/css/mdui.css.map b/plugins/KonataPlugin/wwwroot/libs/mdui/css/mdui.css.map similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/css/mdui.css.map rename to plugins/KonataPlugin/wwwroot/libs/mdui/css/mdui.css.map diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/css/mdui.min.css b/plugins/KonataPlugin/wwwroot/libs/mdui/css/mdui.min.css similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/css/mdui.min.css rename to plugins/KonataPlugin/wwwroot/libs/mdui/css/mdui.min.css diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/css/mdui.min.css.map b/plugins/KonataPlugin/wwwroot/libs/mdui/css/mdui.min.css.map similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/css/mdui.min.css.map rename to plugins/KonataPlugin/wwwroot/libs/mdui/css/mdui.min.css.map diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/LICENSE.txt b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/LICENSE.txt similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/LICENSE.txt rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/LICENSE.txt diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Black.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-BlackItalic.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Bold.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-BoldItalic.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Light.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-LightItalic.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Medium.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-MediumItalic.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Regular.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-RegularItalic.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-Thin.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/fonts/roboto/Roboto-ThinItalic.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/icons/material-icons/LICENSE.txt b/plugins/KonataPlugin/wwwroot/libs/mdui/icons/material-icons/LICENSE.txt similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/icons/material-icons/LICENSE.txt rename to plugins/KonataPlugin/wwwroot/libs/mdui/icons/material-icons/LICENSE.txt diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.ijmap b/plugins/KonataPlugin/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.ijmap similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.ijmap rename to plugins/KonataPlugin/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.ijmap diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff b/plugins/KonataPlugin/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff rename to plugins/KonataPlugin/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff2 b/plugins/KonataPlugin/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff2 similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff2 rename to plugins/KonataPlugin/wwwroot/libs/mdui/icons/material-icons/MaterialIcons-Regular.woff2 diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.esm.js b/plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.esm.js similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.esm.js rename to plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.esm.js diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.esm.js.map b/plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.esm.js.map similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.esm.js.map rename to plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.esm.js.map diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.js b/plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.js similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.js rename to plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.js diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.js.map b/plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.js.map similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.js.map rename to plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.js.map diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.min.js b/plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.min.js similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.min.js rename to plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.min.js diff --git a/src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.min.js.map b/plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.min.js.map similarity index 100% rename from src/QQBotHub.Web/wwwroot/libs/mdui/js/mdui.min.js.map rename to plugins/KonataPlugin/wwwroot/libs/mdui/js/mdui.min.js.map diff --git a/src/QQBotHub.Sdk/QQBotHub.Sdk.csproj b/src/QQBotHub.Sdk/QQBotHub.Sdk.csproj index 00aa78e6c..8dde1783f 100644 --- a/src/QQBotHub.Sdk/QQBotHub.Sdk.csproj +++ b/src/QQBotHub.Sdk/QQBotHub.Sdk.csproj @@ -5,7 +5,7 @@ enable enable QQBotHub.Sdk - 0.1.1 + 1.0.0 yiyun yiyun QQBotHub 插件开发包 @@ -16,10 +16,6 @@ true - - - - diff --git a/src/QQBotHub.Sdk/QQBotStore.cs b/src/QQBotHub.Sdk/QQBotStore.cs deleted file mode 100644 index a0c5a38cc..000000000 --- a/src/QQBotHub.Sdk/QQBotStore.cs +++ /dev/null @@ -1,106 +0,0 @@ -using Konata.Core; -using Konata.Core.Common; - -namespace QQBotHub.Sdk -{ - public class QQBotStore - { - public static Bot Bot { get; set; } - - - - #region 废弃 - //public static class StoreUtil - //{ - // public static T Get(string fileName, T defaultObj) - // { - // T rtnObj = defaultObj; - // string configDir = Path.Combine(Directory.GetCurrentDirectory(), "App_Data"); - // if (!Directory.Exists(configDir)) - // { - // Directory.CreateDirectory(configDir); - // } - // string filePath = Path.Combine(configDir, fileName); - // if (!File.Exists(filePath)) - // { - // string jsonStr = Utils.JsonUtil.Obj2JsonStr(rtnObj); - // File.WriteAllText(path: filePath, contents: jsonStr, encoding: System.Text.Encoding.UTF8); - // } - // else - // { - // string jsonStr = File.ReadAllText(path: filePath, encoding: System.Text.Encoding.UTF8); - // rtnObj = Utils.JsonUtil.JsonStr2Obj(jsonStr); - // } - - // return rtnObj; - // } - - // public static void Set(T obj, string fileName) - // { - // string configDir = Path.Combine(Directory.GetCurrentDirectory(), "App_Data"); - // if (!Directory.Exists(configDir)) - // { - // Directory.CreateDirectory(configDir); - // } - // string filePath = Path.Combine(configDir, fileName); - // string jsonStr = Utils.JsonUtil.Obj2JsonStr(obj); - // File.WriteAllText(path: filePath, contents: jsonStr, encoding: System.Text.Encoding.UTF8); - // } - - //} - - //public static BotConfig BotConfig - //{ - // get - // { - // BotConfig botConfig = BotConfig.Default(); - // botConfig = StoreUtil.Get("config.json", botConfig); - - // return botConfig; - // } - // set - // { - // BotConfig botConfig = value; - // StoreUtil.Set(botConfig, "config.json"); - // } - //} - - //public static BotDevice BotDevice - //{ - // get - // { - // BotDevice botDevice = BotDevice.Default(); - // botDevice = StoreUtil.Get("device.json", botDevice); - - // return botDevice; - // } - // set - // { - // BotDevice botDevice = value; - // StoreUtil.Set(botDevice, "device.json"); - // } - //} - - //public static BotKeyStore BotKeyStore - //{ - // get - // { - // SettingsModel settingsModel = Utils.SettingsUtil.Get(); - // string account = settingsModel.QQ; - // string password = settingsModel.Password; - // BotKeyStore botKeyStore = new BotKeyStore(uin: account, password: password); - // botKeyStore = StoreUtil.Get("keystore.json", botKeyStore); - - // return botKeyStore; - // } - // set - // { - // BotKeyStore botKeyStore = value; - // StoreUtil.Set(botKeyStore, "keystore.json"); - // } - //} - #endregion - - - } -} diff --git a/src/QQBotHub.Sdk/Utils/SettingsUtil.cs b/src/QQBotHub.Sdk/Utils/SettingsUtil.cs new file mode 100644 index 000000000..69ca2c8d4 --- /dev/null +++ b/src/QQBotHub.Sdk/Utils/SettingsUtil.cs @@ -0,0 +1,51 @@ + + +using System.IO; + +namespace QQBotHub.Sdk.Utils +{ + public class SettingsUtil + { + public static void EnsureExist(string pluginId) + where T : PluginCore.Models.PluginSettingsModel, new() + { + string pluginDir = Path.Combine(PluginCore.PluginPathProvider.PluginsRootPath(), pluginId); + string filePath = Path.Combine(pluginDir, "settings.json"); + if (!File.Exists(filePath)) + { + Set(pluginId, new T()); + } + } + + public static T Get(string pluginId) + where T : PluginCore.Models.PluginSettingsModel, new() + { + string pluginDir = Path.Combine(PluginCore.PluginPathProvider.PluginsRootPath(), pluginId); + string filePath = Path.Combine(pluginDir, "settings.json"); + if (!File.Exists(filePath)) + { + T jsonModel = new T(); + string jsonStr = JsonUtil.Obj2JsonStr(jsonModel); + File.WriteAllText(path: filePath, contents: jsonStr, encoding: System.Text.Encoding.UTF8); + + return jsonModel; + } + else + { + string jsonStr = File.ReadAllText(path: filePath, encoding: System.Text.Encoding.UTF8); + T jsonModel = JsonUtil.JsonStr2Obj(jsonStr); + + return jsonModel; + } + } + + public static void Set(string pluginId, T settingsModel) + where T : PluginCore.Models.PluginSettingsModel, new() + { + string pluginDir = Path.Combine(PluginCore.PluginPathProvider.PluginsRootPath(), pluginId); + string filePath = Path.Combine(pluginDir, "settings.json"); + string jsonStr = JsonUtil.Obj2JsonStr(settingsModel); + File.WriteAllText(path: filePath, contents: jsonStr, encoding: System.Text.Encoding.UTF8); + } + } +} diff --git a/src/QQBotHub.Web/Controllers/HomeController.cs b/src/QQBotHub.Web/Controllers/HomeController.cs index ea098b6ab..eabe14247 100644 --- a/src/QQBotHub.Web/Controllers/HomeController.cs +++ b/src/QQBotHub.Web/Controllers/HomeController.cs @@ -5,467 +5,22 @@ using Microsoft.AspNetCore.Mvc; using PluginCore.Interfaces; using PluginCore.IPlugins; -using QQBotHub.Sdk; -using QQBotHub.Sdk.IPlugins; -using QQBotHub.Sdk.Utils; -using QQBotHub.Web.RequestModels; -using QQBotHub.Web.ResponseModels; using System.Threading.Tasks; using static Konata.Core.Events.Model.CaptchaEvent; namespace QQBotHub.Web.Controllers { - [Route("api/[action]")] - [Authorize("PluginCore.Admin")] + [Route("")] + //[Authorize("PluginCore.Admin")] [ApiController] public class HomeController : ControllerBase { - - #region Fields - - private readonly IPluginFinder _pluginFinder; - - private readonly bool _debug; - - #endregion - - #region Ctor - public HomeController(IPluginFinder pluginFinder) - { - _pluginFinder = pluginFinder; - string debugStr = EnvUtil.GetEnv("DEBUG"); - if (!string.IsNullOrEmpty(debugStr) && bool.TryParse(debugStr, out bool debug)) - { - _debug = debug; - } - else - { - _debug = false; - } - } - #endregion - - - #region Actions - - [Route("/")] + [Route("")] [HttpGet] public async Task Index() { - string indexFilePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "index.html"); - - return PhysicalFile(indexFilePath, "text/html"); - } - - - [HttpGet] - public async Task Uin() - { - BaseResponseModel responseModel = new BaseResponseModel(); - try - { - var settings = Utils.SettingsUtil.Get(); - string uin = settings?.Uin ?? ""; - if (!string.IsNullOrEmpty(QQBotStore.Bot?.Uin.ToString())) - { - uin = QQBotStore.Bot?.Uin.ToString() ?? uin; - } - - responseModel.Code = 1; - responseModel.Message = "获取成功"; - responseModel.Data = uin; - } - catch (Exception ex) - { - responseModel.Code = -1; - responseModel.Message = "获取失败"; - responseModel.Data = ex.ToString(); - } - - return await Task.FromResult(responseModel); - } - - /// - /// 登录后,定时访问此api, 获取验证等信息 - /// - /// - [HttpGet] - public async Task Info() - { - BaseResponseModel responseModel = new BaseResponseModel(); - InfoResponseDataModel dataModel = new InfoResponseDataModel(); - - if (QQBotStore.Bot == null) - { - // 未点击登录过 - responseModel.Code = 1; - responseModel.Message = "未登录"; - - dataModel.CaptchaTip = ""; - dataModel.IsOnline = false; - dataModel.CaptchaType = ""; - dataModel.CaptchaUpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); - - responseModel.Data = dataModel; - - return responseModel; - } - - //if (QQBotStore.Bot.IsOnline()) - if (CaptchaStore.IsOnline) - { - responseModel.Code = 2; - responseModel.Message = "已处于登录状态, 无需验证"; - - dataModel.CaptchaTip = ""; - dataModel.IsOnline = true; - dataModel.CaptchaType = ""; - dataModel.CaptchaUpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); - - responseModel.Data = dataModel; - - return responseModel; - } - - // 已经点击登录过一次 - responseModel.Code = 3; - responseModel.Message = "需要验证"; - switch (CaptchaStore.CaptchaType) - { - case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Sms: - dataModel.CaptchaType = "短信验证"; - break; - case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Slider: - dataModel.CaptchaType = "滑块验证"; - break; - case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Unknown: - dataModel.CaptchaType = "未知验证"; - break; - default: - dataModel.CaptchaType = "未知验证-不匹配的验证类型"; - break; - } - dataModel.IsOnline = false; - dataModel.CaptchaTip = CaptchaStore.CaptchaTip; - dataModel.CaptchaUpdateTime = CaptchaStore.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss"); - - responseModel.Data = dataModel; - - return await Task.FromResult(responseModel); - } - - /// - /// 提交验证信息 - /// - /// - /// - [HttpPost] - public async Task SubmitCaptcha([FromBody] SubmitCaptchaRequestModel requestModel) - { - BaseResponseModel responseModel = new BaseResponseModel(); - string captcha = requestModel.Captcha; - if (string.IsNullOrEmpty(captcha)) - { - responseModel.Code = -1; - responseModel.Message = "captcha 不能为空"; - - return responseModel; - } - bool isSuccessCaptcha = false; - try - { - switch (CaptchaStore.CaptchaType) - { - case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Sms: - isSuccessCaptcha = QQBotStore.Bot.SubmitSmsCode(captcha); - break; - case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Slider: - isSuccessCaptcha = QQBotStore.Bot.SubmitSliderTicket(captcha); - break; - case Konata.Core.Events.Model.CaptchaEvent.CaptchaType.Unknown: - break; - default: - break; - } - - responseModel.Code = 1; - responseModel.Message = $"{(isSuccessCaptcha ? "验证通过" : "验证失败, 请重新验证")}"; - } - catch (System.Exception ex) - { - responseModel.Code = -3; - responseModel.Message = "提交验证失败"; - responseModel.Data = ex.ToString(); - - Utils.LogUtil.Exception(ex); - } - - return await Task.FromResult(responseModel); + return Content("正常运行中, 请前往 插件管理"); } - - [HttpPost] - public async Task Login(LoginRequestModel requestModel) - { - BaseResponseModel responseModel = new BaseResponseModel(); - try - { - var oldSettings = Utils.SettingsUtil.Get(); - SettingsModel newSettings = new SettingsModel(); - if (requestModel.LoginType == "password") - { - newSettings = new SettingsModel - { - Uin = requestModel.Uin, - Password = requestModel.Password, - }; - if (string.IsNullOrEmpty(requestModel.Password?.Trim())) - { - newSettings.Password = oldSettings.Password; - } - - InitQQBot(botKeyStore: new BotKeyStore(uin: newSettings.Uin, password: newSettings.Password)); - - Utils.SettingsUtil.Set(newSettings); - } - else if (requestModel.LoginType == "config") - { - newSettings = new SettingsModel(); - if (!string.IsNullOrEmpty(requestModel.BotKeyStore?.Trim())) - { - try - { - newSettings.BotKeyStore = JsonUtil.JsonStr2Obj(requestModel.BotKeyStore.Trim()); - } - catch (Exception ex) - { - Console.WriteLine("requestModel.BotKeyStore 转换失败:"); - Console.WriteLine(ex.ToString()); - } - } - - if (string.IsNullOrEmpty(requestModel.BotKeyStore?.Trim())) - { - newSettings.BotKeyStore = oldSettings.BotKeyStore; - } - - InitQQBot(botKeyStore: newSettings.BotKeyStore); - - Utils.SettingsUtil.Set(newSettings); - } - else - { - responseModel.Code = -2; - responseModel.Message = "未知登录方式"; - - return await Task.FromResult(responseModel); - } - - Task taskLogin = QQBotStore.Bot.Login(); - - responseModel.Code = 1; - responseModel.Message = "提交登录成功"; - } - catch (Exception ex) - { - responseModel.Code = -1; - responseModel.Message = "提交登录失败"; - responseModel.Data = ex.ToString(); - } - - return await Task.FromResult(responseModel); - } - - [HttpPost] - public async Task Logout() - { - BaseResponseModel responseModel = new BaseResponseModel(); - try - { - Task taskLogout = QQBotStore.Bot.Logout(); - - responseModel.Code = 1; - responseModel.Message = "提交退出成功"; - } - catch (Exception ex) - { - responseModel.Code = -1; - responseModel.Message = "提交退出失败"; - responseModel.Data = ex.ToString(); - } - - return await Task.FromResult(responseModel); - } - - #endregion - - #region Helpers - - [NonAction] - public void InitQQBot(BotKeyStore botKeyStore) - { - #region Bot - - // Create a bot instance - #region 准备数据 - // 优先从 环境变量 中获取 - BotConfig botConfig = BotConfig.Default(); - string botConfigJsonStr = EnvUtil.GetEnv("BOT_CONFIG"); - if (!string.IsNullOrEmpty(botConfigJsonStr)) - { - botConfig = JsonUtil.JsonStr2Obj(botConfigJsonStr); - } - - BotDevice botDevice = BotDevice.Default(); - string botDeviceJsonStr = EnvUtil.GetEnv("BOT_DEVICE"); - if (!string.IsNullOrEmpty(botDeviceJsonStr)) - { - botDevice = JsonUtil.JsonStr2Obj(botDeviceJsonStr); - } - - string botKeyStoreJsonStr = EnvUtil.GetEnv("BOT_KEYSTORE"); - if (!string.IsNullOrEmpty(botKeyStoreJsonStr)) - { - botKeyStore = JsonUtil.JsonStr2Obj(botKeyStoreJsonStr); - } - #endregion - - var bot = BotFather.Create(botConfig, botDevice, botKeyStore); - { - // Print the log - bot.OnLog += (s, e) => - { - //#if DEBUG - // Utils.LogUtil.Info(e.EventMessage); - //#endif - if (_debug) - { - Utils.LogUtil.Info(e.EventMessage); - } - }; - - // Handle the captcha - bot.OnCaptcha += (s, e) => - { - Utils.LogUtil.Info("QQ 登录验证:"); - CaptchaStore.UpdateTime = DateTime.Now; - CaptchaStore.CaptchaType = e.Type; - if (e.Type == CaptchaType.Slider) - { - Utils.LogUtil.Info(e.SliderUrl); - //((Bot)s).SubmitSliderTicket(Console.ReadLine()); - CaptchaStore.CaptchaTip = $"{e.SliderUrl}"; - } - else if (e.Type == CaptchaType.Sms) - { - Utils.LogUtil.Info(e.Phone); - //((Bot)s).SubmitSmsCode(Console.ReadLine()); - CaptchaStore.CaptchaTip = $"{e.Phone}"; - } - }; - - // Handle messages from group - bot.OnGroupMessage += (s, e) => - { - Utils.LogUtil.Info($"群消息: {DateTime.Now.ToString()}: {e.Message.Chain?.FirstOrDefault()?.ToString() ?? ""}"); - - var plugins = _pluginFinder.EnablePlugins().ToList(); - Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); - foreach (var plugin in plugins) - { - Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); - if (e.Message.Sender.Uin != s.Uin) - { - // 排除机器人自己 - plugin.OnGroupMessage((s, e), e.Message.Chain?.FirstOrDefault()?.ToString() ?? "", e.GroupName, e.GroupUin, e.MemberUin); - } - } - }; - - // Handle messages from friend - bot.OnFriendMessage += (s, e) => - { - Utils.LogUtil.Info($"好友消息: {DateTime.Now.ToString()}: {e.Message.Chain?.FirstOrDefault()?.ToString() ?? ""}"); - - // 在获取插件这步正常, 没有触发 bot.OnFriendMessage - var plugins = _pluginFinder.EnablePlugins().ToList(); - Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件:"); - //Utils.LogUtil.Info($"响应: {plugins?.Count.ToString()} 个插件: {e.Message.Chain?.FirstOrDefault()?.ToString() ?? ""}"); - foreach (var plugin in plugins) - { - Utils.LogUtil.Info($"插件: {plugin.GetType().ToString()}"); - if (e.Message.Sender.Uin != s.Uin) - { - // 排除机器人自己 - plugin.OnFriendMessage((s, e), e.Message.Chain?.FirstOrDefault()?.ToString() ?? "", e.FriendUin); - } - } - }; - - bot.OnBotOnline += (s, e) => - { - Utils.LogUtil.Info($"{s.Name} 上线"); - - CaptchaStore.IsOnline = true; - - var plugins = _pluginFinder.EnablePlugins(); - foreach (var plugin in plugins) - { - plugin.OnBotOnline((s, e), s.Name, s.Uin); - } - }; - - bot.OnBotOffline += (s, e) => - { - Utils.LogUtil.Info($"{s.Name} 离线"); - - CaptchaStore.IsOnline = false; - - var plugins = _pluginFinder.EnablePlugins(); - foreach (var plugin in plugins) - { - plugin.OnBotOffline((s, e), s.Name, s.Uin); - } - }; - // ... More handlers - } - - // Do login - //Task loginTask = bot.Login(); - - // 下方操作会阻塞, 并且是阻塞到过登录验证 - //if (!bot.Login().Result) - //{ - // Utils.LogUtil.Info($"{nameof(QQBotPlugin)} 启用后 QQ 自动登录失败"); - // return base.AfterEnable(); - //} - //else - //{ - // Utils.LogUtil.Info($"{nameof(QQBotPlugin)} 启用后 QQ 自动登录成功"); - //} - - #endregion - - // 登录成功, 保存起来 - QQBotStore.Bot = bot; - } - - #endregion - } - #region More - - public static class CaptchaStore - { - public static Konata.Core.Events.Model.CaptchaEvent.CaptchaType CaptchaType { get; set; } - - public static string CaptchaTip { get; set; } - - public static DateTime UpdateTime { get; set; } - - public static bool IsOnline { get; set; } - } - - #endregion - } diff --git a/src/QQBotHub.Web/Program.cs b/src/QQBotHub.Web/Program.cs index 52afd5b96..5e657700e 100644 --- a/src/QQBotHub.Web/Program.cs +++ b/src/QQBotHub.Web/Program.cs @@ -36,10 +36,6 @@ // wwwroot app.UseStaticFiles(); -#region ȷ settings.json ļ -QQBotHub.Web.Utils.SettingsUtil.EnsureExist(); -#endregion - app.MapControllers(); app.Run(); diff --git a/src/QQBotHub.Web/QQBotHub.Web.csproj b/src/QQBotHub.Web/QQBotHub.Web.csproj index c96be681a..f8a9e9042 100644 --- a/src/QQBotHub.Web/QQBotHub.Web.csproj +++ b/src/QQBotHub.Web/QQBotHub.Web.csproj @@ -32,14 +32,15 @@ - - Always - Always + + + + bin\Release\net6.0\QQBot.Web.xml diff --git a/src/QQBotHub.Web/ResponseModels/BaseResponseModel.cs b/src/QQBotHub.Web/ResponseModels/BaseResponseModel.cs deleted file mode 100644 index a2f89c473..000000000 --- a/src/QQBotHub.Web/ResponseModels/BaseResponseModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace QQBotHub.Web.ResponseModels -{ - public class BaseResponseModel - { - public int Code { get; set; } - - public string Message { get; set; } - - public object Data { get; set; } - } -} diff --git a/src/QQBotHub.Web/SettingsModel.cs b/src/QQBotHub.Web/SettingsModel.cs deleted file mode 100644 index f4a895fe9..000000000 --- a/src/QQBotHub.Web/SettingsModel.cs +++ /dev/null @@ -1,13 +0,0 @@ - -using Konata.Core.Common; - -namespace QQBotHub.Web -{ - public class SettingsModel - { - // 使用 = "" , 确保不被 json 化为 null - public string Uin { get; set; } = ""; - public string Password { get; set; } = ""; - public BotKeyStore BotKeyStore { get; set; } - } -} diff --git a/src/QQBotHub.Web/Utils/LogUtil.cs b/src/QQBotHub.Web/Utils/LogUtil.cs deleted file mode 100644 index 7515e00d4..000000000 --- a/src/QQBotHub.Web/Utils/LogUtil.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text; -using System.Linq; - -namespace QQBotHub.Web.Utils -{ - public class LogUtil - { - public const string Sign = nameof(QQBotHub.Web); - - public static void Info(string message) - { - Console.ForegroundColor = ConsoleColor.Green; - Console.Write($"{Sign}: "); - Console.ResetColor(); - DateTime now = DateTime.Now; - Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm:ss")); - Console.WriteLine(message); - } - - public static void Error(string message) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.Write($"{Sign}: "); - Console.ResetColor(); - DateTime now = DateTime.Now; - Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm:ss")); - Console.WriteLine(message); - } - - public static void Exception(Exception ex) - { - Error(ex.ToString()); - Exception exception = ex; - while (exception.InnerException != null) - { - exception = ex.InnerException; - Error(exception.Message); - } - } - - } -} diff --git a/src/QQBotHub.Web/wwwroot/css/main.css b/src/QQBotHub.Web/wwwroot/css/main.css deleted file mode 100644 index 191068eaa..000000000 --- a/src/QQBotHub.Web/wwwroot/css/main.css +++ /dev/null @@ -1,9 +0,0 @@ -* { - margin: 0; - padding: 0; -} - -#app { - width: 100%; - color: deepskyblue; -} \ No newline at end of file diff --git a/src/QQBotHub.Web/wwwroot/index.html b/src/QQBotHub.Web/wwwroot/index.html deleted file mode 100644 index 1e2bd83a1..000000000 --- a/src/QQBotHub.Web/wwwroot/index.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - QQBotHub - - - - -
-

QQBotHub

-
- -
- - - -
-
-
- -
加载中...
-
- -
-
-
- - - - -
-
-
-
- - -
-
- - -
- -
- - - - \ No newline at end of file diff --git a/test/ConsoleApp/ConsoleApp.csproj b/test/KonataApp/KonataApp.csproj similarity index 100% rename from test/ConsoleApp/ConsoleApp.csproj rename to test/KonataApp/KonataApp.csproj diff --git a/test/ConsoleApp/Program.cs b/test/KonataApp/Program.cs similarity index 98% rename from test/ConsoleApp/Program.cs rename to test/KonataApp/Program.cs index fb8ad77ac..007b9c640 100644 --- a/test/ConsoleApp/Program.cs +++ b/test/KonataApp/Program.cs @@ -5,7 +5,7 @@ using System.Text.Json; using static Konata.Core.Events.Model.CaptchaEvent; -Console.WriteLine("QQBotHub ConsoleApp - QQ登录软件"); +Console.WriteLine("QQBotHub KonataApp - QQ登录软件"); // Create a bot instance