CikeyQi's picture
Upload 154 files (#1)
af5a34b
import YAML from 'yaml'
import chokidar from 'chokidar'
import fs from 'node:fs'
import YamlReader from './YamlReader.js'
import cfg from '../../../lib/config/config.js'
import _ from 'lodash'
import { modifyWebSocket } from './WebSocket.js'
import { cfgSchema } from '../config/system/cfg_system.js'
const Path = process.cwd()
const Plugin_Name = 'ws-plugin'
const Plugin_Path = `${Path}/plugins/${Plugin_Name}`
class Config {
constructor() {
this.config = {}
this.oldConfig = {}
/** 监听文件 */
this.watcher = { config: {}, defSet: {} }
this.initCfg()
}
/** 初始化配置 */
initCfg() {
let path = `${Plugin_Path}/config/config/`
if (!fs.existsSync(path)) fs.mkdirSync(path)
let pathDef = `${Plugin_Path}/config/default_config/`
const files = fs.readdirSync(pathDef).filter(file => file.endsWith('.yaml'))
for (let file of files) {
if (!fs.existsSync(`${path}${file}`)) {
fs.copyFileSync(`${pathDef}${file}`, `${path}${file}`)
}
this.watch(`${path}${file}`, file.replace('.yaml', ''), 'config')
}
}
/** 主人QQ */
get masterQQ() {
return cfg.masterQQ
}
/** Bot账号:[主人帐号] */
get master() {
return cfg.master
}
/** 云崽黑名单群 */
get blackGroup() {
return cfg.getOther().blackGroup
}
/** 云崽白名单群 */
get whiteGroup() {
return cfg.getOther().whiteGroup
}
/** 心跳 */
get heartbeatInterval() {
return this.getDefOrConfig('ws-config').heartbeatInterval
}
/** 数据上报类型 */
get messagePostFormat() {
return this.getDefOrConfig('ws-config').messagePostFormat
}
/** 连接列表 */
get servers() {
return this.getDefOrConfig('ws-config').servers
}
get noMsgStart() {
return this.getDefOrConfig('msg-config').noMsgStart
}
get noMsgInclude() {
return this.getDefOrConfig('msg-config').noMsgInclude
}
get howToMaster() {
return this.getDefOrConfig('msg-config').howToMaster
}
/**掉线时否通知主人 */
get disconnectToMaster() {
return this.getDefOrConfig('msg-config').disconnectToMaster
}
/**重连成功时是否通知主人 */
get reconnectToMaster() {
return this.getDefOrConfig('msg-config').reconnectToMaster
}
/**首次连接成功时是否通知主人 */
get firstconnectToMaster() {
return this.getDefOrConfig('msg-config').firstconnectToMaster
}
/**消息存储时间 */
get msgStoreTime() {
return this.getDefOrConfig('msg-config').msgStoreTime
}
/**禁用群聊列表 */
get noGroup() {
return this.getDefOrConfig('msg-config').noGroup
}
/** 白名单群聊 */
get yesGroup() {
return this.getDefOrConfig('msg-config').yesGroup
}
/** 禁言拦截 */
get muteStop() {
return this.getDefOrConfig('msg-config').muteStop
}
/** red 发送伪造转发消息方式 */
get redSendForwardMsgType(){
return this.getDefOrConfig('msg-config').redSendForwardMsgType
}
/**群管理员变动是否上报 */
get groupAdmin() {
return this.getDefOrConfig('notice-config').groupAdmin
}
/**群成员减少是否上报 */
get groupDecrease() {
return this.getDefOrConfig('notice-config').groupDecrease
}
/**群成员增加是否上报 */
get groupIncrease() {
return this.getDefOrConfig('notice-config').groupIncrease
}
/**群禁言是否上报 */
get groupBan() {
return this.getDefOrConfig('notice-config').groupBan
}
/**好友添加是否上报 */
get friendIncrease() {
return this.getDefOrConfig('notice-config').friendIncrease
}
/**群消息撤回是否上报 */
get groupRecall() {
return this.getDefOrConfig('notice-config').groupRecall
}
/**好友消息撤回是否上报 */
get friendRecall() {
return this.getDefOrConfig('notice-config').friendRecall
}
/**群内戳一戳是否上报 */
get groupPoke() {
return this.getDefOrConfig('notice-config').groupPoke
}
/** 好友申请是否上报 */
get friendAdd() {
return this.getDefOrConfig('request-config').friendAdd
}
/** 群聊邀请是否上报 (邀请机器人入群) */
get groupInvite() {
return this.getDefOrConfig('request-config').groupInvite
}
/** 群聊申请是否上报 (申请加入群聊) */
get groupAdd() {
return this.getDefOrConfig('request-config').groupAdd
}
/** 默认配置和用户配置 */
getDefOrConfig(name) {
let def = this.getdefSet(name)
let config = this.getConfig(name)
return { ...def, ...config }
}
/** 默认配置 */
getdefSet(name) {
return this.getYaml('default_config', name)
}
/** 用户配置 */
getConfig(name) {
return this.getYaml('config', name)
}
/**
* 获取配置yaml
* @param type 默认跑配置-defSet,用户配置-config
* @param name 名称
*/
getYaml(type, name) {
let file = `${Plugin_Path}/config/${type}/${name}.yaml`
let key = `${type}.${name}`
if (this.config[key]) return this.config[key]
this.config[key] = YAML.parse(
fs.readFileSync(file, 'utf8')
)
this.watch(file, name, type)
return this.config[key]
}
/** 监听配置文件 */
watch(file, name, type = 'default_config') {
let key = `${type}.${name}`
if (!this.oldConfig[key]) this.oldConfig[key] = _.cloneDeep(this.config[key])
if (this.watcher[key]) return
const watcher = chokidar.watch(file)
watcher.on('change', path => {
delete this.config[key]
if (typeof Bot == 'undefined') return
logger.mark(`[ws-plugin][修改配置文件][${type}][${name}]`)
if (name == 'ws-config') {
const oldConfig = this.oldConfig[key]
delete this.oldConfig[key]
const newConfig = this.getYaml(type, name)
const object = this.findDifference(oldConfig, newConfig)
// console.log(object);
for (const key in object) {
if (Object.hasOwnProperty.call(object, key)) {
const value = object[key];
const arr = key.split('.')
if (arr[0] !== 'servers') continue
let data = newConfig.servers[arr[1]]
if (typeof data === 'undefined') data = oldConfig.servers[arr[1]]
const target = {
type: null,
data
}
if (typeof value['newValue'] === 'object' && typeof value['oldValue'] === 'undefined') {
target.type = 'add'
}
else if (typeof value['newValue'] === 'undefined' && typeof value['oldValue'] === 'object') {
target.type = 'del'
}
else if (value['newValue'] === true && (value['oldValue'] === false || typeof value['oldValue'] === 'undefined')) {
target.type = 'close'
}
else if (value['newValue'] === false && (value['oldValue'] === true || typeof value['oldValue'] === 'undefined')) {
target.type = 'open'
}
modifyWebSocket(target)
}
}
}
})
this.watcher[key] = watcher
}
getCfgSchemaMap() {
let ret = {}
_.forEach(cfgSchema, (cfgGroup) => {
_.forEach(cfgGroup.cfg, (cfgItem, cfgKey) => {
ret[cfgItem.key] = cfgItem
cfgItem.cfgKey = cfgKey
})
})
return ret
}
getCfgSchema() {
return cfgSchema
}
getCfg() {
let wsconfig = this.getDefOrConfig('ws-config')
let msgconfig = this.getDefOrConfig('msg-config')
let noticeconfig = this.getDefOrConfig('notice-config')
let requestconfig = this.getDefOrConfig('request-config')
return {
...wsconfig,
...msgconfig,
...noticeconfig,
...requestconfig
}
}
/**
* @description: 修改设置
* @param {String} name 文件名
* @param {String} key 修改的key值
* @param {String|Number} value 修改的value值
* @param {'config'|'default_config'} type 配置文件或默认
*/
modify(name, key, value, type = 'config') {
let path = `${Plugin_Path}/config/${type}/${name}.yaml`
new YamlReader(path).set(key, value)
this.oldConfig[key] = _.cloneDeep(this.config[key])
delete this.config[`${type}.${name}`]
}
/**
* @description: 修改配置数组
* @param {String} name 文件名
* @param {String|Number} key key值
* @param {String|Number} value value
* @param {'add'|'del'} category 类别 add or del
* @param {'config'|'default_config'} type 配置文件或默认
*/
modifyarr(name, key, value, category = 'add', type = 'config') {
let path = `${Plugin_Path}/config/${type}/${name}.yaml`
let yaml = new YamlReader(path)
if (category == 'add') {
yaml.addIn(key, value)
} else {
let index = yaml.jsonData[key].indexOf(value)
yaml.delete(`${key}.${index}`)
}
}
setArr(name, key, item, value, type = 'config') {
let path = `${Plugin_Path}/config/${type}/${name}.yaml`
let yaml = new YamlReader(path)
let arr = yaml.get(key).slice();
arr[item] = value
yaml.set(key, arr)
}
delServersArr(value, name = 'ws-config', type = 'config') {
let path = `${Plugin_Path}/config/${type}/${name}.yaml`
let yaml = new YamlReader(path)
let key = 'servers'
// let index = yaml.jsonData[key].indexOf(value)
let index = yaml.jsonData[key].findIndex(item => item.name === value);
yaml.delete(`${key}.${index}`)
}
/**
* @description 对比两个对象不同的值
* @param {*} oldObj
* @param {*} newObj
* @param {*} parentKey
* @returns
*/
findDifference(obj1, obj2, parentKey = '') {
const result = {};
for (const key in obj1) {
const fullKey = parentKey ? `${parentKey}.${key}` : key;
if (_.isObject(obj1[key]) && _.isObject(obj2[key])) {
const diff = this.findDifference(obj1[key], obj2[key], fullKey);
if (!_.isEmpty(diff)) {
Object.assign(result, diff);
}
} else if (!_.isEqual(obj1[key], obj2[key])) {
result[fullKey] = { oldValue: obj1[key], newValue: obj2[key] };
}
}
for (const key in obj2) {
if (!obj1.hasOwnProperty(key)) {
const fullKey = parentKey ? `${parentKey}.${key}` : key;
result[fullKey] = { oldValue: undefined, newValue: obj2[key] };
}
}
return result;
}
}
export default new Config()