ZZZ-Plugin/apps/guide.js

199 lines
5.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import path from 'path';
import fs from 'fs';
import fetch from 'node-fetch';
import lodash from 'lodash';
import common from '../../../lib/common/common.js';
import { ZZZPlugin } from '../lib/plugin.js';
import { imageResourcesPath } from '../lib/path.js';
import _ from 'lodash';
import settings from '../lib/settings.js';
import { downloadFile } from '../lib/download/core.js';
import { char } from '../lib/convert.js';
import guides from '../lib/guides.js';
import { rulePrefix } from '../lib/common.js';
const ZZZ_GUIDES_PATH = path.join(imageResourcesPath, 'guides');
export class Guide extends ZZZPlugin {
constructor() {
super({
name: '[ZZZ-Plugin]Guide',
dsc: '#zzz角色攻略',
event: 'message',
priority: _.get(settings.getConfig('priority'), 'guide', 70),
rule: [
{
reg: `^${rulePrefix}攻略(说明|帮助)$`,
fnc: 'GuideHelp',
},
{
reg: `${rulePrefix}(更新)?\\S+攻略(\\d+|all)?$`,
fnc: 'Guide',
},
],
});
this.url =
'https://bbs-api.mihoyo.com/post/wapi/getPostFullInCollection?&gids=8&collection_id=';
}
getGuideFolder(groupIndex) {
let guideFolder = path.join(
ZZZ_GUIDES_PATH,
guides.guideSources[groupIndex - 1]
);
return guideFolder;
}
async getGuidePath(groupIndex, characterName, isUpdate = false) {
const filename = `role_guide_${characterName}.png`;
const guidePath = path.join(this.getGuideFolder(groupIndex), filename);
if (fs.existsSync(guidePath) && !isUpdate) return guidePath;
return await this.getImg(characterName, groupIndex);
}
async Guide() {
let reg = new RegExp(`${rulePrefix}(更新|刷新)?(\\S+)攻略(\\d+|all)?$`);
let [
,
,
,
,
isUpdate,
alias,
group = _.get(settings.getConfig('guide'), 'default_guide', 1).toString(),
] = this.e.msg.match(reg);
// all -> 0
if (group === 'all') {
group = '0';
}
group = Number(group);
if (group > guides.guideMaxNum) {
return this.reply(`超过攻略数量(${guides.guideMaxNum}`);
}
if (alias === '设置默认' || alias === '设置所有') {
return false;
}
const name = char.aliasToName(alias);
if (!name) {
return this.reply('该角色不存在');
}
if (group === 0) {
const msg = [];
for (
let i = 1;
i <=
Number(_.get(settings.getConfig('guide'), 'max_forward_guides', 4));
i++
) {
const guidePath = await this.getGuidePath(i, name, !!isUpdate);
// msg.push(segment.image(`file://${guidePath}`));
if (guidePath) {
msg.push(segment.image(guidePath));
} else {
msg.push(`暂无${name}攻略 (${guides.guideSources[i - 1]})`);
}
}
if (msg.length) {
await this.reply(await common.makeForwardMsg(this.e, msg));
}
}
const guidePath = await this.getGuidePath(group, name, !!isUpdate);
if (!guidePath) {
return this.e.reply(
`暂无${name}攻略 (${
guides.guideSources[group - 1]
})\n请尝试其他的攻略来源查询`
);
}
await this.e.reply(segment.image(guidePath));
}
/** 下载攻略图 */
async getImg(name, group) {
let mysRes = [];
guides.collection_id[group].forEach(id =>
mysRes.push(this.getData(this.url + id))
);
try {
mysRes = await Promise.all(mysRes);
} catch (error) {
console.log(`米游社接口报错:${error}}`);
return this.e.reply('暂无攻略数据,请稍后再试');
}
// 搜索时过滤特殊符号譬如「11号」
const filtered_name = name.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '');
let posts = lodash.flatten(lodash.map(mysRes, item => item.data.posts));
let url;
for (const val of posts) {
if (
val.post.subject
.replace(/【[^】]*本[^】]*】/g, '')
.includes(filtered_name)
) {
let max = 0;
val.image_list.forEach((v, i) => {
if (
Number(v.size) >= Number(val.image_list[max].size) &&
v.format != 'gif' // 动图天生 size 会撑得很大
) {
max = i;
}
});
url = val.image_list[max].url;
url += '?x-oss-process=image/resize,s_1200/quality,q_90/auto-orient,0/interlace,1/format,jpg';
// created_at = val.post.created_at;
// updated_at = val.post.updated_at;
break;
}
}
if (!url) {
return false;
}
logger.debug(
`${this.e.logFnc} 下载${name}攻略图 - ${guides.guideSources[group - 1]}`
);
const filename = `role_guide_${name}.png`;
const guidePath = path.join(this.getGuideFolder(group), filename);
const download = await downloadFile(url, guidePath);
logger.debug(
`${this.e.logFnc} 下载${name}攻略成功 - ${guides.guideSources[group - 1]}`
);
return download;
}
/** 获取数据 */
async getData(url) {
let response = await fetch(url, { method: 'get' });
if (!response.ok) {
return false;
}
return await response.json();
}
/** %攻略帮助 */
async GuideHelp() {
let reply_msg = [
'绝区零角色攻略帮助:',
'%艾莲攻略+攻略id',
'%更新艾莲攻略+攻略id',
'%设置默认攻略+攻略id',
'%设置所有攻略显示个数+攻略id',
'示例: %艾莲攻略2',
'',
'攻略来源:',
].concat(
guides.guideSources.map((element, index) => `${index + 1}: ${element}`)
);
await this.e.reply(reply_msg.join('\n'));
}
}