ZZZ-Plugin/apps/guide.js
2024-07-25 12:00:27 +08:00

193 lines
5.2 KiB
JavaScript
Raw 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 { rulePrefix } from '../lib/common.js';
import { atlasToName } from '../lib/convert/char.js';
import { imageResourcesPath } from '../lib/path.js';
import _ from 'lodash';
import settings from '../lib/settings.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}(更新)?\\S+攻略(\\d+)?$`,
fnc: 'Guide',
},
],
});
this.url =
'https://bbs-api.mihoyo.com/post/wapi/getPostFullInCollection?&gids=8&collection_id=';
this.collection_id = [
[],
// 来源:新艾利都快讯
[2712859],
[2727116],
[2721968],
[2724610],
[2722266],
];
this.source = [
'新艾利都快讯',
'清茶沐沐Kiyotya',
'小橙子阿',
'猫冬',
'月光中心',
];
// 最大攻略数量
this.maxNum = this.source.length;
// 最大显示攻略数量
this.maxForwardGuides = 4;
}
async init() {
for (let group = 1; group <= this.maxNum; group++) {
let guideFolder = this.getGuideFolder(group);
if (!fs.existsSync(guideFolder)) {
fs.mkdirSync(guideFolder, { recursive: true });
}
}
}
getGuideFolder(groupIndex) {
let guideFolder = path.join(ZZZ_GUIDES_PATH, this.source[groupIndex - 1]);
return guideFolder;
}
getGuidePath(groupIndex, characterName) {
let filename = `role_guide_${characterName}.png`;
let guidePath = path.join(this.getGuideFolder(groupIndex), filename);
return guidePath;
}
canGetImageFromFile(guidePath, isUpdate) {
return fs.existsSync(guidePath) && !isUpdate;
}
async Guide() {
let reg = new RegExp(`${rulePrefix}(更新)?(\\S+)攻略(\\d+)?$`);
let [
,
,
,
,
isUpdate,
name,
group = _.get(settings.getConfig('guide'), 'default_guide', 1).toString(),
] = this.e.msg.match(reg);
group = +group;
if (group > this.maxNum) {
await this.reply(`超过攻略数量(${this.maxNum}`);
return;
}
let id = atlasToName(name);
if (!id) {
await this.reply('该角色不存在');
return;
}
if (group === 0) {
// eslint-disable-next-line no-unused-vars
let msg = [];
// eslint-disable-next-line no-unused-vars
for (let i = 1; i <= this.maxNum; i++) {
let guidePath = this.getGuidePath(i, name);
if (this.canGetImageFromFile(guidePath, isUpdate)) {
msg.push(segment.image(`file://${guidePath}`));
continue;
}
if (i < this.maxForwardGuides && (await this.getImg(name, i))) {
msg.push(segment.image(`file://${guidePath}`));
}
}
if (msg.length) {
await this.reply(await common.makeForwardMsg(this.e, [msg]));
}
return false;
}
let guidePath = this.getGuidePath(group, name);
if (this.canGetImageFromFile(guidePath, isUpdate)) {
await this.e.reply(segment.image(`file://${guidePath}`));
return;
}
if (await this.getImg(name, group)) {
await this.e.reply(segment.image(`file://${guidePath}`));
}
}
/** 下载攻略图 */
async getImg(name, group) {
let msyRes = [];
this.collection_id[group].forEach(id =>
msyRes.push(this.getData(this.url + id))
);
try {
msyRes = await Promise.all(msyRes);
} catch (error) {
this.e.reply('暂无攻略数据,请稍后再试');
console.log(`米游社接口报错:${error}}`);
return false;
}
let posts = lodash.flatten(lodash.map(msyRes, item => item.data.posts));
let url, created_at, updated_at;
for (let val of posts) {
if (val.post.subject.replace(/【[^】]*本[^】]*】/g, '').includes(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;
created_at = val.post.created_at;
updated_at = val.post.updated_at;
break;
}
}
if (!url) {
this.e.reply(
`暂无${name}攻略(${this.source[group - 1]}\n请尝试其他的攻略来源查询`
);
return false;
}
console.log(`${this.e.logFnc} 下载${name}攻略图`);
const download = await fetch(url);
const arrayBuffer = await download.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
let guidePath = this.getGuidePath(group, name);
fs.writeFileSync(guidePath, buffer);
console.log(`${this.e.logFnc} 下载${name}攻略成功`);
return true;
}
/** 获取数据 */
async getData(url) {
let response = await fetch(url, { method: 'get' });
if (!response.ok) {
return false;
}
return await response.json();
}
}