From 9815b9bcf2c9dedad14804ba5f7335c96d5e5fbc Mon Sep 17 00:00:00 2001 From: Giftina Date: Thu, 19 May 2022 11:50:07 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=93=94=E5=93=A9?= =?UTF-8?q?=E5=93=94=E5=93=A9=E5=AD=97=E5=B9=95=E6=96=87=E4=BB=B6=E5=90=8D?= =?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=9B=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=BC=A0=E8=8F=8A=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=88=B3=E4=B8=80=E6=88=B3=E4=BC=9A=E5=A4=8D=E8=AF=BB?= =?UTF-8?q?undefined=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E7=B3=BB=E7=BB=9F=E4=BC=A0=E5=8F=82=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=93=8D=E5=BA=94=E5=BF=83=E8=B7=B3=E5=AF=BC?= =?UTF-8?q?=E8=87=B4go-cqhttp=E5=87=BA=E7=8E=B0=E5=A4=A7=E9=87=8F=E8=AD=A6?= =?UTF-8?q?=E5=91=8A=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 增加启动更新检测;关闭cmd窗口的快速编辑,防止可能被选中而时停; --- config/constants.js | 15 ++-- index.js | 77 +++++++++++-------- plugin_tester.js | 19 ++--- plugins/go-cqhttp/go-cqhttp.bat | 2 +- plugins/repeat.js | 7 +- plugins/status.js | 10 +-- ...lastst_reply.txt => live_latest_reply.txt} | 0 7 files changed, 73 insertions(+), 57 deletions(-) rename static/xiaoye/{live_lastst_reply.txt => live_latest_reply.txt} (100%) diff --git a/config/constants.js b/config/constants.js index 05d0d5d4..8e63095e 100644 --- a/config/constants.js +++ b/config/constants.js @@ -1,11 +1,10 @@ module.exports = Object.freeze({ - //正则 - rename_reg: new RegExp("^/rename [\u4e00-\u9fa5a-z0-9]{1,10}$"), //允许1-10长度的数英汉昵称 - isImage_reg: new RegExp("\\[CQ:image,file:"), //匹配qqBot图片 + //正则表达式 change_reply_probability_reg: new RegExp("^/回复率 [0-9]*"), //匹配修改qqBot小夜回复率 change_fudu_probability_reg: new RegExp("^/复读率 [0-9]*"), //匹配修改qqBot小夜复读率 + isImage_reg: new RegExp("\\[CQ:image,file:"), //匹配qq图片消息 img_url_reg: new RegExp("https(.*term=3)"), //匹配图片地址 - isVideo_reg: new RegExp("^\\[CQ:video,file:"), //匹配qqBot图片 + isVideo_reg: new RegExp("\\[CQ:video,file:"), //匹配qq视频消息 video_url_reg: new RegExp("http(.*term:unknow)"), //匹配视频地址 come_yap_reg: new RegExp("^/嘴臭(.*)"), //匹配对话语音 hand_grenade_reg: new RegExp("^一个手雷(.*)"), //匹配一个手雷 @@ -14,10 +13,10 @@ module.exports = Object.freeze({ hope_flower_reg: new RegExp("^希望的花(.*)"), //匹配希望的花 loop_bomb_reg: new RegExp("^击鼓传雷(.*)"), //匹配击鼓传雷 is_qq_reg: new RegExp("^[1-9][0-9]{4,9}$"), //校验是否是合法的qq号 - has_qq_reg: new RegExp("\\[CQ:at,qq=(.*)\\]"), //匹配是否有@ + has_qq_reg: new RegExp("\\[CQ:at,qq=(\\d*)\\]"), //匹配是否有@qq i_have_a_friend_reg: new RegExp("我有一个朋友说.*|我有个朋友说.*"), //匹配我有个朋友指令 - open_ju_reg: new RegExp("张菊.*"), //匹配张菊指令 - close_ju_reg: new RegExp("闭菊.*"), //匹配闭菊指令 + open_ju_reg: new RegExp("张菊"), //匹配张菊指令 + close_ju_reg: new RegExp("闭菊"), //匹配闭菊指令 gugua_reg: new RegExp("^/孤寡.*"), //匹配孤寡指令 fake_forward_reg: new RegExp("^/强制迫害.*"), //匹配伪造转发指令 approve_group_invite_reg: new RegExp("^/批准 (.*)"), //匹配批准加群指令 @@ -28,6 +27,6 @@ module.exports = Object.freeze({ only_0to9_reg: new RegExp("^[0-9]$"), //匹配仅0-9 //全局常量 - TTS_FILE_RECV_PATH: "./static/xiaoye/live_lastst_reply.txt", //tts文件存储路径 + TTS_FILE_RECV_PATH: "./static/xiaoye/live_latest_reply.txt", //哔哩哔哩字幕文件存储路径 HTML_PATH: "/static/index.html", //首页 }); diff --git a/index.js b/index.js index dfcbe7a2..939f2933 100644 --- a/index.js +++ b/index.js @@ -18,7 +18,8 @@ if (_cn_reg.test(process.cwd())) { /** * 声明依赖与配置 */ -const version = "ChatDACS v3.5.0"; //版本号,会显示在浏览器tab与标题栏 +const versionNumber = "v3.5.1"; //版本号 +const version = `ChatDACS ${versionNumber}`; //系统版本,会显示在web端标题栏 const utils = require("./plugins/system/utils.js"); //载入系统通用模块 const compression = require("compression"); //用于gzip压缩 const express = require("express"); //轻巧的express框架 @@ -33,6 +34,7 @@ const cookie = require("cookie"); const http = require("http").Server(app); const io = require("socket.io")(http); const request = require("request"); +const axios = require("axios").default; const sqlite3 = require("sqlite3").verbose(); const db = new sqlite3.Database("./db.db"); //数据库位置,默认与index.js同目录 const colors = require("colors"); //Console日志染色颜色配置 @@ -325,7 +327,13 @@ io.on("connection", (socket) => { */ function start_qqbot() { app.post(GO_CQHTTP_SERVICE_ANTI_POST_API, (req, res) => { - //禁言1小时以上自动退群 + //响应心跳 + if (req.body.meta_event_type === "heartbeat") { + res.send(); + return 0; + } + + //被禁言1小时以上自动退群 if (req.body.sub_type == "ban" && req.body.user_id == (req.body.message?.self_id ?? QQBOT_QQ)) { if (req.body.duration >= 3599) { request( @@ -425,11 +433,10 @@ function start_qqbot() { break; case "ban": notify = - `${req.body.user_id} 在群 ${req.body.group_id} 被禁言 ${req.body.duration} 秒` - .error; + `${req.body.user_id} 在群 ${req.body.group_id} 被禁言 ${req.body.duration} 秒`.error; break; case "poke": - notify = "戳了一戳".log; + notify = `${req.body.user_id} 戳了一下 ${req.body.target_id}`.log; break; default: res.send(); @@ -475,9 +482,7 @@ function start_qqbot() { Constants.open_ju_reg.test(req.body.message) && Constants.has_qq_reg.test(req.body.message) ) { - let msg_in = req.body.message.split("菊")[1]; - let who = msg_in.split("[CQ:at,qq=")[1]; - who = who.replace("]", "").trim(); + const who = Constants.has_qq_reg.exec(req.body.message)[1]; if (Constants.is_qq_reg.test(who)) { //如果是自己要被张菊,那么张菊 if ((req.body.message?.self_id ?? QQBOT_QQ) == who) { @@ -524,7 +529,7 @@ function start_qqbot() { return 0; //不是这只小夜被张菊的话,嘲讽那只小夜 } else { - res.send({ reply: `${msg_in}说你呢,快张菊!` }); + res.send({ reply: `[CQ:at,qq=${who}] 说你呢,快张菊!` }); return 0; } } @@ -619,9 +624,7 @@ function start_qqbot() { Constants.close_ju_reg.test(req.body.message) && Constants.has_qq_reg.test(req.body.message) ) { - let msg_in = req.body.message.split("菊")[1]; - let who = msg_in.split("[CQ:at,qq=")[1]; - who = who.replace("]", "").trim(); + const who = Constants.has_qq_reg.exec(req.body.message)[1]; if (Constants.is_qq_reg.test(who)) { //如果是自己要被闭菊,那么闭菊 if ((req.body.message?.self_id ?? QQBOT_QQ) == who) { @@ -637,7 +640,7 @@ function start_qqbot() { return 0; //不是这只小夜被闭菊的话,嘲讽那只小夜 } else { - res.send({ reply: `${msg_in}说你呢,快闭菊!` }); + res.send({ reply: `[CQ:at,qq=${who}] 说你呢,快闭菊!` }); return 0; } } @@ -661,8 +664,12 @@ function start_qqbot() { req.body.user_id, req.body?.sender?.nickname, req.body.group_id, - "", - req.body.message?.self_id); + "", //群名暂时还没加 + { + selfId: req.body.message?.self_id, + targetId: req.body.sub_type == "poke" ? req.body.target_id : null, + } + ); if (pluginsReply != "") { const replyToQQ = utils.PluginAnswerToGoCqhttpStyle(pluginsReply); request( @@ -674,26 +681,25 @@ function start_qqbot() { //戳一戳 if ( req.body.sub_type === "poke" && - req.body.target_id == (req.body.message?.self_id ?? QQBOT_QQ) + req.body.target_id == (req.body?.self_id ?? QQBOT_QQ) ) { + logger.info("小夜被戳了".log); c1c_count++; + if (c1c_count > 2) { c1c_count = 0; - let final = "哎呀戳坏了,不理你了 ٩(๑`^`๑)۶"; + const final = "哎呀戳坏了,不理你了 ٩(๑`^`๑)۶"; request( `http://${GO_CQHTTP_SERVICE_API_URL}/send_group_msg?group_id=${req.body.group_id }&message=${encodeURI(final)}`, function (error, _response, _body) { if (!error) { - logger.info( - `${req.body.user_id} 戳了一下 ${req.body.target_id}`.log, - ); request( `http://${GO_CQHTTP_SERVICE_API_URL}/set_group_ban?group_id=${req.body.group_id}&user_id=${req.body.user_id}&duration=10`, function (error, _response, _body) { if (!error) { logger.info( - `小夜生气了,${req.body.user_id} 被禁言`.error, + `小夜戳坏了,${req.body.user_id} 被禁言10s`.error, ); } }, @@ -705,15 +711,7 @@ function start_qqbot() { const final = "请不要戳小小夜 >_<"; request( `http://${GO_CQHTTP_SERVICE_API_URL}/send_group_msg?group_id=${req.body.group_id - }&message=${encodeURI(final)}`, - function (error, _response, _body) { - if (!error) { - logger.info( - `${req.body.user_id} 戳了一下 ${req.body.target_id}`.log, - ); - } - }, - ); + }&message=${encodeURI(final)}`); } return 0; } @@ -2335,6 +2333,21 @@ async function InitConfig() { ); logger.info("world.execute(me);".alert); }); + + /** + * 检查更新 + */ + axios( + "https://api.github.com/repos/Giftia/ChatDACS/releases/latest", + ).then((res) => { + if (res.data.tag_name !== versionNumber) { + logger.info(`当前小夜版本 ${versionNumber},检测到小夜有新版本 ${res.data.tag_name},请前往 https://github.com/Giftia/ChatDACS/releases 更新小夜吧`.alert); + } else { + logger.info(`当前小夜已经是最新版本 ${versionNumber}`.log); + } + }).catch((err) => { + logger.error(`检查更新失败,错误原因: ${err}`.error); + }); } //异步结巴 by@ssp97 @@ -2639,13 +2652,13 @@ function Talents10x(talents) { } //插件系统核心 -async function ProcessExecute(msg, userId, userName, groupId, groupName, option) { +async function ProcessExecute(msg, userId, userName, groupId, groupName, options) { let pluginReturn = ""; for (const i in plugins) { const reg = new RegExp(plugins[i].指令); if (reg.test(msg)) { try { - pluginReturn = await plugins[i].execute(msg, userId, userName, groupId, groupName, option); + pluginReturn = await plugins[i].execute(msg, userId, userName, groupId, groupName, options); } catch (e) { logger.error( `插件 ${plugins[i].插件名} ${plugins[i].版本} 爆炸啦: ${e.stack}`.error, diff --git a/plugin_tester.js b/plugin_tester.js index 4b2429a4..50a43dff 100644 --- a/plugin_tester.js +++ b/plugin_tester.js @@ -1,5 +1,7 @@ +"use strict"; /** - * 插件测试器 + * Author: Giftina: https://github.com/Giftia/ + * 适合 沙雕Ai聊天系统 ChatDACS 的插件测试器 */ const path = require("path"); @@ -23,7 +25,7 @@ colors.setTheme({ }); //载入插件 -console.log("插件测试器 v1.4,用于快速验证插件功能".alert); +console.log("插件测试器 v1.5,用于快速验证插件功能".alert); console.log("开始加载插件……".log); let plugins = require.all({ dir: path.join(process.cwd(), "plugins"), @@ -37,29 +39,28 @@ let plugins = require.all({ }); console.log(plugins); console.log("插件加载完毕√".log); -console.log("现在可以在命令行中输入指令来验证插件功能,按回车提交".warn); -console.log(); +console.log("现在可以在命令行中输入指令来验证插件功能,按回车提交\r\n".warn); rl.on("line", (input) => { run(input); }); -async function run(ask) { - const qNum = 0, gNum = 0; - const result = await ProcessExecute(ask, qNum, gNum); +async function run(msg) { + const defaultUserId = 0, defaultUserName = "", defaultGroupId = 0, defaultGroupName = "", defaultOptions = {}; + const result = await ProcessExecute(msg, defaultUserId, defaultUserName, defaultGroupId, defaultGroupName, defaultOptions); if (result != "") { console.log(result); } } //插件遍历器,每条消息遍历一遍插件 -async function ProcessExecute(msg, _userId, _userName, _groupId, _groupName) { +async function ProcessExecute(msg, userId, userName, groupId, groupName, options) { let pluginReturn = ""; for (const i in plugins) { const reg = new RegExp(plugins[i].指令); if (reg.test(msg)) { try { - pluginReturn = await plugins[i].execute(msg); + pluginReturn = await plugins[i].execute(msg, userId, userName, groupId, groupName, options); } catch (e) { console.log(`插件 ${plugins[i].插件名} ${plugins[i].版本} 爆炸啦:`.error); console.log(e.stack); diff --git a/plugins/go-cqhttp/go-cqhttp.bat b/plugins/go-cqhttp/go-cqhttp.bat index 82e7d5a5..eb81b32d 100644 --- a/plugins/go-cqhttp/go-cqhttp.bat +++ b/plugins/go-cqhttp/go-cqhttp.bat @@ -1,2 +1,2 @@ -%Created by go-cqhttp. DO NOT EDIT ME!% +reg add HKEY_CURRENT_USER\Console /v QuickEdit /t REG_DWORD /d 00000000 /f start cmd /K "go-cqhttp_windows_amd64.exe -faststart" \ No newline at end of file diff --git a/plugins/repeat.js b/plugins/repeat.js index edc3186d..5ea2458a 100644 --- a/plugins/repeat.js +++ b/plugins/repeat.js @@ -1,15 +1,18 @@ -const repeatStartTimes = 2; //复读机复读消息的触发重复次数 +const repeatStartTimes = 2; //当消息重复几次时,复读消息 module.exports = { 插件名: "复读机插件", 指令: "", - 版本: "2.0", + 版本: "2.1", 作者: "Giftina", 描述: `特殊插件,没有主动触发指令。当某条消息重复 ${repeatStartTimes} 次时,'小夜牌高保真复读机' 会跟风复读一次。`, 使用示例: "[某条消息重复了2次]", 预期返回: "[小夜复读了这条消息]", execute: async function (msg, userId, userName, groupId, groupName, options) { + //如果没有msg,说明应该是戳一戳消息 + msg = msg ?? `[CQ:poke,qq=${options.targetId}]`; + //如果没有groupId,则是web端或哔哩哔哩端消息,给个0 groupId = groupId ?? "0"; diff --git a/plugins/status.js b/plugins/status.js index 31f8020a..bcf189b6 100644 --- a/plugins/status.js +++ b/plugins/status.js @@ -1,21 +1,21 @@ module.exports = { 插件名: "系统配置查询插件", 指令: "^[/!]?(status|系统状态)$", - 版本: "2.0", + 版本: "2.1", 作者: "Giftina", 描述: "查询小夜的相关信息与系统当前的主要配置项", 使用示例: "系统状态", 预期返回: "[小夜的相关信息与系统当前的主要配置项]", - execute: async function (msg, userId, userName, groupId, groupName, option) { - const status = await CheckoutStatus(option); + execute: async function (msg, userId, userName, groupId, groupName, options) { + const status = await CheckoutStatus(options.selfId); return { type: "text", content: status }; }, }; //查询配置 -async function CheckoutStatus(option) { - const selfQQId = !option ? QQBOT_QQ : option == "1648468212" ? "1648468212(小小夜本家)" : option; +async function CheckoutStatus(selfId) { + const selfQQId = !selfId ? QQBOT_QQ : selfId == "1648468212" ? "1648468212(小小夜本家)" : selfId; const stat = `宿主架构: ${os.hostname()} ${os.type()} ${os.arch()} 当前配置: diff --git a/static/xiaoye/live_lastst_reply.txt b/static/xiaoye/live_latest_reply.txt similarity index 100% rename from static/xiaoye/live_lastst_reply.txt rename to static/xiaoye/live_latest_reply.txt