mirror of
https://github.com/ctrlcvs/xiaoyao-cvs-plugin.git
synced 2024-12-22 19:10:53 +08:00
初步兼容yunzaiV3版本
This commit is contained in:
parent
cb9b06c6ef
commit
a7294079e4
@ -1,3 +1,6 @@
|
||||
# 1.1.1
|
||||
* 初步兼容V3版本
|
||||
|
||||
# 1.1.0
|
||||
* 增加`#图鉴帮助`用于查看帮助命令
|
||||
* 增加`#图鉴设置`用于设置图鉴相关功能
|
||||
|
44
adapter/index.js
Normal file
44
adapter/index.js
Normal file
@ -0,0 +1,44 @@
|
||||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import * as Atlas from '../apps/index.js'
|
||||
import { render } from './render.js'
|
||||
import { checkAuth, getMysApi } from './mys.js'
|
||||
|
||||
export class atlas extends plugin {
|
||||
constructor () {
|
||||
super({
|
||||
name: 'xiaoyao-cvs-plugin',
|
||||
desc: '图鉴插件',
|
||||
event: 'message',
|
||||
priority: 50,
|
||||
rule: [{
|
||||
reg: '.+',
|
||||
fnc: 'dispatch'
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
async dispatch (e) {
|
||||
let msg = e.raw_message
|
||||
e.checkAuth = async function (cfg) {
|
||||
return await checkAuth(e, cfg)
|
||||
}
|
||||
e.getMysApi = async function (cfg) {
|
||||
return await getMysApi(e, cfg)
|
||||
}
|
||||
msg = '#' + msg.replace('#', '')
|
||||
for (let fn in Atlas.rule) {
|
||||
let cfg = Atlas.rule[fn]
|
||||
if (Atlas[fn] && new RegExp(cfg.reg).test(msg)) {
|
||||
let ret = await Atlas[fn](e, {
|
||||
render
|
||||
})
|
||||
if (ret === true) {
|
||||
console.log('ret true')
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
114
adapter/mys.js
Normal file
114
adapter/mys.js
Normal file
@ -0,0 +1,114 @@
|
||||
import MysInfo from '../../genshin/model/mys/mysInfo.js'
|
||||
import lodash from 'lodash'
|
||||
|
||||
class User {
|
||||
constructor (cfg) {
|
||||
this.id = cfg.id
|
||||
this.uid = cfg.uid
|
||||
this.cookie = ''
|
||||
}
|
||||
|
||||
// 保存用户配置
|
||||
async setCfg (path, value) {
|
||||
console.log(this.id)
|
||||
let userCfg = await redis.get(`genshin:user-cfg:${this.id}`)
|
||||
userCfg = userCfg ? JSON.parse(userCfg) : {}
|
||||
lodash.set(userCfg, path, value)
|
||||
await redis.set(`genshin:user-cfg:${this.id}`, JSON.stringify(userCfg))
|
||||
}
|
||||
|
||||
/* 获取用户配置 */
|
||||
async getCfg (path, defaultValue) {
|
||||
let userCfg = await redis.get(`genshin:user-cfg:${this.id}`)
|
||||
userCfg = userCfg ? JSON.parse(userCfg) : {}
|
||||
return lodash.get(userCfg, path, defaultValue)
|
||||
}
|
||||
|
||||
async getMysUser () {
|
||||
return {
|
||||
uid: this.uid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Mys {
|
||||
constructor (e, uid, MysApi) {
|
||||
this.selfUser = new User({ id: e.user_id, uid })
|
||||
this.targetUser = {
|
||||
uid
|
||||
}
|
||||
this.e = e
|
||||
this.MysApi = MysApi
|
||||
e.targetUser = this.targetUser
|
||||
e.selfUser = this.selfUser
|
||||
}
|
||||
|
||||
async getData (api, data) {
|
||||
if (!this.MysApi) {
|
||||
return false
|
||||
}
|
||||
let ret = await MysInfo.get(this.e, api, data)
|
||||
if (!ret) {
|
||||
return false
|
||||
}
|
||||
return ret.data || ret
|
||||
}
|
||||
|
||||
// 获取角色信息
|
||||
async getCharacter () {
|
||||
return await this.getData('character')
|
||||
}
|
||||
|
||||
// 获取角色详情
|
||||
async getAvatar (id) {
|
||||
return await this.getData('detail', { avatar_id: id })
|
||||
}
|
||||
|
||||
// 首页宝箱信息
|
||||
async getIndex () {
|
||||
return await this.getData('index')
|
||||
}
|
||||
|
||||
// 获取深渊信息
|
||||
async getSpiralAbyss (type = 1) {
|
||||
return await this.getData('spiralAbyss', { schedule_type: type })
|
||||
}
|
||||
|
||||
async getDetail (id) {
|
||||
return await this.getData('detail', { avatar_id: id })
|
||||
}
|
||||
|
||||
async getCompute (data) {
|
||||
return await this.getData('compute', data)
|
||||
}
|
||||
|
||||
async getAvatarSkill (id) {
|
||||
return await this.getData('avatarSkill', { avatar_id: id })
|
||||
}
|
||||
|
||||
get isSelfCookie () {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export async function getMysApi (e, cfg) {
|
||||
let { auth = 'all' } = cfg
|
||||
let uid = await MysInfo.getUid(e)
|
||||
if (!uid) return false
|
||||
|
||||
/* 检查user ck */
|
||||
let isCookieUser = await MysInfo.checkUidBing(uid)
|
||||
if (auth === 'cookie' && !isCookieUser) {
|
||||
e.reply('尚未绑定Cookie...')
|
||||
return false
|
||||
}
|
||||
let MysApi = await MysInfo.init(e, 'roleIndex')
|
||||
if (!MysApi) {
|
||||
return false
|
||||
}
|
||||
return new Mys(e, uid, MysApi)
|
||||
}
|
||||
|
||||
export async function checkAuth (e, cfg) {
|
||||
return new User({ id: e.user_id })
|
||||
}
|
21
adapter/render.js
Normal file
21
adapter/render.js
Normal file
@ -0,0 +1,21 @@
|
||||
import lodash from 'lodash'
|
||||
import Data from '../components/Data.js'
|
||||
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
|
||||
|
||||
const plugin = 'xiaoyao-cvs-plugin'
|
||||
|
||||
const _path = process.cwd()
|
||||
|
||||
export async function render (app = '', tpl = '', data = {}, imgType = 'jpeg') {
|
||||
// 在data中保存plugin信息
|
||||
data._plugin = plugin
|
||||
|
||||
if (lodash.isUndefined(data._res_path)) {
|
||||
data._res_path = `../../../../../plugins/${plugin}/resources/`
|
||||
}
|
||||
Data.createDir(_path + '/data/', `html/${plugin}/${app}/${tpl}`)
|
||||
data.saveId = data.saveId || data.save_id || tpl
|
||||
data.tplFile = `./plugins/${plugin}/resources/${app}/${tpl}.html`
|
||||
data.pluResPath = data._res_path
|
||||
return await puppeteer.screenshot(`${plugin}/${app}/${tpl}`, data)
|
||||
}
|
141
apps/Note.js
141
apps/Note.js
@ -5,24 +5,20 @@ import fetch from "node-fetch";
|
||||
import Common from "../components/Common.js";
|
||||
import fs from "fs";
|
||||
import format from "date-format";
|
||||
import puppeteer from "puppeteer";
|
||||
|
||||
import { MysUser, User } from "../../../lib/components/Models.js";
|
||||
import common from "../../../lib/common.js";
|
||||
import { isV3 } from '../components/Changelog.js'
|
||||
import MysInfo from '../model/mys/mysInfo.js'
|
||||
// import { MysUser } from "../../../lib/components/Models.js";
|
||||
// import common from "../../../lib/common.js";
|
||||
import lodash from "lodash";
|
||||
import { getPluginRender } from "../../../lib/render.js"
|
||||
import { getPluginRender } from "./render.js";
|
||||
|
||||
import gsCfg from '../model/gsCfg.js'
|
||||
import {
|
||||
Cfg,
|
||||
Data
|
||||
} from "../components/index.js";
|
||||
import moment from 'moment';
|
||||
// import MysApi from "../components/MysApi.js"
|
||||
|
||||
import {
|
||||
getUrl,
|
||||
getHeaders
|
||||
} from "../../../lib/app/mysApi.js";
|
||||
|
||||
import MysApi from "../model/mys/mysApi.js";
|
||||
const _path = process.cwd();
|
||||
let role_user = Data.readJSON(`${_path}/plugins/xiaoyao-cvs-plugin/resources/dailyNote/json/`, "dispatch_time");
|
||||
|
||||
@ -44,63 +40,64 @@ export async function Note(e, {
|
||||
if (!Cfg.get("sys.Note")&&!poke) {
|
||||
return false;
|
||||
}
|
||||
let cookie, uid;
|
||||
if (NoteCookie[e.user_id]) {
|
||||
cookie = NoteCookie[e.user_id].cookie;
|
||||
uid = NoteCookie[e.user_id].uid;
|
||||
} else if (BotConfig.dailyNote && BotConfig.dailyNote[e.user_id]) {
|
||||
cookie = BotConfig.dailyNote[e.user_id].cookie;
|
||||
uid = BotConfig.dailyNote[e.user_id].uid;
|
||||
} else {
|
||||
e.reply(`尚未配置,无法查询体力\n配置教程:${BotConfig.cookieDoc}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
const response = await getDailyNote(uid, cookie);
|
||||
if (!response.ok) {
|
||||
e.reply("米游社接口错误");
|
||||
return true;
|
||||
}
|
||||
const res = await response.json();
|
||||
|
||||
if (res.retcode == 10102) {
|
||||
if (!e.openDailyNote) {
|
||||
e.openDailyNote = true;
|
||||
await openDailyNote(cookie); //自动开启
|
||||
dailyNote(e);
|
||||
let cookie, uid,res;
|
||||
if(isV3){
|
||||
res = await MysInfo.get(e, 'dailyNote')
|
||||
if (!res || res.retcode !== 0) return false
|
||||
}else{
|
||||
if (NoteCookie[e.user_id]) {
|
||||
cookie = NoteCookie[e.user_id].cookie;
|
||||
uid = NoteCookie[e.user_id].uid;
|
||||
} else if (BotConfig.dailyNote && BotConfig.dailyNote[e.user_id]) {
|
||||
cookie = BotConfig.dailyNote[e.user_id].cookie;
|
||||
uid = BotConfig.dailyNote[e.user_id].uid;
|
||||
} else {
|
||||
e.reply("请先开启实时便笺数据展示");
|
||||
e.reply(`尚未配置,无法查询体力\n配置教程:${BotConfig.cookieDoc}`);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (res.retcode != 0) {
|
||||
if (res.message == "Please login") {
|
||||
Bot.logger.mark(`体力cookie已失效`);
|
||||
e.reply(`体力cookie已失效,请重新配置\n注意:退出米游社登录cookie将会失效!`);
|
||||
|
||||
if (NoteCookie[e.user_id]) {
|
||||
await MysUser.delNote(NoteCookie[e.user_id]);
|
||||
delete NoteCookie[e.user_id];
|
||||
saveJson();
|
||||
const response = await getDailyNote(uid, cookie);
|
||||
if (!response.ok) {
|
||||
e.reply("米游社接口错误");
|
||||
return true;
|
||||
}
|
||||
res = await response.json();
|
||||
if (res.retcode == 10102) {
|
||||
if (!e.openDailyNote) {
|
||||
e.openDailyNote = true;
|
||||
await openDailyNote(cookie); //自动开启
|
||||
dailyNote(e);
|
||||
} else {
|
||||
e.reply("请先开启实时便笺数据展示");
|
||||
}
|
||||
} else {
|
||||
e.reply(`体力查询错误:${res.message}`);
|
||||
Bot.logger.mark(`体力查询错误:${JSON.stringify(res)}`);
|
||||
return true;
|
||||
}
|
||||
if (res.retcode != 0) {
|
||||
if (res.message == "Please login") {
|
||||
Bot.logger.mark(`体力cookie已失效`);
|
||||
e.reply(`体力cookie已失效,请重新配置\n注意:退出米游社登录cookie将会失效!`);
|
||||
if (NoteCookie[e.user_id]) {
|
||||
// await MysUser.delNote(NoteCookie[e.user_id]);
|
||||
delete NoteCookie[e.user_id];
|
||||
saveJson();
|
||||
}
|
||||
} else {
|
||||
e.reply(`体力查询错误:${res.message}`);
|
||||
Bot.logger.mark(`体力查询错误:${JSON.stringify(res)}`);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//redis保存uid
|
||||
redis.set(`genshin:uid:${e.user_id}`, uid, {
|
||||
EX: 2592000
|
||||
});
|
||||
|
||||
//更新
|
||||
if (NoteCookie[e.user_id]) {
|
||||
NoteCookie[e.user_id].maxTime = new Date().getTime() + res.data.resin_recovery_time * 1000;
|
||||
saveJson();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//redis保存uid
|
||||
redis.set(`genshin:uid:${e.user_id}`, uid, {
|
||||
EX: 2592000
|
||||
});
|
||||
|
||||
//更新
|
||||
if (NoteCookie[e.user_id]) {
|
||||
NoteCookie[e.user_id].maxTime = new Date().getTime() + res.data.resin_recovery_time * 1000;
|
||||
saveJson();
|
||||
}
|
||||
|
||||
let data = res.data;
|
||||
@ -143,9 +140,9 @@ export async function Note(e, {
|
||||
val.remained_time = new Date().getTime() + val.remained_time * 1000;
|
||||
// console.log(val.remained_time)
|
||||
var urls_avatar_side = val.avatar_side_icon.split("_");
|
||||
let id = YunzaiApps.mysInfo.roleIdToName(urls_avatar_side[urls_avatar_side.length - 1].replace(
|
||||
let id = gsCfg.roleIdToName(urls_avatar_side[urls_avatar_side.length - 1].replace(
|
||||
/(.png|.jpg)/g, ""));
|
||||
let name = YunzaiApps.mysInfo.roleIdToName(id, true);
|
||||
let name = gsCfg.roleIdToName(id, true);
|
||||
var time_cha = 20;
|
||||
if (role_user["12"].includes(name)) {
|
||||
time_cha = 15;
|
||||
@ -287,14 +284,14 @@ async function dateTime_(time) {
|
||||
time) < 19.5 ? "傍晚" : format("hh",
|
||||
time) < 22 ? "晚上" : "深夜";
|
||||
}
|
||||
|
||||
async function getDailyNote(uid, cookie) {
|
||||
let mysApi = new MysApi(uid, cookie)
|
||||
let {
|
||||
url,
|
||||
headers,
|
||||
query,
|
||||
body
|
||||
} = getUrl("dailyNote", uid);
|
||||
} = mysApi.getUrl("dailyNote", uid);
|
||||
headers.Cookie = cookie;
|
||||
const response = await fetch(url, {
|
||||
method: "get",
|
||||
@ -302,7 +299,6 @@ async function getDailyNote(uid, cookie) {
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
||||
export async function saveJson() {
|
||||
let path = "data/NoteCookie/NoteCookie.json";
|
||||
fs.writeFileSync(path, JSON.stringify(NoteCookie, "", "\t"));
|
||||
@ -337,7 +333,10 @@ export async function DailyNoteTask() {
|
||||
};
|
||||
|
||||
e.reply = (msg) => {
|
||||
common.relpyPrivate(user_id, msg);
|
||||
Bot.pickUser(user_id*1).sendMsg(msg).catch((err) => {
|
||||
logger.mark(err)
|
||||
})
|
||||
// common.relpyPrivate(user_id, msg);
|
||||
};
|
||||
//判断今天是否推送
|
||||
if (cookie.maxTime && cookie.maxTime > 0 && new Date().getTime() > cookie.maxTime - (160 - sendResin) * 8 *
|
||||
|
@ -13,9 +13,7 @@ import {
|
||||
Cfg
|
||||
} from "../components/index.js";
|
||||
import Common from "../components/Common.js";
|
||||
import {
|
||||
init
|
||||
} from "../apps/xiaoyao_image.js"
|
||||
|
||||
|
||||
const require = createRequire(
|
||||
import.meta.url);
|
||||
@ -156,14 +154,12 @@ export async function updateRes(e) {
|
||||
}
|
||||
let numRet = /(\d*) files changed,/.exec(stdout);
|
||||
if (numRet && numRet[1]) {
|
||||
init()
|
||||
e.reply(`报告主人,更新成功,此次更新了${numRet[1]}个图片~`);
|
||||
return true;
|
||||
}
|
||||
if (error) {
|
||||
e.reply("更新失败!\nError code: " + error.code + "\n" + error.stack + "\n 请稍后重试。");
|
||||
} else {
|
||||
init()
|
||||
e.reply("图片加量包更新成功~");
|
||||
}
|
||||
});
|
||||
@ -176,7 +172,6 @@ export async function updateRes(e) {
|
||||
if (error) {
|
||||
e.reply("角色图片加量包安装失败!\nError code: " + error.code + "\n" + error.stack + "\n 请稍后重试。");
|
||||
} else {
|
||||
init()
|
||||
e.reply("角色图片加量包安装成功!您后续也可以通过 #图鉴更新 命令来更新图像");
|
||||
}
|
||||
});
|
||||
|
70
apps/index.js
Normal file
70
apps/index.js
Normal file
@ -0,0 +1,70 @@
|
||||
import lodash from "lodash";
|
||||
import {
|
||||
AtlasAlias
|
||||
} from "./xiaoyao_image.js";
|
||||
import {
|
||||
versionInfo,
|
||||
help
|
||||
} from "./help.js";
|
||||
import {
|
||||
Note,DailyNoteTask,
|
||||
Note_appoint,pokeNote
|
||||
} from "./Note.js";
|
||||
import {
|
||||
rule as adminRule,
|
||||
updateRes,
|
||||
sysCfg,
|
||||
updateMiaoPlugin
|
||||
} from "./admin.js";
|
||||
import {
|
||||
currentVersion
|
||||
} from "../components/Changelog.js";
|
||||
export {
|
||||
updateRes,
|
||||
updateMiaoPlugin,
|
||||
versionInfo,
|
||||
Note_appoint,pokeNote,
|
||||
sysCfg,
|
||||
help,DailyNoteTask,
|
||||
AtlasAlias,
|
||||
Note
|
||||
};
|
||||
|
||||
let rule = {
|
||||
versionInfo: {
|
||||
reg: "^#图鉴版本$",
|
||||
describe: "【#帮助】 图鉴版本介绍",
|
||||
},
|
||||
help: {
|
||||
reg: "^#?(图鉴)?(命令|帮助|菜单|help|说明|功能|指令|使用说明)$",
|
||||
describe: "查看插件的功能",
|
||||
},
|
||||
AtlasAlias: {
|
||||
reg: "^(#(.*)|.*图鉴)$",
|
||||
describe: "角色、食物、怪物、武器信息图鉴",
|
||||
},
|
||||
Note: {
|
||||
reg: "^#*(体力|树脂|查询体力|便笺|便签)$",
|
||||
describe: "体力",
|
||||
},
|
||||
Note_appoint: {
|
||||
reg: "^#体力模板(设置(.*)|列表)$",
|
||||
describe: "体力模板设置",
|
||||
},
|
||||
pokeNote: {
|
||||
reg: "#poke#",
|
||||
describe: "体力",
|
||||
},
|
||||
|
||||
...adminRule
|
||||
};
|
||||
|
||||
lodash.forEach(rule, (r) => {
|
||||
r.priority = r.priority || 50;
|
||||
r.prehash = true;
|
||||
r.hashMark = true;
|
||||
});
|
||||
|
||||
export {
|
||||
rule
|
||||
};
|
@ -3,7 +3,7 @@ import fs from "fs";
|
||||
import puppeteer from "puppeteer";
|
||||
import lodash from "lodash";
|
||||
|
||||
import { Data } from "../../../lib/components/index.js";
|
||||
import { Data } from "../components/index.js";
|
||||
|
||||
const _path = process.cwd();
|
||||
//html模板
|
||||
@ -33,6 +33,7 @@ let shoting = [];
|
||||
* @param data 前端参数,必传 data.save_id 用来区分模板
|
||||
* @param imgType 图片类型 jpeg,png(清晰一点,大小更大)
|
||||
*/
|
||||
const plugin="xiaoyao-cvs-plugin"
|
||||
async function render1(app = "", type = "", data = {}, imgType = "jpeg") {
|
||||
if (lodash.isUndefined(data._res_path)) {
|
||||
data._res_path = `../../../../../plugins/xiaoyao-cvs-plugin/resources/`;
|
||||
@ -197,4 +198,29 @@ async function browserInit() {
|
||||
}
|
||||
}
|
||||
|
||||
export { render1, browserInit, renderNum };
|
||||
function getPluginRender(plugin) {
|
||||
return async function (app = "", type = "", data = {}, imgType = "jpeg") {
|
||||
// 在data中保存plugin信息
|
||||
data._plugin = plugin;
|
||||
|
||||
if (lodash.isUndefined(data._res_path)) {
|
||||
data._res_path = `../../../../../plugins/${plugin}/resources/`;
|
||||
}
|
||||
if (lodash.isUndefined(data._sys_res_path)) {
|
||||
data._sys_res_path = `../../../../../resources/`;
|
||||
}
|
||||
let tplKey = `${plugin}.${app}.${type}`;
|
||||
let saveId = data.save_id;
|
||||
let tplFile = _path + `/plugins/${plugin}/resources/${app}/${type}.html`;
|
||||
Data.createDir(_path + `/data/`, `html/plugin_${plugin}/${app}/${type}`);
|
||||
let savePath = _path + `/data/html/plugin_${plugin}/${app}/${type}/${saveId}.html`;
|
||||
return await doRender(app, type, data, imgType, {
|
||||
tplKey,
|
||||
tplFile,
|
||||
savePath,
|
||||
saveId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { render1, browserInit, renderNum,getPluginRender };
|
||||
|
@ -8,10 +8,11 @@ import {
|
||||
import Data from "../components/Data.js"
|
||||
import path from 'path';
|
||||
import fetch from "node-fetch";
|
||||
import gsCfg from '../model/gsCfg.js'
|
||||
const _path = process.cwd();
|
||||
const __dirname = path.resolve();
|
||||
|
||||
const list = ["shiwu_tujian", "yuanmo_tujian", "mijin_tujian", "shengyiwu_tujian"]
|
||||
const list = ["wuqi_tujian","shiwu_tujian", "yuanmo_tujian", "mijin_tujian", "shengyiwu_tujian"]
|
||||
export async function AtlasAlias(e) {
|
||||
if (!Cfg.get("Atlas.all")) {
|
||||
return false;
|
||||
@ -25,7 +26,7 @@ export async function AtlasAlias(e) {
|
||||
}
|
||||
if (await Atlas_list(e)) return true;
|
||||
if (await roleInfo(e)) return true;
|
||||
if (await weaponInfo(e)) return true;
|
||||
// if (await weaponInfo(e)) return true;
|
||||
// if (await foodInfo(e)) return true;
|
||||
// if (await RelicsInfo(e)) return true;
|
||||
// if (await monsterInfo(e)) return true;
|
||||
@ -37,7 +38,7 @@ export async function AtlasAlias(e) {
|
||||
export async function roleInfo(e) {
|
||||
// let msg=e.msg.replace(/#|图鉴/g,"");
|
||||
let msg = e.msg.replace(/#|#|信息|图鉴|命座|天赋|突破/g, "");
|
||||
let id = YunzaiApps.mysInfo.roleIdToName(msg);
|
||||
let id = gsCfg.roleNameToID(msg)
|
||||
let name;
|
||||
if (["10000005", "10000007", "20000000"].includes(id)) {
|
||||
if (!["风主", "岩主", "雷主"].includes(msg)) {
|
||||
@ -46,7 +47,7 @@ export async function roleInfo(e) {
|
||||
}
|
||||
name = msg;
|
||||
} else {
|
||||
name = YunzaiApps.mysInfo.roleIdToName(id, true);
|
||||
name = gsCfg.roleIdToName(id, true);
|
||||
if (!name) return false;
|
||||
}
|
||||
send_Msg(e, "juese_tujian", name)
|
||||
@ -77,43 +78,43 @@ const send_Msg = function(e, type, name) {
|
||||
e.reply(segment.image(`file:///${path}`));
|
||||
return true;
|
||||
}
|
||||
let weapon = new Map();
|
||||
let weaponFile = [];
|
||||
await init();
|
||||
export async function init(isUpdate = false) {
|
||||
let weaponJson = JSON.parse(fs.readFileSync("./config/genshin/weapon.json", "utf8"));
|
||||
for (let i in weaponJson) {
|
||||
for (let val of weaponJson[i]) {
|
||||
weapon.set(val, i);
|
||||
}
|
||||
}
|
||||
let paths = "./plugins/xiaoyao-cvs-plugin/resources/xiaoyao-plus/wuqi_tujian";
|
||||
if (!fs.existsSync(paths)) {
|
||||
return true;
|
||||
}
|
||||
weaponFile = fs.readdirSync(paths);
|
||||
for (let val of weaponFile) {
|
||||
let name = val.replace(".png", "");
|
||||
weapon.set(name, name);
|
||||
}
|
||||
}
|
||||
// let weapon = new Map();
|
||||
// let weaponFile = [];
|
||||
// await init();
|
||||
// export async function init(isUpdate = false) {
|
||||
// let weaponJson = JSON.parse(fs.readFileSync("./config/genshin/weapon.json", "utf8"));
|
||||
// for (let i in weaponJson) {
|
||||
// for (let val of weaponJson[i]) {
|
||||
// weapon.set(val, i);
|
||||
// }
|
||||
// }
|
||||
// let paths = "./plugins/xiaoyao-cvs-plugin/resources/xiaoyao-plus/wuqi_tujian";
|
||||
// if (!fs.existsSync(paths)) {
|
||||
// return true;
|
||||
// }
|
||||
// weaponFile = fs.readdirSync(paths);
|
||||
// for (let val of weaponFile) {
|
||||
// let name = val.replace(".png", "");
|
||||
// weapon.set(name, name);
|
||||
// }
|
||||
// }
|
||||
|
||||
export async function weaponInfo(e) {
|
||||
let msg = e.msg || '';
|
||||
if (e.atBot) {
|
||||
msg = "#" + msg.replace("#", "");
|
||||
}
|
||||
if (!/(#*(.*)(信息|图鉴|突破|武器|材料)|#(.*))$/.test(msg)) return;
|
||||
// export async function weaponInfo(e) {
|
||||
// let msg = e.msg || '';
|
||||
// if (e.atBot) {
|
||||
// msg = "#" + msg.replace("#", "");
|
||||
// }
|
||||
// if (!/(#*(.*)(信息|图鉴|突破|武器|材料)|#(.*))$/.test(msg)) return;
|
||||
|
||||
let name = weapon.get(msg.replace(/#|#|信息|图鉴|突破|武器|材料/g, ""));
|
||||
// let name = weapon.get(msg.replace(/#|#|信息|图鉴|突破|武器|材料/g, ""));
|
||||
|
||||
if (name) {
|
||||
send_Msg(e, "wuqi_tujian", name)
|
||||
return true;
|
||||
}
|
||||
// if (name) {
|
||||
// send_Msg(e, "wuqi_tujian", name)
|
||||
// return true;
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
// return false;
|
||||
// }
|
||||
export async function Atlas_list(e) {
|
||||
let list = Data.readJSON(`${_path}/plugins/xiaoyao-cvs-plugin/resources/Atlas_alias/`, "Atlas_list");
|
||||
let name = e.msg.replace(/#|井/g, "")
|
||||
|
@ -1,46 +1,48 @@
|
||||
import fs from "fs";
|
||||
import lodash from "lodash";
|
||||
import fs from 'fs'
|
||||
import lodash from 'lodash'
|
||||
|
||||
const _path = process.cwd();
|
||||
const _logPath = `${_path}/plugins/xiaoyao-cvs-plugin/CHANGELOG.md`;
|
||||
const _path = process.cwd()
|
||||
const _logPath = `${_path}/plugins/xiaoyao-cvs-plugin/CHANGELOG.md`
|
||||
|
||||
let logs = {};
|
||||
let changelogs = [];
|
||||
let currentVersion;
|
||||
let versionCount = 4;
|
||||
let logs = {}
|
||||
let changelogs = []
|
||||
let currentVersion
|
||||
let versionCount = 4
|
||||
|
||||
let packageJson = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
||||
let packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'))
|
||||
|
||||
const getLine = function (line) {
|
||||
line = line.replace(/(^\s*\*|\r)/g, '');
|
||||
line = line.replace(/\s*`([^`]+`)/g, '<span class="cmd">$1');
|
||||
line = line.replace(/`\s*/g, '</span>');
|
||||
line = line.replace(/(^\s*\*|\r)/g, '')
|
||||
line = line.replace(/\s*`([^`]+`)/g, '<span class="cmd">$1')
|
||||
line = line.replace(/`\s*/g, '</span>')
|
||||
line = line.replace(/\s*\*\*([^\*]+\*\*)/g, '<span class="strong">$1')
|
||||
line = line.replace(/\*\*\s*/g, '</span>');
|
||||
line = line.replace(/ⁿᵉʷ/g, '<span class="new"></span>');
|
||||
return line;
|
||||
line = line.replace(/\*\*\s*/g, '</span>')
|
||||
line = line.replace(/ⁿᵉʷ/g, '<span class="new"></span>')
|
||||
return line
|
||||
}
|
||||
|
||||
try {
|
||||
if (fs.existsSync(_logPath)) {
|
||||
logs = fs.readFileSync(_logPath, "utf8") || "";
|
||||
logs = logs.split("\n");
|
||||
let temp = {}, lastLine = {};
|
||||
logs = fs.readFileSync(_logPath, 'utf8') || ''
|
||||
logs = logs.split('\n')
|
||||
|
||||
let temp = {};
|
||||
let lastLine = {}
|
||||
lodash.forEach(logs, (line) => {
|
||||
if (versionCount <= -1) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
let versionRet = /^#\s*([0-9\\.~\s]+?)\s*$/.exec(line);
|
||||
let versionRet = /^#\s*([0-9\\.~\s]+?)\s*$/.exec(line)
|
||||
if (versionRet && versionRet[1]) {
|
||||
let v = versionRet[1].trim();
|
||||
let v = versionRet[1].trim()
|
||||
if (!currentVersion) {
|
||||
currentVersion = v;
|
||||
currentVersion = v
|
||||
} else {
|
||||
changelogs.push(temp);
|
||||
changelogs.push(temp)
|
||||
if (/0\s*$/.test(v) && versionCount > 0) {
|
||||
versionCount = 0;
|
||||
versionCount = 0
|
||||
} else {
|
||||
versionCount--;
|
||||
versionCount--
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,26 +52,25 @@ try {
|
||||
}
|
||||
} else {
|
||||
if (!line.trim()) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
if (/^\*/.test(line)) {
|
||||
lastLine = {
|
||||
title: getLine(line),
|
||||
logs: []
|
||||
}
|
||||
temp.logs.push(lastLine);
|
||||
} else if (/^\s{3,}\*/.test(line)) {
|
||||
lastLine.logs.push(getLine(line));
|
||||
temp.logs.push(lastLine)
|
||||
} else if (/^\s{2,}\*/.test(line)) {
|
||||
lastLine.logs.push(getLine(line))
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
// do nth
|
||||
}
|
||||
|
||||
const yunzaiVersion = packageJson.version;
|
||||
const yunzaiVersion = packageJson.version
|
||||
const isV3 = yunzaiVersion[0] === '3'
|
||||
|
||||
export { currentVersion, yunzaiVersion, changelogs };
|
||||
export { currentVersion, yunzaiVersion, isV3, changelogs }
|
||||
|
@ -29,7 +29,7 @@ export const render_path = async function (path, params, cfg,path_) {
|
||||
let paths = path.split("/");
|
||||
let { render, e } = cfg;
|
||||
let _layout_path = process.cwd() + path_;
|
||||
let base64 = await render(paths[0], paths[1], {
|
||||
let base64 = await render1(paths[0], paths[1], {
|
||||
...params,
|
||||
_layout_path,
|
||||
defaultLayout: _layout_path + "default.html",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import lodash from "lodash";
|
||||
import fs from "fs";
|
||||
import request from "request";
|
||||
const _path = process.cwd()
|
||||
|
||||
let Data = {
|
||||
|
||||
@ -51,7 +51,18 @@ let Data = {
|
||||
Data.createDir(path, true);
|
||||
return fs.writeFileSync(`${path}/${file}`, JSON.stringify(data, null, space));
|
||||
},
|
||||
|
||||
async importModule (path, file, rootPath = _path) {
|
||||
if (!/\.js$/.test(file)) {
|
||||
file = file + '.js'
|
||||
}
|
||||
// 检查并创建目录
|
||||
Data.createDir(_path, path, true)
|
||||
if (fs.existsSync(`${_path}/${path}/${file}`)) {
|
||||
let data = await import(`file://${_path}/${path}/${file}`)
|
||||
return data || {}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
/*
|
||||
* 返回一个从 target 中选中的属性的对象
|
||||
*
|
||||
@ -146,34 +157,11 @@ let Data = {
|
||||
return Promise.all(ret);
|
||||
},
|
||||
|
||||
async cacheFile(fileList, cacheRoot) {
|
||||
|
||||
let ret = {};
|
||||
let cacheFn = async function (url) {
|
||||
let path = Data.getUrlPath(url);
|
||||
if (fs.existsSync(`${cacheRoot}/${path.path}/${path.filename}`)) {
|
||||
console.log("已存在,跳过 " + path.path + "/" + path.filename);
|
||||
ret[url] = `${path.path}/${path.filename}`;
|
||||
return true;
|
||||
}
|
||||
|
||||
Data.pathExists(cacheRoot, path.path);
|
||||
await request(url).pipe(fs.createWriteStream(`${cacheRoot}/${path.path}/` + path.filename));
|
||||
console.log("下载成功: " + path.path + "/" + path.filname);
|
||||
ret[url] = `${path.path}/${path.filename}`;
|
||||
return true;
|
||||
};
|
||||
|
||||
await Data.asyncPool(10, fileList, cacheFn);
|
||||
return ret;
|
||||
|
||||
},
|
||||
|
||||
sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default Data;
|
||||
|
2
config/.gitignore
vendored
Normal file
2
config/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
3
defSet/mys/pubCk.yaml
Normal file
3
defSet/mys/pubCk.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
# 米游社公共查询ck,支持多个一行一个,横杆空格开头
|
||||
- ltoken=xxx; ltuid=xxx; cookie_token=xxx; account_id=xxx;
|
||||
- ltoken=xxx; ltuid=xxx; cookie_token=xxx; account_id=xxx;
|
6
defSet/mys/set.yaml
Normal file
6
defSet/mys/set.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
# 公共查询是否使用用户ck 0-不使用 1-使用
|
||||
allowUseCookie: 0
|
||||
# 默认cookie帮助文档链接地址
|
||||
cookieDoc: docs.qq.com/doc/DUWNVQVFTU3liTVlO
|
||||
# 米游社原神签到定时任务,Cron表达式,默认00:02开始执行,每10s签到一个
|
||||
signTime: 0 2 0 * * ?
|
601
defSet/role/name.yaml
Normal file
601
defSet/role/name.yaml
Normal file
@ -0,0 +1,601 @@
|
||||
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
|
19
defSet/role/other.yaml
Normal file
19
defSet/role/other.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
# 角色名称缩短
|
||||
sortName:
|
||||
达达利亚: 公子
|
||||
神里绫华: 绫华
|
||||
神里绫人: 绫人
|
||||
枫原万叶: 万叶
|
||||
雷电将军: 雷神
|
||||
珊瑚宫心海: 心海
|
||||
荒泷一斗: 一斗
|
||||
八重神子: 八重
|
||||
九条裟罗: 九条
|
||||
罗莎莉亚: 罗莎
|
||||
鹿野院平藏: 平藏
|
||||
|
||||
costumes:
|
||||
- 海风之梦
|
||||
- 闪耀协奏
|
||||
- 纱中幽兰
|
||||
- 霓裾翩跹
|
104
index.js
104
index.js
@ -1,84 +1,26 @@
|
||||
import lodash from "lodash";
|
||||
import {
|
||||
AtlasAlias
|
||||
} from "./apps/xiaoyao_image.js";
|
||||
import {
|
||||
versionInfo,
|
||||
help
|
||||
} from "./apps/help.js";
|
||||
// 适配V3 Yunzai,将index.js移至app/index.js
|
||||
import { currentVersion, isV3 } from './components/Changelog.js'
|
||||
import Data from './components/Data.js'
|
||||
|
||||
import common from "../../lib/common.js";
|
||||
import {
|
||||
Note,DailyNoteTask,
|
||||
Note_appoint,pokeNote
|
||||
} from "./apps/Note.js";
|
||||
import {
|
||||
rule as adminRule,
|
||||
updateRes,
|
||||
sysCfg,
|
||||
updateMiaoPlugin
|
||||
} from "./apps/admin.js";
|
||||
import {
|
||||
currentVersion
|
||||
} from "./components/Changelog.js";
|
||||
export {
|
||||
updateRes,
|
||||
updateMiaoPlugin,
|
||||
versionInfo,
|
||||
Note_appoint,pokeNote,
|
||||
sysCfg,
|
||||
help,DailyNoteTask,
|
||||
AtlasAlias,
|
||||
Note
|
||||
};
|
||||
export * from './apps/index.js'
|
||||
let index = { atlas: {} }
|
||||
if (isV3) {
|
||||
index = await Data.importModule('/plugins/xiaoyao-cvs-plugin/adapter', 'index.js')
|
||||
console.log(index)
|
||||
}
|
||||
export const atlas = index.atlas || {}
|
||||
|
||||
let rule = {
|
||||
versionInfo: {
|
||||
reg: "^#图鉴版本$",
|
||||
describe: "【#帮助】 图鉴版本介绍",
|
||||
},
|
||||
help: {
|
||||
reg: "^#?(图鉴)?(命令|帮助|菜单|help|说明|功能|指令|使用说明)$",
|
||||
describe: "查看插件的功能",
|
||||
},
|
||||
AtlasAlias: {
|
||||
reg: "^(#(.*)|.*图鉴)$",
|
||||
describe: "角色、食物、怪物、武器信息图鉴",
|
||||
},
|
||||
Note: {
|
||||
reg: "^#*(体力|树脂|查询体力|便笺|便签)$",
|
||||
describe: "体力",
|
||||
},
|
||||
Note_appoint: {
|
||||
reg: "^#体力模板(设置(.*)|列表)$",
|
||||
describe: "体力模板设置",
|
||||
},
|
||||
pokeNote: {
|
||||
reg: "#poke#",
|
||||
describe: "体力",
|
||||
},
|
||||
|
||||
...adminRule
|
||||
};
|
||||
console.log(`图鉴插件${currentVersion}初始化~`)
|
||||
|
||||
lodash.forEach(rule, (r) => {
|
||||
r.priority = r.priority || 50;
|
||||
r.prehash = true;
|
||||
r.hashMark = true;
|
||||
});
|
||||
|
||||
export {
|
||||
rule
|
||||
};
|
||||
|
||||
console.log(`图鉴插件${currentVersion}初始化~`);
|
||||
setTimeout(async function() {
|
||||
let msgStr = await redis.get("xiaoyao:restart-msg");
|
||||
if (msgStr) {
|
||||
let msg = JSON.parse(msgStr);
|
||||
await common.relpyPrivate(msg.qq, msg.msg);
|
||||
await redis.del("xiaoyao:restart-msg");
|
||||
let msgs = [`当前版本: ${currentVersion}`, `您可使用 #图鉴版本 命令查看更新信息`];
|
||||
await common.relpyPrivate(msg.qq, msgs.join("\n"));
|
||||
}
|
||||
}, 1000);
|
||||
setTimeout(async function () {
|
||||
let msgStr = await redis.get('xiaoyao:restart-msg')
|
||||
let relpyPrivate = async function () {
|
||||
}
|
||||
if (msgStr) {
|
||||
let msg = JSON.parse(msgStr)
|
||||
await relpyPrivate(msg.qq, msg.msg)
|
||||
await redis.del('xiaoyao:restart-msg')
|
||||
let msgs = [`当前图鉴版本: ${currentVersion}`, '您可使用 #图鉴版本 命令查看更新信息']
|
||||
await relpyPrivate(msg.qq, msgs.join('\n'))
|
||||
}
|
||||
}, 1000)
|
||||
|
233
model/gsCfg.js
Normal file
233
model/gsCfg.js
Normal file
@ -0,0 +1,233 @@
|
||||
import YAML from 'yaml'
|
||||
import chokidar from 'chokidar'
|
||||
import fs from 'node:fs'
|
||||
import { promisify } from 'node:util'
|
||||
import lodash from 'lodash'
|
||||
|
||||
const plugin="xiaoyao-cvs-plugin"
|
||||
/** 配置文件 */
|
||||
class GsCfg {
|
||||
constructor () {
|
||||
/** 默认设置 */
|
||||
this.defSetPath = `./plugins/${plugin}/defSet/`
|
||||
this.defSet = {}
|
||||
|
||||
/** 用户设置 */
|
||||
this.configPath = `./plugins/${plugin}/config/`
|
||||
this.config = {}
|
||||
|
||||
/** 监听文件 */
|
||||
this.watcher = { config: {}, defSet: {} }
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @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) => {
|
||||
ck[String(i)] = v
|
||||
if (v.isMain && !ckQQ[String(v.qq)]) {
|
||||
ckQQ[String(v.qq)] = v
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return { ck, ckQQ }
|
||||
}
|
||||
|
||||
getBingCkSingle (userId) {
|
||||
let file = `./data/MysCookie/${userId}.yaml`
|
||||
try {
|
||||
let ck = fs.readFileSync(file, 'utf-8')
|
||||
ck = YAML.parse(ck)
|
||||
return ck
|
||||
} catch (error) {
|
||||
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')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 原神角色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()
|
219
model/mys/mysApi.js
Normal file
219
model/mys/mysApi.js
Normal file
@ -0,0 +1,219 @@
|
||||
import md5 from 'md5'
|
||||
import lodash from 'lodash'
|
||||
import fetch from 'node-fetch'
|
||||
|
||||
export default class MysApi {
|
||||
/**
|
||||
* @param uid 游戏uid
|
||||
* @param cookie 米游社cookie
|
||||
* @param option 其他参数
|
||||
* @param option.log 是否显示日志
|
||||
*/
|
||||
constructor (uid, cookie, option = {}) {
|
||||
this.uid = uid
|
||||
this.cookie = cookie
|
||||
this.server = this.getServer()
|
||||
|
||||
let op = {
|
||||
log: true,
|
||||
...option
|
||||
}
|
||||
this.option = op
|
||||
}
|
||||
|
||||
getUrl (type, data = {}) {
|
||||
let host, hostRecord
|
||||
if (['cn_gf01', 'cn_qd01'].includes(this.server)) {
|
||||
host = 'https://api-takumi.mihoyo.com/'
|
||||
hostRecord = 'https://api-takumi-record.mihoyo.com/'
|
||||
}
|
||||
|
||||
let urlMap = {
|
||||
/** 首页宝箱 */
|
||||
index: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/index`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
/** 深渊 */
|
||||
spiralAbyss: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/spiralAbyss`,
|
||||
query: `role_id=${this.uid}&schedule_type=${data.schedule_type || 1}&server=${this.server}`
|
||||
},
|
||||
/** 角色详情 */
|
||||
character: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/character`,
|
||||
body: { role_id: this.uid, server: this.server }
|
||||
},
|
||||
/** 树脂 */
|
||||
dailyNote: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/dailyNote`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
/** 签到信息 */
|
||||
bbs_sign_info: {
|
||||
url: `${host}event/bbs_sign_reward/info`,
|
||||
query: `act_id=e202009291139501®ion=${this.server}&uid=${this.uid}`,
|
||||
sign: true
|
||||
},
|
||||
/** 签到奖励 */
|
||||
bbs_sign_home: {
|
||||
url: `${host}event/bbs_sign_reward/home`,
|
||||
query: `act_id=e202009291139501®ion=${this.server}&uid=${this.uid}`,
|
||||
sign: true
|
||||
},
|
||||
/** 签到 */
|
||||
bbs_sign: {
|
||||
url: `${host}event/bbs_sign_reward/sign`,
|
||||
body: { act_id: 'e202009291139501', region: this.server, uid: this.uid },
|
||||
sign: true
|
||||
},
|
||||
/** 详情 */
|
||||
detail: {
|
||||
url: `${host}event/e20200928calculate/v1/sync/avatar/detail`,
|
||||
query: `uid=${this.uid}®ion=${this.server}&avatar_id=${data.avatar_id}`
|
||||
},
|
||||
/** 札记 */
|
||||
ys_ledger: {
|
||||
url: 'https://hk4e-api.mihoyo.com/event/ys_ledger/monthInfo',
|
||||
query: `month=${data.month}&bind_uid=${this.uid}&bind_region=${this.server}`
|
||||
},
|
||||
/** 养成计算器 */
|
||||
compute: {
|
||||
url: `${host}event/e20200928calculate/v2/compute`,
|
||||
body: data
|
||||
},
|
||||
/** 角色技能 */
|
||||
avatarSkill: {
|
||||
url: `${host}event/e20200928calculate/v1/avatarSkill/list`,
|
||||
query: `avatar_id=${data.avatar_id}`
|
||||
}
|
||||
}
|
||||
|
||||
if (!urlMap[type]) return false
|
||||
|
||||
let { url, query = '', body = '', sign = '' } = urlMap[type]
|
||||
|
||||
if (query) url += `?${query}`
|
||||
if (body) body = JSON.stringify(body)
|
||||
|
||||
let headers = this.getHeaders(query, body, sign)
|
||||
|
||||
return { url, headers, body }
|
||||
}
|
||||
|
||||
getServer () {
|
||||
let uid = this.uid
|
||||
switch (String(uid)[0]) {
|
||||
case '1':
|
||||
case '2':
|
||||
return 'cn_gf01' // 官服
|
||||
case '5':
|
||||
return 'cn_qd01' // B服
|
||||
}
|
||||
return 'cn_gf01'
|
||||
}
|
||||
|
||||
async getData (type, data = {}, isForce = true) {
|
||||
let { url, headers, body } = this.getUrl(type, data)
|
||||
|
||||
if (!url) return false
|
||||
|
||||
let cahce = await redis.get(`Yz:genshin:mys:cache:${type}:${this.uid}`)
|
||||
if (cahce && !isForce) return JSON.parse(cahce)
|
||||
|
||||
headers.Cookie = this.cookie
|
||||
let param = {
|
||||
headers,
|
||||
timeout: 10000
|
||||
}
|
||||
|
||||
if (body) {
|
||||
param.method = 'post'
|
||||
param.body = body
|
||||
} else {
|
||||
param.method = 'get'
|
||||
}
|
||||
let response = {}
|
||||
let start = Date.now()
|
||||
try {
|
||||
response = await fetch(url, param)
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
return false
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
logger.error(response)
|
||||
return false
|
||||
}
|
||||
if (this.option.log) {
|
||||
logger.mark(`[米游社接口][${type}][${this.uid}] ${Date.now() - start}ms`)
|
||||
}
|
||||
const res = await response.json()
|
||||
|
||||
if (!res) {
|
||||
logger.mark('mys接口没有返回')
|
||||
return false
|
||||
}
|
||||
|
||||
if (res.retcode !== 0) {
|
||||
logger.debug(`[米游社接口][请求参数] ${url} ${JSON.stringify(param)}`)
|
||||
}
|
||||
|
||||
res.api = type
|
||||
|
||||
this.cache(res, type)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
getHeaders (query = '', body = '', sign = false) {
|
||||
if (sign) {
|
||||
return {
|
||||
'x-rpc-app_version': '2.3.0',
|
||||
'x-rpc-client_type': 5,
|
||||
'x-rpc-device_id': this.getGuid(),
|
||||
'User-Agent': ' miHoYoBBS/2.3.0',
|
||||
DS: this.getDsSign()
|
||||
}
|
||||
}
|
||||
return {
|
||||
'x-rpc-app_version': '2.31.1',
|
||||
'x-rpc-client_type': 5,
|
||||
DS: this.getDs(query, body)
|
||||
}
|
||||
}
|
||||
|
||||
getDs (q = '', b = '') {
|
||||
let n = ''
|
||||
if (['cn_gf01', 'cn_qd01'].includes(this.server)) {
|
||||
n = 'xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs'
|
||||
}
|
||||
let t = Math.round(new Date().getTime() / 1000)
|
||||
let r = Math.floor(Math.random() * 900000 + 100000)
|
||||
let DS = md5(`salt=${n}&t=${t}&r=${r}&b=${b}&q=${q}`)
|
||||
return `${t},${r},${DS}`
|
||||
}
|
||||
|
||||
/** 签到ds */
|
||||
getDsSign () {
|
||||
const n = 'h8w582wxwgqvahcdkpvdhbh2w9casgfl'
|
||||
const t = Math.round(new Date().getTime() / 1000)
|
||||
const r = lodash.sampleSize('abcdefghijklmnopqrstuvwxyz0123456789', 6).join('')
|
||||
const DS = md5(`salt=${n}&t=${t}&r=${r}`)
|
||||
return `${t},${r},${DS}`
|
||||
}
|
||||
|
||||
getGuid () {
|
||||
function S4 () {
|
||||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
|
||||
}
|
||||
|
||||
return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4())
|
||||
}
|
||||
|
||||
async cache (res, type) {
|
||||
if (!res || res.retcode !== 0) return
|
||||
redis.setEx(`Yz:genshin:mys:cache:${type}:${this.uid}`, 300, JSON.stringify(res))
|
||||
}
|
||||
}
|
650
model/mys/mysInfo.js
Normal file
650
model/mys/mysInfo.js
Normal file
@ -0,0 +1,650 @@
|
||||
import MysApi from './mysApi.js'
|
||||
import GsCfg from '../gsCfg.js'
|
||||
import lodash from 'lodash'
|
||||
import moment from 'moment'
|
||||
|
||||
/** 公共ck */
|
||||
let pubCk = {}
|
||||
/** 绑定ck */
|
||||
let bingCkUid = {}
|
||||
let bingCkQQ = {}
|
||||
let bingCkLtuid = {}
|
||||
|
||||
export default class MysInfo {
|
||||
/** redis key */
|
||||
static keyPre = 'Yz:genshin:mys:'
|
||||
static key = {
|
||||
/** ck使用次数统计 */
|
||||
count: `${MysInfo.keyPre}ck:count`,
|
||||
/** ck使用详情 */
|
||||
detail: `${MysInfo.keyPre}ck:detail`,
|
||||
/** 单个ck使用次数 */
|
||||
ckNum: `${MysInfo.keyPre}ckNum:`,
|
||||
/** 已失效的ck使用详情 */
|
||||
delDetail: `${MysInfo.keyPre}ck:delDetail`,
|
||||
/** qq-uid */
|
||||
qqUid: `${MysInfo.keyPre}qq-uid:`
|
||||
}
|
||||
|
||||
static tips = '请先#绑定cookie\n发送【体力帮助】查看配置教程'
|
||||
|
||||
constructor (e) {
|
||||
if (e) {
|
||||
this.e = e
|
||||
this.userId = String(e.user_id)
|
||||
}
|
||||
/** 当前查询原神uid */
|
||||
this.uid = ''
|
||||
/** 当前ck信息 */
|
||||
this.ckInfo = {
|
||||
ck: '',
|
||||
uid: '',
|
||||
qq: '',
|
||||
ltuid: '',
|
||||
type: ''
|
||||
}
|
||||
|
||||
this.auth = ['dailyNote', 'bbs_sign_info', 'bbs_sign_home', 'bbs_sign']
|
||||
}
|
||||
|
||||
static async init (e, api) {
|
||||
let mysInfo = new MysInfo(e)
|
||||
|
||||
/** 检查时间 */
|
||||
if (!mysInfo.checkTime()) return false
|
||||
|
||||
/** 初始化绑定ck */
|
||||
await mysInfo.initBingCk()
|
||||
|
||||
/** 初始化公共ck */
|
||||
await mysInfo.initPubCk()
|
||||
|
||||
if (mysInfo.checkAuth(api)) {
|
||||
/** 获取ck绑定uid */
|
||||
mysInfo.uid = (await MysInfo.getSelfUid(e)).uid
|
||||
} else {
|
||||
/** 获取uid */
|
||||
mysInfo.uid = await MysInfo.getUid(e)
|
||||
}
|
||||
|
||||
if (!mysInfo.uid) return false
|
||||
|
||||
mysInfo.e.uid = mysInfo.uid
|
||||
|
||||
/** 获取ck */
|
||||
await mysInfo.getCookie()
|
||||
|
||||
/** 判断回复 */
|
||||
await mysInfo.checkReply()
|
||||
|
||||
return mysInfo
|
||||
}
|
||||
|
||||
/** 获取uid */
|
||||
static async getUid (e) {
|
||||
if (e.uid) return e.uid
|
||||
|
||||
let { msg = '', at = '' } = e
|
||||
|
||||
if (!msg) return false
|
||||
|
||||
let uid = false
|
||||
/** at用户 */
|
||||
if (at) {
|
||||
uid = await redis.get(`${MysInfo.key.qqUid}${at}`)
|
||||
if (uid) return String(uid)
|
||||
e.reply('尚未绑定uid', false, { at })
|
||||
return false
|
||||
}
|
||||
|
||||
let matchUid = (msg = '') => {
|
||||
let ret = /[1|2|5][0-9]{8}/g.exec(msg)
|
||||
if (!ret) return false
|
||||
return ret[0]
|
||||
}
|
||||
|
||||
/** 命令消息携带 */
|
||||
uid = matchUid(msg)
|
||||
if (uid) return String(uid)
|
||||
|
||||
/** 绑定的uid */
|
||||
uid = await redis.get(`${MysInfo.key.qqUid}${e.user_id}`)
|
||||
if (uid) return String(uid)
|
||||
|
||||
/** 群名片 */
|
||||
uid = matchUid(e.sender.card)
|
||||
if (uid) return String(uid)
|
||||
|
||||
e.reply('请先#绑定uid', false, { at })
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/** 获取ck绑定uid */
|
||||
static async getSelfUid (e) {
|
||||
if (e.uid) return e.uid
|
||||
|
||||
let { msg = '', at = '' } = e
|
||||
|
||||
if (!msg) return false
|
||||
|
||||
/** at用户 */
|
||||
if (at && (!bingCkQQ[at] || !bingCkQQ[at].uid)) {
|
||||
e.reply('尚未绑定cookie', false, { at })
|
||||
return false
|
||||
}
|
||||
|
||||
if (!e.user_id || !bingCkQQ[e.user_id] || !bingCkQQ[e.user_id].uid) {
|
||||
e.reply(MysInfo.tips, false, { at })
|
||||
return false
|
||||
}
|
||||
|
||||
return bingCkQQ[e.user_id]
|
||||
}
|
||||
|
||||
/** 判断绑定ck才能查询 */
|
||||
checkAuth (api) {
|
||||
if (lodash.isObject(api)) {
|
||||
for (let i in api) {
|
||||
if (this.auth.includes(i)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else if (this.auth.includes(api)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param api
|
||||
* * `index` 米游社原神首页宝箱等数据
|
||||
* * `spiralAbyss` 原神深渊
|
||||
* * `character` 原神角色详情
|
||||
* * `dailyNote` 原神树脂
|
||||
* * `bbs_sign` 米游社原神签到
|
||||
* * `detail` 详情
|
||||
* * `ys_ledger` 札记
|
||||
* * `compute` 养成计算器
|
||||
* * `avatarSkill` 角色技能
|
||||
*/
|
||||
static async get (e, api, data = {}) {
|
||||
let mysInfo = await MysInfo.init(e, api)
|
||||
|
||||
if (!mysInfo.uid || !mysInfo.ckInfo.ck) return false
|
||||
e.uid = mysInfo.uid
|
||||
|
||||
let mysApi = new MysApi(mysInfo.uid, mysInfo.ckInfo.ck)
|
||||
|
||||
let res
|
||||
if (lodash.isObject(api)) {
|
||||
let all = []
|
||||
lodash.forEach(api, (v, i) => {
|
||||
all.push(mysApi.getData(i, v))
|
||||
})
|
||||
res = await Promise.all(all)
|
||||
|
||||
for (let i in res) {
|
||||
res[i] = await mysInfo.checkCode(res[i], res[i].api)
|
||||
if (res[i].retcode === 0) continue
|
||||
break
|
||||
}
|
||||
} else {
|
||||
res = await mysApi.getData(api, data)
|
||||
if (!res) return false
|
||||
|
||||
res = await mysInfo.checkCode(res, api)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
async checkReply () {
|
||||
if (!this.uid) {
|
||||
this.e.reply('请先#绑定uid')
|
||||
}
|
||||
|
||||
if (!this.ckInfo.ck) {
|
||||
if (lodash.isEmpty(pubCk)) {
|
||||
this.e.reply('请先配置公共查询ck')
|
||||
} else {
|
||||
this.e.reply('公共ck查询次数已用完,暂无法查询新uid')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getCookie () {
|
||||
if (this.ckInfo.ck) return this.ckInfo.ck
|
||||
// 使用用户uid绑定的ck
|
||||
await this.getBingCK() ||
|
||||
// 使用uid已查询的ck
|
||||
await this.getCheckCK() ||
|
||||
// 使用用户绑定的ck
|
||||
await this.getBingCKqq() ||
|
||||
// 使用公共ck
|
||||
await this.getPublicCK()
|
||||
|
||||
return this.ckInfo.ck
|
||||
}
|
||||
|
||||
async getBingCK () {
|
||||
if (!bingCkUid[this.uid]) return false
|
||||
|
||||
this.isSelf = true
|
||||
|
||||
let ck = bingCkUid[this.uid]
|
||||
|
||||
this.ckInfo = ck
|
||||
this.ckInfo.type = 'self'
|
||||
|
||||
logger.mark(`[米游社查询][uid:${this.uid}]${logger.green(`[使用已绑定ck:${ck.ltuid}]`)}`)
|
||||
|
||||
return ck.ck
|
||||
}
|
||||
|
||||
async getCheckCK () {
|
||||
let ltuid = await redis.zScore(MysInfo.key.detail, this.uid)
|
||||
|
||||
if (!ltuid) return false
|
||||
|
||||
this.ckInfo.ltuid = ltuid
|
||||
this.ckInfo.type = 'public'
|
||||
|
||||
/** 使用用户绑定ck */
|
||||
if (bingCkLtuid[ltuid]) {
|
||||
logger.mark(`[米游社查询][uid:${this.uid}]${logger.blue(`[已查询][使用用户ck:${ltuid}]`)}`)
|
||||
|
||||
this.ckInfo = bingCkLtuid[ltuid]
|
||||
this.ckInfo.type = 'self'
|
||||
|
||||
return this.ckInfo.ck
|
||||
}
|
||||
|
||||
/** 公共ck */
|
||||
if (pubCk[ltuid]) {
|
||||
logger.mark(`[米游社查询][uid:${this.uid}]${logger.cyan(`[已查询][使用公共ck:${ltuid}]`)}`)
|
||||
|
||||
this.ckInfo.ck = pubCk[ltuid]
|
||||
return this.ckInfo.ck
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/** 使用用户绑定的ck */
|
||||
async getBingCKqq () {
|
||||
/** 用户没有绑定ck */
|
||||
if (!bingCkQQ[this.userId]) return false
|
||||
|
||||
let ck = bingCkQQ[this.userId]
|
||||
|
||||
/** 判断用户ck使用次数 */
|
||||
let num = await redis.get(`${MysInfo.key.ckNum}${ck.ltuid}`)
|
||||
if (num && num >= 27) {
|
||||
logger.mark(`[米游社查询][uid:${this.uid}] 绑定用户ck次数已用完`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!num) num = 0
|
||||
|
||||
this.ckInfo = ck
|
||||
this.ckInfo.type = 'bing'
|
||||
|
||||
/** 插入查询详情 */
|
||||
await redis.zAdd(MysInfo.key.detail, { score: ck.ltuid, value: this.uid })
|
||||
/** 获取ck查询详情 */
|
||||
let count = await redis.zRangeByScore(MysInfo.key.detail, ck.ltuid, ck.ltuid)
|
||||
|
||||
/** 用户ck也配置公共ck */
|
||||
if (pubCk[ck.ltuid]) {
|
||||
/** 统计ck查询次数 */
|
||||
redis.zAdd(MysInfo.key.count, { score: count.length || 1, value: String(ck.ltuid) })
|
||||
}
|
||||
this.expire(MysInfo.key.detail)
|
||||
|
||||
/** 插入单个查询次数 */
|
||||
redis.setEx(`${MysInfo.key.ckNum}${ck.ltuid}`, this.getEnd(), String(count.length))
|
||||
|
||||
logger.mark(`[米游社查询][uid:${this.uid}]${logger.blue(`[使用用户ck:${ck.ltuid}]`)}[次数:${++num}次]`)
|
||||
|
||||
return ck.ck
|
||||
}
|
||||
|
||||
async getPublicCK () {
|
||||
if (lodash.isEmpty(pubCk)) {
|
||||
logger.mark('请先配置公共查询ck')
|
||||
return false
|
||||
}
|
||||
|
||||
/** 获取使用次数最少的ck */
|
||||
let list = await redis.zRangeByScore(MysInfo.key.count, 0, 27, true)
|
||||
|
||||
if (lodash.isEmpty(list)) {
|
||||
logger.mark('公共查询ck已用完')
|
||||
return false
|
||||
}
|
||||
|
||||
let ltuid = list[0]
|
||||
|
||||
if (!pubCk[ltuid]) {
|
||||
logger.mark(`公共查询ck错误[ltuid:${ltuid}]`)
|
||||
await redis.zAdd(MysInfo.key.count, { score: 99, value: ltuid })
|
||||
return false
|
||||
}
|
||||
|
||||
this.ckInfo.ck = pubCk[ltuid]
|
||||
this.ckInfo.ltuid = ltuid
|
||||
this.ckInfo.type = 'public'
|
||||
|
||||
/** 非原子操作,可能存在误差 */
|
||||
|
||||
/** 插入查询详情 */
|
||||
await redis.zAdd(MysInfo.key.detail, { score: ltuid, value: this.uid })
|
||||
/** 获取ck查询详情 */
|
||||
let count = await redis.zRangeByScore(MysInfo.key.detail, ltuid, ltuid)
|
||||
/** 统计ck查询次数 */
|
||||
redis.zAdd(MysInfo.key.count, { score: count.length, value: ltuid })
|
||||
/** 插入单个查询次数 */
|
||||
redis.setEx(`${MysInfo.key.ckNum}${ltuid}`, this.getEnd(), String(count.length))
|
||||
|
||||
this.expire(MysInfo.key.detail)
|
||||
|
||||
logger.mark(`[米游社查询][uid:${this.uid}]${logger.yellow(`[使用公共ck:${ltuid}][次数:${count.length}]`)}`)
|
||||
|
||||
return pubCk[ltuid]
|
||||
}
|
||||
|
||||
/** 初始化公共查询ck */
|
||||
async initPubCk () {
|
||||
/** 没配置每次都会初始化 */
|
||||
if (!lodash.isEmpty(pubCk)) return
|
||||
|
||||
let ckList = await redis.zRangeByScore(MysInfo.key.count, 0, 100)
|
||||
|
||||
await this.addPubCk(ckList)
|
||||
|
||||
/** 使用用户ck当公共查询 */
|
||||
let set = GsCfg.getConfig('mys', 'set')
|
||||
let userNum = 0
|
||||
if (set.allowUseCookie == 1) {
|
||||
lodash.forEach(bingCkUid, async v => {
|
||||
if (pubCk[v.ltuid]) return
|
||||
pubCk[v.ltuid] = v.ck
|
||||
|
||||
userNum++
|
||||
/** 加入redis统计 */
|
||||
if (!ckList.includes(v.ltuid)) {
|
||||
await redis.zAdd(MysInfo.key.count, { score: 0, value: String(v.ltuid) })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.expire(MysInfo.key.count)
|
||||
|
||||
if (userNum > 0) logger.mark(`加载用户ck:${userNum}个`)
|
||||
}
|
||||
|
||||
/** 加入公共ck池 */
|
||||
async addPubCk (ckList = '') {
|
||||
let ckArr = GsCfg.getConfig('mys', 'pubCk')
|
||||
|
||||
if (!ckList) {
|
||||
ckList = await redis.zRangeByScore(MysInfo.key.count, 0, 100)
|
||||
}
|
||||
|
||||
let pubNum = 0
|
||||
for (let v of ckArr) {
|
||||
let [ltuid = ''] = v.match(/ltuid=(\w{0,9})/g)
|
||||
if (!ltuid) return
|
||||
|
||||
ltuid = String(lodash.trim(ltuid, 'ltuid='))
|
||||
|
||||
if (isNaN(ltuid)) return
|
||||
|
||||
pubCk[ltuid] = v
|
||||
|
||||
pubNum++
|
||||
|
||||
/** 加入redis统计 */
|
||||
if (!ckList.includes(ltuid)) {
|
||||
await redis.zAdd(MysInfo.key.count, { score: 0, value: ltuid })
|
||||
}
|
||||
}
|
||||
if (pubNum > 0) logger.mark(`加载公共ck:${pubNum}个`)
|
||||
}
|
||||
|
||||
async initBingCk () {
|
||||
if (!lodash.isEmpty(bingCkUid)) return
|
||||
|
||||
let res = await GsCfg.getBingCk()
|
||||
bingCkUid = res.ck
|
||||
bingCkQQ = res.ckQQ
|
||||
bingCkLtuid = lodash.keyBy(bingCkUid, 'ltuid')
|
||||
}
|
||||
|
||||
async checkCode (res, type) {
|
||||
res.retcode = Number(res.retcode)
|
||||
if (type == 'bbs_sign') {
|
||||
if ([-5003].includes(res.retcode)) {
|
||||
res.retcode = 0
|
||||
}
|
||||
}
|
||||
switch (res.retcode) {
|
||||
case 0:break
|
||||
case -1:
|
||||
case -100:
|
||||
case 1001:
|
||||
case 10001:
|
||||
case 10103:
|
||||
if (/(登录|login)/i.test(res.message)) {
|
||||
if (this.ckInfo.uid) {
|
||||
this.e.reply(`UID:${this.ckInfo.uid},米游社cookie已失效,请重新绑定cookie`)
|
||||
} else {
|
||||
this.e.reply(`ltuid:${this.ckInfo.ltuid},米游社cookie已失效`)
|
||||
}
|
||||
await this.delCk()
|
||||
} else {
|
||||
this.e.reply(`米游社接口报错,暂时无法查询:${res.message}`)
|
||||
}
|
||||
break
|
||||
case 1008:
|
||||
this.e.reply('\n请先去米游社绑定角色', false, { at: this.userId })
|
||||
break
|
||||
case 10101:
|
||||
this.disableToday()
|
||||
this.e.reply('查询已达今日上限')
|
||||
break
|
||||
case 10102:
|
||||
if (res.message == 'Data is not public for the user') {
|
||||
this.e.reply(`\nUID:${this.ckInfo.uid},米游社数据未公开`, false, { at: this.userId })
|
||||
} else {
|
||||
this.e.reply(`uid:${this.uid},请先去米游社绑定角色`)
|
||||
}
|
||||
break
|
||||
// 伙伴不存在~
|
||||
case -1002:
|
||||
if (res.api == 'detail') res.retcode = 0
|
||||
break
|
||||
default:
|
||||
this.e.reply(`米游社接口报错,暂时无法查询:${res.message || 'error'}`)
|
||||
break
|
||||
}
|
||||
|
||||
if (res.retcode !== 0) {
|
||||
logger.mark(`mys接口报错:${JSON.stringify(res)},uid:${this.uid}`)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
/** 删除失效ck */
|
||||
async delCk () {
|
||||
let ltuid = this.ckInfo.ltuid
|
||||
|
||||
/** 记录公共ck失效 */
|
||||
if (this.ckInfo.type == 'public') {
|
||||
if (bingCkLtuid[ltuid]) {
|
||||
this.ckInfo = bingCkLtuid[ltuid]
|
||||
this.ckInfo.type = 'self'
|
||||
} else {
|
||||
logger.mark(`删除失效ck[ltuid:${ltuid}]`)
|
||||
}
|
||||
}
|
||||
|
||||
if (this.ckInfo.type == 'self' || this.ckInfo.type == 'bing') {
|
||||
/** 获取用户绑定ck */
|
||||
let ck = GsCfg.getBingCkSingle(this.userId)
|
||||
let tmp = ck[this.ckInfo.uid]
|
||||
if (tmp) {
|
||||
ltuid = tmp.ltuid
|
||||
|
||||
logger.mark(`删除失效绑定ck[qq:${this.userId}]`)
|
||||
/** 删除文件保存ck */
|
||||
delete ck[this.ckInfo.uid]
|
||||
GsCfg.saveBingCk(this.userId, ck)
|
||||
|
||||
this.redisDel(ltuid)
|
||||
|
||||
delete pubCk[ltuid]
|
||||
delete bingCkUid[tmp.uid]
|
||||
delete bingCkQQ[tmp.qq]
|
||||
}
|
||||
}
|
||||
|
||||
delete pubCk[ltuid]
|
||||
|
||||
await this.redisDel(ltuid)
|
||||
}
|
||||
|
||||
async redisDel (ltuid) {
|
||||
/** 统计次数设为超限 */
|
||||
await redis.zRem(MysInfo.key.count, String(ltuid))
|
||||
// await redis.setEx(`${MysInfo.key.ckNum}${ltuid}`, this.getEnd(), '99')
|
||||
|
||||
/** 将当前查询记录移入回收站 */
|
||||
await this.detailDel(ltuid)
|
||||
}
|
||||
|
||||
/** 将当前查询记录移入回收站 */
|
||||
async detailDel (ltuid) {
|
||||
let detail = await redis.zRangeByScore(MysInfo.key.detail, ltuid, ltuid)
|
||||
if (!lodash.isEmpty(detail)) {
|
||||
let delDetail = []
|
||||
detail.forEach((v) => {
|
||||
delDetail.push({ score: ltuid, value: String(v) })
|
||||
})
|
||||
await redis.zAdd(MysInfo.key.delDetail, delDetail)
|
||||
this.expire(MysInfo.key.delDetail)
|
||||
}
|
||||
/** 删除当前ck查询记录 */
|
||||
await redis.zRemRangeByScore(MysInfo.key.detail, ltuid, ltuid)
|
||||
}
|
||||
|
||||
async disableToday () {
|
||||
/** 统计次数设为超限 */
|
||||
await redis.zAdd(MysInfo.key.count, { score: 99, value: String(this.ckInfo.ltuid) })
|
||||
await redis.setEx(`${MysInfo.key.ckNum}${this.ckInfo.ltuid}`, this.getEnd(), '99')
|
||||
}
|
||||
|
||||
async expire (key) {
|
||||
return await redis.expire(key, this.getEnd())
|
||||
}
|
||||
|
||||
getEnd () {
|
||||
let end = moment().endOf('day').format('X')
|
||||
return end - moment().format('X')
|
||||
}
|
||||
|
||||
/** 处理用户绑定ck */
|
||||
async addBingCk (ck) {
|
||||
/** 加入缓存 */
|
||||
bingCkUid[ck.uid] = ck
|
||||
bingCkQQ[ck.qq] = ck
|
||||
bingCkLtuid[ck.ltuid] = ck
|
||||
|
||||
let set = GsCfg.getConfig('mys', 'set')
|
||||
|
||||
/** qq-uid */
|
||||
await redis.setEx(`${MysInfo.key.qqUid}${ck.qq}`, 3600 * 24 * 30, String(ck.uid))
|
||||
|
||||
/** 恢复回收站查询记录,会覆盖原来记录 */
|
||||
let detail = await redis.zRangeByScore(MysInfo.key.delDetail, ck.ltuid, ck.ltuid)
|
||||
if (!lodash.isEmpty(detail)) {
|
||||
let delDetail = []
|
||||
detail.forEach((v) => {
|
||||
delDetail.push({ score: ck.ltuid, value: String(v) })
|
||||
})
|
||||
await redis.zAdd(MysInfo.key.detail, delDetail)
|
||||
this.expire(MysInfo.key.detail)
|
||||
}
|
||||
/** 删除回收站记录 */
|
||||
await redis.zRemRangeByScore(MysInfo.key.delDetail, ck.ltuid, ck.ltuid)
|
||||
|
||||
/** 获取ck查询详情 */
|
||||
let count = await redis.zRangeByScore(MysInfo.key.detail, ck.ltuid, ck.ltuid)
|
||||
|
||||
/** 开启了用户ck查询 */
|
||||
if (set.allowUseCookie == 1) {
|
||||
pubCk[ck.ltuid] = ck
|
||||
let ckList = await redis.zRangeByScore(MysInfo.key.count, 0, 100)
|
||||
if (!ckList.includes(ck.ltuid)) {
|
||||
await redis.zAdd(MysInfo.key.count, { score: count.length, value: String(ck.ltuid) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async delBingCk (ck) {
|
||||
delete bingCkUid[ck.uid]
|
||||
delete bingCkQQ[ck.qq]
|
||||
delete bingCkLtuid[ck.ltuid]
|
||||
|
||||
this.detailDel(ck.ltuid)
|
||||
}
|
||||
|
||||
async resetCk () {
|
||||
return await redis.del(MysInfo.key.count)
|
||||
}
|
||||
|
||||
static async initCk () {
|
||||
if (lodash.isEmpty(bingCkUid)) {
|
||||
let mysInfo = new MysInfo()
|
||||
await mysInfo.initBingCk()
|
||||
}
|
||||
}
|
||||
|
||||
static async getBingCkUid () {
|
||||
await MysInfo.initCk()
|
||||
|
||||
return bingCkUid
|
||||
}
|
||||
|
||||
/** 切换uid */
|
||||
static toggleUid (qq, ck) {
|
||||
bingCkQQ[qq] = ck
|
||||
}
|
||||
|
||||
static async checkUidBing (uid) {
|
||||
await MysInfo.initCk()
|
||||
|
||||
if (bingCkUid[uid]) return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/** 数据更新中,请稍后再试 */
|
||||
checkTime () {
|
||||
let hour = moment().hour()
|
||||
let min = moment().minute()
|
||||
let second = moment().second()
|
||||
|
||||
if (hour == 23 && min == 59 && second >= 58) {
|
||||
this.e.reply('数据更新中,请稍后再试')
|
||||
return false
|
||||
}
|
||||
if (hour == 0 && min == 0 && second <= 3) {
|
||||
this.e.reply('数据更新中,请稍后再试')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
88
resources/Atlas_alias/wuqi_tujian.json
Normal file
88
resources/Atlas_alias/wuqi_tujian.json
Normal file
@ -0,0 +1,88 @@
|
||||
{
|
||||
"磐岩结绿": ["绿箭", "绿剑"],
|
||||
"斫峰之刃": ["斫峰", "盾剑"],
|
||||
"无工之剑": ["蜈蚣", "蜈蚣大剑", "无工大剑", "盾大剑", "无工"],
|
||||
"贯虹之槊": ["贯虹", "岩枪", "盾枪"],
|
||||
"赤角石溃杵": ["赤角", "石溃杵"],
|
||||
"尘世之锁": ["尘世锁", "尘世", "盾书", "锁"],
|
||||
|
||||
"终末嗟叹之诗": ["终末", "终末弓", "叹气弓", "乐团弓"],
|
||||
"松籁响起之时": ["松籁", "乐团大剑", "松剑"],
|
||||
"苍古自由之誓": ["苍古", "乐团剑"],
|
||||
|
||||
"渔获": ["鱼叉"],
|
||||
"衔珠海皇": ["海皇", "咸鱼剑", "咸鱼大剑"],
|
||||
|
||||
"匣里日月": ["日月"],
|
||||
"匣里灭辰": ["灭辰"],
|
||||
"匣里龙吟": ["龙吟"],
|
||||
|
||||
"天空之翼": ["天空弓"],
|
||||
"天空之刃": ["天空剑"],
|
||||
"天空之卷": ["天空书", "厕纸"],
|
||||
"天空之脊": ["天空枪", "薄荷枪"],
|
||||
"天空之傲": ["天空大剑"],
|
||||
"四风原典": ["四风"],
|
||||
|
||||
"试作斩岩": ["斩岩"],
|
||||
"试作星镰": ["星镰"],
|
||||
"试作金珀": ["金珀"],
|
||||
"试作古华": ["古华"],
|
||||
"试作澹月": ["澹月"],
|
||||
|
||||
"千岩长枪": ["千岩枪"],
|
||||
"千岩古剑": ["千岩剑", "千岩大剑"],
|
||||
|
||||
"暗巷闪光": ["暗巷剑"],
|
||||
"暗巷猎手": ["暗巷弓"],
|
||||
|
||||
"阿莫斯之弓": ["阿莫斯", "ams", "痛苦弓"],
|
||||
"雾切之回光": ["雾切"],
|
||||
"飞雷之弦振": ["飞雷", "飞雷弓"],
|
||||
"薙草之稻光": ["薙草", "稻光", "薙草稻光", "马尾枪", "马尾", "薙刀"],
|
||||
"神乐之真意": ["神乐", "真意"],
|
||||
"狼的末路": ["狼末"],
|
||||
"护摩之杖": ["护摩", "护摩枪","护膜"],
|
||||
"和璞鸢": ["鸟枪", "绿枪"],
|
||||
"风鹰剑": ["风鹰"],
|
||||
"冬极白星": ["冬极"],
|
||||
"不灭月华": ["月华"],
|
||||
"波乱月白经津": ["波乱", "月白", "波乱月白", "经津", "波波津"],
|
||||
"若水": ["麒麟弓","Aqua","aqua"],
|
||||
"笼钓瓶一心":["妖刀", "红刀", "笼钓瓶", "一心传名刀"],
|
||||
"昭心": ["糟心"],
|
||||
"幽夜华尔兹": ["幽夜", "幽夜弓", "华尔兹", "皇女弓"],
|
||||
"雪葬的星银": ["雪葬", "星银", "雪葬星银", "雪山大剑"],
|
||||
"喜多院十文字": ["喜多院", "十文字"],
|
||||
"万国诸海图谱": ["万国", "万国诸海"],
|
||||
"天目影打刀": ["天目刀", "天目"],
|
||||
"破魔之弓": ["破魔弓"],
|
||||
"曚云之月": ["曚云弓"],
|
||||
"流月针": ["针"],
|
||||
"流浪乐章": ["赌狗书", "赌狗乐章", "赌狗"],
|
||||
"桂木斩长正": ["桂木", "斩长正"],
|
||||
"腐殖之剑": ["腐殖", "腐殖剑"],
|
||||
|
||||
"风花之颂": ["风花弓"],
|
||||
"证誓之明瞳": ["证誓", "明瞳", "证誓明瞳"],
|
||||
"嘟嘟可故事集": ["嘟嘟可"],
|
||||
"辰砂之纺锤": ["辰砂", "辰砂纺锤", "纺锤"],
|
||||
"白辰之环": ["白辰", "白辰环"],
|
||||
|
||||
"决斗之枪": ["决斗枪", "决斗", "月卡枪"],
|
||||
"螭骨剑": ["螭骨", "丈育剑", "离骨剑", "月卡大剑"],
|
||||
"黑剑": ["月卡剑"],
|
||||
"苍翠猎弓": ["绿弓", "月卡弓"],
|
||||
|
||||
"讨龙英杰谭": ["讨龙"],
|
||||
"神射手之誓": ["脚气弓", "神射手"],
|
||||
"黑缨枪": ["史莱姆枪"],
|
||||
|
||||
"贯月矢":["贯月矢","月矢"],
|
||||
"竭泽":["竭泽"],
|
||||
"猎人之径":["猎人之径"],
|
||||
"森林王器":["森林王器","王器"],
|
||||
"王下近侍":["王下近侍","近侍"],
|
||||
"盈满之实":["盈满之实","盈满"],
|
||||
"原木刀":["原木刀","木刀"]
|
||||
}
|
Loading…
Reference in New Issue
Block a user