From b450b7f08bd3a4b7b243f84b5fe15b5771d9d3f7 Mon Sep 17 00:00:00 2001 From: bietiaop <1527109126@qq.com> Date: Sun, 14 Jul 2024 23:36:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=B8=8B=E8=BD=BD=E3=80=81=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=9B=BE=E7=89=87=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/card.js | 6 ++ apps/manage.js | 139 ++++++++++++++++++++++++++++++++++++++++++ apps/panel.js | 9 ++- lib/authkey.js | 6 +- lib/convert/char.js | 8 +++ lib/convert/equip.js | 8 +++ lib/convert/weapon.js | 8 +++ lib/download.js | 3 - 8 files changed, 180 insertions(+), 7 deletions(-) create mode 100644 apps/manage.js diff --git a/apps/card.js b/apps/card.js index 62e7cb3..cd819dc 100644 --- a/apps/card.js +++ b/apps/card.js @@ -39,7 +39,13 @@ export class Card extends ZZZPlugin { const finalIndexData = new ZZZIndexResp(indexData); this.e.playerCard.player.region_name = finalIndexData.stats.world_level_name; + const timer = setTimeout(() => { + if (this?.reply) { + this.reply('查询成功,正在下载图片资源,请稍候。'); + } + }, 3000); await finalIndexData.get_assets(); + clearTimeout(timer); const data = { card: finalIndexData, }; diff --git a/apps/manage.js b/apps/manage.js new file mode 100644 index 0000000..f6f8f3d --- /dev/null +++ b/apps/manage.js @@ -0,0 +1,139 @@ +import { ZZZPlugin } from '../lib/plugin.js'; +import { rulePrefix } from '../lib/common.js'; +import { getAllCharactersID } from '../lib/convert/char.js'; +import { getAllEquipID } from '../lib/convert/equip.js'; +import { getAllWeaponID } from '../lib/convert/weapon.js'; +import { imageResourcesPath } from '../lib/path.js'; +import fs from 'fs'; +import { + getRoleImage, + getSquareAvatar, + getSuitImage, + getWeaponImage, +} from '../lib/download.js'; + +export class Panel extends ZZZPlugin { + constructor() { + super({ + name: '[ZZZ-Plugin]Manage', + dsc: 'zzzmanage', + event: 'message', + priority: 100, + rule: [ + { + reg: `${rulePrefix}下载(全部|所有)资源$`, + fnc: 'downloadAll', + }, + { + reg: `${rulePrefix}删除(全部|所有)资源$`, + fnc: 'deleteAll', + }, + ], + }); + } + async downloadAll() { + if (!this.e.isMaster) return false; + const charIDs = getAllCharactersID(); + const equipSprites = getAllEquipID(); + const weaponSprites = getAllWeaponID(); + const result = { + char: { + success: 0, + failed: 0, + total: charIDs.length, + }, + charSquare: { + success: 0, + failed: 0, + total: charIDs.length, + }, + equip: { + success: 0, + failed: 0, + total: equipSprites.length, + }, + weapon: { + success: 0, + failed: 0, + total: weaponSprites.length, + }, + }; + await this.reply( + '开始下载资源,注意,仅支持下载面板的角色图、武器图、套装图,以及角色卡片的角色头像图。暂不支持下载邦布头像。' + ); + for (const id of charIDs) { + try { + await getSquareAvatar(id); + result.charSquare.success++; + } catch (error) { + logger.error('getSquareAvatar', id, error); + result.charSquare.failed++; + } + try { + await getRoleImage(id); + result.char.success++; + } catch (error) { + logger.error('getRoleImage', id, error); + result.char.failed++; + } + } + for (const sprite of equipSprites) { + try { + await getSuitImage(sprite); + result.equip.success++; + } catch (error) { + logger.error('getSuitImage', sprite, error); + result.equip.failed++; + } + } + for (const sprite of weaponSprites) { + try { + await getWeaponImage(sprite); + result.weapon.success++; + } catch (error) { + logger.error('getWeaponImage', sprite, error); + result.weapon.failed++; + } + } + const messages = [ + '资源下载完成(成功的包含先前下载的图片)', + '角色图需下载' + + charIDs.length + + '张,成功' + + result.char.success + + '张,失败' + + result.char.failed + + '张', + '角色头像图需下载' + + charIDs.length + + '张,成功' + + result.charSquare.success + + '张,失败' + + result.charSquare.failed + + '张', + '套装图需下载' + + equipSprites.length + + '张,成功' + + result.equip.success + + '张,失败' + + result.equip.failed + + '张', + '武器图需下载' + + weaponSprites.length + + '张,成功' + + result.weapon.success + + '张,失败' + + result.weapon.failed + + '张', + ]; + await this.reply(messages.join('\n')); + } + async deleteAll() { + if (!this.e.isMaster) return false; + await this.reply('【注意】正在删除所有资源图片,后续使用需要重新下载!'); + if (fs.existsSync(imageResourcesPath)) { + fs.rmdirSync(imageResourcesPath, { recursive: true }); + } + await this.reply('资源图片已删除!'); + } +} diff --git a/apps/panel.js b/apps/panel.js index 4aed472..7b50ff8 100644 --- a/apps/panel.js +++ b/apps/panel.js @@ -39,7 +39,7 @@ export class Panel extends ZZZPlugin { const { api, deviceFp } = await this.getAPI(); if (!api) return false; await redis.set(`ZZZ:PANEL:${uid}:LASTTIME`, Date.now()); - await this.reply('正在刷新面板列表,请稍后...'); + await this.reply('正在刷新面板列表,请稍候...'); await this.getPlayerInfo(); const result = await refreshPanel(this.e, api, uid, deviceFp); const newChar = result.filter(item => item.isNew); @@ -83,8 +83,13 @@ export class Panel extends ZZZPlugin { await this.reply(`未找到角色${name}的面板信息`); return; } - await this.reply('正在下载面板图片资源,请稍后...'); + const timer = setTimeout(() => { + if (this?.reply) { + this.reply('查询成功,正在下载图片资源,请稍候。'); + } + }, 3000); await data.get_detail_assets(); + clearTimeout(timer); const finalData = { charData: data, }; diff --git a/lib/authkey.js b/lib/authkey.js index aa61cab..e65abb9 100644 --- a/lib/authkey.js +++ b/lib/authkey.js @@ -21,7 +21,7 @@ export function getStoken(e, mysid = '') { try { let cks = fs.readFileSync(file, 'utf-8'); cks = YAML.parse(cks); - for (let ck in cks) { + for (const ck in cks) { if (cks[ck]['stuid'] === mysid) { return cks[ck]; } @@ -47,7 +47,9 @@ export async function getAuthKey(e, _user, zzzUid, authAppid = 'csc') { } let ck = getStoken(e, uidData.ltuid); if (!ck) { - throw new Error('获取cookie失败,请确认绑定了 cookie'); + throw new Error( + '获取cookie失败,请确认绑定了cookie或者查询的UID是否与cookie对应,请确认bot所使用的是绝区零UID' + ); } if (uidData.ltuid !== ck.stuid) { throw new Error( diff --git a/lib/convert/char.js b/lib/convert/char.js index 21dbaa0..cd1702a 100644 --- a/lib/convert/char.js +++ b/lib/convert/char.js @@ -83,3 +83,11 @@ export const atlasToID = name => { const id = charNameToID(_name); return id; }; + +/** + * 获取所有角色ID + * @returns string[] + */ +export const getAllCharactersID = () => { + return Object.keys(PartnerId2SpriteId); +}; diff --git a/lib/convert/equip.js b/lib/convert/equip.js index c3334c5..4a7cab1 100644 --- a/lib/convert/equip.js +++ b/lib/convert/equip.js @@ -17,3 +17,11 @@ export function equipIdToSprite(equipId) { } return null; } + +/** + * 获取所有装备的id + * @returns {string[]} + */ +export function getAllEquipID() { + return Object.keys(equipData); +} diff --git a/lib/convert/weapon.js b/lib/convert/weapon.js index c2daa7f..798059a 100644 --- a/lib/convert/weapon.js +++ b/lib/convert/weapon.js @@ -22,3 +22,11 @@ export const weaponFileNameToID = name => { } return null; }; + +/** + * 获取所有武器的ID + * @returns string[] + */ +export const getAllWeaponID = () => { + return Object.keys(WeaponId2Sprite); +}; diff --git a/lib/download.js b/lib/download.js index 85a989d..d897cf3 100644 --- a/lib/download.js +++ b/lib/download.js @@ -80,16 +80,13 @@ export const getSquareBangboo = async bangbooId => { * @returns Promise */ export const getWeaponImage = async id => { - logger.debug('getWeaponImage', id); const name = weapon.IDToWeaponFileName(id); - logger.debug('getWeaponImage', name); const filename = `${name}.png`; const weaponPath = path.join(ZZZ_WEAPON_PATH, filename); if (fs.existsSync(weaponPath)) return weaponPath; const url = await getResourceRemotePath('weapon', filename); const savePath = weaponPath; const download = await downloadFile(url, savePath); - logger.debug('getWeaponImage', download); return download; };