291 lines
9.3 KiB
TypeScript
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)
|
|
})()
|