import YAML from 'yaml' import chokidar from 'chokidar' import fs from 'node:fs' import lodash from 'lodash' import MysInfo from './mys/mysInfo.js' import NoteUser from './mys/NoteUser.js' /** 配置文件 */ class GsCfg { constructor () { this.isSr = false /** 默认设置 */ this.defSetPath = './plugins/genshin/defSet/' this.defSet = {} /** 用户设置 */ this.configPath = './plugins/genshin/config/' this.config = {} /** 监听文件 */ this.watcher = { config: {}, defSet: {} } this.ignore = ['mys.pubCk', 'gacha.set', 'bot.help', 'role.name'] } get element () { return { ...this.getdefSet('element', 'role'), ...this.getdefSet('element', 'weapon') } } /** * @param app 功能 * @param name 配置文件名称 */ getdefSet (app, name) { return this.getYaml(app, name, 'defSet') } /** 用户配置 */ getConfig (app, name) { if (this.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] try { this[type][key] = YAML.parse( fs.readFileSync(file, 'utf8') ) } catch (error) { logger.error(`[${app}][${name}] 格式错误 ${error}`) return false } 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 } /** 读取所有用户绑定的ck */ async getBingCk (game = 'gs') { let ck = {} let ckQQ = {} let noteCk = {} await NoteUser.forEach(async function (user) { let qq = user.qq + '' let tmp = {} lodash.forEach(user.mysUsers, (mys) => { let uids = mys.getUids(game) lodash.forEach(uids, (uid) => { let ckData = mys.getCkInfo(game) ckData.qq = qq if (!ck[uid]) { ck[uid] = ckData ckQQ[qq] = ckData } tmp[uid] = ckData }) }) noteCk[qq] = tmp }) return { ck, ckQQ, noteCk } } /** * 原神角色id转换角色名字 */ roleIdToName (id) { let name = this.getdefSet('role', this.isSr ? 'sr_name' : 'name') if (name[id]) { return name[id][0] } return '' } /** 原神角色别名转id */ roleNameToID (keyword, isSr) { if (isSr) this.isSr = isSr if (!isNaN(keyword)) keyword = Number(keyword) this.getAbbr() let roelId = this[this.isSr ? 'sr_nameID' : 'nameID'].get(String(keyword)) return roelId || false } /** 获取角色别名 */ getAbbr () { if (this[this.isSr ? 'sr_nameID' : 'nameID']) return this.nameID = new Map() this.sr_nameID = new Map() let nameArr = this.getdefSet('role', 'name') let sr_nameArr = this.getdefSet('role', 'sr_name') let nameArrUser = this.getConfig('role', 'name') let nameID = {} for (let i in nameArr) { nameID[nameArr[i][0]] = i for (let abbr of nameArr[i]) { this.nameID.set(String(abbr), i) } } for (let i in sr_nameArr) { nameID[sr_nameArr[i][0]] = i for (let abbr of sr_nameArr[i]) { this.sr_nameID.set(String(abbr), i) } } for (let i in nameArrUser) { for (let abbr of nameArrUser[i]) { this.nameID.set(String(abbr), nameID[i]) } } } /** * 原神角色武器长名称缩写 * @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 () { await MysInfo.initCache() await MysInfo.initPubCk() } 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-9][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 = '', isSr = false) { let alias = msg.replace(/#|老婆|老公|[1|2|5-9][0-9]{8}/g, '').trim() if (filterMsg) { alias = alias.replace(new RegExp(filterMsg, 'g'), '').trim() } this.isSr = isSr /** 判断是否命中别名 */ let roleId = this.roleNameToID(alias) if (!roleId) return false /** 获取uid */ let uid = this.getMsgUid(msg) || '' return { roleId, uid, alias, name: this.roleIdToName(roleId) } } cpCfg (app, name) { if (!fs.existsSync('./plugins/genshin/config')) { fs.mkdirSync('./plugins/genshin/config') } let set = `./plugins/genshin/config/${app}.${name}.yaml` if (!fs.existsSync(set)) { fs.copyFileSync(`./plugins/genshin/defSet/${app}/${name}.yaml`, set) } } getWeaponDataByWeaponHash (hash) { console.log('gsCfg.getWeaponDataByWeaponHash() 已废弃') return {} } getAllAbbr () { console.log('gsCfg.getAllAbbr() 已废弃') return {} } getBingCkSingle (userId) { console.log('gsCfg.getBingCkSingle() 已废弃') return {} } saveBingCk (userId, data) { console.log('gsCfg.saveBingCk() 已废弃') } getElementByRoleName (roleName) { console.log('gsCfg.getElementByRoleName() 已废弃') return '' } getSkillDataByskillId (skillId, roleName) { console.log('gsCfg.getSkillDataByskillId() 已废弃') return {} } fightPropIdToName (propId) { console.log('gsCfg.fightPropIdToName() 已废弃') return '' } getRoleTalentByTalentId (talentId) { console.log('gsCfg.getRoleTalentByTalentId 已废弃') return {} } } export default new GsCfg()