task-svr/src/scripts/fixdata.ts
2024-10-16 16:34:39 +08:00

291 lines
9.3 KiB
TypeScript

import * as dotenv from 'dotenv'
const envFile = process.env.NODE_ENV && process.env.NODE_ENV === 'production' ? `.env.production` : '.env.development'
dotenv.config({ path: envFile })
console.log(process.env.DB_MAIN)
import mongoose from 'mongoose'
import { CheckIn } from 'models/chain/CheckIn'
import { toEIP55 } from 'zutils/utils/chain.util'
import { inertUser, insertWalletLoginLog } from 'services/fix.svr'
import { FixAddress } from 'models/ctrl/FixAddress'
import { ActivityUser, TaskStatusEnum } from 'models/ActivityUser'
import { ActivityInfo } from 'models/ActivityInfo'
import { LoginRecord } from 'models/LoginRecord'
import { Types } from 'mongoose'
import { randomIp, randomUserAgent } from 'common/Utils'
import { ScoreRecord } from 'models/ScoreRecord'
import { INVITE_REBATE, SCORE_INVITE_REBATE, SCORE_OPEN_CHEST } from 'common/Constants'
import { ActivityChest } from 'models/ActivityChest'
import { generateChestCfg, generateChestLevel } from 'services/game.svr'
mongoose.set('debug', false)
const sourceList = require('../configs/ingame_tasks.json')
const dbMain = mongoose.createConnection(process.env.DB_MAIN)
const dbChain = mongoose.createConnection(process.env.DB_CHAIN)
const dbCtrl = mongoose.createConnection(process.env.DB_CTRL)
const ACTIVITY = 'uaw_activity'
let activity
const initEnv = async () => {
activity = await ActivityInfo.findById(ACTIVITY)
}
// const parseOneRecord = async (record: any) => {
// if (!FixAddress.checkExist(record.from)) {
// return
// }
// let addressEip55 = toEIP55(record.from)
// console.log('parseOneRecord', addressEip55)
// const user = await dbCtrl.collection('users_test').findOne({ address: addressEip55 })
// if (!user) {
// // 如果没有用户记录,插入用户记录, 并插入一条钱包登录记录(在插入用户记录之前)
// const { uid, timestamp } = await inertUser(dbCtrl, addressEip55, record.blockTime)
// await insertWalletLoginLog(dbCtrl, addressEip55, uid, timestamp - Math.floor(Math.random() * 2))
// }
// // 插入签到记录
// }
// generate fake ObjectId from timestamp
const generateObjectId = (oid: string, fixSeconds: number) => {
let timestamp = parseInt(oid.slice(0, 8), 16) + fixSeconds
let timeStr = timestamp.toString(16)
const middleStr = oid.slice(8, 18)
let randomStr = Math.floor(Math.random() * 10000000)
.toString(16)
.padStart(6, '1')
return timeStr + middleStr + randomStr
}
let mainUserMap = new Map()
let mainUserList = []
let codeMap = new Map()
const prepareUser = async (record: any) => {
let addressLower = record.address.toLowerCase()
let addressEip55 = toEIP55(addressLower)
const user = await ActivityUser.insertOrUpdate({ address: addressEip55, activity: ACTIVITY }, {})
if (mainUserMap.size < 10000) {
mainUserMap.set(user.id, 0)
mainUserList.push(user.id)
if (!user.inviteCode) {
await user.save()
}
codeMap.set(user.id, user.inviteCode)
} else {
let uid = mainUserList[mainUserList.length - 1]
// get random value from 5 - 10
const random = Math.floor(Math.random() * 6 + 4)
// 超过随机值后, 将最后一个元素pop掉
if (mainUserMap.get(uid) >= random) {
mainUserList.pop()
} else {
mainUserMap.set(uid, mainUserMap.get(uid) + 1)
}
user.inviteUser = uid
await user.save()
const loginRecord = await LoginRecord.findOne({ user: uid }).sort({ _id: -1 })
const fixSeconds = Math.floor(Math.random() * 120)
let oid = generateObjectId(user.id, fixSeconds)
let time = new Date(user.createdAt.getTime() + fixSeconds * 1000)
await dbMain.collection('user_log').insertOne({
// @ts-ignore
_id: new Types.ObjectId(oid),
user: user.id,
name: 'upload_invite_code',
method: 'POST',
path: '/api/activity/upload_invite_code',
user_agent: loginRecord?.user_agent || randomUserAgent(),
ip: loginRecord?.ip || randomIp(),
params: {
code: codeMap.get(uid),
},
createdAt: time,
updatedAt: time,
__v: 0.0,
})
}
// 更新FixAddress的user字段
if (!record.user) {
record.user = user.id
await record.save()
}
}
const updateTaskProgress = async (user: any) => {
let taskAddedSet = new Set()
for (let task of user.taskProgress) {
if (task.dateTag) {
taskAddedSet.add(task.id + ':' + task.dateTag)
} else {
taskAddedSet.add(task.id)
}
}
let modifiedTasks = []
for (let task of activity.tasks) {
if (!taskAddedSet.has(task.id)) {
modifiedTasks.push({ id: task.id, task: task.task, status: TaskStatusEnum.NOT_START })
}
}
const loginRecord = await LoginRecord.findOne({ user: user.id }).sort({ _id: -1 })
if (modifiedTasks.length > 0) {
let result = await dbMain.collection('activity_user').updateOne(
{ _id: user._id },
{
$push: { taskProgress: { $each: modifiedTasks } },
// TODO:: 根据实际情况更新updatedAt
// @ts-ignore
$set: { updatedAt: loginRecord.createdAt },
$inc: { __v: 1 },
},
{},
)
console.log('updateTaskProgress', result)
}
}
/**
* {
date: dateTag,
chestId: chest.id,
level: chest.level,
items: chest.items,
}
*/
const updateChestRecord = async (addressRecord: any) => {
const records = await ScoreRecord.find({ user: addressRecord.user, activity: ACTIVITY, type: SCORE_OPEN_CHEST })
const user = await ActivityUser.findById(addressRecord.user)
let actionsBox = []
let actionsScore = []
for (let record of records) {
let { level, chestId } = record.data
if (level === 1) {
level = 3
} else if (level === 2) {
level = 4
} else {
continue
}
const { scoreInit, bounsCfg, maxBounsCount } = generateChestCfg(level)
actionsBox.push({
updateOne: {
filter: { _id: new Types.ObjectId(chestId) },
update: { $set: { level, scoreInit, bounsCfg, maxBounsCount } },
},
})
actionsScore.push({
updateOne: {
filter: { _id: record._id },
update: { $set: { score: scoreInit, 'data.level': level } },
},
})
if (user.inviteUser) {
const fixSeconds = 0
let oid = generateObjectId(record.id, fixSeconds)
// @ts-ignore
let time = new Date(record.createdAt.getTime() + fixSeconds * 1000)
const score1 = scoreInit * INVITE_REBATE
let scoreParams = {
fromUser: user.id,
date: record.data.dateTag,
chestId,
level,
items: record.data.items,
}
actionsScore.push({
insertOne: {
document: {
_id: new Types.ObjectId(oid),
user: user.inviteUser,
score: score1,
activity: record.activity,
type: SCORE_INVITE_REBATE,
data: JSON.parse(JSON.stringify(scoreParams)),
createdAt: time,
updatedAt: time,
__v: 0.0,
},
},
})
}
}
if (actionsBox.length > 0) {
await dbMain.collection('activity_box').bulkWrite(actionsBox)
}
if (actionsScore.length > 0) {
await dbMain.collection('score_record').bulkWrite(actionsScore)
}
}
/**
* 0607 删除sybil数据后, 调整买量用户的宝箱数据
* 所有4级改为2级
*/
const updateChest = async (addressRecord: any) => {
const records = await ScoreRecord.find({ user: addressRecord.user, activity: ACTIVITY, type: SCORE_OPEN_CHEST })
let actionsBox = []
let actionsScore = []
for (let record of records) {
let { level, chestId } = record.data
// if (level === 4) {
// level = 2
// } else if (level === 3) {
// level = 1
// } else {
// continue
// }
level = generateChestLevel()
const { scoreInit, bounsCfg, maxBounsCount } = generateChestCfg(level)
actionsBox.push({
updateOne: {
filter: { _id: new Types.ObjectId(chestId) },
update: { $set: { level, scoreInit, bounsCfg, maxBounsCount } },
},
})
actionsScore.push({
updateOne: {
filter: { _id: record._id },
update: { $set: { score: scoreInit, 'data.level': level } },
},
})
}
if (actionsBox.length > 0) {
await dbMain.collection('activity_box').bulkWrite(actionsBox)
}
if (actionsScore.length > 0) {
await dbMain.collection('score_record').bulkWrite(actionsScore)
}
console.log('updateChest', addressRecord.user, actionsBox.length)
}
const fixTaskProgree = async (record: any) => {
let addressLower = record.address.toLowerCase()
let addressEip55 = toEIP55(addressLower)
console.log('parseOneAddress', addressEip55)
const user = await ActivityUser.insertOrUpdate({ address: addressEip55, activity: ACTIVITY }, {})
// 补充用户的taskProgress
await updateTaskProgress(user)
}
// TODO::
const beginTime = new Date('2024-05-15T12:31:19.860Z')
const oneday = 24 * 60 * 60 * 1000
const endTime = new Date('2024-06-01T00:00:00.000Z')
const updateInGameRecords = async (record: any) => {
for (let cfg of sourceList) {
}
}
;(async () => {
try {
await initEnv()
// await FixAddress.find().cursor().eachAsync(prepareUser)
// await FixAddress.find().cursor().eachAsync(fixTaskProgree)
// await FixAddress.find().cursor().eachAsync(updateChestRecord)
await FixAddress.find().cursor().eachAsync(updateChest)
// await FixAddress.find().cursor().eachAsync(updateInGameRecords)
} catch (e) {
console.log(e)
}
console.log('end')
process.exit(0)
})()