2
0
mirror of https://github.com/ctrlcvs/xiaoyao-cvs-plugin.git synced 2024-12-22 19:10:53 +08:00

移除部分文件、优化部分代码

This commit is contained in:
Ctrlcvs 2022-08-29 21:18:09 +08:00
parent f3438233a7
commit c8cf523d1b
10 changed files with 45 additions and 1391 deletions

View File

@ -16,12 +16,12 @@ yunzai-bot扩展图鉴以及体力优化;
#### 安装教程
```
使用gitee
```
git clone https://gitee.com/Ctrlcvs/xiaoyao-cvs-plugin.git ./plugins/xiaoyao-cvs-plugin/
```
使用github
```
git clone https://github.com/Ctrlcvs/xiaoyao-cvs-plugin.git ./plugins/xiaoyao-cvs-plugin/
```
@ -50,15 +50,17 @@ cnpm i superagent
cnpm i promise-retry
```
#### 命令说明
1. 发送 #图鉴更新 获取最新的图鉴记录。(必须)
2. 发送 #**图鉴 进行触发,例如发送 #刻晴图鉴,即可返回对应的图片信息。
3. 发送 #图鉴插件(强制)更新获取最新代码
1. 发送 【#图鉴更新】 获取最新的图鉴记录。(必须)
2. 发送 #**图鉴 进行触发,例如发送 #刻晴图鉴,即可返回对应的图片信息。
3. 发送 【#图鉴插件更新】获取最新代码
4. 别名文件在 /xiaoyao-cvs-plugin/resources/Atlas_alias 目录下面,当前只支持食物及原魔的别名
5. 树脂背景图文件在 /xiaoyao-cvs-plugin/resources/dailyNote/background_image 目录下
6. 发送 #图鉴帮助 获取帮助面板
7. 发送 #图鉴设置 获取图鉴管理面板
8. 发送 #图鉴版本 获取图鉴更新日志
9. 其余具体功能通过 #图鉴帮助 #图鉴版本 查看
10. 发送 #崩坏3签到 可签到崩坏3游戏模块 具体支持【崩坏3、崩坏2、未定义事件】
11. 发送 #云原神签到 可签到云原神游戏
## 其他
<!---

View File

@ -1,3 +0,0 @@
# 米游社公共查询ck支持多个一行一个横杆空格开头
- ltoken=xxx; ltuid=xxx; cookie_token=xxx; account_id=xxx;
- ltoken=xxx; ltuid=xxx; cookie_token=xxx; account_id=xxx;

View File

@ -1,6 +0,0 @@
# 公共查询是否使用用户ck 0-不使用 1-使用
allowUseCookie: 0
# 默认cookie帮助文档链接地址
cookieDoc: docs.qq.com/doc/DUWNVQVFTU3liTVlO
# 米游社原神签到定时任务Cron表达式默认00:02开始执行每10s签到一个
signTime: 0 2 0 * * ?

View File

@ -1,601 +0,0 @@
20000000:
- 主角
- 旅行者
- 卑鄙的外乡人
- 荣誉骑士
-
- 风主
- 岩主
- 雷主
- 草主
- 履刑者
- 抽卡不歪真君
10000002:
- 神里绫华
- Kamisato Ayaka
- Ayaka
- ayaka
- 神里
- 绫华
- 神里凌华
- 凌华
- 白鹭公主
- 神里大小姐
10000003:
-
- Jean
- jean
- 团长
- 代理团长
- 琴团长
- 蒲公英骑士
10000005:
-
- 男主
- 男主角
- 龙哥
- 空哥
10000006:
- 丽莎
- Lisa
- lisa
- 图书管理员
- 图书馆管理员
- 蔷薇魔女
10000007:
-
- 女主
- 女主角
-
-
- 黄毛阿姨
- 荧妹
10000014:
- 芭芭拉
- Barbara
- barbara
- 巴巴拉
- 拉粑粑
- 拉巴巴
- 内鬼
- 加湿器
- 闪耀偶像
- 偶像
10000015:
- 凯亚
- Kaeya
- kaeya
- 盖亚
- 凯子哥
- 凯鸭
- 矿工
- 矿工头子
- 骑兵队长
- 凯子
- 凝冰渡海真君
10000016:
- 迪卢克
- diluc
- Diluc
- 卢姥爷
- 姥爷
- 卢老爷
- 卢锅巴
- 正义人
- 正e人
- 正E人
- 卢本伟
- 暗夜英雄
- 卢卢伯爵
- 落魄了
- 落魄了家人们
10000020:
- 雷泽
- razor
- Razor
- 狼少年
- 狼崽子
- 狼崽
- 卢皮卡
- 小狼
- 小狼狗
10000021:
- 安柏
- Amber
- amber
- 安伯
- 兔兔伯爵
- 飞行冠军
- 侦查骑士
- 点火姬
- 点火机
- 打火机
- 打火姬
10000022:
- 温迪
- Venti
- venti
- 温蒂
- 风神
- 卖唱的
- 巴巴托斯
- 巴巴脱丝
- 芭芭托斯
- 芭芭脱丝
- 干点正事
- 不干正事
- 吟游诗人
- 诶嘿
- 唉嘿
- 摸鱼
10000023:
- 香菱
- Xiangling
- xiangling
- 香玲
- 锅巴
- 厨师
- 万民堂厨师
- 香师傅
10000024:
- 北斗
- Beidou
- beidou
- 大姐头
- 大姐
- 无冕的龙王
- 龙王
10000025:
- 行秋
- Xingqiu
- xingqiu
- 秋秋人
- 秋妹妹
- 书呆子
- 水神
- 飞云商会二少爷
10000026:
-
- Xiao
- xiao
- 杏仁豆腐
- 打桩机
- 插秧
- 三眼五显仙人
- 三眼五显真人
- 降魔大圣
- 护法夜叉
- 快乐风男
- 无聊
- 靖妖傩舞
- 矮子仙人
- 三点五尺仙人
- 跳跳虎
10000027:
- 凝光
- Ningguang
- ningguang
- 富婆
- 天权星
10000029:
- 可莉
- Klee
- klee
- 嘟嘟可
- 火花骑士
- 蹦蹦炸弹
- 炸鱼
- 放火烧山
- 放火烧山真君
- 蒙德最强战力
- 逃跑的太阳
- 啦啦啦
- 哒哒哒
- 炸弹人
- 禁闭室
10000030:
- 钟离
- Zhongli
- zhongli
- 摩拉克斯
- 岩王爷
- 岩神
- 钟师傅
- 天动万象
- 岩王帝君
- 未来可期
- 帝君
- 拒收病婿
10000031:
- 菲谢尔
- Fischl
- fischl
- 皇女
- 小艾米
- 小艾咪
- 奥兹
- 断罪皇女
- 中二病
- 中二少女
- 中二皇女
- 奥兹发射器
10000032:
- 班尼特
- Bennett
- bennett
- 点赞哥
- 点赞
- 倒霉少年
- 倒霉蛋
- 霹雳闪雷真君
- 班神
- 班爷
- 倒霉
- 火神
- 六星真神
10000033:
- 达达利亚
- Tartaglia
- tartaglia
- Childe
- childe
- Ajax
- ajax
- 达达鸭
- 达达利鸭
- 公子
- 玩具销售员
- 玩具推销员
- 钱包
- 鸭鸭
- 愚人众末席
10000034:
- 诺艾尔
- Noelle
- noelle
- 女仆
- 高达
- 岩王帝姬
10000035:
- 七七
- Qiqi
- qiqi
- 僵尸
- 肚饿真君
- 度厄真君
- 77
10000036:
- 重云
- Chongyun
- chongyun
- 纯阳之体
- 冰棍
10000037:
- 甘雨
- Ganyu
- ganyu
- 椰羊
- 椰奶
- 王小美
10000038:
- 阿贝多
- Albedo
- albedo
- 可莉哥哥
- 升降机
- 升降台
- 电梯
- 白垩之子
- 贝爷
- 白垩
- 阿贝少
- 花呗多
- 阿贝夕
- abd
- 阿师傅
10000039:
- 迪奥娜
- Diona
- diona
- 迪欧娜
- dio
- dio娜
- 冰猫
- 猫猫
- 猫娘
- 喵喵
- 调酒师
10000041:
- 莫娜
- Mona
- mona
- 穷鬼
- 穷光蛋
-
- 莫纳
- 占星术士
- 占星师
- 讨龙真君
- 半部讨龙真君
- 阿斯托洛吉斯·莫娜·梅姬斯图斯
10000042:
- 刻晴
- Keqing
- keqing
- 刻情
- 氪晴
- 刻师傅
- 刻师父
- 牛杂
- 牛杂师傅
- 斩尽牛杂
- 免疫
- 免疫免疫
- 屁斜剑法
- 玉衡星
- 阿晴
- 啊晴
10000043:
- 砂糖
- Sucrose
- sucrose
- 雷莹术士
- 雷萤术士
- 雷荧术士
10000044:
- 辛焱
- Xinyan
- xinyan
- 辛炎
- 黑妹
- 摇滚
10000045:
- 罗莎莉亚
- Rosaria
- rosaria
- 罗莎莉娅
- 白色史莱姆
- 白史莱姆
- 修女
- 罗莎利亚
- 罗莎利娅
- 罗沙莉亚
- 罗沙莉娅
- 罗沙利亚
- 罗沙利娅
- 萝莎莉亚
- 萝莎莉娅
- 萝莎利亚
- 萝莎利娅
- 萝沙莉亚
- 萝沙莉娅
- 萝沙利亚
- 萝沙利娅
10000046:
- 胡桃
- Hu Tao
- hu tao
- HuTao
- hutao
- Hutao
- 胡淘
- 往生堂堂主
- 火化
- 抬棺的
- 蝴蝶
- 核桃
- 堂主
- 胡堂主
- 雪霁梅香
10000047:
- 枫原万叶
- Kaedehara Kazuha
- Kazuha
- kazuha
- 万叶
- 叶天帝
- 天帝
- 叶师傅
10000048:
- 烟绯
- Yanfei
- yanfei
- 烟老师
- 律师
- 罗翔
10000049:
- 宵宫
- Yoimiya
- yoimiya
- 霄宫
- 烟花
- 肖宫
- 肖工
- 绷带女孩
10000050:
- 托马
- Thoma
- thoma
- 家政官
- 太郎丸
- 地头蛇
- 男仆
- 拖马
10000051:
- 优菈
- Eula
- eula
- 优拉
- 尤拉
- 尤菈
- 浪花骑士
- 记仇
- 劳伦斯
10000052:
- 雷电将军
- Raiden Shogun
- Raiden
- raiden
- 雷神
- 将军
- 雷军
- 巴尔
- 阿影
-
- 巴尔泽布
- 煮饭婆
- 奶香一刀
- 无想一刀
- 宅女
10000053:
- 早柚
- Sayu
- sayu
- 小狸猫
- 狸猫
- 忍者
10000054:
- 珊瑚宫心海
- Sangonomiya Kokomi
- Kokomi
- kokomi
- 心海
- 军师
- 珊瑚宫
- 书记
- 观赏鱼
- 水母
-
- 美人鱼
10000055:
- 五郎
- Gorou
- gorou
- 柴犬
- 土狗
- 希娜
- 希娜小姐
10000056:
- 九条裟罗
- Kujou Sara
- Sara
- sara
- 九条
- 九条沙罗
- 裟罗
- 沙罗
- 天狗
10000057:
- 荒泷一斗
- Arataki Itto
- Itto
- itto
- 荒龙一斗
- 荒泷天下第一斗
- 一斗
- 一抖
- 荒泷
- 1斗
- 牛牛
- 斗子哥
- 牛子哥
- 牛子
- 孩子王
- 斗虫
- 巧乐兹
- 放牛的
10000058:
- 八重神子
- Yae Miko
- Miko
- miko
- 八重
- 神子
- 狐狸
- 想得美哦
- 巫女
- 屑狐狸
- 骚狐狸
- 八重宫司
- 婶子
- 小八
10000059:
- 鹿野院平藏
- shikanoin heizou
- Heizou
- heizou
- heizo
- 鹿野苑
- 鹿野院
- 平藏
- 鹿野苑平藏
- 鹿野
- 小鹿
10000060:
- 夜兰
- Yelan
- yelan
- 夜阑
- 叶澜
- 腋兰
- 夜天后
10000062:
- 埃洛伊
- Aloy
- aloy
10000063:
- 申鹤
- Shenhe
- shenhe
- 神鹤
- 小姨
- 小姨子
- 审鹤
10000064:
- 云堇
- Yun Jin
- yunjin
- yun jin
- 云瑾
- 云先生
- 云锦
- 神女劈观
10000065:
- 久岐忍
- Kuki Shinobu
- Kuki
- kuki
- Shinobu
- shinobu
- 97忍
- 小忍
- 久歧忍
- 97
- 茄忍
- 阿忍
- 忍姐
10000066:
- 神里绫人
- Kamisato Ayato
- Ayato
- ayato
- 绫人
- 神里凌人
- 凌人
- 0人
- 神人
- 零人
- 大舅哥
10000067:
- 柯莱
- Collei
- collei
10000068:
- 多莉
- Dori
- dori
- 多利
10000069:
- 提纳里
- Tighnari
- tighnari

View File

@ -1,19 +0,0 @@
# 角色名称缩短
sortName:
达达利亚: 公子
神里绫华: 绫华
神里绫人: 绫人
枫原万叶: 万叶
雷电将军: 雷神
珊瑚宫心海: 心海
荒泷一斗: 一斗
八重神子: 八重
九条裟罗: 九条
罗莎莉亚: 罗莎
鹿野院平藏: 平藏
costumes:
- 海风之梦
- 闪耀协奏
- 纱中幽兰
- 霓裾翩跹

View File

@ -8,23 +8,20 @@ import lodash from 'lodash'
import {
Data
} from "../components/index.js";
import {
isV3
} from '../components/Changelog.js';
const plugin = "xiaoyao-cvs-plugin"
/** 配置文件 */
const pathPlugin=`./plugins/${plugin}/data/`
/**
* 配置文件
* 主要用于处理 stoken以及云原神账号数据
*/
class GsCfg {
constructor() {
/** 默认设置 */
this.defSetPath = `./plugins/${plugin}/defSet/`
this.defSet = {}
/** 用户设置 */
this.configPath = `./plugins/${plugin}/config/`
this.config = {}
/** 监听文件 */
this.watcher = {
config: {},
defSet: {}
}
}
async getyunToken(e) {
let file = `${yunpath}/${e.user_id}.yaml`
@ -38,99 +35,27 @@ class GsCfg {
return ""
}
}
/**
* @param app 功能
* @param name 配置文件名称
*/
getdefSet(app, name) {
return this.getYaml(app, name, 'defSet')
}
/** 用户配置 */
getConfig(app, name) {
let ignore = ['mys.pubCk', 'gacha.set']
if (ignore.includes(`${app}.${name}`)) {
return this.getYaml(app, name, 'config')
}
return {
...this.getdefSet(app, name),
...this.getYaml(app, name, 'config')
}
}
/** 通用yaml读取*/
getfileYaml(path, name) {
return YAML.parse(
fs.readFileSync(path + name + ".yaml", 'utf8')
)
}
/**
* 获取配置yaml
* @param app 功能
* @param name 名称
* @param type 默认跑配置-defSet用户配置-config
*/
getYaml(app, name, type) {
let file = this.getFilePath(app, name, type)
let key = `${app}.${name}`
if (this[type][key]) return this[type][key]
this[type][key] = YAML.parse(
fs.readFileSync(file, 'utf8')
)
this.watch(file, app, name, type)
return this[type][key]
}
getFilePath(app, name, type) {
if (type == 'defSet') return `${this.defSetPath}${app}/${name}.yaml`
else return `${this.configPath}${app}.${name}.yaml`
}
/** 监听配置文件 */
watch(file, app, name, type = 'defSet') {
let key = `${app}.${name}`
if (this.watcher[type][key]) return
const watcher = chokidar.watch(file)
watcher.on('change', path => {
delete this[type][key]
logger.mark(`[修改配置文件][${type}][${app}][${name}]`)
if (this[`change_${app}${name}`]) {
this[`change_${app}${name}`]()
}
})
this.watcher[type][key] = watcher
}
get element() {
return {
...this.getdefSet('element', 'role'),
...this.getdefSet('element', 'weapon')
}
}
/** 读取用户绑定的ck */
async getBingCk() {
let ck = {}
let ckQQ = {}
let dir = './data/MysCookie/'
let files = fs.readdirSync(dir).filter(file => file.endsWith('.yaml'))
const readFile = promisify(fs.readFile)
let promises = []
files.forEach((v) => promises.push(readFile(`${dir}${v}`, 'utf8')))
const res = await Promise.all(promises)
res.forEach((v) => {
let tmp = YAML.parse(v)
lodash.forEach(tmp, (v, i) => {
@ -140,7 +65,7 @@ class GsCfg {
}
})
})
return {
ck,
ckQQ
@ -152,11 +77,11 @@ class GsCfg {
let ckQQ = {}
let dir = `plugins/${plugin}/data/yaml/`
let files = fs.readdirSync(dir).filter(file => file.endsWith('.yaml'))
const readFile = promisify(fs.readFile)
let promises = []
files.forEach((v) => promises.push(readFile(`${dir}${v}`, 'utf8')))
const res = await Promise.all(promises)
res.forEach((v, index) => {
@ -197,15 +122,24 @@ class GsCfg {
return {}
}
}
saveBingCk(userId, data) {
let file = `./data/MysCookie/${userId}.yaml`
if (lodash.isEmpty(data)) {
fs.existsSync(file) && fs.unlinkSync(file)
} else {
let yaml = YAML.stringify(data)
fs.writeFileSync(file, yaml, 'utf8')
getStoken(userId) {
let file = `${YamlDataUrl}/${userId}.yaml`
try {
let ck = fs.readFileSync(file, 'utf-8')
ck = YAML.parse(ck)
if(ck?.uid){
let datalist={};
ck.userId=this.e.user_id
datalist[ck.uid]=ck;
ck=datalist
this.saveBingStoken(this.e.user_id,datalist)
}
return ck[this.e.uid]||{}
} catch (error) {
return {}
}
}
saveBingStoken(userId, data) {
let file = `./plugins/${plugin}/data/yaml/${userId}.yaml`
if (lodash.isEmpty(data)) {
@ -227,101 +161,7 @@ class GsCfg {
})
}
}
/**
* 原神角色id转换角色名字
*/
roleIdToName(id) {
let name = this.getdefSet('role', 'name')
if (name[id]) {
return name[id][0]
}
return ''
}
/** 原神角色别名转id */
roleNameToID(keyword) {
if (!this.nameID) {
this.nameID = new Map()
let nameArr = this.getdefSet('role', 'name')
for (let i in nameArr) {
for (let val of nameArr[i]) {
this.nameID.set(val, i)
}
}
}
if (!isNaN(keyword)) keyword = Number(keyword)
let roelId = this.nameID.get(keyword)
return roelId || false
}
/**
* 原神角色武器长名称缩写
* @param name 名称
* @param isWeapon 是否武器
*/
shortName(name, isWeapon = false) {
let other = {}
if (isWeapon) {
other = this.getdefSet('weapon', 'other')
} else {
other = this.getdefSet('role', 'other')
}
return other.sortName[name] ?? name
}
/** 公共配置ck文件修改hook */
async change_myspubCk() {
let MysInfo = await import('./mys/mysInfo.js').default
await new MysInfo().addPubCk()
}
getGachaSet(groupId = '') {
let config = this.getYaml('gacha', 'set', 'config')
let def = config.default
if (config[groupId]) {
return {
...def,
...config[groupId]
}
}
return def
}
getMsgUid(msg) {
let ret = /[1|2|5][0-9]{8}/g.exec(msg)
if (!ret) return false
return ret[0]
}
/**
* 获取消息内原神角色名称uid
* @param msg 判断消息
* @param filterMsg 过滤消息
* @return roleId 角色id
* @return name 角色名称
* @return alias 当前别名
* @return uid 游戏uid
*/
getRole(msg, filterMsg = '') {
let alias = msg.replace(/#|老婆|老公|[1|2|5][0-9]{8}/g, '').trim()
if (filterMsg) {
alias = alias.replace(new RegExp(filterMsg, 'g'), '').trim()
}
/** 判断是否命中别名 */
let roleId = this.roleNameToID(alias)
if (!roleId) return false
/** 获取uid */
let uid = this.getMsgUid(msg) || ''
return {
roleId,
uid,
alias,
name: this.roleIdToName(roleId)
}
}
}
export default new GsCfg()

View File

@ -1,280 +0,0 @@
import fs from "fs";
import cheerio from "cheerio";
import lodash from "lodash";
import fetch from "node-fetch";
import {roleId, abbr} from "../../../config/genshin/roleId.js";
const _path = process.cwd();
let roleIdMap = {};
lodash.forEach(roleId, (names, id) => {
roleIdMap[names[0]] = id;
});
function getBasic($, name) {
let ret = {}
if (name) {
ret.name = name;
} else {
// 采集基础信息
ret.name = $("#scroll_card_item").next("table").find("tr:first td:eq(1)").text();
}
ret.abbr = abbr[ret.name] || ret.name;
ret.id = roleIdMap[ret.name] || '';
let basic = $(".data_cont_wrapper table:first");
let title = function (title) {
return basic.find(`td:contains('${title}')`).next("td").text();
}
ret.title = title("Title");
ret.star = basic.find(`td:contains('Rarity')`).next("td").find(".sea_char_stars_wrap").length;
let elem = basic.find(`td:contains('Element')`).next("td").find("img").attr("data-src");
let elemRet = /\/([^\/]*)_35/.exec(elem);
if (elemRet) {
ret.elem = elemRet[1];
}
ret.allegiance = title("Allegiance");
ret.weapon = title("Weapon Type");
ret.britydah = title("Birthday");
ret.astro = title("Astrolabe Name");
ret.cncv = title("Chinese Seiyuu");
ret.jpcv = title("Japanese Seiyuu");
ret.desc = title("In-game Description");
return ret;
}
function getStat($) {
// 采集属性信息
let stat = $("#beta_scroll_stat").next(".skilldmgwrapper").find("table");
let attrs = [], idx = 4;
stat.find("tr:first td:gt(0)").each(function (i) {
let title = $(this).text();
if (title === "Ascension") {
idx = i + 1;
console.log(idx);
return false;
}
attrs.push($(this).text())
})
let lvs = [], lvStat = {};
stat.find("tr:gt(0)").each(function (i) {
let tr = $(this), lvl = tr.find("td:first").text();
lvs.push(lvl);
let data = [];
tr.find(`td:lt(${idx})`).each(function (i) {
if (i > 0) {
data.push($(this).text())
}
})
lvStat[lvl] = data;
});
return {
lvs,
stat: attrs,
detail: lvStat
};
}
function getTalents($, eq, onlyLv1 = false) {
let root = $("#beta_scroll_attack_talent");
let info = root.nextAll(`.item_main_table:eq(${eq})`);
let name = info.find("tr:first td:eq(1)").text();
let icon = info.find("tr:first td:first img").attr("data-src");
// 说明
let desc = info.find("tr:eq(1) td div.skill_desc_layout").html();
desc = desc.replace(/<color=[^>]*>/g, "");
desc = desc.replace(/<\/color=[^>]*>/g, "");
desc = desc.replace(/<span class=[^>]*>/g, "<strong>");
desc = desc.replace(/<\/span>/g, "</strong>");
desc = desc.split("<br>");
lodash.forEach(desc, (txt, i) => {
desc[i] = lodash.trim(txt);
})
// detail
let detail = root.nextAll(`.skilldmgwrapper:eq(${eq})`).find("table");
let lvs = [], details = [];
detail.find("tr:first td").each(function (i) {
if (onlyLv1 && i > 1) {
return false;
}
if (i > 0) {
lvs.push($(this).text())
}
});
detail.find("tr:gt(0)").each(function () {
let name = $(this).find("td:eq(0)").text();
let values = [], isSame = true;
$(this).find("td:gt(0)").each(function (i) {
if (onlyLv1 && i > 0) {
return false;
}
let val = lodash.trim($(this).text());
values.push(val);
if (i > 0 && values[0] !== val) {
isSame = false;
}
});
details.push({
name, isSame, values
})
});
return {
name,
icon,
desc,
tables: details,
lvs
}
}
let getPassive = function ($, name) {
let table = $("#beta_scroll_passive_talent").next("table")
let ret = [];
table.find("tr").each(function (idx) {
if (idx % 2 === 0) {
let ds = {};
ds.icon = $(this).find("td:first img").attr("data-src");
ds.name = $(this).find("td:eq(1)").text();
ret[idx / 2] = ds;
} else {
ret[(idx - 1) / 2].desc = $(this).find("td").text();
}
})
if (name === "莫娜" || name === "神里绫华") {
ret.push(getTalents($, 2, true))
}
return ret;
}
let getCons = function ($) {
let table = $("#beta_scroll_constellation").next("table")
let ret = {};
table.find("tr").each(function (idx) {
if (idx % 2 === 0) {
let ds = {};
ds.icon = $(this).find("td:first img").attr("data-src");
ds.name = $(this).find("td:eq(1)").text();
ret[idx / 2 + 1] = ds;
} else {
ret[(idx + 1) / 2].desc = $(this).find("td").text();
}
})
return ret;
}
let getImgs = function ($) {
let cont = $("#scroll_gallery").next(".homepage_index_cont");
let img = function (idx, _cont) {
return (_cont || cont).find(`.gallery_content_cont:eq(${idx}) a`).attr("href");
}
let card = $("#scroll_name_card").nextAll(".homepage_index_cont:first");
return {
face: img(0),
side: img(1),
gacha_card: img(2),
gacha_splash: img(3),
profile: img(1, card),
party: img(2, card),
char: $("#live_data table.item_main_table:first td:first img").attr("data-src")
}
}
let getCharData = async function (url, key, name = '') {
url = "https://genshin.honeyhunterworld.com/" + url;
console.log('req' + key, url)
let req = await fetch(url);
let txt = await req.text();
const $ = cheerio.load(txt);
let ret = getBasic($, name);
name = ret.name;
ret.lvStat = getStat($);
ret.talent = {
a: getTalents($, 0),
e: getTalents($, 1),
q: getTalents($, name === "莫娜" || name === "神里绫华" ? 3 : 2)
}
ret.passive = getPassive($, name);
ret.cons = getCons($);
ret.imgs = getImgs($);
return ret;
}
async function saveCharData(url, key, name) {
let data = await getCharData(url, key, name);
name = name || data.name;
if(!name){
console.log("角色名不存在"+url);
return ;
}
let charPath = `${_path}/plugins/miao-plugin/resources/meta/character/${data.name}/`
if (!fs.existsSync(charPath)) {
fs.mkdirSync(charPath);
}
fs.writeFileSync(`${charPath}data.json`, JSON.stringify(data, "", "\t"));
console.log(data.name + "下载完成");
}
async function down() {
// const url = "https://genshin.honeyhunterworld.com/db/char/characters/?lang=CHS";
const url = "https://genshin.honeyhunterworld.com/db/char/unreleased-and-upcoming-characters/?lang=CHS";
let req = await fetch(url);
let txt = await req.text();
let $ = cheerio.load(txt);
let char = $(".char_sea_cont");
char.each(async function () {
let url = $(this).find("a:first").attr("href");
let keyRet = /\/char\/(\w*)\//.exec(url);
if (keyRet && keyRet[1]) {
let key = keyRet[1],
tRet = /traveler_(girl|boy)_(\w*)/.exec(key),
name;
if (tRet) {
if (tRet[1] === "girl") {
name = {anemo: "风", geo: "岩", electro: "雷"}[tRet[2]] + "主";
} else {
return
}
}
if (key === "heizo") {
name = "鹿野院平藏"
}
await saveCharData(url, key, name);
}
});
}
//await saveCharData("https://genshin.honeyhunterworld.com/db/char/ayaka/?lang=CHS", "ayaka");
await down();

View File

@ -1,96 +0,0 @@
import {Data} from "../components/index.js";
import lodash from "lodash";
import fs from "fs";
import request from "request";
const _root = process.cwd() + "/plugins/miao-plugin/";
const _cRoot = _root + "resources/meta/character/";
let readDir = fs.readdirSync(_cRoot);
console.log(readDir);
let imgs = [];
function img(char, url, target) {
imgs.push({
url,
file: `${char.name}/${target}`
})
}
lodash.forEach(readDir, (c) => {
console.log(c);
if (!fs.existsSync(`${_cRoot}/${c}/data.json`)) {
return;
}
let char = Data.readJSON(`${_cRoot}/${c}/`, 'data.json');
if (char.name) {
// 正面
// 角色条
img(char, char.imgs.profile, "profile.png");
// 名片
img(char, char.imgs.party, "party.png");
// img(char, char.imgs.char, "char.png");
// 立绘-竖版
img(char, char.imgs.gacha_card, "gacha_card.png");
// 立绘
img(char, char.imgs.gacha_splash, "gacha_splash.png");
// 正面像
img(char, char.imgs.face, "face.png");
img(char, char.imgs.side, "face.png");
// 天赋
if (char.talent) {
img(char, char.talent.a.icon, "talent_a.png");
img(char, char.talent.e.icon, "talent_e.png");
img(char, char.talent.q.icon, "talent_q.png");
}
// 被动天赋
lodash.forEach(char.passive, (p, idx) => {
img(char, p.icon, `passive_${idx}.png`);
});
// 命座
lodash.forEach(char.cons, (con, idx) => {
img(char, con.icon, `cons_${idx}.png`)
});
}
})
let cacheFile = async function () {
let cacheFn = async function (file) {
if (fs.existsSync(`${_cRoot}/${file.file}`)) {
console.log(`已存在,跳过 ${file.file}`);
return true;
}
try {
let stream = fs.createWriteStream(`${_cRoot}/${file.file}`);
await request("https://genshin.honeyhunterworld.com/" + file.url).pipe(stream);
return new Promise((resolve) => {
stream.on('finish', resolve)
});
} catch (e) {
return false;
}
console.log(`下载成功: ${file.file}`);
return true;
};
console.log('开始下载');
await Data.asyncPool(5, imgs, cacheFn);
}
await cacheFile();
console.log('下载成功');

View File

@ -1,148 +0,0 @@
import Data from "../components/Data.js";
import lodash from "lodash";
import { Character } from "../components/models.js";
import fs from "fs";
import { roleId, abbr } from "../../../config/genshin/roleId.js";
let roleIdMap = {};
lodash.forEach(roleId, (names, id) => {
roleIdMap[names[0]] = id;
})
let _root = process.cwd();
let characterMeta = Data.readJSON("./plugins/miao-plugin/components/meta", "characters.json");
let characters = {};
let pathName = process.cwd() + "/plugins/miao-plugin/resources/meta/character/";
// 获取指定角色的Meta信息
const getMetaData = function (name) {
if (!characterMeta[name]) {
return {};
}
const metaCfg = { lowerFirstKey: true },
meta = characterMeta[name];
// 处理基础信息
let ret = Data.getData(meta, "Name,Key,Title,desc:Description,astro:AstrolabeName", metaCfg);
ret.star = /4star/.test(meta.Star) ? 4 : 5;
let weaponid = /s_(\d*).png$/.exec(meta.Weapon);
if (weaponid) {
ret.weapon = {
233101: "长柄武器",
33101: "单手剑",
43101: "法器",
163101: "双手剑",
213101: "弓"
}[weaponid[1]]
}
// 处理图像信息
//ret.img = Data.getData(meta, "Weapon,Element,City,Profile,GachaCard,GachaSplash,Source", metaCfg);
// 处理元素
let elemRet = /([^\/]*).png$/.exec(meta.Element);
console.log(elemRet[1]);
if (elemRet && elemRet[1]) {
ret.elem = elemRet[1];
ret.element = elemName[ret.elem];
}
// 处理属性
ret.stat = Data.getData(meta, "hp:BaseHP,atk:BaseATK,def:BaseDEF,growStat:AscensionStat,growValue:AscensionStatValue", metaCfg);
ret.lvStat = lodash.map(meta.CharStat, (d) => Data.getData(d, "Name,Values", metaCfg));
if (/Mende/.test(meta.City)) {
ret.city = "蒙德"
} else if (/Liyue/.test(meta.City)) {
ret.city = "璃月";
} else if (/Daoqi/.test(meta.City)) {
ret.city = "稻妻";
}
// 处理材料
let itemKey = lodash.map("talent,boss,gemStone,Local,monster,weekly".split(","), (a) => `${a}:${lodash.upperFirst(a)}.Name`);
ret.item = Data.getData(meta, itemKey, metaCfg)
// 处理天赋
ret.talent = {
a: getTalentData(meta.NormalAttack),
e: getTalentData(meta.TalentE),
q: getTalentData(meta.TalentQ),
};
// 处理其他天赋
ret.passive = lodash.map(meta.PassiveTalents, (d) => Data.getData(d, "Name,desc:Description", metaCfg))
// 处理命座信息
let cons = {};
lodash.forEach(meta.Constellation, (data, key) => {
cons[key.replace("Constellation", "")] = Data.getData(data, "Name,desc:Description", metaCfg);
})
ret.cons = cons;
return ret;
}
// 获取Meta中的天赋信息
const getTalentData = function (data) {
let ret = Data.getData(data, "Name,desc:Description", { lowerFirstKey: true });
let attr = [], table = [], tableKeys;
lodash.forEach(data.Table, (tr) => {
let tmp = { name: tr.Name }, isTable = true, isDef = false, lastVal;
// 检查当前行是否是表格数据
lodash.forEach(tr.Values, (v) => {
// 如果为空则退出循环
if (v === "") {
isTable = false;
return false;
}
if (typeof (lastVal) === "undefined") {
// 设定初始值
lastVal = v;
} else if (lastVal != v) {
// 如果与初始值不一样,则标记退出循环
isDef = true;
return false;
}
});
if (isTable && isDef) {
if (!tableKeys) {
tableKeys = lodash.keys(tr.Values);
}
tmp.value = lodash.map(tableKeys, (k) => tr.Values[k])
table.push(tmp);
} else {
tmp.value = lastVal;
attr.push(tmp)
}
})
ret.attr = attr;
ret.table = table;
ret.tableKeys = tableKeys;
return ret;
}
lodash.forEach(characterMeta, (c) => {
let meta = Character.getMetaData(c.Name);
let data = {
id: roleIdMap[meta.name],
key: meta.key,
name: meta.name,
abbr: abbr[meta.name] || meta.name,
city: meta.city
};
lodash.defaults(data, meta)
Data.createDir(pathName, data.name)
fs.writeFileSync(`${pathName}${data.name}/data.json`, JSON.stringify(data, "", "\t"));
characters[data.id] = { id: data.id, key: data.key, name: meta.name };
})
fs.writeFileSync(`${pathName}index.json`, JSON.stringify(characters, "", "\t"));

File diff suppressed because one or more lines are too long