增加关联游戏帐号和检查游戏成就的任务

This commit is contained in:
CounterFire2023 2024-05-06 17:18:30 +08:00
parent 8496afa4b5
commit 49235fefb9
10 changed files with 625 additions and 161 deletions

View File

@ -60,6 +60,10 @@
1. 检查签到并领取奖励(23), 增加post参数, 可以领取指定天数的奖励 1. 检查签到并领取奖励(23), 增加post参数, 可以领取指定天数的奖励
1. 宝箱助力(18), 宝箱助力状态查询(26) 增加返回scoreBonus, 表示当前宝箱已得到的助力积分 1. 宝箱助力(18), 宝箱助力状态查询(26) 增加返回scoreBonus, 表示当前宝箱已得到的助力积分
#### 20240506
1. 增加验证google的access token(32)
2. 增加两种任务类型: GoogleConnect, GameAchievement
### 1. 钱包预登录 ### 1. 钱包预登录
#### Request #### Request
@ -960,4 +964,31 @@ body:
```js ```js
['1234567890ab'] // 激活码列表 ['1234567890ab'] // 激活码列表
```
### 32.\* 验证google的access token
#### Request
- URL`/api/user/verify_google`
- 方法POST
- 头部:
- Authorization: Bearer JWT_token
body:
```js
{
"code": "google oauth access token"
}
```
#### Response
```js
{
}
``` ```

View File

@ -6,162 +6,261 @@
"baseTasks": ["e2yhq2lj30vwcpedv7p", "e2fclylj30vwcpe0szl", "e2far3lj30vwcpe0mh7", "e2far3lj30vwcpe0mf8"], "baseTasks": ["e2yhq2lj30vwcpedv7p", "e2fclylj30vwcpe0szl", "e2far3lj30vwcpe0mh7", "e2far3lj30vwcpe0mf8"],
"tasks": [ "tasks": [
{ {
"id": "e2yhq2lj30vwcpedv7p", "id": "e2yhq2lj30vwcpedv7p",
"task": "TwitterConnect", "task": "TwitterConnect",
"title": "Connect your X", "title": "Connect your X",
"type": 1, "type": 1,
"desc": "Please connect your X account", "desc": "Please connect your X account",
"score": 100, "score": 100,
"category": "Social Tasks", "category": "Social Tasks",
"autoclaim": false, "autoclaim": false,
"cfg": {"icon": "twitter"}, "cfg": { "icon": "twitter" },
"start": "2024-01-01 00:00", "start": "2024-01-01 00:00",
"end": "2025-01-01 00:00", "end": "2025-01-01 00:00",
"checkChain": false, "checkChain": false,
"params": {} "params": {}
}, { },
"id": "e2fclylj30vwcpe0szl", {
"task": "TwitterFollow", "id": "e2fclylj30vwcpe0szl",
"title": "Follow @playCounterFire on X", "task": "TwitterFollow",
"type": 1, "title": "Follow @playCounterFire on X",
"desc": "Follow Counter Fires official X account", "type": 1,
"category": "Social Tasks", "desc": "Follow Counter Fires official X account",
"score": 100, "category": "Social Tasks",
"autoclaim": false, "score": 100,
"pretasks": ["e2yhq2lj30vwcpedv7p"], "autoclaim": false,
"cfg": {"account": "playCounterFire", "icon": "twitter"}, "pretasks": ["e2yhq2lj30vwcpedv7p"],
"start": "2024-01-01 00:00", "cfg": { "account": "playCounterFire", "icon": "twitter" },
"end": "2025-01-01 00:00", "start": "2024-01-01 00:00",
"checkChain": false, "end": "2025-01-01 00:00",
"params": {"time": 6, "failRate": 0} "checkChain": false,
}, { "params": { "time": 6, "failRate": 0 }
"id": "e2far3lj30vwcpe0mh7", },
"task": "DiscordConnect", {
"title": "Connect your Discord", "id": "e2far3lj30vwcpe0mh7",
"type": 1, "task": "DiscordConnect",
"desc": "Connect your Discord account", "title": "Connect your Discord",
"category": "", "type": 1,
"score": 100, "desc": "Connect your Discord account",
"autoclaim": false, "category": "",
"pretasks": [], "score": 100,
"cfg": {"icon": "discord"}, "autoclaim": false,
"start": "2024-01-01 00:00", "pretasks": [],
"end": "2025-01-01 00:00", "cfg": { "icon": "discord" },
"checkChain": false, "start": "2024-01-01 00:00",
"params": {} "end": "2025-01-01 00:00",
},{ "checkChain": false,
"id": "e2far3lj30vwcpe0mf8", "params": {}
"task": "DiscordJoin", },
"title": "Join Counter Fire Discord", {
"type": 1, "id": "e2far3lj30vwcpe0mf8",
"desc": "Join Counter Fires official Discord server", "task": "DiscordJoin",
"category": "Social Tasks", "title": "Join Counter Fire Discord",
"score": 100, "type": 1,
"autoclaim": false, "desc": "Join Counter Fires official Discord server",
"pretasks": ["e2far3lj30vwcpe0mh7"], "category": "Social Tasks",
"cfg": {"icon": "discord", "account": "counterfire"}, "score": 100,
"start": "2024-01-01 00:00", "autoclaim": false,
"end": "2025-01-01 00:00", "pretasks": ["e2far3lj30vwcpe0mh7"],
"checkChain": false, "cfg": { "icon": "discord", "account": "counterfire" },
"params": {"time": 6, "failRate": 0} "start": "2024-01-01 00:00",
}, { "end": "2025-01-01 00:00",
"id": "e2fuah0j30vwcpe0my7", "checkChain": false,
"task": "TwitterRetweet", "params": { "time": 6, "failRate": 0 }
"title": "RT - Hill's Treasure Hunt", },
"type": 1, {
"desc": "Retweet specific tweets", "id": "e2fuah0j30vwcpe0my7",
"category": "Social Tasks", "task": "TwitterRetweet",
"score": 50, "title": "RT - Hill's Treasure Hunt",
"autoclaim": false, "type": 1,
"pretasks": ["e2yhq2lj30vwcpedv7p"], "desc": "Retweet specific tweets",
"cfg": {"icon": "twitter", "content": "1779507826714681538"}, "category": "Social Tasks",
"start": "2024-01-01 00:00", "score": 50,
"end": "2025-01-01 00:00", "autoclaim": false,
"checkChain": false, "pretasks": ["e2yhq2lj30vwcpedv7p"],
"params": {"time": 6, "failRate": 0} "cfg": { "icon": "twitter", "content": "1779507826714681538" },
}, "start": "2024-01-01 00:00",
{ "end": "2025-01-01 00:00",
"id": "e2fuah0j30vwcpe0my9", "checkChain": false,
"task": "TwitterLike", "params": { "time": 6, "failRate": 0 }
"title": "Like - Hill's Treasure Hunt", },
"type": 1, {
"desc": "Like specific tweets", "id": "e2fuah0j30vwcpe0my9",
"category": "Social Tasks", "task": "TwitterLike",
"score": 50, "title": "Like - Hill's Treasure Hunt",
"autoclaim": false, "type": 1,
"pretasks": ["e2yhq2lj30vwcpedv7p"], "desc": "Like specific tweets",
"cfg": {"icon": "twitter", "content": "1779507826714681538"}, "category": "Social Tasks",
"start": "2024-01-01 00:00", "score": 50,
"end": "2025-01-01 00:00", "autoclaim": false,
"checkChain": false, "pretasks": ["e2yhq2lj30vwcpedv7p"],
"params": {"time": 6, "failRate": 0} "cfg": { "icon": "twitter", "content": "1779507826714681538" },
}, "start": "2024-01-01 00:00",
{ "end": "2025-01-01 00:00",
"id": "e2il5vwl0u2bl0uyxbq", "checkChain": false,
"task": "TwitterRetweet", "params": { "time": 6, "failRate": 0 }
"title": "RT - Hill's Treasure Hunt #2", },
"type": 1, {
"desc": "Retweet specific tweets", "id": "e2il5vwl0u2bl0uyxbq",
"category": "Social Tasks", "task": "TwitterRetweet",
"score": 50, "title": "RT - Hill's Treasure Hunt #2",
"autoclaim": false, "type": 1,
"pretasks": ["e2yhq2lj30vwcpedv7p"], "desc": "Retweet specific tweets",
"cfg": {"icon": "twitter", "content": "1781323951853228188"}, "category": "Social Tasks",
"start": "2024-01-01 00:00", "score": 50,
"end": "2025-01-01 00:00", "autoclaim": false,
"checkChain": false, "pretasks": ["e2yhq2lj30vwcpedv7p"],
"params": {"time": 6, "failRate": 0} "cfg": { "icon": "twitter", "content": "1781323951853228188" },
}, "start": "2024-01-01 00:00",
{ "end": "2025-01-01 00:00",
"id": "e27r3pxezl1z8idqzq5", "checkChain": false,
"task": "TwitterLike", "params": { "time": 6, "failRate": 0 }
"title": "Like - Hill's Treasure Hunt #2", },
"type": 1, {
"desc": "Like specific tweets", "id": "e27r3pxezl1z8idqzq5",
"category": "Social Tasks", "task": "TwitterLike",
"score": 50, "title": "Like - Hill's Treasure Hunt #2",
"autoclaim": false, "type": 1,
"pretasks": ["e2yhq2lj30vwcpedv7p"], "desc": "Like specific tweets",
"cfg": {"icon": "twitter", "content": "1781323951853228188"}, "category": "Social Tasks",
"start": "2024-01-01 00:00", "score": 50,
"end": "2025-01-01 00:00", "autoclaim": false,
"checkChain": false, "pretasks": ["e2yhq2lj30vwcpedv7p"],
"params": {"time": 6, "failRate": 0} "cfg": { "icon": "twitter", "content": "1781323951853228188" },
}, "start": "2024-01-01 00:00",
{ "end": "2025-01-01 00:00",
"id": "e2ltjmohtvldpdhtz6o", "checkChain": false,
"task": "TwitterRetweet", "params": { "time": 6, "failRate": 0 }
"title": "RT - Counter Fire x opBNB", },
"type": 1, {
"desc": "Retweet specific tweets", "id": "e2ltjmohtvldpdhtz6o",
"category": "Social Tasks", "task": "TwitterRetweet",
"score": 50, "title": "RT - Counter Fire x opBNB",
"autoclaim": false, "type": 1,
"pretasks": ["e2yhq2lj30vwcpedv7p"], "desc": "Retweet specific tweets",
"cfg": {"icon": "twitter", "content": "1782375351244804306"}, "category": "Social Tasks",
"start": "2024-01-01 00:00", "score": 50,
"end": "2025-01-01 00:00", "autoclaim": false,
"checkChain": false, "pretasks": ["e2yhq2lj30vwcpedv7p"],
"params": {"time": 6, "failRate": 0} "cfg": { "icon": "twitter", "content": "1782375351244804306" },
}, "start": "2024-01-01 00:00",
{ "end": "2025-01-01 00:00",
"id": "e2dcbweojt7tzgl5xh4", "checkChain": false,
"task": "TwitterLike", "params": { "time": 6, "failRate": 0 }
"title": "Like - Counter Fire x opBNB", },
"type": 1, {
"desc": "Like specific tweets", "id": "e2dcbweojt7tzgl5xh4",
"category": "Social Tasks", "task": "TwitterLike",
"score": 50, "title": "Like - Counter Fire x opBNB",
"autoclaim": false, "type": 1,
"pretasks": ["e2yhq2lj30vwcpedv7p"], "desc": "Like specific tweets",
"cfg": {"icon": "twitter", "content": "1782375351244804306"}, "category": "Social Tasks",
"start": "2024-01-01 00:00", "score": 50,
"end": "2025-01-01 00:00", "autoclaim": false,
"checkChain": false, "pretasks": ["e2yhq2lj30vwcpedv7p"],
"params": {"time": 6, "failRate": 0} "cfg": { "icon": "twitter", "content": "1782375351244804306" },
} "start": "2024-01-01 00:00",
"end": "2025-01-01 00:00",
"checkChain": false,
"params": { "time": 6, "failRate": 0 }
},
{
"id": "e2ltjmohtvldpdhtz7o",
"task": "TwitterRetweet",
"title": "RT - Preseason Testing",
"type": 1,
"desc": "Retweet specific tweets",
"category": "Social Tasks",
"score": 50,
"autoclaim": false,
"pretasks": ["e2yhq2lj30vwcpedv7p"],
"cfg": { "icon": "twitter", "content": "1785304706325340422" },
"start": "2024-01-01 00:00",
"end": "2025-01-01 00:00",
"checkChain": false,
"params": { "time": 6, "failRate": 0 }
},
{
"id": "e2dcbweojt7tzgl5x74",
"task": "TwitterLike",
"title": "Like - Preseason Testing",
"type": 1,
"desc": "Like specific tweets",
"category": "Social Tasks",
"score": 50,
"autoclaim": false,
"pretasks": ["e2yhq2lj30vwcpedv7p"],
"cfg": { "icon": "twitter", "content": "1785304706325340422" },
"start": "2024-01-01 00:00",
"end": "2025-01-01 00:00",
"checkChain": false,
"params": { "time": 6, "failRate": 0 }
},
{
"id": "e2ltjmohtvldpdhtz8o",
"task": "TwitterRetweet",
"title": "RT - Play Counter Fire!",
"type": 1,
"desc": "Retweet specific tweets",
"category": "Social Tasks",
"score": 50,
"autoclaim": false,
"pretasks": ["e2yhq2lj30vwcpedv7p"],
"cfg": { "icon": "twitter", "content": "1786035573653979616" },
"start": "2024-01-01 00:00",
"end": "2025-01-01 00:00",
"checkChain": false,
"params": { "time": 6, "failRate": 0 }
},
{
"id": "e2dcbweojt7tzgl5x84",
"task": "TwitterLike",
"title": "Like - Play Counter Fire! ",
"type": 1,
"desc": "Like specific tweets",
"category": "Social Tasks",
"score": 50,
"autoclaim": false,
"pretasks": ["e2yhq2lj30vwcpedv7p"],
"cfg": { "icon": "twitter", "content": "1786035573653979616" },
"start": "2024-01-01 00:00",
"end": "2025-01-01 00:00",
"checkChain": false,
"params": { "time": 6, "failRate": 0 }
},
{
"id": "e2yhq2lj30vwcpedv8p",
"task": "GoogleConnect",
"title": "Connect your game account",
"type": 1,
"desc": "Please connect your game account",
"score": 100,
"category": "Social Tasks",
"autoclaim": false,
"cfg": { "icon": "google" },
"start": "2024-01-01 00:00",
"end": "2025-01-01 00:00",
"checkChain": false,
"params": {}
},
{
"id": "e2fclylj30vwcpe1szl",
"task": "GameAchievement",
"title": "Receive Game Achievement",
"type": 1,
"desc": "Receive Game Achievement",
"category": "Social Tasks",
"score": 100,
"autoclaim": false,
"pretasks": ["e2yhq2lj30vwcpedv8p"],
"cfg": { },
"start": "2024-01-01 00:00",
"end": "2025-01-01 00:00",
"checkChain": false,
"params": { "time": 6, "failRate": 0 }
}
], ],
"startTime": 1713355200000, "startTime": 1713355200000,
"endTime": 1715903999999 "endTime": 1715903999999
} }
] ]

View File

@ -34,6 +34,7 @@
"fastify": "^4.15.0", "fastify": "^4.15.0",
"fastify-plugin": "^3.0.0", "fastify-plugin": "^3.0.0",
"fastify-xml-body-parser": "^2.2.0", "fastify-xml-body-parser": "^2.2.0",
"google-auth-library": "^9.9.0",
"ioredis": "^5.4.1", "ioredis": "^5.4.1",
"mongodb-extended-json": "^1.11.1", "mongodb-extended-json": "^1.11.1",
"mongoose": "8.2.3", "mongoose": "8.2.3",

View File

@ -22,6 +22,7 @@ import {
import { formatNumShow, isObjectIdString } from 'common/Utils' import { formatNumShow, isObjectIdString } from 'common/Utils'
import { ChestEnhanceRecord } from 'models/ChestEnhanceRecord' import { ChestEnhanceRecord } from 'models/ChestEnhanceRecord'
import logger from 'logger/logger' import logger from 'logger/logger'
import { verifyToken } from 'services/google.svr'
const LOGIN_TIP = 'This signature is just to verify your identity' const LOGIN_TIP = 'This signature is just to verify your identity'
@ -174,4 +175,31 @@ class SignController extends BaseController {
await user.save() await user.save()
return { boost: user.boost, boostExpire: user.boostExpire } return { boost: user.boost, boostExpire: user.boostExpire }
} }
@router('post /api/user/verify_google')
async verifyGoogleToken(req) {
const user = req.user
if (user.googleId) {
throw new ZError(11, 'already bind google')
}
const { openId, data } = await verifyToken(req)
const exstisUser = await ActivityUser.findOne({
googleId: openId,
})
if (exstisUser) {
throw new ZError(12, 'google account already bind')
}
if (data.email) {
user.googleEmail = data.email
}
if (data.nickname) {
user.googleName = data.nickname
}
if (data.avatar) {
user.googleAvatar = data.avatar
}
user.googleId = openId
await user.save()
return {}
}
} }

View File

@ -49,6 +49,7 @@ export interface ActivityUserClass extends Base, TimeStamps {}
@index({ inviteCode: 1, activity: 1 }, { unique: true, partialFilterExpression: { inviteCode: { $exists: true } } }) @index({ inviteCode: 1, activity: 1 }, { unique: true, partialFilterExpression: { inviteCode: { $exists: true } } })
@index({ inviteUser: 1, activity: 1 }, { unique: false }) @index({ inviteUser: 1, activity: 1 }, { unique: false })
@index({ twitterId: 1 }, { unique: true, partialFilterExpression: { twitterId: { $exists: true } } }) @index({ twitterId: 1 }, { unique: true, partialFilterExpression: { twitterId: { $exists: true } } })
@index({ googleId: 1 }, { unique: true, partialFilterExpression: { twitterId: { $exists: true } } })
@index({ discordId: 1 }, { unique: true, partialFilterExpression: { discordId: { $exists: true } } }) @index({ discordId: 1 }, { unique: true, partialFilterExpression: { discordId: { $exists: true } } })
@modelOptions({ @modelOptions({
schemaOptions: { collection: 'activity_user', timestamps: true }, schemaOptions: { collection: 'activity_user', timestamps: true },
@ -101,6 +102,15 @@ export class ActivityUserClass extends BaseModule {
@prop() @prop()
public discordName?: string public discordName?: string
@prop()
public googleId?: string
@prop()
public googleName?: string
@prop()
public googleAvatar?: string
@prop()
public googleEmail?: string
@prop({ default: false }) @prop({ default: false })
public inWhiteList: boolean public inWhiteList: boolean

70
src/rankquery.ts Normal file
View File

@ -0,0 +1,70 @@
import mongoose from 'mongoose'
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 { ZRedisClient } from 'zutils'
import { RANK_SCORE_SCALE } from 'common/Constants'
import { ScoreRecord } from 'models/ScoreRecord'
const db = mongoose.connection
;(async () => {
try {
// const activity = 'uaw_activity'
// const start = 0
// const end = 500
// let opts = { url: process.env.REDIS }
// new ZRedisClient(opts)
// const records = await new ZRedisClient().zrevrange(`uaw_activity:score`, start, 100)
// let score100 = 0
// console.log(records.length)
// for (let i = 0; i < records.length; i += 2) {
// let score = parseInt(records[i + 1]) / 100
// score100 += score
// }
// const record500 = await new ZRedisClient().zrevrange(`uaw_activity:score`, start, 500)
// let score500 = 0
// console.log(record500.length)
// for (let i = 0; i < record500.length; i += 2) {
// let score = parseInt(record500[i + 1]) / 100
// score500 += score
// }
// console.log('score100:', score100)
// console.log('score500:', score500)
let begin = new Date('2024-04-17T00:00:00.000Z')
const oneDay = 24 * 60 * 60 * 1000
let end = new Date(begin.getTime() + oneDay)
let resultMap1 = new Map()
let resultMap2 = new Map()
let resultMap = new Map()
while (end < new Date()) {
let record = await ScoreRecord.aggregate([
{
$match: {
type: { $ne: 'invite_rebate' },
$and: [{ createdAt: { $gte: begin } }, { createdAt: { $lt: end } }],
},
},
{ $group: { _id: null, count: { $sum: '$score' } } },
])
let record2 = await ScoreRecord.aggregate([
{
$match: {
type: 'invite_rebate',
$and: [{ createdAt: { $gte: begin } }, { createdAt: { $lt: end } }],
},
},
{ $group: { _id: null, count: { $sum: '$score' } } },
])
console.log(begin, '\t', record[0].count + record2[0].count, '\t', record[0].count, '\t', record2[0].count)
begin = end
end = new Date(begin.getTime() + oneDay)
}
} catch (e) {
console.log(e)
}
process.exit(0)
})()

View File

@ -1,4 +1,6 @@
import { RECAPTCHA_MIN_SCORE } from 'common/Constants' import { RECAPTCHA_MIN_SCORE } from 'common/Constants'
import { OAuth2Client } from 'google-auth-library'
import logger from 'logger/logger'
import { ZError } from 'zutils' import { ZError } from 'zutils'
export const checkReCaptcha = async (req: any, action: string) => { export const checkReCaptcha = async (req: any, action: string) => {
@ -25,3 +27,68 @@ export const checkReCaptcha = async (req: any, action: string) => {
} }
return true return true
} }
const GOOGLE_OAUTH_ISS = 'https://accounts.google.com'
const GOOGLE_OAUTH_ISS1 = 'accounts.google.com'
const IOS_TEST = '53206975661-0d6q9pqljn84n9l63gm0to1ulap9cbk4.apps.googleusercontent.com'
const CLIENT_ID = '53206975661-asnf3qe4bg29p8h981pgf099osvrjbme.apps.googleusercontent.com'
const CLIENT_ID2 = '53206975661-ih3r0ubph3rqejdq97b029difbrk2bqj.apps.googleusercontent.com'
const CLIENT_ID_IOS = '53206975661-qan0rnefniegjv53ohild375pv0p7ekd.apps.googleusercontent.com'
const CLIENT_ID3 = '436789193812-5vh7ahctkaofjir9tnilfnvm19cf3vve.apps.googleusercontent.com'
const CLIENT_ID4 = '436789193812-9vubggj1op881elm41i7b9raeec9dgrj.apps.googleusercontent.com'
const CLIENT_ID5 = '436789193812-9vubggj1op881elm41i7b9raeec9dgrj.apps.googleusercontent.com'
const CLIENTS = [CLIENT_ID, CLIENT_ID2, CLIENT_ID3, CLIENT_ID4, CLIENT_ID_IOS, IOS_TEST, CLIENT_ID5]
export const verifyToken = async (req: any) => {
let { code, token } = req.params
code = code || token
if (!code) {
throw new ZError(50, 'code is required')
}
const client = new OAuth2Client(CLIENT_ID)
let data: any = {}
let openId: string
try {
const ticket = await client.verifyIdToken({
idToken: code,
audience: CLIENTS, // Specify the CLIENT_ID of the app that accesses the backend
// Or, if multiple clients access the backend:
//[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
})
const payload = ticket.getPayload()
if (!(payload.iss === GOOGLE_OAUTH_ISS || payload.iss === GOOGLE_OAUTH_ISS1)) {
throw new ZError(10, 'id token error')
}
if (CLIENTS.indexOf(payload.aud) === -1) {
throw new ZError(11, 'client id mismatch')
}
if (payload.email) data.email = payload.email
if (process.env.NODE_ENV !== 'development') {
if (payload.email_verified !== undefined) data.emailVerified = payload.email_verified
}
if (payload.locale) data.locale = payload.locale
if (payload.name) data.nickname = payload.name
if (payload.picture) data.avatar = payload.picture
openId = payload.sub
} catch (err) {
logger.log('error parse google id token', err)
try {
let info: any = await client.getTokenInfo(code)
console.log(info)
if (info.email) data.email = info.email
if (info.aud !== CLIENT_ID2) {
throw new ZError(11, 'client id mismatch')
}
if (process.env.NODE_ENV !== 'development') {
if (info.email_verified !== undefined) data.emailVerified = info.email_verified
}
if (info.name) data.nickname = info.name
openId = info.sub
} catch (e2) {
logger.log('error parse google access token', e2)
throw new ZError(10, 'id token error')
}
}
return { openId, data }
}

View File

@ -0,0 +1,37 @@
import { ZError } from 'zutils'
import { ITask } from './base/ITask'
import { TaskStatusEnum } from 'models/ActivityUser'
import { TaskCfg } from 'models/ActivityInfo'
export default class GameAchievement extends ITask {
static desc = 'acquire game achievement'
static show: boolean = true
async execute(data: any) {
const { task } = data
let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id)
let time = cfg.params.time
if (Date.now() - task.timeStart < time * 1000) {
throw new ZError(11, 'check game achievement failed')
}
let num = Math.random() * 100
if (num < cfg.params.failRate) {
throw new ZError(12, 'check game achievement failed')
}
task.status = TaskStatusEnum.SUCCESS
task.timeFinish = Date.now()
task.data = {}
try {
await this.user.save()
} catch (err) {
throw new ZError(100, 'already acquired game achievement')
}
if (cfg.autoclaim) {
try {
await this.claimReward(task)
} catch (err) {
console.log(err)
}
}
return true
}
}

View File

@ -0,0 +1,38 @@
import { ITask } from './base/ITask'
import { TaskStatusEnum } from 'models/ActivityUser'
import { ZError } from 'zutils'
import { TaskCfg } from 'models/ActivityInfo'
export default class GoogleConnect extends ITask {
static desc = 'google connect'
static show: boolean = true
async execute(data: any) {
if (!this.user.googleId) {
throw new ZError(100, 'google account already binded')
}
const { task } = data
if (task.status === TaskStatusEnum.RUNNING) {
task.status = TaskStatusEnum.SUCCESS
task.timeFinish = Date.now()
task.data = {
userid: this.user.googleId,
email: this.user.googleEmail,
}
try {
await this.user.save()
} catch (err) {
throw new ZError(100, 'google account already binded')
}
let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id)
if (cfg.autoclaim) {
try {
await this.claimReward(task)
} catch (err) {
console.log(err)
}
}
}
return true
}
}

View File

@ -1628,6 +1628,13 @@ aes-js@3.0.0:
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d"
integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==
agent-base@^7.0.2:
version "7.1.1"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317"
integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==
dependencies:
debug "^4.3.4"
ajv-formats@^2.1.1: ajv-formats@^2.1.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz"
@ -1871,7 +1878,7 @@ base-x@^3.0.2, base-x@^3.0.8:
dependencies: dependencies:
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
base64-js@^1.3.1: base64-js@^1.3.0, base64-js@^1.3.1:
version "1.5.1" version "1.5.1"
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
@ -2037,6 +2044,11 @@ bson@^6.2.0:
resolved "https://registry.yarnpkg.com/bson/-/bson-6.2.0.tgz#4b6acafc266ba18eeee111373c2699304a9ba0a3" resolved "https://registry.yarnpkg.com/bson/-/bson-6.2.0.tgz#4b6acafc266ba18eeee111373c2699304a9ba0a3"
integrity sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q== integrity sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==
buffer-from@^1.0.0: buffer-from@^1.0.0:
version "1.1.2" version "1.1.2"
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
@ -2452,7 +2464,7 @@ debug@2.6.9, debug@^2.2.0:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@4.x, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: debug@4, debug@4.x, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4" version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -2591,7 +2603,7 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0" jsbn "~0.1.0"
safer-buffer "^2.1.0" safer-buffer "^2.1.0"
ecdsa-sig-formatter@^1.0.11: ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11:
version "1.0.11" version "1.0.11"
resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
@ -3125,7 +3137,7 @@ ext@^1.7.0:
dependencies: dependencies:
type "^2.7.2" type "^2.7.2"
extend@~3.0.2: extend@^3.0.2, extend@~3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@ -3449,6 +3461,25 @@ function-bind@^1.1.2:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
gaxios@^6.0.0, gaxios@^6.1.1:
version "6.5.0"
resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-6.5.0.tgz#21bc20e24f21189ce8907079b56205ff9fd2c0d7"
integrity sha512-R9QGdv8j4/dlNoQbX3hSaK/S0rkMijqjVvW3YM06CoBdbU/VdKd159j4hePpng0KuE6Lh6JJ7UdmVGJZFcAG1w==
dependencies:
extend "^3.0.2"
https-proxy-agent "^7.0.1"
is-stream "^2.0.0"
node-fetch "^2.6.9"
uuid "^9.0.1"
gcp-metadata@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-6.1.0.tgz#9b0dd2b2445258e7597f2024332d20611cbd6b8c"
integrity sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==
dependencies:
gaxios "^6.0.0"
json-bigint "^1.0.0"
gensync@^1.0.0-beta.2: gensync@^1.0.0-beta.2:
version "1.0.0-beta.2" version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@ -3552,6 +3583,18 @@ globby@^11.1.0:
merge2 "^1.4.1" merge2 "^1.4.1"
slash "^3.0.0" slash "^3.0.0"
google-auth-library@^9.9.0:
version "9.9.0"
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-9.9.0.tgz#71488ef444335ff4ea91611729b88c0f57625fdf"
integrity sha512-9l+zO07h1tDJdIHN74SpnWIlNR+OuOemXlWJlLP9pXy6vFtizgpEzMuwJa4lqY9UAdiAv5DVd5ql0Am916I+aA==
dependencies:
base64-js "^1.3.0"
ecdsa-sig-formatter "^1.0.11"
gaxios "^6.1.1"
gcp-metadata "^6.1.0"
gtoken "^7.0.0"
jws "^4.0.0"
gopd@^1.0.1: gopd@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
@ -3605,6 +3648,14 @@ graphemer@^1.4.0:
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
gtoken@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-7.1.0.tgz#d61b4ebd10132222817f7222b1e6064bd463fc26"
integrity sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==
dependencies:
gaxios "^6.0.0"
jws "^4.0.0"
har-schema@^2.0.0: har-schema@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
@ -3748,6 +3799,14 @@ http2-wrapper@^2.1.10:
quick-lru "^5.1.1" quick-lru "^5.1.1"
resolve-alpn "^1.2.0" resolve-alpn "^1.2.0"
https-proxy-agent@^7.0.1:
version "7.0.4"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168"
integrity sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==
dependencies:
agent-base "^7.0.2"
debug "4"
human-signals@^2.1.0: human-signals@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
@ -4402,6 +4461,13 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json-bigint@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1"
integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==
dependencies:
bignumber.js "^9.0.0"
json-buffer@3.0.1: json-buffer@3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
@ -4471,6 +4537,23 @@ jsprim@^1.2.2:
json-schema "0.4.0" json-schema "0.4.0"
verror "1.10.0" verror "1.10.0"
jwa@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc"
integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==
dependencies:
buffer-equal-constant-time "1.0.1"
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
jws@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4"
integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==
dependencies:
jwa "^2.0.0"
safe-buffer "^5.0.1"
kareem@2.5.1: kareem@2.5.1:
version "2.5.1" version "2.5.1"
resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d" resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d"
@ -4958,7 +5041,7 @@ node-addon-api@^2.0.0:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32"
integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==
node-fetch@2, node-fetch@^2.6.12: node-fetch@2, node-fetch@^2.6.12, node-fetch@^2.6.9:
version "2.7.0" version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
@ -6436,7 +6519,7 @@ uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^9.0.0: uuid@^9.0.0, uuid@^9.0.1:
version "9.0.1" version "9.0.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==