调整UID记录逻辑,防止刷新时导致的UID绑定丢失

This commit is contained in:
Kokomi 2023-06-04 05:03:50 +08:00
parent e8725f5d3d
commit ff8c209811
7 changed files with 128 additions and 98 deletions

View File

@ -31,6 +31,8 @@ class PluginsLoader {
/** 插件监听 */ /** 插件监听 */
this.watcher = {} this.watcher = {}
this.msgThrottle = {}
/** 星铁命令前缀 */ /** 星铁命令前缀 */
this.srReg = /^#?(\*|星铁|星轨|穹轨|星穹|崩铁|星穹铁道|崩坏星穹铁道|铁道)+/ this.srReg = /^#?(\*|星铁|星轨|穹轨|星穹|崩铁|星穹铁道|崩坏星穹铁道|铁道)+/
} }
@ -220,7 +222,7 @@ class PluginsLoader {
// e.isSr = true且命令标准化为 #星铁 开头 // e.isSr = true且命令标准化为 #星铁 开头
if (this.srReg.test(e.msg) || /\/common\//.test(e.msg)) { if (this.srReg.test(e.msg) || /\/common\//.test(e.msg)) {
e.isSr = true e.isSr = true
e.msg = e.msg.replace(this.srReg, "#星铁") e.msg = e.msg.replace(this.srReg, '#星铁')
} }
/** accept */ /** accept */
@ -246,9 +248,9 @@ class PluginsLoader {
/** 判断事件 */ /** 判断事件 */
if (v.event && !this.filtEvent(e, v)) continue if (v.event && !this.filtEvent(e, v)) continue
const regExp = new RegExp(v.reg); const regExp = new RegExp(v.reg)
/** 匹配消息或者小程序 */ /** 匹配消息或者小程序 */
const messageOrApplet = e.msg || e.message?.[0]?.data; const messageOrApplet = e.msg || e.message?.[0]?.data
if (regExp.test(messageOrApplet)) { if (regExp.test(messageOrApplet)) {
e.logFnc = `[${plugin.name}][${v.fnc}]` e.logFnc = `[${plugin.name}][${v.fnc}]`
@ -367,7 +369,7 @@ class PluginsLoader {
for (let val of e.message) { for (let val of e.message) {
switch (val.type) { switch (val.type) {
case 'text': case 'text':
e.msg = (e.msg || "") + (val.text || "").replace(/^\s*[#井#]+\s*/, "#").replace(/^\s*[\\*※]+\s*/, "*").trim() e.msg = (e.msg || '') + (val.text || '').replace(/^\s*[#井#]+\s*/, '#').replace(/^\s*[\\*※]+\s*/, '*').trim()
break break
case 'image': case 'image':
if (!e.img) { if (!e.img) {
@ -637,6 +639,17 @@ class PluginsLoader {
return false return false
} }
let { msgThrottle } = this
let msgId = e.user_id + ':' + e.raw_message
if (msgThrottle[msgId]) {
return false
}
msgThrottle[msgId] = true
setTimeout(() => {
delete msgThrottle[msgId]
}, 200)
return true return true
} }

View File

@ -59,12 +59,8 @@ export class user extends plugin {
} }
async init () { async init () {
let file = './data/MysCookie'
if (!fs.existsSync(file)) {
fs.mkdirSync(file)
}
/** 加载旧的绑定ck json */ /** 加载旧的绑定ck json */
this.loadOldData() await this.loadOldData()
} }
/** 接受到消息都会执行一次 */ /** 接受到消息都会执行一次 */
@ -169,9 +165,10 @@ export class user extends plugin {
} }
/** 加载旧的绑定ck json */ /** 加载旧的绑定ck json */
loadOldData () { async loadOldData () {
this.User.loadOldDataV2() await this.User.loadOldDataV2()
this.User.loadOldDataV3() await this.User.loadOldDataV3()
await this.User.loadOldUid()
} }
/** 检查用户CK状态 **/ /** 检查用户CK状态 **/

View File

@ -23,3 +23,4 @@ export default class BaseModel extends Model {
model.COLUMNS = columns model.COLUMNS = columns
} }
} }
export { sequelize }

View File

@ -25,7 +25,31 @@ const COLUMNS = {
// 头像 // 头像
face: Types.STRING, face: Types.STRING,
ltuids: Types.STRING ltuids: Types.STRING,
games: {
type: Types.STRING,
get () {
let data = this.getDataValue('games')
let ret = {}
try {
data = JSON.parse(data) || {}
} catch (e) {
data = {}
}
MysUtil.eachGame((game) => {
let ds = data[game] || {}
ret[game] = {
uid: ds.uid || '',
data: ds.data || {}
}
})
return ret
},
set (data) {
this.setDataValue('games', JSON.stringify(data))
}
},
data: Types.STRING
} }
class UserDB extends BaseModel { class UserDB extends BaseModel {
@ -33,12 +57,7 @@ class UserDB extends BaseModel {
// user_id // user_id
id = type === 'qq' ? '' + id : type + id id = type === 'qq' ? '' + id : type + id
// DB查询 // DB查询
let user = await UserDB.findByPk(id, { let user = await UserDB.findByPk(id)
include: {
model: UserGameDB,
as: 'games'
}
})
if (!user) { if (!user) {
user = await UserDB.build({ user = await UserDB.build({
id, id,
@ -57,21 +76,12 @@ class UserDB extends BaseModel {
} }
}) })
db.ltuids = ltuids.join(',') db.ltuids = ltuids.join(',')
let games = [] db.games = user._games
MysUtil.eachGame((key) => {
let game = user.games[key]
if (game) {
games.push(game)
}
})
if (games.length > 0) {
await this.setGames(games)
}
await this.save() await this.save()
} }
} }
BaseModel.initDB(UserDB, COLUMNS) BaseModel.initDB(UserDB, COLUMNS)
await UserDB.sync() await UserDB.sync({ alter: true })
export default UserDB export default UserDB

View File

@ -1,24 +1,6 @@
import UserDB from './UserDB.js' import UserDB from './UserDB.js'
import MysUserDB from './MysUserDB.js' import MysUserDB from './MysUserDB.js'
import UserGameDB from './UserGameDB.js' import UserGameDB from './UserGameDB.js'
import { sequelize } from './BaseModel.js'
export { UserDB, MysUserDB, UserGameDB, sequelize }
UserDB.belongsToMany(MysUserDB, {
through: 'UserLtuids'
})
MysUserDB.belongsToMany(UserDB, {
through: 'UserLtuids'
})
UserDB.hasMany(UserGameDB, {
onDelete: 'RESTRICT',
onUpdate: 'RESTRICT',
foreignKey: 'userId',
as: 'games'
})
UserGameDB.belongsTo(UserDB, {
foreignKey: 'userId',
as: 'games'
})
export { UserDB, MysUserDB, UserGameDB }

View File

@ -117,7 +117,7 @@ export default class NoteUser extends BaseModel {
this.db = await UserDB.find(this.qq, 'qq') this.db = await UserDB.find(this.qq, 'qq')
} }
await this.initMysUser() await this.initMysUser()
await this.initGameDs() this._games = this.db.games
await this.save() await this.save()
} }
@ -133,35 +133,6 @@ export default class NoteUser extends BaseModel {
} }
} }
// 初始化Uid
async initGameDs () {
let self = this
self.games = self.games || {}
const { db, games } = self
let hasChange = false
let gameDBs = {}
lodash.forEach(db?.games, (gameDB) => {
gameDBs[gameDB.game] = gameDB
})
await MysUtil.eachGame(async (key) => {
let gameDB = gameDBs[key]
if (!gameDB) {
gameDB = await db.createGame({
game: key
})
await gameDB.save()
hasChange = true
}
games[key] = gameDB
// 优先设置CK UID
})
if (hasChange) {
await this.save()
}
}
async save () { async save () {
await this.db.saveDB(this) await this.db.saveDB(this)
} }
@ -236,7 +207,11 @@ export default class NoteUser extends BaseModel {
/** 获取当前UID */ /** 获取当前UID */
getUid (game = 'gs') { getUid (game = 'gs') {
// todo 刷新uid // todo 刷新uid
return this.getGameDs(game).uid || '' let ds = this.getGameDs(game)
if (!ds.uid) {
this.setMainUid('', game)
}
return ds.uid || ''
} }
/** 获取UID列表 */ /** 获取UID列表 */
@ -258,18 +233,16 @@ export default class NoteUser extends BaseModel {
} }
// 添加UID // 添加UID
addRegUid (uid, game = 'gs') { addRegUid (uid, game = 'gs', save = true) {
game = this.gameKey(game) game = this.gameKey(game)
uid = uid + '' uid = uid + ''
let gameDs = this.getGameDs(game) let gameDs = this.getGameDs(game)
if (!this.hasUid(uid, game)) { gameDs.data[uid] = { uid, type: 'reg' }
let dsData = gameDs.data this._map = false
dsData[uid] = { uid, type: 'reg' } this.setMainUid(uid, game, false)
gameDs.data = dsData if (save) {
this._map = false this.save()
} }
this.setMainUid(uid, game)
this.save()
} }
// 删除UID // 删除UID
@ -281,15 +254,22 @@ export default class NoteUser extends BaseModel {
gameDs.data = dsData gameDs.data = dsData
this._map = false this._map = false
if (gameDs.uid === uid) { if (gameDs.uid === uid) {
this.setMainUid('', game) this.setMainUid('', game, false)
} }
this.save() this.save()
} }
getGameDs (game = 'gs') { getGameDs (game = 'gs') {
return this.games[this.gameKey(game)] if (!this._games[game]) {
this._games[game] = {
uid: '',
data: {}
}
}
return this._games[game]
} }
/** /**
* 设置当前用户的绑定uid * 设置当前用户的绑定uid
* @param uid 要绑定的uid * @param uid 要绑定的uid
@ -304,17 +284,19 @@ export default class NoteUser extends BaseModel {
} }
// 切换绑定CK生效的UID // 切换绑定CK生效的UID
setMainUid (uid = '', game = 'gs') { setMainUid (uid = '', game = 'gs', save = true) {
this._map = false this._map = false
game = this.gameKey(game) game = this.gameKey(game)
if (uid < 100 || !uid) { if (uid < 100 || !uid) {
let uids = this.getUidList(game) let uids = this.getUidList(game)
uid = (uids[uid] || uids[0]).uid uid = (uids[uid] || uids[0]).uid || ''
} }
if (this.hasUid(uid, game)) { if (this.hasUid(uid, game)) {
let gameDs = this.getGameDs(game) let gameDs = this.getGameDs(game)
gameDs.uid = uid gameDs.uid = uid
gameDs.save() }
if (save) {
this.save()
} }
} }
@ -325,10 +307,10 @@ export default class NoteUser extends BaseModel {
MysUtil.eachGame((game) => { MysUtil.eachGame((game) => {
let uid = mysUser.getUid(game) let uid = mysUser.getUid(game)
if (uid) { if (uid) {
this.setMainUid(uid, game) this.setMainUid(uid, game, false)
} }
}) })
await this.save() this.save()
} }
// 删除当前用户绑定CK // 删除当前用户绑定CK

View File

@ -10,6 +10,7 @@ import { promisify } from 'node:util'
import YAML from 'yaml' import YAML from 'yaml'
import { Data } from '#miao' import { Data } from '#miao'
import { Player } from '#miao.models' import { Player } from '#miao.models'
import { UserGameDB, sequelize } from './db/index.js'
export default class User extends base { export default class User extends base {
constructor (e) { constructor (e) {
@ -306,8 +307,11 @@ export default class User extends base {
} }
/** 加载V3ck */ /** 加载V3ck */
async loadOldDataV3 (data) { async loadOldDataV3 () {
let dir = './data/MysCookie/' let dir = './data/MysCookie/'
if (!fs.existsSync(dir)) {
return false
}
Data.createDir('./temp/MysCookieBak') Data.createDir('./temp/MysCookieBak')
let files = fs.readdirSync(dir).filter(file => file.endsWith('.yaml')) let files = fs.readdirSync(dir).filter(file => file.endsWith('.yaml'))
const readFile = promisify(fs.readFile) const readFile = promisify(fs.readFile)
@ -335,6 +339,48 @@ export default class User extends base {
} }
} }
async loadOldUid () {
// 从DB中导入
await sequelize.query(`delete from UserGames where userId is null or data is null`, {})
let games = await UserGameDB.findAll()
let count = 0
await Data.asyncPool(20, games, async (game) => {
if (!game.userId) {
game.destroy()
return true
}
count++
let user = await NoteUser.create(game.userId)
if (game.userId && game.data) {
lodash.forEach(game.data, (ds) => {
let { uid } = ds
user.addRegUid(uid, game.game, false)
})
}
if (game.uid) {
user.setMainUid(game.uid, game.game, false)
}
await user.save()
await game.destroy()
})
// 从Redis中导入
let keys = await redis.keys('Yz:genshin:mys:qq-uid:*')
for (let key of keys) {
let uid = await redis.get(key)
let qqRet = /Yz:genshin:mys:qq-uid:(\d{5,12})/.exec(key)
if (qqRet?.[1] && uid) {
let user = await NoteUser.create(qqRet[1])
if (!user.getUid('gs')) {
user.addRegUid(uid, 'gs')
}
}
redis.del(key)
}
await sequelize.query(`delete from Users where (ltuids is null or ltuids='') and games is null`, {})
console.log('load Uid Data Done...')
}
async loadOldData (data) { async loadOldData (data) {
let count = 0 let count = 0
if (!lodash.isPlainObject(data)) { if (!lodash.isPlainObject(data)) {
@ -384,7 +430,6 @@ export default class User extends base {
} }
count++ count++
} }
return count
} }
/** 我的ck */ /** 我的ck */