diff --git a/src/AI/AI.ts b/src/AI/AI.ts index f1add92..3b73e46 100644 --- a/src/AI/AI.ts +++ b/src/AI/AI.ts @@ -1,12 +1,12 @@ -import { ImageManager } from "./image"; +import { Image, ImageManager } from "./image"; import { ConfigManager } from "../config/config"; -import { replyToSender } from "../utils/utils"; -import { endStream, pollStream, sendChatRequest, startStream } from "./service"; +import { replyToSender, transformMsgId } from "../utils/utils"; +import { endStream, pollStream, sendChatRequest, startStream } from "../service"; import { Context } from "./context"; import { Memory } from "./memory"; import { handleMessages, parseBody } from "../utils/utils_message"; import { ToolManager } from "../tool/tool"; -import { logger } from "./logger"; +import { logger } from "../logger"; import { checkRepeat, handleReply } from "../utils/utils_string"; import { checkContextUpdate } from "../utils/utils_update"; @@ -85,7 +85,24 @@ export class AI { this.tool.toolCallCount = 0; } - async chat(ctx: seal.MsgContext, msg: seal.Message): Promise { + async handleReceipt(ctx: seal.MsgContext, msg: seal.Message, ai: AI, message: string, CQTypes: string[]) { + // 图片偷取,以及图片转文字 + let images: Image[] = []; + if (CQTypes.includes('image')) { + const result = await ImageManager.handleImageMessage(ctx, message); + message = result.message; + images = result.images; + if (ai.imageManager.stealStatus) { + ai.imageManager.updateStolenImages(images); + } + } + + await ai.context.addMessage(ctx, msg, ai, message, images, 'user', transformMsgId(msg.rawId)); + } + + async chat(ctx: seal.MsgContext, msg: seal.Message, reason: string = ''): Promise { + logger.info('触发回复:', reason || '未知原因'); + const { bucketLimit, fillInterval } = ConfigManager.received; // 补充并检查触发次数 if (Date.now() - this.bucket.lastTime > fillInterval * 1000) { @@ -113,6 +130,7 @@ export class AI { } if (stream) { await this.chatStream(ctx, msg); + AIManager.saveAI(this.id); return; } @@ -168,6 +186,7 @@ export class AI { } clearTimeout(timeout); + AIManager.saveAI(this.id); } async chatStream(ctx: seal.MsgContext, msg: seal.Message): Promise { diff --git a/src/AI/context.ts b/src/AI/context.ts index dc70092..777cbeb 100644 --- a/src/AI/context.ts +++ b/src/AI/context.ts @@ -4,7 +4,7 @@ import { Image, ImageManager } from "./image"; import { createCtx, createMsg } from "../utils/utils_seal"; import { levenshteinDistance } from "../utils/utils_string"; import { AI, AIManager } from "./AI"; -import { logger } from "./logger"; +import { logger } from "../logger"; import { transformMsgId } from "../utils/utils"; export interface Message { @@ -194,7 +194,7 @@ export class Context { this.messages.push(message); } - async limitMessages(maxRounds: number) { + limitMessages(maxRounds: number) { const messages = this.messages; let round = 0; for (let i = messages.length - 1; i >= 0; i--) { diff --git a/src/AI/image.ts b/src/AI/image.ts index 07b0ab6..bd64a83 100644 --- a/src/AI/image.ts +++ b/src/AI/image.ts @@ -1,7 +1,7 @@ import { ConfigManager } from "../config/config"; -import { sendITTRequest } from "./service"; +import { sendITTRequest } from "../service"; import { generateId } from "../utils/utils"; -import { logger } from "./logger"; +import { logger } from "../logger"; export class Image { id: string; diff --git a/src/AI/memory.ts b/src/AI/memory.ts index 1041fd4..369b986 100644 --- a/src/AI/memory.ts +++ b/src/AI/memory.ts @@ -3,8 +3,8 @@ import { ConfigManager } from "../config/config"; import { AI, AIManager } from "./AI"; import { Context, Message } from "./context"; import { generateId } from "../utils/utils"; -import { logger } from "./logger"; -import { fetchData } from "./service"; +import { logger } from "../logger"; +import { fetchData } from "../service"; import { parseBody } from "../utils/utils_message"; import { ToolManager } from "../tool/tool"; diff --git a/src/index.ts b/src/index.ts index baf3875..3b5c6ad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,34 +1,24 @@ import { AIManager } from "./AI/AI"; -import { Image, ImageManager } from "./AI/image"; +import { ImageManager } from "./AI/image"; import { ToolManager } from "./tool/tool"; -import { timerQueue } from "./tool/tool_time"; import { ConfigManager, CQTYPESALLOW } from "./config/config"; -import { transformMsgId } from "./utils/utils"; -import { createMsg, createCtx } from "./utils/utils_seal"; import { buildSystemMessage } from "./utils/utils_message"; import { triggerConditionMap } from "./tool/tool_trigger"; -import { logger } from "./AI/logger"; +import { logger } from "./logger"; import { transformTextToArray } from "./utils/utils_string"; import { checkUpdate } from "./utils/utils_update"; -import { get_chart_url } from "./AI/service"; +import { get_chart_url } from "./service"; +import { TimerManager } from "./timer"; function main() { ConfigManager.registerConfig(); + checkUpdate(); AIManager.getUsageMap(); ToolManager.registerTool(); - checkUpdate(); + TimerManager.init(); const ext = ConfigManager.ext; - try { - JSON.parse(ext.storageGet(`timerQueue`) || '[]') - .forEach((item: any) => { - timerQueue.push(item); - }); - } catch (e) { - logger.error('在获取timerQueue时出错', e); - } - const cmdAI = seal.ext.newCmdItemInfo(); cmdAI.name = 'ai'; // 指令名字,可用中文 cmdAI.help = `帮助: @@ -530,10 +520,11 @@ function main() { case 'sum': { const { shortMemorySummaryRound } = ConfigManager.memory; ai.context.summaryCounter = 0; - ai.memory.updateShortMemory(ctx, msg, ai, ai.context.messages.slice(0, shortMemorySummaryRound)).then(() => { - const s = ai.memory.shortMemory.map((item, index) => `${index + 1}. ${item}`).join('\n'); - seal.replyToSender(ctx, msg, s || '无'); - }); + ai.memory.updateShortMemory(ctx, msg, ai, ai.context.messages.slice(0, shortMemorySummaryRound)) + .then(() => { + const s = ai.memory.shortMemory.map((item, index) => `${index + 1}. ${item}`).join('\n'); + seal.replyToSender(ctx, msg, s || '无'); + }); return ret; } default: { @@ -674,9 +665,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { } tool.solve(ctx, msg, ai, args) - .then(s => { - seal.replyToSender(ctx, msg, s); - }); + .then(s => seal.replyToSender(ctx, msg, s)); return ret; } catch (e) { const s = `调用函数 (${val2}) 失败:${e.message}`; @@ -841,13 +830,8 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { const val3 = cmdArgs.getArgN(3); if (val3 === 'chart') { - get_chart_url('year', obj).then(url => { - if (!url) { - seal.replyToSender(ctx, msg, `图表生成失败`); - return; - } - seal.replyToSender(ctx, msg, `[CQ:image,file=${url}]`); - }); + get_chart_url('year', obj) + .then(url => seal.replyToSender(ctx, msg, url ? `[CQ:image,file=${url}]` : '图表生成失败')); return ret; } @@ -913,13 +897,8 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { const val3 = cmdArgs.getArgN(3); if (val3 === 'chart') { - get_chart_url('month', obj).then(url => { - if (!url) { - seal.replyToSender(ctx, msg, `图表生成失败`); - return; - } - seal.replyToSender(ctx, msg, `[CQ:image,file=${url}]`); - }); + get_chart_url('month', obj) + .then(url => seal.replyToSender(ctx, msg, url ? `[CQ:image,file=${url}]` : '图表生成失败')); return ret; } @@ -1019,13 +998,8 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { const val4 = cmdArgs.getArgN(4); if (val4 === 'chart') { - get_chart_url('year', obj).then(url => { - if (!url) { - seal.replyToSender(ctx, msg, `图表生成失败`); - return; - } - seal.replyToSender(ctx, msg, `[CQ:image,file=${url}]`); - }); + get_chart_url('year', obj) + .then(url => seal.replyToSender(ctx, msg, url ? `[CQ:image,file=${url}]` : '图表生成失败')); return ret; } @@ -1091,13 +1065,8 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { const val4 = cmdArgs.getArgN(4); if (val4 === 'chart') { - get_chart_url('month', obj).then(url => { - if (!url) { - seal.replyToSender(ctx, msg, `图表生成失败`); - return; - } - seal.replyToSender(ctx, msg, `[CQ:image,file=${url}]`); - }); + get_chart_url('month', obj) + .then(url => seal.replyToSender(ctx, msg, url ? `[CQ:image,file=${url}]` : '图表生成失败')); return ret; } @@ -1152,9 +1121,8 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { return ret; } - ai.stopCurrentChatStream().then(() => { - seal.replyToSender(ctx, msg, '已停止当前对话'); - }); + ai.stopCurrentChatStream() + .then(() => seal.replyToSender(ctx, msg, '已停止当前对话')); return ret; } default: { @@ -1205,13 +1173,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { case 'stl': case 'stolen': { ai.imageManager.drawStolenImageFile() - .then(file => { - if (!file) { - seal.replyToSender(ctx, msg, '暂无偷取图片'); - } else { - seal.replyToSender(ctx, msg, `[CQ:image,file=${file}]`); - } - }); + .then(file => seal.replyToSender(ctx, msg, file ? `[CQ:image,file=${file}]` : '暂无偷取图片')); return ret; } case 'save': { @@ -1224,13 +1186,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { } case 'all': { ai.imageManager.drawImageFile() - .then(image => { - if (!image) { - seal.replyToSender(ctx, msg, '暂无图片'); - } else { - seal.replyToSender(ctx, msg, `[CQ:image,file=${image}]`); - } - }); + .then(file => seal.replyToSender(ctx, msg, file ? `[CQ:image,file=${file}]` : '暂无图片')); return ret; } default: { @@ -1304,13 +1260,11 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { .then(url => { if (!url) { seal.replyToSender(ctx, msg, '图片偷取为空'); - } else { - const text = cmdArgs.getRestArgsFrom(3); - ImageManager.imageToText(url, text) - .then(s => { - seal.replyToSender(ctx, msg, `[CQ:image,file=${url}]\n` + s); - }); + return; } + const text = cmdArgs.getRestArgsFrom(3); + ImageManager.imageToText(url, text) + .then(s => seal.replyToSender(ctx, msg, `[CQ:image,file=${url}]\n` + s)); }); } else { const match = val2.match(/\[CQ:image,file=(.*?)\]/); @@ -1321,9 +1275,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { const url = match[1]; const text = cmdArgs.getRestArgsFrom(3); ImageManager.imageToText(url, text) - .then(s => { - seal.replyToSender(ctx, msg, `[CQ:image,file=${url}]\n` + s); - }); + .then(s => seal.replyToSender(ctx, msg, `[CQ:image,file=${url}]\n` + s)); } return ret; } @@ -1394,7 +1346,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { ext.cmdMap['img'] = cmdImage; //接受非指令消息 - ext.onNotCommandReceived = async (ctx, msg) => { + ext.onNotCommandReceived = (ctx, msg): void | Promise => { try { const { disabledInPrivate, globalStandby, triggerRegexes, ignoreRegexes, triggerCondition } = ConfigManager.received; if (ctx.isPrivate && disabledInPrivate) { @@ -1406,7 +1358,6 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { const id = ctx.isPrivate ? userId : groupId; let message = msg.message; - let images: Image[] = []; const ai = AIManager.getAI(id); // 非指令消息忽略 @@ -1444,22 +1395,8 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { if (pattern && pattern.test(message)) { const fmtCondition = parseInt(seal.format(ctx, `{${triggerCondition}}`)); if (fmtCondition === 1) { - // 图片偷取,以及图片转文字 - if (CQTypes.includes('image')) { - const result = await ImageManager.handleImageMessage(ctx, message); - message = result.message; - images = result.images; - if (ai.imageManager.stealStatus) { - ai.imageManager.updateStolenImages(images); - } - } - - await ai.context.addMessage(ctx, msg, ai, message, images, 'user', transformMsgId(msg.rawId)); - - logger.info('非指令触发回复'); - await ai.chat(ctx, msg); - AIManager.saveAI(id); - return; + return ai.handleReceipt(ctx, msg, ai, message, CQTypes) + .then(() => ai.chat(ctx, msg, '非指令')); } } } @@ -1475,71 +1412,40 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { continue; } - // 图片偷取,以及图片转文字 - if (CQTypes.includes('image')) { - const result = await ImageManager.handleImageMessage(ctx, message); - message = result.message; - images = result.images; - if (ai.imageManager.stealStatus) { - ai.imageManager.updateStolenImages(images); - } - } - - await ai.context.addMessage(ctx, msg, ai, message, images, 'user', transformMsgId(msg.rawId)); - await ai.context.addSystemUserMessage('触发原因提示', condition.reason, []); - triggerConditionMap[id].splice(i, 1); - - logger.info('AI设定触发条件触发回复'); - await ai.chat(ctx, msg); - AIManager.saveAI(id); - return; + return ai.handleReceipt(ctx, msg, ai, message, CQTypes) + .then(() => ai.context.addSystemUserMessage('触发原因提示', condition.reason, [])) + .then(() => triggerConditionMap[id].splice(i, 1)) + .then(() => ai.chat(ctx, msg, 'AI设定触发条件')); } } // 开启任一模式时 const pr = ai.privilege; if (pr.standby || globalStandby) { - // 图片偷取,以及图片转文字 - if (CQTypes.includes('image')) { - const result = await ImageManager.handleImageMessage(ctx, message); - message = result.message; - images = result.images; - if (ai.imageManager.stealStatus) { - ai.imageManager.updateStolenImages(images); - } - } - - await ai.context.addMessage(ctx, msg, ai, message, images, 'user', transformMsgId(msg.rawId)); - } - - if (pr.counter > -1) { - ai.context.counter += 1; - if (ai.context.counter >= pr.counter) { - ai.context.counter = 0; - logger.info('计数器触发回复'); - await ai.chat(ctx, msg); - AIManager.saveAI(id); - return; - } - } + ai.handleReceipt(ctx, msg, ai, message, CQTypes) + .then((): void | Promise => { + if (pr.counter > -1) { + ai.context.counter += 1; + if (ai.context.counter >= pr.counter) { + ai.context.counter = 0; + return ai.chat(ctx, msg, '计数器'); + } + } - if (pr.prob > -1) { - const ran = Math.random() * 100; - if (ran <= pr.prob) { - logger.info('概率触发回复'); - await ai.chat(ctx, msg); - AIManager.saveAI(id); - return; - } - } + if (pr.prob > -1) { + const ran = Math.random() * 100; + if (ran <= pr.prob) { + return ai.chat(ctx, msg, '概率'); + } + } - if (pr.timer > -1) { - ai.context.timer = setTimeout(async () => { - ai.context.timer = null; - logger.info('计时器触发回复'); - await ai.chat(ctx, msg); - AIManager.saveAI(id); - }, pr.timer * 1000 + Math.floor(Math.random() * 500)); + if (pr.timer > -1) { + ai.context.timer = setTimeout(() => { + ai.context.timer = null; + ai.chat(ctx, msg, '计时器'); + }, pr.timer * 1000 + Math.floor(Math.random() * 500)); + } + }); } } } catch (e) { @@ -1548,7 +1454,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { } //接受的指令 - ext.onCommandReceived = async (ctx, msg, cmdArgs) => { + ext.onCommandReceived = (ctx, msg, cmdArgs) => { try { if (ToolManager.cmdArgs === null) { ToolManager.cmdArgs = cmdArgs; @@ -1563,23 +1469,12 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { const ai = AIManager.getAI(id); let message = msg.message; - let images: Image[] = []; const CQTypes = transformTextToArray(message).filter(item => item.type !== 'text').map(item => item.type); if (CQTypes.length === 0 || CQTypes.every(item => CQTYPESALLOW.includes(item))) { const pr = ai.privilege; if (pr.standby) { - // 图片偷取,以及图片转文字 - if (CQTypes.includes('image')) { - const result = await ImageManager.handleImageMessage(ctx, message); - message = result.message; - images = result.images; - if (ai.imageManager.stealStatus) { - ai.imageManager.updateStolenImages(images); - } - } - - await ai.context.addMessage(ctx, msg, ai, message, images, 'user', transformMsgId(msg.rawId)); + ai.handleReceipt(ctx, msg, ai, message, CQTypes); } } } @@ -1589,7 +1484,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { } //骰子发送的消息 - ext.onMessageSend = async (ctx, msg) => { + ext.onMessageSend = (ctx, msg) => { try { const uid = ctx.player.userId; const gid = ctx.group.groupId; @@ -1598,7 +1493,6 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { const ai = AIManager.getAI(id); let message = msg.message; - let images: Image[] = []; ai.tool.listen.resolve?.(message); // 将消息传递给监听工具 @@ -1613,18 +1507,7 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { if (CQTypes.length === 0 || CQTypes.every(item => CQTYPESALLOW.includes(item))) { const pr = ai.privilege; if (pr.standby) { - // 图片偷取,以及图片转文字 - if (CQTypes.includes('image')) { - const result = await ImageManager.handleImageMessage(ctx, message); - message = result.message; - images = result.images; - if (ai.imageManager.stealStatus) { - ai.imageManager.updateStolenImages(images); - } - } - - await ai.context.addMessage(ctx, msg, ai, message, images, 'assistant', transformMsgId(msg.rawId)); - return; + ai.handleReceipt(ctx, msg, ai, message, CQTypes); } } } @@ -1632,66 +1515,6 @@ ${Object.keys(tool.info.function.parameters.properties).map(key => { logger.error(`获取发送消息处理出错,错误信息:${e.message}`); } } - - let isTaskRunning = false; - seal.ext.registerTask(ext, "cron", "* * * * *", async () => { - try { - if (timerQueue.length === 0) { - return; - } - - if (isTaskRunning) { - logger.info('定时器任务正在运行,跳过'); - return; - } - - isTaskRunning = true; - - let changed = false; - for (let i = 0; i < timerQueue.length && i >= 0; i++) { - const timestamp = timerQueue[i].timestamp; - if (timestamp > Math.floor(Date.now() / 1000)) { - continue; - } - - const setTime = timerQueue[i].setTime; - const content = timerQueue[i].content; - const id = timerQueue[i].id; - const messageType = timerQueue[i].messageType; - const uid = timerQueue[i].uid; - const gid = timerQueue[i].gid; - const epId = timerQueue[i].epId; - const msg = createMsg(messageType, uid, gid); - const ctx = createCtx(epId, msg); - const ai = AIManager.getAI(id); - - const s = `你设置的定时器触发了,请按照以下内容发送回复: -定时器设定时间:${setTime} -当前触发时间:${new Date().toLocaleString()} -提示内容:${content}`; - - await ai.context.addSystemUserMessage("定时器触发提示", s, []); - - logger.info('定时任务触发回复'); - await ai.chat(ctx, msg); - AIManager.saveAI(id); - - timerQueue.splice(i, 1); - i--; - changed = true; - - await new Promise(resolve => setTimeout(resolve, 2000)); - } - - if (changed) { - ext.storageSet(`timerQueue`, JSON.stringify(timerQueue)); - } - - isTaskRunning = false; - } catch (e) { - logger.error(`定时任务处理出错,错误信息:${e.message}`); - } - }) } main(); diff --git a/src/AI/logger.ts b/src/logger.ts similarity index 96% rename from src/AI/logger.ts rename to src/logger.ts index 532e533..cb66e3a 100644 --- a/src/AI/logger.ts +++ b/src/logger.ts @@ -1,4 +1,4 @@ -import { ConfigManager } from "../config/config"; +import { ConfigManager } from "./config/config"; class Logger { name: string; diff --git a/src/AI/service.ts b/src/service.ts similarity index 98% rename from src/AI/service.ts rename to src/service.ts index b2c32ff..110cd61 100644 --- a/src/AI/service.ts +++ b/src/service.ts @@ -1,8 +1,8 @@ -import { AI, AIManager } from "./AI"; -import { ToolCall, ToolManager } from "../tool/tool"; -import { ConfigManager } from "../config/config"; -import { handleMessages, parseBody } from "../utils/utils_message"; -import { ImageManager } from "./image"; +import { AI, AIManager } from "./AI/AI"; +import { ToolCall, ToolManager } from "./tool/tool"; +import { ConfigManager } from "./config/config"; +import { handleMessages, parseBody } from "./utils/utils_message"; +import { ImageManager } from "./AI/image"; import { logger } from "./logger"; export async function sendChatRequest(ctx: seal.MsgContext, msg: seal.Message, ai: AI, messages: { diff --git a/src/timer.ts b/src/timer.ts new file mode 100644 index 0000000..13f8515 --- /dev/null +++ b/src/timer.ts @@ -0,0 +1,125 @@ +import { ConfigManager } from "./config/config"; +import { createCtx, createMsg } from "./utils/utils_seal"; +import { AI, AIManager } from "./AI/AI"; +import { logger } from "./logger"; + +export interface TimerInfo { + id: string, + messageType: 'private' | 'group', + uid: string, + gid: string, + epId: string, + timestamp: number, + setTime: string, + content: string +}; + +export class TimerManager { + static timerQueue: TimerInfo[] = []; + static isTaskRunning = false; + static intervalId: number | null = null; + + static getTimerQueue() { + try { + JSON.parse(ConfigManager.ext.storageGet(`timerQueue`) || '[]') + .forEach((item: any) => { + this.timerQueue.push(item); + }); + } catch (e) { + logger.error('在获取timerQueue时出错', e); + } + } + + static saveTimerQueue() { + ConfigManager.ext.storageSet(`timerQueue`, JSON.stringify(this.timerQueue)); + } + + static addTimer(ctx: seal.MsgContext, msg: seal.Message, ai: AI, t: number, content: string) { + this.timerQueue.push({ + id: ai.id, + messageType: msg.messageType, + uid: ctx.player.userId, + gid: ctx.group.groupId, + epId: ctx.endPoint.userId, + timestamp: Math.floor(Date.now() / 1000) + t * 60, + setTime: new Date().toLocaleString(), + content: content + }) + + this.saveTimerQueue(); + + if (!this.intervalId) { + logger.info('定时器任务启动'); + this.executeTask(); + } + } + + static async task() { + try { + if (this.isTaskRunning) { + logger.info('定时器任务正在运行,跳过'); + return; + } + + this.isTaskRunning = true; + + const remainingTimers: TimerInfo[] = []; + let changed = false; + for (const timer of this.timerQueue) { + const timestamp = timer.timestamp; + if (timestamp > Math.floor(Date.now() / 1000)) { + remainingTimers.push(timer); + continue; + } + + const { id, messageType, uid, gid, epId, setTime, content } = timer; + const msg = createMsg(messageType, uid, gid); + const ctx = createCtx(epId, msg); + const ai = AIManager.getAI(id); + + const s = `你设置的定时器触发了,请按照以下内容发送回复: +定时器设定时间:${setTime} +当前触发时间:${new Date().toLocaleString()} +提示内容:${content}`; + + await ai.context.addSystemUserMessage("定时器触发提示", s, []); + await ai.chat(ctx, msg, '定时任务'); + + changed = true; + await new Promise(resolve => setTimeout(resolve, 2000)); + } + + if (changed) { + this.timerQueue = remainingTimers; + this.saveTimerQueue(); + } + + this.isTaskRunning = false; + } catch (e) { + logger.error(`定时任务处理出错,错误信息:${e.message}`); + } + } + + static async executeTask() { + if (this.timerQueue.length === 0) { + this.destroy(); + return; + } + + await this.task(); + this.intervalId = setTimeout(this.executeTask.bind(this), 5000); + } + + static destroy() { + if (this.intervalId) { + clearTimeout(this.intervalId); + this.intervalId = null; + logger.info('定时器任务已停止'); + } + } + + static init() { + this.getTimerQueue(); + this.executeTask(); + } +} \ No newline at end of file diff --git a/src/tool/tool.ts b/src/tool/tool.ts index b69c17d..8087d6d 100644 --- a/src/tool/tool.ts +++ b/src/tool/tool.ts @@ -21,7 +21,7 @@ import { registerGetContext } from "./tool_context" import { registerGetGroupMemberList, registerGetList, registerSearchChat, registerSearchCommonGroup } from "./tool_qq_list" import { registerSetTriggerCondition } from "./tool_trigger" import { registerMusicPlay } from "./tool_music" -import { logger } from "../AI/logger" +import { logger } from "../logger" export interface ToolInfo { type: "function", diff --git a/src/tool/tool_ban.ts b/src/tool/tool_ban.ts index 5b44d1b..0ae8d7f 100644 --- a/src/tool/tool_ban.ts +++ b/src/tool/tool_ban.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { Tool, ToolInfo, ToolManager } from "./tool"; diff --git a/src/tool/tool_deck.ts b/src/tool/tool_deck.ts index 9663ddf..f887e13 100644 --- a/src/tool/tool_deck.ts +++ b/src/tool/tool_deck.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { Tool, ToolInfo, ToolManager } from "./tool" diff --git a/src/tool/tool_essence_msg.ts b/src/tool/tool_essence_msg.ts index c22621f..bf8c9d2 100644 --- a/src/tool/tool_essence_msg.ts +++ b/src/tool/tool_essence_msg.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { transformMsgIdBack } from "../utils/utils"; import { ToolInfo, Tool, ToolManager } from "./tool"; diff --git a/src/tool/tool_group_sign.ts b/src/tool/tool_group_sign.ts index f40828f..6f2a8a0 100644 --- a/src/tool/tool_group_sign.ts +++ b/src/tool/tool_group_sign.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { Tool, ToolInfo, ToolManager } from "./tool"; export function registerGroupSign() { diff --git a/src/tool/tool_image.ts b/src/tool/tool_image.ts index 1b66757..afeb2d4 100644 --- a/src/tool/tool_image.ts +++ b/src/tool/tool_image.ts @@ -1,5 +1,5 @@ import { Image, ImageManager } from "../AI/image"; -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { Tool, ToolInfo, ToolManager } from "./tool"; diff --git a/src/tool/tool_message.ts b/src/tool/tool_message.ts index ac96a94..86f736a 100644 --- a/src/tool/tool_message.ts +++ b/src/tool/tool_message.ts @@ -1,6 +1,6 @@ import { AIManager } from "../AI/AI"; import { Image, ImageManager } from "../AI/image"; -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager, CQTYPESALLOW } from "../config/config"; import { replyToSender, transformMsgId, transformMsgIdBack } from "../utils/utils"; import { createCtx, createMsg } from "../utils/utils_seal"; diff --git a/src/tool/tool_music.ts b/src/tool/tool_music.ts index f65313c..b773504 100644 --- a/src/tool/tool_music.ts +++ b/src/tool/tool_music.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { Tool, ToolInfo, ToolManager } from "./tool"; export function registerMusicPlay() { diff --git a/src/tool/tool_person_info.ts b/src/tool/tool_person_info.ts index 3ea1b0f..e083e84 100644 --- a/src/tool/tool_person_info.ts +++ b/src/tool/tool_person_info.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { createMsg, createCtx } from "../utils/utils_seal"; import { Tool, ToolInfo, ToolManager } from "./tool"; diff --git a/src/tool/tool_qq_list.ts b/src/tool/tool_qq_list.ts index 26284e6..8d18d59 100644 --- a/src/tool/tool_qq_list.ts +++ b/src/tool/tool_qq_list.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { Tool, ToolInfo, ToolManager } from "./tool"; diff --git a/src/tool/tool_rename.ts b/src/tool/tool_rename.ts index cb3c131..17c0e59 100644 --- a/src/tool/tool_rename.ts +++ b/src/tool/tool_rename.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { createMsg, createCtx } from "../utils/utils_seal"; import { Tool, ToolInfo, ToolManager } from "./tool"; diff --git a/src/tool/tool_time.ts b/src/tool/tool_time.ts index 761b02a..73e0f98 100644 --- a/src/tool/tool_time.ts +++ b/src/tool/tool_time.ts @@ -1,17 +1,7 @@ +import { TimerManager } from "../timer"; import { ConfigManager } from "../config/config"; import { Tool, ToolInfo, ToolManager } from "./tool"; -export const timerQueue: { - id: string, - messageType: 'private' | 'group', - uid: string, - gid: string, - epId: string, - timestamp: number, - setTime: string, - content: string -}[] = []; - export function registerGetTime() { const info: ToolInfo = { type: "function", @@ -75,18 +65,7 @@ export function registerSetTimer() { return '时间应为数字'; } - timerQueue.push({ - id: ai.id, - messageType: msg.messageType, - uid: ctx.player.userId, - gid: ctx.group.groupId, - epId: ctx.endPoint.userId, - timestamp: Math.floor(Date.now() / 1000) + t * 60, - setTime: new Date().toLocaleString(), - content: content - }) - - ConfigManager.ext.storageSet(`timerQueue`, JSON.stringify(timerQueue)); + TimerManager.addTimer(ctx, msg, ai, t, content); return `设置定时器成功,请等待`; } @@ -111,7 +90,7 @@ export function registerShowTimerList() { const tool = new Tool(info); tool.solve = async (_, __, ai, ___) => { - const timers = timerQueue.filter(t => t.id === ai.id); + const timers = TimerManager.timerQueue.filter(t => t.id === ai.id); if (timers.length === 0) { return '当前对话没有定时器'; @@ -153,7 +132,7 @@ export function registerCancelTimer() { const tool = new Tool(info); tool.solve = async (_, __, ai, args) => { const { index_list } = args; - const timers = timerQueue.filter(t => t.id === ai.id); + const timers = TimerManager.timerQueue.filter(t => t.id === ai.id); if (timers.length === 0) { return '当前对话没有定时器'; @@ -168,15 +147,15 @@ export function registerCancelTimer() { return `序号${index}超出范围`; } - const i = timerQueue.indexOf(timers[index - 1]); + const i = TimerManager.timerQueue.indexOf(timers[index - 1]); if (i === -1) { return `出错了:找不到序号${index}的定时器`; } - timerQueue.splice(i, 1); + TimerManager.timerQueue.splice(i, 1); } - ConfigManager.ext.storageSet(`timerQueue`, JSON.stringify(timerQueue)); + ConfigManager.ext.storageSet(`TimerMatimerQueue`, JSON.stringify(TimerManager.timerQueue)); return '定时器取消成功'; } diff --git a/src/tool/tool_voice.ts b/src/tool/tool_voice.ts index 7db3130..a0bd1ed 100644 --- a/src/tool/tool_voice.ts +++ b/src/tool/tool_voice.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { Tool, ToolInfo, ToolManager } from "./tool"; diff --git a/src/tool/tool_web_search.ts b/src/tool/tool_web_search.ts index 5dde285..c090aeb 100644 --- a/src/tool/tool_web_search.ts +++ b/src/tool/tool_web_search.ts @@ -1,4 +1,4 @@ -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { Tool, ToolInfo, ToolManager } from "./tool"; diff --git a/src/AI/update.ts b/src/update.ts similarity index 95% rename from src/AI/update.ts rename to src/update.ts index 67fe2b3..0298df5 100644 --- a/src/AI/update.ts +++ b/src/update.ts @@ -1,7 +1,8 @@ // 版本更新日志,格式为 "版本号": "更新内容",版本号格式为 "x.y.z",按照时间顺序从新到旧排列。 export const updateInfo = { "4.10.1": `- 修复了构建ctx时,isPrivate始终为0的问题 -- 新增保存图片功能`, +- 新增保存图片功能 +- 重构了定时任务的执行`, "4.10.0": `- 新增了全局待机模式配置项 - 修改了部分正则和部分默认配置项 - 修复了无法调用内置指令 diff --git a/src/utils/utils.ts b/src/utils/utils.ts index f1aa600..f1294cc 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,5 +1,5 @@ import { AI } from "../AI/AI"; -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { transformTextToArray } from "./utils_string"; diff --git a/src/utils/utils_message.ts b/src/utils/utils_message.ts index 7638fbe..47e5593 100644 --- a/src/utils/utils_message.ts +++ b/src/utils/utils_message.ts @@ -1,7 +1,7 @@ import Handlebars from "handlebars"; import { AI } from "../AI/AI"; import { Message } from "../AI/context"; -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { ToolInfo } from "../tool/tool"; diff --git a/src/utils/utils_string.ts b/src/utils/utils_string.ts index a4f9a84..1c109ed 100644 --- a/src/utils/utils_string.ts +++ b/src/utils/utils_string.ts @@ -1,7 +1,7 @@ import Handlebars from "handlebars"; import { Context } from "../AI/context"; import { Image, ImageManager } from "../AI/image"; -import { logger } from "../AI/logger"; +import { logger } from "../logger"; import { ConfigManager } from "../config/config"; import { transformMsgIdBack } from "./utils"; import { AI } from "../AI/AI"; diff --git a/src/utils/utils_update.ts b/src/utils/utils_update.ts index 274c497..78435e0 100644 --- a/src/utils/utils_update.ts +++ b/src/utils/utils_update.ts @@ -1,6 +1,6 @@ import { AI, AIManager } from "../AI/AI"; -import { logger } from "../AI/logger"; -import { updateInfo } from "../AI/update"; +import { logger } from "../logger"; +import { updateInfo } from "../update"; import { ConfigManager, VERSION } from "../config/config"; /**