diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b7a67e..b2f2ded 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,40 +1,54 @@ +# 1.4.2 +* 版本机制 + # 1.4.1 + * 绑定设备 * 优化部分代码 # 1.4 + * 添加 `练度统计` 功能,发送 `%练度统计` 或 `%练度` 查看 # 1.3 + * 添加驱动盘评分 # 1.2 + * 添加伤害计算,支持目前为止所有 `驱动盘` 以及 `艾莲` 、 `朱鸢` 的伤害计算,`强攻武器` 支持 `B` 级以上。 * 修复攻略问题,若有对不上的问题,请“刷新攻略”。 # 1.1 + * 支持自定义面板图,详情请查看 `README`。 # 1.0 + * 重构帮助指令,发送 `%帮助` # 0.3 + * 修复攻略图角色“本”图片错误 * 将 `mysid` 比较转为字符串,解决部分适配问题 # 0.2 + * 添加“式舆防卫战”查询,发送 `%式舆防卫战` 或者 `%深渊` # 0.1 + * 刷新角色面板图片版 * 优化指令分配 * 添加版本信息 # 0.05 + * 支持查看角色面板,发送 `%角色名/别名+面板` * 修复一些问题 # 0.04 + * 支持获取抽卡链接,发送 `%获取抽卡链接` * 支持面板刷新,发送 `%刷新面板` diff --git a/apps/help.js b/apps/help.js index 5861af6..7ec8e75 100644 --- a/apps/help.js +++ b/apps/help.js @@ -189,6 +189,27 @@ const helpData = [ needSK: false, commands: ['解绑设备'], }, + { + title: '更新日志', + desc: '查看插件的Commit日志', + needCK: false, + needSK: false, + commands: ['[插件]更新日志'], + }, + { + title: '版本', + desc: '查看插件版本日志', + needCK: false, + needSK: false, + commands: ['[插件]版本'], + }, + { + title: '检查更新', + desc: '检查插件是否更新', + needCK: false, + needSK: false, + commands: ['[插件]检查更新'], + }, ], }, ]; diff --git a/apps/manage.js b/apps/manage.js index cb63958..17345a6 100644 --- a/apps/manage.js +++ b/apps/manage.js @@ -60,6 +60,18 @@ export class Panel extends ZZZPlugin { reg: `${rulePrefix}删除(\\S+)(角色|面板)图(.+)$`, fnc: 'deleteCharacterImg', }, + { + reg: `${rulePrefix}(插件)?版本$`, + fnc: 'getChangeLog', + }, + { + reg: `^${rulePrefix}(插件)?更新日志$`, + fnc: 'getCommitLog', + }, + { + reg: `^${rulePrefix}(插件)?检查更新$`, + fnc: 'hasUpdate', + }, ], }); @@ -75,5 +87,8 @@ export class Panel extends ZZZPlugin { this.uploadCharacterImg = manage.panel.uploadCharacterImg; this.getCharacterImages = manage.panel.getCharacterImages; this.deleteCharacterImg = manage.panel.deleteCharacterImg; + this.getChangeLog = manage.version.getChangeLog; + this.getCommitLog = manage.version.getCommitLog; + this.hasUpdate = manage.version.hasUpdate; } } diff --git a/apps/manage/index.js b/apps/manage/index.js index 4ce3760..28114bf 100644 --- a/apps/manage/index.js +++ b/apps/manage/index.js @@ -8,10 +8,13 @@ import * as alias from './alias.js'; import * as panel from './panel.js'; +import * as version from './version.js'; + export default { assets, guides, config, alias, panel, + version, }; diff --git a/apps/manage/version.js b/apps/manage/version.js new file mode 100644 index 0000000..2d1bd70 --- /dev/null +++ b/apps/manage/version.js @@ -0,0 +1,49 @@ +import version from '../../lib/version.js'; +import render from '../../lib/render.js'; +import { ZZZUpdate } from '../../lib/update.js'; +import { pluginName } from '../../lib/path.js'; + +export async function getChangeLog() { + const versionData = version.changelogs; + await render(this.e, 'help/version.html', { + versionData, + }); + return false; +} + +export async function getCommitLog() { + if (!ZZZUpdate) return false; + let updatePlugin = new ZZZUpdate(); + updatePlugin.e = this.e; + updatePlugin.reply = this.reply; + if (updatePlugin.getPlugin(pluginName)) { + try { + const commitData = await updatePlugin.getZZZAllLog(); + await render(this.e, 'help/commit.html', { + commitData, + }); + } catch (error) { + this.reply(`[${pluginName}]获取更新日志失败\n${error.message}`); + } + } + return true; +} + +export async function hasUpdate() { + if (!ZZZUpdate) return false; + let updatePlugin = new ZZZUpdate(); + updatePlugin.e = this.e; + updatePlugin.reply = this.reply; + if (updatePlugin.getPlugin(pluginName)) { + const result = await updatePlugin.hasUpdate(); + if (result.hasUpdate) { + await this.reply(`[${pluginName}]有${result.logs.length || 1}个更新`); + await render(this.e, 'help/commit.html', { + commitData: result.logs, + }); + } else { + await this.reply(`[${pluginName}]已是最新`); + } + } + return true; +} diff --git a/apps/update.js b/apps/update.js index 4e9da9f..2f9f8d7 100644 --- a/apps/update.js +++ b/apps/update.js @@ -1,15 +1,8 @@ -import _ from 'lodash' -import { rulePrefix } from '../lib/common.js' -import { pluginName } from '../lib/path.js' -import settings from '../lib/settings.js' - -let Update = null -try { - Update = (await import("../../other/update.js").catch(e => null))?.update - Update ||= (await import("../../system/apps/update.ts")).update -} catch (e) { - logger.error(`[${pluginName}]未获取到更新js ${logger.yellow("更新功能")} 将无法使用`) -} +import _ from 'lodash'; +import { rulePrefix } from '../lib/common.js'; +import { pluginName } from '../lib/path.js'; +import settings from '../lib/settings.js'; +import { ZZZUpdate } from '../lib/update.js'; export class update extends plugin { constructor() { @@ -23,30 +16,15 @@ export class update extends plugin { reg: `^${rulePrefix}(插件)?(强制)?更新(插件)?$`, fnc: 'update', }, - { - reg: `^${rulePrefix}(插件)?更新日志$`, - fnc: 'update_log', - } ], - }) + }); } async update(e = this.e) { - if (!e.isMaster) return - e.msg = `#${e.msg.includes("强制") ? "强制" : ""}更新${pluginName}` - const up = new Update(e) - up.e = e - return up.update() - } - - async update_log() { - let Update_Plugin = new Update() - Update_Plugin.e = this.e - Update_Plugin.reply = this.reply - - if (Update_Plugin.getPlugin(pluginName)) { - this.e.reply(await Update_Plugin.getLog(pluginName)) - } - return true + if (!e.isMaster || !ZZZUpdate) return false; + e.msg = `#${e.msg.includes('强制') ? '强制' : ''}更新${pluginName}`; + const up = new ZZZUpdate(e); + up.e = e; + return up.update(); } } diff --git a/apps/user.js b/apps/user.js index 881a87a..e10fa19 100644 --- a/apps/user.js +++ b/apps/user.js @@ -108,7 +108,7 @@ export class Panel extends ZZZPlugin { '1. 使用抓包软件抓取米游社APP的请求', '2. 在请求头内找到【x-rpc-device_id】和【x-rpc-device_fp】', '3. 自行构造如下格式的信息:', - ' {device_id: "x-rpc-device_id的内容", device_fp: "x-rpc-device_fp的内容"}', + ' {"device_id": "x-rpc-device_id的内容", "device_fp": "x-rpc-device_fp的内容"}', '4. 给机器人发送"%绑定设备"指令', '5. 机器人会提示发送设备信息', '6. 粘贴自行构造的信息发送', diff --git a/lib/update.js b/lib/update.js new file mode 100644 index 0000000..d565bee --- /dev/null +++ b/lib/update.js @@ -0,0 +1,105 @@ +import _ from 'lodash'; +import { pluginName } from '../lib/path.js'; +import { mdLogLineToHTML } from '../utils/data.js'; + +let Update = null; +try { + Update = (await import('../../other/update.js').catch(e => null))?.update; + Update ||= (await import('../../system/apps/update.ts')).update; +} catch (e) { + logger.error( + `[${pluginName}]未获取到更新js ${logger.yellow('更新功能')} 将无法使用` + ); +} +let ZZZUpdate = null; +/** + * @typedef {Object} CommitLog + * @property {string} commit 提交ID + * @property {string} date 提交时间 + * @property {string} msg 提交信息 + * @property {boolean} local 是否本地记录 + * @property {current} boolean 是否当前版本 + */ +/** + * @typedef {Object} UpdateInfo + * @property {boolean} hasUpdate 是否有更新 + * @property {CommitLog[]} logs 更新日志 + */ +if (Update) { + ZZZUpdate = class ZZZUpdate extends Update { + async handleLog(remote = false) { + let cmdStr = 'git log -100 --pretty="%h||%cd||%s" --date=format:"%F %T"'; + if (remote) { + cmdStr = + 'git log -100 --pretty="%h||%cd||%s" --date=format:"%F %T" origin/main'; + } + const cm = await this.exec(cmdStr, pluginName); + if (cm.error) { + throw new Error(cm.error.message); + } + + const logAll = cm.stdout.split('\n'); + if (!logAll.length) { + throw new Error('未获取到更新日志'); + } + /** @type CommitLog[] */ + const log = []; + let current = true; + for (let str of logAll) { + str = str.split('||'); + if (str[0] === this.oldCommitId) break; + if (str[2].includes('Merge')) continue; + /** @type CommitLog */ + const commit = { + commit: str[0], + date: str[1], + msg: mdLogLineToHTML(str[2]), + local: !remote, + current: false, + }; + if (!remote && current) { + commit.current = true; + current = false; + } + log.push(commit); + } + return log; + } + async getZZZLog() { + const log = await this.handleLog(); + return log; + } + + async getZZZRemoteLog() { + const log = await this.handleLog(true); + return log; + } + + async getZZZAllLog() { + const localLog = await this.getZZZLog(); + const remoteLog = await this.getZZZRemoteLog(); + const logs = _.unionBy(localLog, remoteLog, 'commit'); + logs.sort((a, b) => { + return new Date(b.date) - new Date(a.date); + }); + return logs; + } + + async hasUpdate() { + const logs = await this.getZZZAllLog(); + const newLogs = logs.filter(log => !log.local); + /** @type UpdateInfo */ + let result = { + hasUpdate: false, + logs: [], + }; + if (newLogs.length) { + result.hasUpdate = true; + result.logs = newLogs; + } + return result; + } + }; +} + +export { ZZZUpdate }; diff --git a/lib/version.js b/lib/version.js index fe4311b..e6d6d64 100644 --- a/lib/version.js +++ b/lib/version.js @@ -2,6 +2,7 @@ import fs from 'fs'; import lodash from 'lodash'; import path from 'path'; import { pluginPath } from './path.js'; +import { mdLogLineToHTML } from '../utils/data.js'; // 更新日志文件位置 const _logPath = path.join(pluginPath, 'CHANGELOG.md'); @@ -21,26 +22,6 @@ let versionCount = 4; // 读取 package.json(此处为读取Yunzai-Bot的package.json) let packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')); -/** - * 将 Markdown 行转换为 HTML - * @param {*} line - * @returns - */ -const getLine = function (line) { - // 去除行首空格和换行符 - line = line.replace(/(^\s*\*|\r)/g, ''); - // 替换行内代码块 - line = line.replace(/\s*`([^`]+`)/g, '$1'); - line = line.replace(/`\s*/g, ''); - // 替换行内加粗 - line = line.replace(/\s*\*\*([^\*]+\*\*)/g, '$1'); - line = line.replace(/\*\*\s*/g, ''); - // 替换行内表示更新内容 - line = line.replace(/ⁿᵉʷ/g, ''); - // 返回转换后的行内容(HTML) - return line; -}; - // 尝试读取更新日志文件 try { if (fs.existsSync(_logPath)) { @@ -54,9 +35,9 @@ try { let lastLine = {}; lodash.forEach(logs, line => { // 如果版本数量小于0,返回false - if (versionCount <= -1) { - return false; - } + // if (versionCount <= -1) { + // return false; + // } // 匹配版本号 const versionRet = /^#\s*([0-9a-zA-Z\\.~\s]+?)\s*$/.exec(line); if (versionRet && versionRet[1]) { @@ -86,12 +67,12 @@ try { // 如果行以 * 开头,表示更新内容 if (/^\*/.test(line)) { lastLine = { - title: getLine(line), + title: mdLogLineToHTML(line), logs: [], }; temp.logs.push(lastLine); } else if (/^\s{2,}\*/.test(line)) { - lastLine.logs.push(getLine(line)); + lastLine.logs.push(mdLogLineToHTML(line)); } } }); diff --git a/resources/help/commit.css b/resources/help/commit.css new file mode 100644 index 0000000..f87af2e --- /dev/null +++ b/resources/help/commit.css @@ -0,0 +1,141 @@ +@charset "UTF-8"; +.special-title { + padding: 0; + font-size: 1.2em; +} + +.card { + margin: 0 1em; + padding: 1em 0; +} +.card .list { + display: flex; + flex-direction: column; + gap: 0.5em; + font-size: 0.9em; +} +.card .list .item { + background-color: rgba(255, 255, 255, 0.1); + padding: 0.5em 1em; + border-radius: 0.5em; + border: 0.1em solid rgba(255, 255, 255, 0.1); + backdrop-filter: blur(0.5em); + position: relative; +} +.card .list .item .version { + filter: drop-shadow(0 0 0.05em #f0d480); + position: relative; + margin-bottom: 0.5em; + font-size: 0.8em; + display: flex; +} +.card .list .item .version .id { + background: linear-gradient(90deg, #ffe6b4, #f2c94c); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + position: relative; + margin-right: 0.5em; +} +.card .list .item .version .id::before { + content: ""; + position: absolute; + width: 100%; + height: 0.2em; + bottom: 0; + left: 0; + background: linear-gradient(0deg, #f2c94c, #ffe6b4); + z-index: -1; + border-radius: 0.5em; +} +.card .list .item .version .time { + background: linear-gradient(90deg, #ffe6b4, #f2c94c); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; +} +.card .list .item.current { + background-color: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(1.5em); +} +.card .list .item.current::after { + content: "当前版本"; + font-size: 0.8em; + position: absolute; + right: 0.5em; + top: 0.5em; + color: #f2c94c; + opacity: 0.5; +} +.card .list .item.current .version { + filter: drop-shadow(0 0 0.1em rgba(231, 241, 35, 0.3)); + font-size: 1em; +} +.card .list .item.current .version .id { + color: #f2784c; + background: none; + background-clip: unset; + -webkit-text-fill-color: unset; + font-size: 0.8em; + padding-top: 0.3em; +} +.card .list .item.current .version .id::before { + background: #f2784c; +} +.card .list .item.current .version .time { + background: linear-gradient(90deg, #f2784c, #ffbca4); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; +} +.card .list .item.newc::after { + content: "NEW"; + font-size: 0.4em; + background: linear-gradient(90deg, #f2c94c, #ffe6b4); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + filter: drop-shadow(0 0 0.05em #f0d480); + top: 1em; + right: 1em; + position: absolute; + border: 0.1em solid #f2c94c; + padding: 0.1em 0.3em 0.2em 0.3em; + border-radius: 0.5em; +} +.card .list .item .content { + font-size: 0.8em; + margin: 0 1em; +} +.card .list .item .cmd { + font-size: 0.8em; + background-color: rgba(255, 255, 255, 0.1); + padding: 0.2em 0.4em; + border-radius: 0.5em; + margin: 0em 0.3em; + border: 0.1em solid rgba(255, 255, 255, 0.1); + color: #cadc9e; +} +.card .list .item .strong { + color: #f2c94c; +} +.card .list .item .new { + position: relative; +} +.card .list .item .new::before { + content: "new"; + font-size: 0.4em; + background: linear-gradient(90deg, #f2c94c, #ffe6b4); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + filter: drop-shadow(0 0 0.05em #f0d480); + bottom: 1.8em; + left: 0em; + position: relative; + border: 0.1em solid #f2c94c; + padding: 0em 0.3em 0.2em 0.3em; + border-radius: 0.5em; +} + +/*# sourceMappingURL=commit.css.map */ diff --git a/resources/help/commit.html b/resources/help/commit.html new file mode 100644 index 0000000..413d280 --- /dev/null +++ b/resources/help/commit.html @@ -0,0 +1,27 @@ +{{extend defaultLayout}} + +{{block 'css'}} + +{{/block}} + +{{block 'main'}} +