From bfc55df6a6f9354d02a42966872e97bb751c4302 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Sun, 26 Mar 2023 16:15:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=9D=E8=AF=95=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=AE=BE=E5=AE=9A=E5=88=86=E4=BA=AB=E5=92=8C=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=20(#286)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 尝试支持设定分享和导入 * fix: 设定分享和洗脑操作的帮助 * fix: 导入设定失败的提示 * fix: 允许覆盖修改 * fix: version --- apps/help.js | 30 +++++- apps/prompts.js | 240 +++++++++++++++++++++++++++++++++++++++++++++-- utils/common.js | 4 + utils/config.js | 2 +- utils/prompts.js | 8 ++ 5 files changed, 268 insertions(+), 16 deletions(-) diff --git a/apps/help.js b/apps/help.js index 87572c2..aa5592d 100644 --- a/apps/help.js +++ b/apps/help.js @@ -194,28 +194,48 @@ let helpData = [ { icon: 'coin', title: '#chatgpt添加设定', - desc: '添加一个设定,分此输入设定名称和设定内容' + desc: '添加一个设定,分此输入设定名称和设定内容。如果名字已存在,则会覆盖(相当于修改)' }, { icon: 'switch', title: '#chatgpt使用设定【设定名】', - desc: '使用某个设定' + desc: '使用某个设定。如果处于自设定模式,会自动修改洗脑名称。' }, { icon: 'confirm', title: '#chatgpt(上传|分享|共享)设定', - desc: '敬请期待' + desc: '上传设定' + }, + { + icon: 'confirm', + title: '#chatgpt浏览设定+关键词', + desc: '搜索公开的设定' }, { icon: 'confirm', title: '#chatgpt导入设定', - desc: '敬请期待' + desc: '导入其他人分享的设定。注意:相同名字的设定,会覆盖本地已有的设定' + }, + { + icon: 'confirm', + title: '#chatgpt开启/关闭洗脑', + desc: '开启或关闭洗脑' + }, + { + icon: 'confirm', + title: '#chatgpt设置洗脑强度+【强度】', + desc: '设置洗脑强度' + }, + { + icon: 'confirm', + title: '#chatgpt设置洗脑名称+【名称】', + desc: '设置洗脑名称' }, { icon: 'help', title: '#chatgpt设定帮助', desc: '设定帮助' - }, + } ] }, { diff --git a/apps/prompts.js b/apps/prompts.js index 2591887..b95ef70 100644 --- a/apps/prompts.js +++ b/apps/prompts.js @@ -2,8 +2,8 @@ import plugin from '../../../lib/plugins/plugin.js' import fs from 'fs' import _ from 'lodash' import { Config } from '../utils/config.js' -import {limitString, makeForwardMsg} from '../utils/common.js' -import { getPromptByName, readPrompts, saveOnePrompt } from '../utils/prompts.js' +import { getMasterQQ, limitString, makeForwardMsg } from '../utils/common.js' +import { deleteOnePrompt, getPromptByName, readPrompts, saveOnePrompt } from '../utils/prompts.js' export class help extends plugin { constructor (e) { super({ @@ -32,6 +32,11 @@ export class help extends plugin { fnc: 'addPrompt', permission: 'master' }, + { + reg: '^#(chatgpt|ChatGPT)(删除|移除)设定', + fnc: 'removePrompt', + permission: 'master' + }, { reg: '^#(chatgpt|ChatGPT)(上传|分享|共享)设定', fnc: 'uploadPrompt', @@ -42,10 +47,29 @@ export class help extends plugin { fnc: 'importPrompt', permission: 'master' }, + { + reg: '^#(chatgpt|ChatGPT)(在线)?(浏览|查找)设定', + fnc: 'browsePrompt' + }, { reg: '^#(chatgpt|ChatGPT)设定帮助$', fnc: 'helpPrompt', permission: 'master' + }, + { + reg: '^#(chatgpt|ChatGPT)(开启|关闭)洗脑$', + fnc: 'setSydneyBrainWash', + permission: 'master' + }, + { + reg: '^#(chatgpt|ChatGPT)(设置)?洗脑强度', + fnc: 'setSydneyBrainWashStrength', + permission: 'master' + }, + { + reg: '^#(chatgpt|ChatGPT)(设置)?洗脑名称', + fnc: 'setSydneyBrainWashName', + permission: 'master' } ] }) @@ -123,10 +147,52 @@ export class help extends plugin { if (keyMap[use]) { Config[keyMap[use]] = prompt.content await redis.set(`CHATGPT:PROMPT_USE_${use}`, promptName) - await e.reply(`你当前正在使用${use}模式,已将该模式设定应用为"${promptName}。更该设定后建议结束对话以使设定更好生效"`, true) + await e.reply(`你当前正在使用${use}模式,已将该模式设定应用为"${promptName}"。更该设定后建议结束对话以使设定更好生效`, true) } else { await e.reply(`你当前正在使用${use}模式,该模式不支持设定`, true) } + if (use === 'Custom') { + Config.sydneyBrainWashName = promptName + } + } + + async setSydneyBrainWashName (e) { + let name = e.msg.replace(/^#(chatgpt|ChatGPT)设置洗脑名称/, '') + if (name) { + Config.sydneyBrainWashName = name + await e.reply('操作成功', true) + } + } + + async setSydneyBrainWash (e) { + if (e.msg.indexOf('开启') > -1) { + Config.sydneyBrainWash = true + } else { + Config.sydneyBrainWash = false + } + await e.reply('操作成功', true) + } + + async setSydneyBrainWashStrength (e) { + let strength = e.msg.replace(/^#(chatgpt|ChatGPT)(设置)?洗脑强度/, '') + if (!strength) { + return + } + strength = parseInt(strength) + if (strength > 0) { + Config.sydneyBrainWashStrength = strength + await e.reply('操作成功', true) + } + } + + async removePrompt (e) { + let promptName = e.msg.replace(/^#(chatgpt|ChatGPT)(删除|移除)设定/, '') + if (!promptName) { + await e.reply('你要删除哪个设定呢?') + return + } + deleteOnePrompt(promptName) + await e.reply(`设定${promptName}已删除。`) } async addPrompt (e) { @@ -139,9 +205,9 @@ export class help extends plugin { let name = this.e.msg let prompt = getPromptByName(name) if (prompt) { - await this.e.reply('该设定已存在', true) - this.finish('addPromptName') - return + await this.e.reply('【警告】该设定已存在,新增的内容将会覆盖之前的设定', true) + // this.finish('addPromptName') + // return } await redis.set('CHATGPT:ADD_PROMPT_NAME', name) await this.reply('请输入设定内容', true) @@ -159,12 +225,166 @@ export class help extends plugin { this.finish('addPromptContext') } - async uploadPrompt () { - await this.reply('敬请期待', true) + async uploadPrompt (e) { + if (await redis.get('CHATGPT:UPLOAD_PROMPT')) { + await this.reply('本机器人存在其他人正在上传设定,请稍后') + return + } + let use = await redis.get('CHATGPT:USE') || 'api' + if (use.toLowerCase() === 'bing') { + if (Config.toneStyle === 'Custom') { + use = 'Custom' + } + } + let currentUse = e.msg.replace(/^#(chatgpt|ChatGPT)(上传|分享|共享)设定/, '') + if (!currentUse) { + currentUse = await redis.get(`CHATGPT:PROMPT_USE_${use}`) + } + await this.reply(`即将上传设定${currentUse},确定请回复确定,取消请回复取消,或者回复其他本地存在设定的名字`, true) + let extraData = { + currentUse, + use + } + await redis.set('CHATGPT:UPLOAD_PROMPT', JSON.stringify(extraData), 3600) + this.setContext('uploadPromptConfirm') } - async importPrompt () { - await this.reply('敬请期待', true) + async uploadPromptConfirm () { + if (!this.e.msg) return + let name = this.e.msg.trim() + if (name === '取消') { + await redis.del('CHATGPT:UPLOAD_PROMPT') + await this.reply('已取消上传', true) + this.finish('uploadPromptConfirm') + return + } + let extraData = JSON.parse(await redis.get('CHATGPT:UPLOAD_PROMPT')) + if (name !== '确定') { + extraData.currentUse = name + } + if (!getPromptByName(extraData.currentUse)) { + await redis.del('CHATGPT:UPLOAD_PROMPT') + await this.reply(`设定${extraData.currentUse}不存在,已取消上传`, true) + this.finish('uploadPromptConfirm') + return + } + await redis.set('CHATGPT:UPLOAD_PROMPT', JSON.stringify(extraData), 600) + await this.reply('请输入对该设定的描述或备注,便于其他人快速了解该设定', true) + this.finish('uploadPromptConfirm') + this.setContext('uploadPromptDescription') + } + + async uploadPromptDescription () { + if (!this.e.msg) return + let description = this.e.msg.trim() + if (description === '取消') { + await redis.del('CHATGPT:UPLOAD_PROMPT') + await this.reply('已取消上传', true) + this.finish('uploadPromptDescription') + return + } + let extraData = JSON.parse(await redis.get('CHATGPT:UPLOAD_PROMPT')) + extraData.description = description + await redis.set('CHATGPT:UPLOAD_PROMPT', JSON.stringify(extraData), 3600) + await this.reply('该设定是否是R18设定?请回复是或否', true) + this.finish('uploadPromptDescription') + this.setContext('uploadPromptR18') + } + + async uploadPromptR18 () { + if (this.e.msg.trim() === '取消') { + await redis.del('CHATGPT:UPLOAD_PROMPT') + await this.reply('已取消上传', true) + this.finish('uploadPromptR18') + return + } + if (!this.e.msg || (this.e.msg !== '是' && this.e.msg !== '否')) { + return + } + let r18 = this.e.msg.trim() === '是' + await this.reply('资料录入完成,正在上传中……', true) + let extraData = JSON.parse(await redis.get('CHATGPT:UPLOAD_PROMPT')) + const { currentUse, description } = extraData + const { content } = getPromptByName(currentUse) + let toUploadBody = { + title: currentUse, + prompt: content, + qq: (await getMasterQQ())[0], // 上传者设定为主人qq而不是机器人qq + use: extraData.use === 'Custom' ? 'Sydney' : 'ChatGPT', + r18, + description + } + logger.info(toUploadBody) + let response = await fetch('https://chatgpt.roki.best/prompt', { + method: 'POST', + body: JSON.stringify(toUploadBody), + headers: { + 'Content-Type': 'application/json', + 'FROM-CHATGPT': 'ikechan8370' + } + }) + await redis.del('CHATGPT:UPLOAD_PROMPT') + if (response.status === 200) { + response = await response.json() + if (response.data === true) { + await this.reply(`设定${currentUse}已上传,其他人可以通过#chatgpt导入设定${currentUse} 来快速导入该设定。感谢您的分享。`, true) + } else { + await this.reply(`设定上传失败,原因:${response.msg}`) + } + } else { + await this.reply(`设定上传失败: ${await response.text()}`) + } + this.finish('uploadPromptR18') + } + + async browsePrompt (e) { + let search = e.msg.replace(/^#(chatgpt|ChatGPT)(在线)?(浏览|查找)设定/, '') + let response = await fetch('https://chatgpt.roki.best/prompt/list?search=' + search, { + method: 'GET', + headers: { + 'FROM-CHATGPT': 'ikechan8370' + } + }) + if (response.status === 200) { + const { totalElements, content, pageable } = (await response.json()).data + let output = '| 【设定名称】 | 上传者QQ | 上传时间 | 是否R18 | 使用场景 |\n' + output += '----------------------------------------------------------------------------------------\n' + content.forEach(c => { + output += `| 【${c.title}】 | ${c.qq} | ${c.createTime} | ${c.r18} | ${c.use}|\n` + }) + output += '**************************************************************************\n' + output += ` 当前为第${pageable.pageNumber + 1}页,共${totalElements}个设定` + await this.reply(output) + } else { + await this.reply('查询失败:' + await response.text()) + } + } + + async importPrompt (e) { + let promptName = e.msg.replace(/^#(chatgpt|ChatGPT)导入设定/, '') + if (!promptName) { + await e.reply('设定名字呢?', true) + return true + } + let response = await fetch('https://chatgpt.roki.best/prompt?name=' + promptName, { + method: 'GET', + headers: { + 'FROM-CHATGPT': 'ikechan8370' + } + }) + if (response.status === 200) { + let r = await response.json() + if (r.code === 200) { + const { prompt, title } = r.data + saveOnePrompt(title, prompt) + e.reply(`导入成功。您现在可以使用 #chatgpt使用设定${title} 来体验这个设定了。`) + } else { + await e.reply('导入失败:' + r.msg) + } + } else { + await this.reply('导入失败:' + await response.text()) + } + // await this.reply('敬请期待', true) } async helpPrompt () { diff --git a/utils/common.js b/utils/common.js index 178c3b7..b9c1f10 100644 --- a/utils/common.js +++ b/utils/common.js @@ -221,6 +221,10 @@ export function mkdirs (dirname) { } } +export async function getMasterQQ () { + return (await import('../../../lib/config/config.js')).default.masterQQ +} + /** * * @param pluginKey plugin key diff --git a/utils/config.js b/utils/config.js index 39d6b90..747ec61 100644 --- a/utils/config.js +++ b/utils/config.js @@ -70,7 +70,7 @@ const defaultConfig = { allowOtherMode: true, sydneyContext: '', emojiBaseURL: 'https://www.gstatic.com/android/keyboard/emojikitchen', - version: 'v2.3.4' + version: 'v2.4.0' } const _path = process.cwd() let config = {} diff --git a/utils/prompts.js b/utils/prompts.js index 60f78c7..40d4943 100644 --- a/utils/prompts.js +++ b/utils/prompts.js @@ -40,3 +40,11 @@ export function saveOnePrompt (name, content) { let filePath = `${_path}/plugins/chatgpt-plugin/prompts/${name}.txt` fs.writeFileSync(filePath, content) } + +export function deleteOnePrompt (name) { + const _path = process.cwd() + mkdirs(`${_path}/plugins/chatgpt-plugin/prompts`) + let filePath = `${_path}/plugins/chatgpt-plugin/prompts/${name}.txt` + fs.unlinkSync(filePath) +} +