新增`#绑定用户`命令,用于打通多个平台间的用户

This commit is contained in:
Kokomi 2023-11-04 04:29:34 +08:00
parent 669e331d98
commit e3d789fc91
6 changed files with 172 additions and 103 deletions

View File

@ -1,3 +1,10 @@
# 3.1.2
* 新增`#绑定用户`命令
* 可将其他QQ绑定至当前用户以打通多个用户子用户使用主用户的CK与UID等信息
* 同时也可绑定其他平台的用户例如频道、微信等。如需链接至其他平台需使用TRSS-Yunzai或Lain-plugin
* 部分命令可能无法识别绑定后的主用户,如遇问题可反馈
# 3.1.1
* 初步适配原神4.0版本,增加对应资源及信息展示,感谢**Ca(HCO₃)₂**、**@touchscale**、**@teriri7**

View File

@ -1,6 +1,6 @@
{
"name": "miao-yunzai",
"version": "3.1.1",
"version": "3.1.2",
"author": "Yoimiya-Kokomi, Le-niao",
"description": "QQ group Bot",
"main": "app.js",

View File

@ -52,6 +52,14 @@ export class user extends plugin {
{
reg: '^#\\s*(检查|我的)*ck(状态)*$',
fnc: 'checkCkStatus'
},
{
reg: '^#(接受)?绑定(主|子)?用户(\\[\\w+\\]){0,2}$',
fnc: 'bindNoteUser'
},
{
reg: '^#(删除绑定|取消绑定|解除绑定|解绑|删除|取消)(主|子)用户$',
fnc: 'bindNoteUser'
}
]
})
@ -175,4 +183,8 @@ export class user extends plugin {
async checkCkStatus () {
await this.User.checkCkStatus()
}
async bindNoteUser () {
await this.User.bindNoteUser()
}
}

View File

@ -1,11 +1,9 @@
import YAML from 'yaml'
import chokidar from 'chokidar'
import fs from 'node:fs'
import { promisify } from 'node:util'
import lodash from 'lodash'
import MysInfo from './mys/mysInfo.js'
import NoteUser from './mys/NoteUser.js'
import MysUser from './mys/MysUser.js'
/** 配置文件 */
class GsCfg {
@ -73,8 +71,11 @@ class GsCfg {
}
getFilePath (app, name, type) {
if (type == 'defSet') return `${this.defSetPath}${app}/${name}.yaml`
else return `${this.configPath}${app}.${name}.yaml`
if (type == 'defSet') {
return `${this.defSetPath}${app}/${name}.yaml`
} else {
return `${this.configPath}${app}.${name}.yaml`
}
}
/** 监听配置文件 */
@ -121,16 +122,6 @@ class GsCfg {
return { ck, ckQQ, noteCk }
}
/** 获取qq号绑定ck */
getBingCkSingle(userId) {
console.log('gsCfg.getBingCkSingle() 即将废弃')
return {}
}
saveBingCk(userId, data) {
console.log('gsCfg.saveBingCk() 即将废弃')
}
/**
* 原神角色id转换角色名字
*/
@ -143,18 +134,6 @@ class GsCfg {
return ''
}
/**
* 原神武器id转换成武器名字
*/
getWeaponDataByWeaponHash(hash) {
let data = this.getdefSet('weapon', 'data')
let weaponData = {}
weaponData.name = data.Name[hash]
weaponData.type = data.Type[weaponData.name]
weaponData.icon = data.Icon[weaponData.name]
return weaponData
}
/** 原神角色别名转id */
roleNameToID (keyword, isSr) {
if (isSr) this.isSr = isSr
@ -197,19 +176,6 @@ class GsCfg {
}
}
/** 返回所有别名,包括用户自定义的 */
getAllAbbr() {
let nameArr = this.getdefSet('role', this.isSr ? 'sr_name' : 'name')
let nameArrUser = this.getConfig('role', 'name')
for (let i in nameArrUser) {
let id = this.roleNameToID(i)
nameArr[id] = nameArr[id].concat(nameArrUser[i])
}
return nameArr
}
/**
* 原神角色武器长名称缩写
* @param name 名称
@ -287,52 +253,43 @@ class GsCfg {
}
}
/**
* 根据角色名获取对应的元素类型
*/
getElementByRoleName(roleName) {
let element = this.getdefSet('element', 'role')
if (element[roleName]) {
return element[roleName]
}
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 ''
}
/**
* 根据技能id获取对应的技能数据,角色名用于命座加成的技能等级
*/
getSkillDataByskillId (skillId, roleName) {
let skillMap = this.getdefSet('skill', 'data')
let skillData = {}
if (skillMap.Name[skillId]) {
skillData.name = skillMap.Name[skillId]
}
if (skillMap.Icon[skillId]) {
skillData.icon = skillMap.Icon[skillId]
}
if (skillMap.Talent[roleName]) {
skillData.talent = skillMap.Talent[roleName]
}
return skillData
console.log('gsCfg.getSkillDataByskillId() 已废弃')
return {}
}
fightPropIdToName (propId) {
let propMap = this.getdefSet('prop', 'prop')
if (propMap[propId]) {
return propMap[propId]
}
console.log('gsCfg.fightPropIdToName() 已废弃')
return ''
}
getRoleTalentByTalentId (talentId) {
let talentMap = this.getdefSet('role', 'talent')
let talent = {}
if (talentMap.Name[talentId]) {
talent.name = talentMap.Name[talentId]
}
if (talentMap.Icon[talentId]) {
talent.icon = talentMap.Icon[talentId]
}
return talent
console.log('gsCfg.getRoleTalentByTalentId 已废弃')
return {}
}
}

View File

@ -86,7 +86,14 @@ export default class NoteUser extends BaseModel {
// 兼容处理传入e
if (qq && qq.user_id) {
let e = qq
let user = await NoteUser.create(e.user_id)
let id = e.originalUserId || e.user_id
let mainId = await redis.get(`Yz:NoteUser:mainId:${e.user_id}`)
if (mainId) {
id = mainId
e.mainUserId = mainId
e.originalUserId = e.originalUserId || e.user_id
}
let user = await NoteUser.create(id)
e.user = user
return user
}

View File

@ -499,4 +499,90 @@ export default class User extends base {
...this.screenData
}
}
async bindNoteUser () {
let user = await this.user()
let id = user.qq
let { e } = this
let { msg } = e
if (!id) {
return true
}
if (/(删除绑定|取消绑定|解除绑定|解绑|删除|取消)/.test(msg)) {
// 删除用户
id = e.originalUserId || id
if (/主/.test(msg)) {
let mainId = await redis.get(`Yz:NoteUser:mainId:${id}`)
if (!mainId) {
e.reply('当前用户没有主用户,在主用户中通过【#绑定用户】可进行绑定...')
return true
}
let subIds = await Data.getCacheJSON(`Yz:NoteUser:subIds:${mainId}`)
delete subIds[id]
await redis.del(`Yz:NoteUser:mainId:${id}`)
await Data.setCacheJSON(`Yz:NoteUser:subIds:${mainId}`, subIds)
e.reply('已经解除与主用户的绑定...')
} else if (/子/.test(msg)) {
let subIds = await Data.getCacheJSON(`Yz:NoteUser:subIds:${id}`)
let count = 0
for (let key in subIds) {
await redis.del(`Yz:NoteUser:mainId:${key}`)
count++
}
if (count > 0) {
e.reply(`已删除${count}个子用户...`)
await redis.del(`Yz:NoteUser:subIds:${id}`)
} else {
e.reply(`当前用户没有子用户,通过【#绑定用户】可绑定子用户...`)
}
}
return true
}
msg = msg.replace(/^#\s*(接受)?绑定(主|子)?用户/, '')
let idRet = /^\[(\w{5,})](?:\[(\w+)])?$/.exec(msg)
if (idRet && idRet[1]) {
let mainId = idRet[1]
let currId = id.toString()
if (!idRet[2]) {
// 子用户绑定
if (currId === mainId) {
e.reply('请切换到需要绑定的子用户并发送绑定命令...')
return true
}
let verify = (Math.floor(100000000 + Math.random() * 100000000)).toString()
await redis.set(`Yz:NoteUser:verify:${mainId}`, verify + '||' + currId, { EX: 300 })
e.reply(['此账号即将作为子用户,绑定至主用户:${mainId}',
'成功绑定后此用户输入的命令将视作主用户命令使用主用户的CK与UID等信息',
'如需继续绑定请在5分钟内使用主账户发送以下命令', '',
`#接受绑定子用户[${mainId}][${verify}]`
].join('\n'))
return true
} else {
// 接受绑定
if (currId !== mainId) {
e.reply('请切换到主用户并发送接受绑定的命令...')
return true
}
let verify = await redis.get(`Yz:NoteUser:verify:${mainId}`) || ''
verify = verify.split('||')
if (!verify || verify[0] !== idRet[2] || !verify[1]) {
e.reply('校验失败,请发送【#绑定用户】重新开始绑定流程')
return true
}
let subId = verify[1]
await redis.del(`Yz:NoteUser:verify:${mainId}`)
await redis.set(`Yz:NoteUser:mainId:${subId}`, mainId, { EX: 3600 * 24 * 365 })
let subIds = await Data.getCacheJSON(`Yz:NoteUser:subIds:${mainId}`)
subIds[subId] = 'true'
await Data.setCacheJSON(`Yz:NoteUser:subIds:${mainId}`, subIds)
e.reply('绑定成功绑定的子用户可使用主用户的UID/CK等信息\n请勿接受不是自己用户的绑定如需解绑可通过【#解绑子用户】进行解绑')
return true
}
} else {
this.e.reply(['将此账号作为主用户同Bot已绑定的子用户可使用主用户的CK及UID信息等信息。',
'可在多个QQ或频道间打通用户信息推荐使用QQ账户作为主用户。',
'请【切换至需要绑定的子用户】,输入以下命令,获得绑定验证码', '请勿接受不是自己用户的绑定!', '',
`#绑定主用户[${id}]`].join('\n'))
}
}
}