245 lines
7.9 KiB
TypeScript
245 lines
7.9 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 { ActivityUser } from 'models/ActivityUser'
|
|
import { ScoreRecord } from 'models/ScoreRecord'
|
|
import { ZRedisClient } from 'zutils'
|
|
import { formatNumShow } from 'common/Utils'
|
|
import { RANK_SCORE_SCALE } from 'common/Constants'
|
|
import { InGameScoreRecord } from 'models/InGameScoreRecord'
|
|
import { DeleteRecord } from 'models/DeleteRecord'
|
|
import { Types } from 'mongoose'
|
|
import { InGameStats } from 'models/InGameStats'
|
|
import { NFTHolderRecord } from 'models/NFTHodlerRecord'
|
|
let fs = require('fs')
|
|
/**
|
|
* 生成积分明细
|
|
*/
|
|
|
|
mongoose.set('debug', false)
|
|
const ACTIVITY = 'uaw_activity'
|
|
|
|
const totalKey = 'uaw_activity:static:score'
|
|
const gameTotalKey = 'uaw_activity:static:gamescore'
|
|
const releationKey = `uaw_score_invite_rebate`
|
|
const pageSize = 100
|
|
|
|
const updateRedis2 = (key, vals) => {
|
|
return new Promise((resolve, reject) => {
|
|
new ZRedisClient().pub.zadd(key, vals, function (err, res) {
|
|
if (err) {
|
|
reject(err)
|
|
} else {
|
|
resolve(res)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
const saveScoreToRedis = async () => {
|
|
let records = await ScoreRecord.aggregate([{ $group: { _id: '$user', count: { $sum: '$score' } } }])
|
|
let vals = []
|
|
for (let i = 0, l = records.length; i < l; i++) {
|
|
if (records[i].count == 0) {
|
|
continue
|
|
}
|
|
vals.push((records[i].count * RANK_SCORE_SCALE) | 0)
|
|
vals.push(records[i]._id)
|
|
if (i % 1000 === 0) {
|
|
await updateRedis2(totalKey, vals)
|
|
vals.length = 0
|
|
}
|
|
}
|
|
if (vals.length > 0) {
|
|
await updateRedis2(totalKey, vals)
|
|
}
|
|
}
|
|
|
|
const saveTypeScoreToRedis = async (type: string) => {
|
|
const key = `uaw_score_${type}`
|
|
await new ZRedisClient().del(key)
|
|
let records = await ScoreRecord.aggregate([
|
|
{ $match: { type } },
|
|
{ $group: { _id: '$user', count: { $sum: '$score' } } },
|
|
])
|
|
let vals = []
|
|
|
|
for (let i = 0, l = records.length; i < l; i++) {
|
|
if (records[i].count == 0) {
|
|
continue
|
|
}
|
|
vals.push((records[i].count * RANK_SCORE_SCALE) | 0)
|
|
vals.push(records[i]._id)
|
|
if (i % 1000 === 0) {
|
|
await updateRedis2(key, vals)
|
|
vals.length = 0
|
|
}
|
|
}
|
|
if (vals.length > 0) {
|
|
await updateRedis2(key, vals)
|
|
}
|
|
}
|
|
|
|
const generateScoreList = async (start: number) => {
|
|
let end = start + pageSize
|
|
const records = await new ZRedisClient().zrevrange(totalKey, start, end)
|
|
let results = []
|
|
for (let i = 0; i < records.length; i += 2) {
|
|
const id = records[i]
|
|
let score = formatNumShow(parseInt(records[i + 1]) / RANK_SCORE_SCALE)
|
|
const releatScore = await new ZRedisClient().zscore(releationKey, id)
|
|
const releatScoreShow = formatNumShow(releatScore ? parseInt(releatScore + '') / RANK_SCORE_SCALE : 0)
|
|
const user = await ActivityUser.findById(id)
|
|
const rank = start + i / 2 + 1
|
|
results.push(
|
|
`${rank}\t${user?.address}\t${score}\t${releatScoreShow}\t${holderMap.get(user?.address.toLowerCase()) || 1}\t${founderSet.has(user.address) ? 1 : 0}\t${explorerSet.has(user.address) ? 1 : 0}\t${badgeSet.has(user.address) ? 1 : 0}\t${candySet.has(user.address) ? 1 : 0}`,
|
|
)
|
|
}
|
|
fs.writeFileSync('outdatas/scorelist.txt', results.join('\n') + '\n', { flag: 'a+' })
|
|
}
|
|
|
|
const saveGameScoreToRedis = async () => {
|
|
let records = await InGameScoreRecord.aggregate([{ $group: { _id: '$user', count: { $sum: '$score' } } }])
|
|
let vals = []
|
|
for (let i = 0, l = records.length; i < l; i++) {
|
|
if (records[i].count == 0) {
|
|
continue
|
|
}
|
|
vals.push((records[i].count * 100) | 0)
|
|
vals.push(records[i]._id)
|
|
if (i % 1000 === 0) {
|
|
await updateRedis2(gameTotalKey, vals)
|
|
vals.length = 0
|
|
}
|
|
}
|
|
if (vals.length > 0) {
|
|
await updateRedis2(gameTotalKey, vals)
|
|
}
|
|
}
|
|
|
|
const generateGameScoreList = async (start: number) => {
|
|
let end = start + pageSize
|
|
// const records = await new ZRedisClient().zrevrange(gameTotalKey, start, end)
|
|
const records = await InGameStats.find({ score: { $gt: 0 } })
|
|
.sort({ score: -1 })
|
|
.skip(start)
|
|
.limit(pageSize)
|
|
let results = []
|
|
for (let i = 0; i < records.length; i++) {
|
|
let score = records[i].score
|
|
if (score === 0) {
|
|
continue
|
|
}
|
|
let address = ''
|
|
const user = await ActivityUser.findById(records[i].user)
|
|
if (!user) {
|
|
const userDel = await DeleteRecord.findOne({ 'data._id': new Types.ObjectId(records[i].user) })
|
|
if (userDel) {
|
|
address = userDel.data.address
|
|
}
|
|
} else {
|
|
address = user.address
|
|
}
|
|
const rank = start + i + 1
|
|
results.push(`${rank}\t${address}\t${score}`)
|
|
}
|
|
fs.writeFileSync('outdatas/gameScorelist.txt', results.join('\n') + '\n', { flag: 'a+' })
|
|
}
|
|
|
|
const generateWhiteList = async () => {
|
|
let records = await ActivityUser.find({ whiteListNum: { $gt: 0 } })
|
|
let results = []
|
|
for (let i = 0; i < records.length; i++) {
|
|
results.push(`${records[i].address} \t ${records[i].whiteListNum}`)
|
|
}
|
|
let records2 = await DeleteRecord.find({ 'data.whiteListNum': { $gt: 0 } })
|
|
for (let i = 0; i < records2.length; i++) {
|
|
results.push(`${records2[i].data.address} \t ${records2[i].data.whiteListNum}`)
|
|
}
|
|
fs.writeFileSync('outdatas/whitelist.txt', results.join('\n') + '\n', { flag: 'a+' })
|
|
}
|
|
|
|
const holders = [
|
|
['explorer', '0x0cee888fa25810ca648d697099bc17a2c9e1dfbf', 1.5],
|
|
['candy', '0xefd4c863e73e7e9cc33d46fb30ce51510fcfdeb0', 1.5],
|
|
['badge', '0xd728de3d9ebed90e84abe84539280cbc5b18e304', 2],
|
|
['founder', '0xec23679653337d4c6390d0eeba682246a6067777', 3],
|
|
]
|
|
const holderMap = new Map()
|
|
let explorerSet = new Set()
|
|
let candySet = new Set()
|
|
let badgeSet = new Set()
|
|
let founderSet = new Set()
|
|
const queryHolder = async () => {
|
|
for (let holder of holders) {
|
|
const [name, contract] = holder
|
|
let records = await NFTHolderRecord.find({ contract: contract + '' })
|
|
for (let i = 0; i < records.length; i++) {
|
|
const uid = records[i].user
|
|
let user = await ActivityUser.findById(uid)
|
|
if (!user) {
|
|
continue
|
|
}
|
|
let address = user.address.toLowerCase()
|
|
if (name === 'explorer') {
|
|
explorerSet.add(address)
|
|
} else if (name === 'candy') {
|
|
candySet.add(address)
|
|
} else if (name === 'badge') {
|
|
badgeSet.add(address)
|
|
} else if (name === 'founder') {
|
|
founderSet.add(address)
|
|
}
|
|
if (!holderMap.has(address)) {
|
|
holderMap.set(address, 1)
|
|
}
|
|
holderMap.set(address, holderMap.get(address) * parseFloat(holder[2] + ''))
|
|
}
|
|
}
|
|
}
|
|
|
|
;(async () => {
|
|
try {
|
|
let opts = { url: process.env.REDIS }
|
|
new ZRedisClient(opts)
|
|
await new ZRedisClient().del(totalKey)
|
|
// await new ZRedisClient().del(gameTotalKey)
|
|
console.time('update redis')
|
|
await saveScoreToRedis()
|
|
console.timeEnd('update redis')
|
|
console.time('query holder info')
|
|
await queryHolder()
|
|
console.timeEnd('query holder info')
|
|
console.time('update releation redis')
|
|
await saveTypeScoreToRedis('invite_rebate')
|
|
console.timeEnd('update releation redis')
|
|
console.time('generate score list')
|
|
const total = (await new ZRedisClient().zcard(totalKey)) as number
|
|
for (let i = 0; i < total; i += pageSize) {
|
|
await generateScoreList(i)
|
|
}
|
|
console.timeEnd('generate score list')
|
|
|
|
// console.time('update game redis')
|
|
// await saveGameScoreToRedis()
|
|
// console.timeEnd('update game redis')
|
|
// console.time('generate game score list')
|
|
// const totalGame = (await new ZRedisClient().zcard(gameTotalKey)) as number
|
|
// const totalGame = await InGameStats.countDocuments({ score: { $gt: 0 } })
|
|
// for (let i = 0; i < totalGame; i += pageSize) {
|
|
// await generateGameScoreList(i)
|
|
// }
|
|
// console.timeEnd('generate game score list')
|
|
// console.time('generate white list')
|
|
// await generateWhiteList()
|
|
// console.timeEnd('generate white list')
|
|
} catch (e) {
|
|
console.log(e)
|
|
}
|
|
console.log('end')
|
|
process.exit(0)
|
|
})()
|