diff --git a/apps/admin.js b/apps/admin.js index 625c9d9..a7f0c28 100644 --- a/apps/admin.js +++ b/apps/admin.js @@ -9,18 +9,7 @@ import Common from "../components/Common.js"; const require = createRequire(import.meta.url); -let cfgMap = { - "角色": "char.char", - "面板": "char.profile", - "老婆": "char.wife", - "查他人": "char.queryOther", - "图鉴": "wiki.wiki", - "图片": "wiki.pic", - "深渊": "wiki.abyss", - "渲染": "sys.scale", - "帮助": "sys.help", -}; -let sysCfgReg = `^#喵喵设置\s*(${lodash.keys(cfgMap).join("|")})?\s*(.*)$`; + export const rule = { updateRes: { hashMark: true, @@ -32,16 +21,12 @@ export const rule = { reg: "^#图鉴(强制)?更新", describe: "【#管理】图鉴更新", }, - // sysCfg: { - // hashMark: true, - // reg: sysCfgReg, - // describe: "【#管理】系统设置" - // } + }; const _path = process.cwd(); -const resPath = `${_path}/plugins/miao-plugin/resources/`; +const resPath = `${_path}/plugins/cvs-plugin/resources/`; const plusPath = `${resPath}/res-plus/`; const checkAuth = async function (e) { @@ -51,54 +36,6 @@ const checkAuth = async function (e) { (*/ω\*)` }); } - -export async function sysCfg(e, { render }) { - if (!await checkAuth(e)) { - return true; - } - - let cfgReg = new RegExp(sysCfgReg); - let regRet = cfgReg.exec(e.msg); - - if (!regRet) { - return true; - } - - if (regRet[1]) { - // 设置模式 - let val = regRet[2] || ""; - - let cfgKey = cfgMap[regRet[1]]; - if (cfgKey === "sys.scale") { - val = Math.min(200, Math.max(50, val * 1 || 100)); - } else { - val = !/关闭/.test(val); - } - - if (cfgKey) { - Cfg.set(cfgKey, val); - } - } - - let cfg = { - chars: getStatus("char.char"), - profile: getStatus("char.profile"), - wife: getStatus("char.wife"), - other: getStatus("char.queryOther"), - wiki: getStatus("wiki.wiki"), - pic: getStatus("wiki.pic"), - abyss: getStatus("wiki.abyss"), - imgPlus: fs.existsSync(plusPath), - help: getStatus("sys.help", false), - scale: Cfg.get("sys.scale", 100) - } - - //渲染图像 - return await Common.render("admin/index", { - ...cfg, - }, { e, render, scale: 1.4 }); -} - const getStatus = function (rote, def = true) { if (Cfg.get(rote, def)) { return `
已开启
`; @@ -113,10 +50,10 @@ export async function updateRes(e) { return true; } let command = ""; - if (fs.existsSync(`${resPath}/miao-res-plus/`)) { + if (fs.existsSync(`${resPath}/res-plus/`)) { e.reply("开始尝试更新,请耐心等待~"); command = `git pull`; - exec(command, { cwd: `${resPath}/miao-res-plus/` }, function (error, stdout, stderr) { + exec(command, { cwd: `${resPath}/res-plus/` }, function (error, stdout, stderr) { //console.log(stdout); if (/Already up to date/.test(stdout)) { e.reply("目前所有图片都已经是最新了~"); @@ -134,7 +71,7 @@ export async function updateRes(e) { } }); } else { - command = `git clone https://gitee.com/yoimiya-kokomi/miao-res-plus.git "${resPath}/miao-res-plus/"`; + command = `git clone https://gitee.com/leiyilu/image.git "${resPath}/res-plus/"`; e.reply("开始尝试安装图片加量包,可能会需要一段时间,请耐心等待~"); exec(command, function (error, stdout, stderr) { if (error) { @@ -161,7 +98,7 @@ export async function updateMiaoPlugin(e) { } else { e.reply("正在执行更新操作,请稍等"); } - exec(command, { cwd: `${_path}/plugins/miao-plugin/` }, function (error, stdout, stderr) { + exec(command, { cwd: `${_path}/plugins/cvs-plugin/` }, function (error, stdout, stderr) { //console.log(stdout); if (/Already up to date/.test(stdout)) { e.reply("目前已经是最新版喵喵了~"); diff --git a/apps/xiaoyao_image.js b/apps/xiaoyao_image.js new file mode 100644 index 0000000..992b557 --- /dev/null +++ b/apps/xiaoyao_image.js @@ -0,0 +1,84 @@ +import { + segment +} from "oicq"; +import fs from "fs"; + +import path from 'path'; +const _path = process.cwd(); +const __dirname = path.resolve(); + +export async function roleInfo(e) { + // let msg=e.msg.replace(/#|图鉴/g,""); + let msg = e.msg.replace(/#|#|信息|图鉴|命座|天赋|突破/g, ""); + + let id = YunzaiApps.mysInfo.roleIdToName(msg); + let name; + if (["10000005", "10000007", "20000000"].includes(id)) { + if (!["风主", "岩主", "雷主"].includes(msg)) { + e.reply("请选择:风主图鉴、岩主图鉴、雷主图鉴"); + return true; + } + name = msg; + } else { + name = YunzaiApps.mysInfo.roleIdToName(id, true); + if (!name) return false; + } + console.log(name) + + send_Msg(e,"image","爆炒肉片") + return true; +} + +const send_Msg=function(e,type,name){ + let path = `${_path}/plugins/cvs-plugin/resources/res-plus/${type}/${name}.png` + if (!fs.existsSync(path)) { + return true; + } + e.reply(segment.image(`file:///${path}`)); +} +let weapon = new Map(); +let weaponFile = []; +await init(); +export async function init(isUpdate = false) { + let weaponJson = JSON.parse(fs.readFileSync("./config/genshin/weapon.json", "utf8")); + for (let i in weaponJson) { + for (let val of weaponJson[i]) { + weapon.set(val, i); + } + } + + weaponFile = fs.readdirSync("./resources/weaponInfo_xiaoyao"); + for (let val of weaponFile) { + let name = val.replace(".png", ""); + weapon.set(name, name); + } +} + +export async function weaponInfo(e) { + + let msg = e.msg || ''; + + if(e.atBot){ + msg = "#" + msg.replace("#", ""); + } + + if(!/(#*(.*)(信息|图鉴|突破)|#(.*))$/.test(msg)) return; + + let name = weapon.get(msg.replace(/#|#|信息|图鉴|突破/g, "")); + + if (name) { + + Bot.logger.mark(`[${e.group_name}] ${e.msg}:weaponInfo`); + + let path = `${_path}/resources/weaponInfo_xiaoyao/${name}.png` + + if (!fs.existsSync(path)) { + return true; + } + + e.reply(segment.image(`file:///${path}`)); + return true; + } + + return false; +} diff --git a/components/Cfg.js b/components/Cfg.js new file mode 100644 index 0000000..2561a91 --- /dev/null +++ b/components/Cfg.js @@ -0,0 +1,41 @@ +import fs from "fs"; +import lodash from "lodash"; + +const _path = process.cwd(); +const _cfgPath = `${_path}/plugins/miao-plugin/components/`; +let cfg = {}; + +try { + if (fs.existsSync(_cfgPath + "cfg.json")) { + cfg = JSON.parse(fs.readFileSync(_cfgPath + "cfg.json", "utf8")) || {}; + } +} catch (e) { + // do nth +} + +let Cfg = { + get(rote, def = '') { + return lodash.get(cfg, rote, def); + }, + set(rote, val) { + lodash.set(cfg, rote, val); + fs.writeFileSync(_cfgPath + "cfg.json", JSON.stringify(cfg, null, "\t")); + }, + scale(pct = 1) { + let scale = Cfg.get("sys.scale", 100); + scale = Math.min(2, Math.max(0.5, scale / 100)); + pct = pct * scale; + return `style=transform:scale(${pct})`; + }, + isDisable(e, rote) { + if (Cfg.get(rote, true)) { + return false; + } + if (/^#*喵喵/.test(e.msg || "")) { + return false; + } + return true; + } +}; + +export default Cfg; \ No newline at end of file diff --git a/components/Changelog.js b/components/Changelog.js new file mode 100644 index 0000000..72eaadd --- /dev/null +++ b/components/Changelog.js @@ -0,0 +1,72 @@ +import fs from "fs"; +import lodash from "lodash"; + +const _path = process.cwd(); +const _logPath = `${_path}/plugins/miao-plugin/CHANGELOG.md`; + +let logs = {}; +let changelogs = []; +let currentVersion; +let versionCount = 4; + +let packageJson = JSON.parse(fs.readFileSync("package.json", "utf8")); + +const getLine = function (line) { + line = line.replace(/(^\s*\*|\r)/g, ''); + line = line.replace(/\s*`([^`]+`)/g, '$1'); + line = line.replace(/`\s*/g, ''); + line = line.replace(/ⁿᵉʷ/g, ''); + return line; +} + +try { + if (fs.existsSync(_logPath)) { + logs = fs.readFileSync(_logPath, "utf8") || ""; + logs = logs.split("\n"); + + let temp = {}, lastLine = {}; + lodash.forEach(logs, (line) => { + if (versionCount <= -1) { + return false; + } + let versionRet = /^#\s*([0-9\\.~\s]+?)\s*$/.exec(line); + if (versionRet && versionRet[1]) { + let v = versionRet[1].trim(); + if (!currentVersion) { + currentVersion = v; + } else { + changelogs.push(temp); + if (/0\s*$/.test(v) && versionCount > 0) { + versionCount = 0; + } else { + versionCount--; + } + } + + temp = { + version: v, + logs: [] + } + } else { + if (!line.trim()) { + return; + } + if (/^\*/.test(line)) { + lastLine = { + title: getLine(line), + logs: [] + } + temp.logs.push(lastLine); + } else if (/^\s{3,}\*/.test(line)) { + lastLine.logs.push(getLine(line)); + } + } + }); + } +} catch (e) { + // do nth +} + +const yunzaiVersion = packageJson.version; + +export { currentVersion, yunzaiVersion, changelogs }; \ No newline at end of file diff --git a/components/Common.js b/components/Common.js new file mode 100644 index 0000000..b2baf03 --- /dev/null +++ b/components/Common.js @@ -0,0 +1,32 @@ +import { Cfg } from "./index.js"; +import { segment } from "oicq"; +import { currentVersion, yunzaiVersion } from "./Changelog.js"; + +export const render = async function (path, params, cfg) { + let paths = path.split("/"); + let { render, e } = cfg; + let _layout_path = process.cwd() + "/plugins/miao-plugin/resources/common/layout/"; + let base64 = await render(paths[0], paths[1], { + ...params, + _layout_path, + defaultLayout: _layout_path + "default.html", + elemLayout: _layout_path + "elem.html", + sys: { + scale: Cfg.scale(cfg.scale || 1), + copyright: `Created By Yunzai-Bot${yunzaiVersion} & Miao-Plugin${currentVersion}` + } + }); + + if (base64) { + e.reply(segment.image(`base64://${base64}`)); + } + + return true; +} + + +export default { + render, + cfg: Cfg.get, + isDisable: Cfg.isDisable +}; \ No newline at end of file diff --git a/components/Data.js b/components/Data.js new file mode 100644 index 0000000..00d5129 --- /dev/null +++ b/components/Data.js @@ -0,0 +1,179 @@ +import lodash from "lodash"; +import fs from "fs"; +import request from "request"; + +let Data = { + + /* + * 根据指定的path依次检查与创建目录 + * */ + createDir(rootPath = "", path = "", includeFile = false) { + let pathList = path.split("/"), + nowPath = rootPath; + pathList.forEach((name, idx) => { + name = name.trim(); + if (!includeFile && idx <= pathList.length - 1) { + nowPath += name + "/"; + if (name) { + if (!fs.existsSync(nowPath)) { + fs.mkdirSync(nowPath); + } + } + } + }) + }, + + /* + * 读取json + * */ + readJSON(root, path) { + if (!/\.json$/.test(path)) { + path = path + ".json"; + } + // 检查并创建目录 + Data.createDir(root, path, true); + if (fs.existsSync(`${root}/${path}`)) { + let jsonRet = fs.readFileSync(`${root}/${path}`, "utf8"); + return JSON.parse(jsonRet); + } + return {} + }, + + /* + * 写JSON + * */ + writeJson(path, file, data, space = "\t") { + if (!/\.json$/.test(file)) { + file = file + ".json"; + } + + // 检查并创建目录 + Data.createDir(path, true); + return fs.writeFileSync(`${path}/${file}`, JSON.stringify(data, null, space)); + }, + + /* + * 返回一个从 target 中选中的属性的对象 + * + * keyList : 获取字段列表,逗号分割字符串 + * key1, key2, toKey1:fromKey1, toKey2:fromObj.key + * + * defaultData: 当某个字段为空时会选取defaultData的对应内容 + * toKeyPrefix:返回数据的字段前缀,默认为空。defaultData中的键值无需包含toKeyPrefix + * + * */ + + getData(target, keyList = "", cfg = {}) { + target = target || {}; + let defaultData = cfg.defaultData || {}; + let ret = {}; + // 分割逗号 + if (typeof (keyList) === "string") { + keyList = keyList.split(","); + } + + lodash.forEach(keyList, (keyCfg) => { + // 处理通过:指定 toKey & fromKey + let _keyCfg = keyCfg.split(":"); + let keyTo = _keyCfg[0].trim(), + keyFrom = (_keyCfg[1] || _keyCfg[0]).trim(), + keyRet = keyTo; + if (cfg.lowerFirstKey) { + keyRet = lodash.lowerFirst(keyRet); + } + if (cfg.keyPrefix) { + keyRet = cfg.keyPrefix + keyRet; + } + // 通过Data.getVal获取数据 + ret[keyRet] = Data.getVal(target, keyFrom, defaultData[keyTo], cfg); + }) + return ret; + }, + + getVal(target, keyFrom, defaultValue) { + return lodash.get(target, keyFrom, defaultValue); + }, + + getUrlPath(url) { + let reg = /^https*:\/\/(.*)\/(\w+\.(png|jpg|jpeg|webp))(\?.*)?$/; + let ret = reg.exec(url); + if (!ret) { + return false; + } + return { + path: ret[1], + filename: ret[2], + type: ret[3], + url + } + }, + pathExists(root, path) { + if (fs.existsSync(root + "/" + path)) { + return true; + } + path = path.replace("\\", "/"); + const dirList = path.split("/"); + let currentDir = root; + + for (let dir of dirList) { + currentDir = currentDir + "/" + dir; + if (!fs.existsSync(currentDir)) { + fs.mkdirSync(currentDir); + } + } + return true; + }, + async asyncPool(poolLimit, array, iteratorFn) { + const ret = []; // 存储所有的异步任务 + const executing = []; // 存储正在执行的异步任务 + for (const item of array) { + // 调用iteratorFn函数创建异步任务 + const p = Promise.resolve().then(() => iteratorFn(item, array)); + // 保存新的异步任务 + ret.push(p); + + // 当poolLimit值小于或等于总任务个数时,进行并发控制 + if (poolLimit <= array.length) { + // 当任务完成后,从正在执行的任务数组中移除已完成的任务 + const e = p.then(() => executing.splice(executing.indexOf(e), 1)); + executing.push(e); // 保存正在执行的异步任务 + if (executing.length >= poolLimit) { + // 等待较快的任务执行完成 + await Promise.race(executing); + } + } + } + return Promise.all(ret); + }, + + async cacheFile(fileList, cacheRoot) { + + let ret = {}; + let cacheFn = async function (url) { + let path = Data.getUrlPath(url); + if (fs.existsSync(`${cacheRoot}/${path.path}/${path.filename}`)) { + console.log("已存在,跳过 " + path.path + "/" + path.filename); + ret[url] = `${path.path}/${path.filename}`; + return true; + } + + Data.pathExists(cacheRoot, path.path); + await request(url).pipe(fs.createWriteStream(`${cacheRoot}/${path.path}/` + path.filename)); + console.log("下载成功: " + path.path + "/" + path.filname); + ret[url] = `${path.path}/${path.filename}`; + return true; + }; + + await Data.asyncPool(10, fileList, cacheFn); + return ret; + + }, + + sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + + +} + +export default Data; diff --git a/components/cfg.json b/components/cfg.json new file mode 100644 index 0000000..9135015 --- /dev/null +++ b/components/cfg.json @@ -0,0 +1,5 @@ +{ + "sys": { + "help": true + } +} \ No newline at end of file diff --git a/components/index.js b/components/index.js new file mode 100644 index 0000000..ddb92f4 --- /dev/null +++ b/components/index.js @@ -0,0 +1,4 @@ +import Data from "./Data.js"; +import Cfg from "./Cfg.js"; + +export { Data, Cfg } \ No newline at end of file diff --git a/index.js b/index.js index 6c9ee70..37f4cfa 100644 --- a/index.js +++ b/index.js @@ -1,63 +1,51 @@ -// import { -// character, -// getProfile, -// wife, -// wifeReg, -// enemyLv, -// getArtis, -// getProfileAll, -// profileHelp -// } from "./apps/character.js"; -// import { consStat, abyssPct, abyssTeam } from "./apps/stat.js"; -// import { wiki, calendar } from "./apps/wiki.js"; -// import { help, versionInfo } from "./apps/help.js"; -// import lodash from "lodash"; -// import common from "../../lib/common.js"; -// import { rule as adminRule, updateRes, sysCfg, updateMiaoPlugin } from "./apps/admin.js"; -// import { currentVersion } from "./components/Changelog.js"; - -// export { -// character, -// wife, -// consStat, -// abyssPct, -// abyssTeam, -// wiki, -// updateRes, -// updateMiaoPlugin, -// sysCfg, -// help, -// versionInfo, -// getProfile, -// enemyLv, -// getArtis, -// getProfileAll, -// profileHelp, -// calendar -// }; +import lodash from "lodash"; +import { + roleInfo,weaponInfo +} from "./apps/xiaoyao_image.js" +import { + rule as adminRule, + updateRes, + updateMiaoPlugin +} from "./apps/admin.js"; +export { + updateRes, + roleInfo,weaponInfo +}; -// let rule = { -// versionInfo: { -// reg: "^#图鉴版本$", -// describe: "【#帮助】 喵喵版本介绍", -// }, -// calendar: { -// reg: "^#图鉴列表$", -// describe: "【#日历】 活动日历", -// }, -// ...adminRule -// }; +let rule = { + versionInfo: { + reg: "^#图鉴版本$", + describe: "【#帮助】 喵喵版本介绍", + }, + calendar: { + reg: "^#图鉴列表$", + describe: "【#日历】 活动日历", + }, + roleInfo: { + reg: "#*(.*)(信息|图鉴|命座|天赋|突破|材料|素材)$", //匹配消息正则,命令正则 + priority: 900, //优先级,越小优先度越高 + describe: "【刻晴信息、刻晴图鉴、刻晴突破、刻晴命座】角色信息图鉴", //【命令】功能说明 + }, + weaponInfo: { + reg: "", //匹配消息正则,命令正则 + priority: 900, //优先级,越小优先度越高 + describe: "【刻晴信息、刻晴图鉴、刻晴突破、刻晴命座】角色信息图鉴", //【命令】功能说明 + }, + ...adminRule +}; -// lodash.forEach(rule, (r) => { -// r.priority = r.priority || 50; -// r.prehash = true; -// r.hashMark = true; -// }); +lodash.forEach(rule, (r) => { + r.priority = r.priority || 50; + r.prehash = true; + r.hashMark = true; +}); -// export { rule }; +export { + rule +}; -// console.log(`图鉴${currentVersion}初始化~`); +console.log(`图鉴初始化~`); // setTimeout(async function () { // let msgStr = await redis.get("miao:restart-msg"); @@ -68,4 +56,4 @@ // let msgs = [`当前版本: ${currentVersion}`, `您可使用 #版本 命令查看更新信息`]; // await common.relpyPrivate(msg.qq, msgs.join("\n")); // } -// }, 1000); \ No newline at end of file +// }, 1000);