完善一些检查
This commit is contained in:
parent
6ff402e670
commit
a0ba5249fc
41
configs/chest.json
Normal file
41
configs/chest.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"chests": [
|
||||
{
|
||||
"level": 1,
|
||||
"name": "Wooden Chest",
|
||||
"initScoreMin": 10,
|
||||
"initScoreMax": 50,
|
||||
"maxBonus": 10,
|
||||
"minBonus": 5,
|
||||
"maxBounsCount": 10
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"name": "Iron Chest",
|
||||
"initScoreMin": 20,
|
||||
"initScoreMax": 60,
|
||||
"maxBonus": 20,
|
||||
"minBonus": 10,
|
||||
"maxBounsCount": 15
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"name": "Bronze Chest",
|
||||
"initScoreMin": 30,
|
||||
"initScoreMax": 80,
|
||||
"maxBonus": 30,
|
||||
"minBonus": 15,
|
||||
"maxBounsCount": 20
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"name": "Sliver Chest",
|
||||
"initScoreMin": 40,
|
||||
"initScoreMax": 100,
|
||||
"maxBonus": 40,
|
||||
"minBonus": 20,
|
||||
"maxBounsCount": 50
|
||||
}
|
||||
]
|
||||
|
||||
}
|
4
configs/share_cfg.json
Normal file
4
configs/share_cfg.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"inviter": 10,
|
||||
"invitee": 10
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
[
|
||||
{
|
||||
"_id": "first_activity",
|
||||
"name": "First Activity1",
|
||||
"description": "This is the first test activity",
|
||||
"tasks": [{
|
||||
"_id": "uaw_activity",
|
||||
"name": "UAW Activity",
|
||||
"description": "UAW",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "e2yhq2lj30vwcpedv7p",
|
||||
"task": "TwitterConnect",
|
||||
"title": "",
|
||||
@ -147,7 +148,7 @@
|
||||
"task": "TwitterRetweet",
|
||||
"title": "",
|
||||
"type": 2,
|
||||
"desc": "Showcase your performance in Counter Fire to your friends!",
|
||||
"desc": "Showcase your performance in Counter Fire to your friends!",
|
||||
"category": "Social Tasks",
|
||||
"score": 300,
|
||||
"autoclaim": false,
|
||||
@ -170,117 +171,8 @@
|
||||
"start": "2024-01-01 00:00",
|
||||
"end": "2025-01-01 00:00",
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"id": "e2f7fplj30vwcpe0l97",
|
||||
"task": "DailyCheckIn",
|
||||
"title": "",
|
||||
"type": 1,
|
||||
"desc": "Check-in for 3 consecutive days.",
|
||||
"category": "Referral to Earn",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {},
|
||||
"start": "2024-01-01 00:00",
|
||||
"end": "2025-01-01 00:00",
|
||||
"params": {"days": 3}
|
||||
}, {
|
||||
"id": "e2f7fplj30vwcpe0l98",
|
||||
"task": "OkxLogin",
|
||||
"title": "",
|
||||
"type": 1,
|
||||
"desc": "Sign in via OKX Wallet.",
|
||||
"category": "Referral to Earn",
|
||||
"score": 300,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"account": "okx", "icon": "okx"},
|
||||
"start": "2024-01-01 00:00",
|
||||
"end": "2025-01-01 00:00",
|
||||
"params": {"item": {"lottery_ticket": 1}}
|
||||
}, {
|
||||
"id": "e2f7fplj30vwcpe0l96",
|
||||
"task": "DailyCheckIn",
|
||||
"title": "",
|
||||
"type": 2,
|
||||
"desc": "Daily check-in! Score more Flames with 7 days of consecutive check-ins. Ignite it now!",
|
||||
"category": "Social Tasks",
|
||||
"score": 20,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"score": [0, 15, 20, 20, 40, 40, 60]},
|
||||
"start": "2024-01-01 00:00",
|
||||
"end": "2025-01-01 00:00",
|
||||
"params": {"days": 1, "score": [0, 15, 20, 20, 40, 40, 60]}
|
||||
}, {
|
||||
"id": "e2f7t4lj30vwcpe0ldr",
|
||||
"task": "ShareCode",
|
||||
"title": "",
|
||||
"desc": "Click here if your are referred by a friend!",
|
||||
"type": 1,
|
||||
"category": "Social Tasks",
|
||||
"show": true,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {},
|
||||
"score": 500,
|
||||
"params": {"score": [500]}
|
||||
}, {
|
||||
"id": "e2f7t4lj31vwcpe0ldr",
|
||||
"task": "BurnNft",
|
||||
"type": 1,
|
||||
"show": true,
|
||||
"repeat": 2,
|
||||
"title": "Hero NFT",
|
||||
"desc": "Click to burn and redeem Flame",
|
||||
"category": "CF Pal",
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"address": "0xCD4bb3402f1a444a1AF10F31946Ed37DaC0eaC4d"},
|
||||
"score": 200,
|
||||
"params": {"address": "0xCD4bb3402f1a444a1AF10F31946Ed37DaC0eaC4d"}
|
||||
}, {
|
||||
"id": "e2f7t4lj32vwcpe0ldr",
|
||||
"task": "BurnNft",
|
||||
"type": 1,
|
||||
"show": true,
|
||||
"repeat": 2,
|
||||
"title": "Candy Badge",
|
||||
"desc": "Click to burn and redeem Flame",
|
||||
"category": "CF Pal",
|
||||
"pretasks": [],
|
||||
"cfg": {"address": "0x6a673D946a976776fd5F163d9d831b2fEB600015"},
|
||||
"score": 100,
|
||||
"params": {"address": "0x6a673D946a976776fd5F163d9d831b2fEB600015"}
|
||||
}, {
|
||||
"id": "e2f7t4lj33vwcpe0ldr",
|
||||
"task": "BurnNft",
|
||||
"type": 1,
|
||||
"show": true,
|
||||
"repeat": 2,
|
||||
"title": "Explorer Badge",
|
||||
"desc": "Click to burn and redeem Flame",
|
||||
"category": "CF Pal",
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"address": "0x7b6399DFbed8Bc46F6A498C6B1040E80c2B5C4bc"},
|
||||
"score": 100,
|
||||
"params": {"address": "0x7b6399DFbed8Bc46F6A498C6B1040E80c2B5C4bc"}
|
||||
}, {
|
||||
"id": "e2f7t4lj33vwcpe0ldr",
|
||||
"task": "BurnNft",
|
||||
"type": 1,
|
||||
"show": true,
|
||||
"repeat": 2,
|
||||
"title": "Gacha Badge",
|
||||
"desc": "Click to burn and redeem Flame",
|
||||
"category": "CF Pal",
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"address": "0xe2E4D5a4045fBFcbCBECAf5b8A94303712d2FA97"},
|
||||
"score": 200,
|
||||
"params": {"address": "0xe2E4D5a4045fBFcbCBECAf5b8A94303712d2FA97"}
|
||||
}],
|
||||
}
|
||||
],
|
||||
"startTime": 1711086450119,
|
||||
"endTime": 1713678477701
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
[
|
||||
{
|
||||
"_id": "uaw_activity",
|
||||
"name": "UAW Activity",
|
||||
"description": "UAW",
|
||||
"tasks": [
|
||||
{
|
||||
"_id": "first_activity",
|
||||
"name": "First Activity1",
|
||||
"description": "This is the first test activity",
|
||||
"tasks": [{
|
||||
"id": "e2yhq2lj30vwcpedv7p",
|
||||
"task": "TwitterConnect",
|
||||
"title": "",
|
||||
@ -171,8 +170,117 @@
|
||||
"start": "2024-01-01 00:00",
|
||||
"end": "2025-01-01 00:00",
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}
|
||||
],
|
||||
}, {
|
||||
"id": "e2f7fplj30vwcpe0l97",
|
||||
"task": "DailyCheckIn",
|
||||
"title": "",
|
||||
"type": 1,
|
||||
"desc": "Check-in for 3 consecutive days.",
|
||||
"category": "Referral to Earn",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {},
|
||||
"start": "2024-01-01 00:00",
|
||||
"end": "2025-01-01 00:00",
|
||||
"params": {"days": 3}
|
||||
}, {
|
||||
"id": "e2f7fplj30vwcpe0l98",
|
||||
"task": "OkxLogin",
|
||||
"title": "",
|
||||
"type": 1,
|
||||
"desc": "Sign in via OKX Wallet.",
|
||||
"category": "Referral to Earn",
|
||||
"score": 300,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"account": "okx", "icon": "okx"},
|
||||
"start": "2024-01-01 00:00",
|
||||
"end": "2025-01-01 00:00",
|
||||
"params": {"item": {"lottery_ticket": 1}}
|
||||
}, {
|
||||
"id": "e2f7fplj30vwcpe0l96",
|
||||
"task": "DailyCheckIn",
|
||||
"title": "",
|
||||
"type": 2,
|
||||
"desc": "Daily check-in! Score more Flames with 7 days of consecutive check-ins. Ignite it now!",
|
||||
"category": "Social Tasks",
|
||||
"score": 20,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"score": [0, 15, 20, 20, 40, 40, 60]},
|
||||
"start": "2024-01-01 00:00",
|
||||
"end": "2025-01-01 00:00",
|
||||
"params": {"days": 1, "score": [0, 15, 20, 20, 40, 40, 60]}
|
||||
}, {
|
||||
"id": "e2f7t4lj30vwcpe0ldr",
|
||||
"task": "ShareCode",
|
||||
"title": "",
|
||||
"desc": "Click here if your are referred by a friend!",
|
||||
"type": 1,
|
||||
"category": "Social Tasks",
|
||||
"show": true,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {},
|
||||
"score": 500,
|
||||
"params": {"score": [500]}
|
||||
}, {
|
||||
"id": "e2f7t4lj31vwcpe0ldr",
|
||||
"task": "BurnNft",
|
||||
"type": 1,
|
||||
"show": true,
|
||||
"repeat": 2,
|
||||
"title": "Hero NFT",
|
||||
"desc": "Click to burn and redeem Flame",
|
||||
"category": "CF Pal",
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"address": "0xCD4bb3402f1a444a1AF10F31946Ed37DaC0eaC4d"},
|
||||
"score": 200,
|
||||
"params": {"address": "0xCD4bb3402f1a444a1AF10F31946Ed37DaC0eaC4d"}
|
||||
}, {
|
||||
"id": "e2f7t4lj32vwcpe0ldr",
|
||||
"task": "BurnNft",
|
||||
"type": 1,
|
||||
"show": true,
|
||||
"repeat": 2,
|
||||
"title": "Candy Badge",
|
||||
"desc": "Click to burn and redeem Flame",
|
||||
"category": "CF Pal",
|
||||
"pretasks": [],
|
||||
"cfg": {"address": "0x6a673D946a976776fd5F163d9d831b2fEB600015"},
|
||||
"score": 100,
|
||||
"params": {"address": "0x6a673D946a976776fd5F163d9d831b2fEB600015"}
|
||||
}, {
|
||||
"id": "e2f7t4lj33vwcpe0ldr",
|
||||
"task": "BurnNft",
|
||||
"type": 1,
|
||||
"show": true,
|
||||
"repeat": 2,
|
||||
"title": "Explorer Badge",
|
||||
"desc": "Click to burn and redeem Flame",
|
||||
"category": "CF Pal",
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"address": "0x7b6399DFbed8Bc46F6A498C6B1040E80c2B5C4bc"},
|
||||
"score": 100,
|
||||
"params": {"address": "0x7b6399DFbed8Bc46F6A498C6B1040E80c2B5C4bc"}
|
||||
}, {
|
||||
"id": "e2f7t4lj33vwcpe0ldr",
|
||||
"task": "BurnNft",
|
||||
"type": 1,
|
||||
"show": true,
|
||||
"repeat": 2,
|
||||
"title": "Gacha Badge",
|
||||
"desc": "Click to burn and redeem Flame",
|
||||
"category": "CF Pal",
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"cfg": {"address": "0xe2E4D5a4045fBFcbCBECAf5b8A94303712d2FA97"},
|
||||
"score": 200,
|
||||
"params": {"address": "0xe2E4D5a4045fBFcbCBECAf5b8A94303712d2FA97"}
|
||||
}],
|
||||
"startTime": 1711086450119,
|
||||
"endTime": 1713678477701
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
"@fastify/formbody": "^7.4.0",
|
||||
"@fastify/helmet": "^10.1.0",
|
||||
"@fastify/jwt": "^6.7.1",
|
||||
"@typegoose/typegoose": "^12.1.0",
|
||||
"@typegoose/typegoose": "^12.2.0",
|
||||
"bson": "^4.0.4",
|
||||
"dotenv": "^16.0.3",
|
||||
"ethers": "^5.6.8",
|
||||
@ -26,7 +26,7 @@
|
||||
"fastify-plugin": "^3.0.0",
|
||||
"fastify-xml-body-parser": "^2.2.0",
|
||||
"mongodb-extended-json": "^1.11.1",
|
||||
"mongoose": "8.1.0",
|
||||
"mongoose": "8.2.3",
|
||||
"node-schedule": "^2.0.0",
|
||||
"siwe": "^2.1.4",
|
||||
"tracer": "^1.1.6",
|
||||
|
@ -14,3 +14,5 @@ export const CONFIRM_MAIL_HTML = `
|
||||
<p>点击链接进入确认页面, 如果无法跳转, 就复制链接, 电脑上直接用浏览器打开, 手机上使用MetaMask的浏览器打开</p>
|
||||
<p><a href="{{link}}" target="_blank">{{link2}}</a></p>
|
||||
`
|
||||
// 是否需要手动开启游戏
|
||||
export const MANUAL_OPEN_GAME = true
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { ActivityInfo } from 'models/ActivityInfo'
|
||||
import { ActivityUser } from 'models/ActivityUser'
|
||||
import { rankKey, rankLevel } from 'services/rank.svr'
|
||||
import { rankKey, rankLevel, updateRankScore } from 'services/rank.svr'
|
||||
import { BaseController, ROLE_ANON, SyncLocker, ZError, ZRedisClient, role, router } from 'zutils'
|
||||
import { ScoreRecord } from 'models/ScoreRecord'
|
||||
import { formatAddress } from 'zutils/utils/chain.util'
|
||||
import { formatDate } from 'zutils/utils/date.util'
|
||||
const shareCfg = require('../../configs/share_cfg.json')
|
||||
|
||||
const MAX_LIMIT = 100
|
||||
export default class ActivityController extends BaseController {
|
||||
@ -38,6 +40,30 @@ export default class ActivityController extends BaseController {
|
||||
if (!inviteUser) {
|
||||
throw new ZError(12, 'invalid invite code')
|
||||
}
|
||||
// TODO:: 检查自己是否符合条件
|
||||
const dateTag = formatDate(new Date())
|
||||
// 更新邀请积分-邀请人
|
||||
await updateRankScore({
|
||||
user: inviteUser.id,
|
||||
score: shareCfg.inviter,
|
||||
activity: user.activity,
|
||||
scoreType: 'invite_user',
|
||||
scoreParams: {
|
||||
date: dateTag,
|
||||
user: user.id,
|
||||
},
|
||||
})
|
||||
// 更新邀请积分-被邀请人
|
||||
await updateRankScore({
|
||||
user: user.id,
|
||||
score: shareCfg.invitee,
|
||||
activity: user.activity,
|
||||
scoreType: 'invite_invitee',
|
||||
scoreParams: {
|
||||
date: dateTag,
|
||||
user: inviteUser.id,
|
||||
},
|
||||
})
|
||||
user.inviteUser = inviteUser.id
|
||||
await user.save()
|
||||
return {}
|
||||
|
@ -5,6 +5,13 @@ import { mongoose } from '@typegoose/typegoose'
|
||||
import { rankKey, rankLevel, updateRankScore } from 'services/rank.svr'
|
||||
import { formatDate } from 'zutils/utils/date.util'
|
||||
import { ScoreRecord } from 'models/ScoreRecord'
|
||||
import { ChestRecord } from 'models/chain/ChestRecord'
|
||||
const chestCfg = require('../../configs/chest.json')
|
||||
const chestLevelMap = new Map()
|
||||
|
||||
for (let cfg of chestCfg.chests) {
|
||||
chestLevelMap.set(cfg.level, cfg)
|
||||
}
|
||||
/**
|
||||
* 宝箱相关接口
|
||||
*/
|
||||
@ -67,25 +74,37 @@ class BoxController extends BaseController {
|
||||
const { code } = req.params
|
||||
const user = req.user
|
||||
const uid = user.uid
|
||||
const score = 10 //TODO:: 根据规则生成助力积分
|
||||
|
||||
const session = await mongoose.startSession()
|
||||
session.startTransaction()
|
||||
try {
|
||||
// TODO:: 检查用户是否符合助力条件
|
||||
const chest = await ActivityChest.findOne({ shareCode: code, activity: user.activity }).session(session)
|
||||
if (chest.bonusUsers.includes(uid)) {
|
||||
throw new ZError(10, 'user already enhanced')
|
||||
}
|
||||
if (chest.bonusUsers.length >= chest.maxBonus) {
|
||||
if (chest.bonusUsers.length >= chest.maxBounsCount) {
|
||||
throw new ZError(12, 'enhanced times exceed')
|
||||
}
|
||||
if (chest.status === 9) {
|
||||
throw new ZError(13, 'chest already opened')
|
||||
}
|
||||
if (chest.status === 0) {
|
||||
throw new ZError(14, 'chest is locked')
|
||||
}
|
||||
if (chest.user === uid) {
|
||||
throw new ZError(15, 'can not enhance self')
|
||||
}
|
||||
const score = Math.floor(Math.random() * (chest.bounsCfg[1] - chest.bounsCfg[0] + 1) + chest.bounsCfg[0])
|
||||
chest.bonusUsers.push(uid)
|
||||
chest.bonusScores.push(score)
|
||||
chest.scoreBonus += score
|
||||
await chest.save({ session })
|
||||
// TODO:: 新用户给一个锁住的箱子
|
||||
await session.commitTransaction()
|
||||
session.endSession()
|
||||
return {
|
||||
score: 1, // TODO:: 根据规则生成自己获得助力积分
|
||||
score: 1,
|
||||
}
|
||||
} catch (error) {
|
||||
session.abortTransaction()
|
||||
@ -96,6 +115,12 @@ class BoxController extends BaseController {
|
||||
|
||||
/**
|
||||
* 开启宝箱
|
||||
* 流程如下:
|
||||
* 1. 客户端组装json string: data:,{"p":"cf-20","op":"chest_open","id":"${chestId}"}
|
||||
* 2. 将字符串转成hex
|
||||
* 3. 将hex字符串作为data, 发起一笔至特定地址的0ETH交易
|
||||
* 4. 服务端监听到交易后, 解析input, 获取chestId
|
||||
* 5. 服务端调用此接口, 传入chestId, 完成开箱操作
|
||||
*/
|
||||
@router('post /api/chest/open')
|
||||
async openChest(req) {
|
||||
@ -105,6 +130,10 @@ class BoxController extends BaseController {
|
||||
if (!chestid) {
|
||||
throw new ZError(11, 'chestid is required')
|
||||
}
|
||||
const openRecord = await ChestRecord.findOne({ from: user.address, chestId: chestid })
|
||||
if (!openRecord) {
|
||||
throw new ZError(12, 'onchain open record not found')
|
||||
}
|
||||
const chest = await ActivityChest.findById(chestid)
|
||||
if (!chest) {
|
||||
throw new ZError(12, 'chest not found')
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { MANUAL_OPEN_GAME } from 'common/Constants'
|
||||
import { ActivityGame } from 'models/ActivityGame'
|
||||
import { DAILY_SIGN, SIGN_TOTAL, TicketRecord, USE_TICKET } from 'models/TicketRecord'
|
||||
import { queryCheckInList } from 'services/chain.svr'
|
||||
import { checkInToday, seqSignCfg, seqSignScore, totalSignCfg, totalSignScore } from 'services/sign.svr'
|
||||
import { ZError, SyncLocker, ZRedisClient, BaseController, ROLE_ANON, role, router } from 'zutils'
|
||||
import { formatDate } from 'zutils/utils/date.util'
|
||||
const chestCfg = require('../../configs/chest.json')
|
||||
/**
|
||||
* 探索游戏相关接口
|
||||
*/
|
||||
@ -18,7 +20,7 @@ class GameController extends BaseController {
|
||||
const { address } = user
|
||||
const dateTag = formatDate(new Date())
|
||||
const gameRecord = await ActivityGame.insertOrUpdate({ user: user.id, activity: user.activity }, {})
|
||||
if (gameRecord.status === 0) {
|
||||
if (MANUAL_OPEN_GAME && gameRecord.status === 0) {
|
||||
throw new ZError(11, 'map not open')
|
||||
}
|
||||
if (dateTag === gameRecord.lastSignDay) {
|
||||
@ -101,17 +103,27 @@ class GameController extends BaseController {
|
||||
score,
|
||||
})
|
||||
const gameRecord = await ActivityGame.insertOrUpdate({ user: user.id, activity: user.activity }, {})
|
||||
if (MANUAL_OPEN_GAME && gameRecord.status === 0) {
|
||||
throw new ZError(12, 'map not open')
|
||||
}
|
||||
gameRecord.tickets += score
|
||||
await gameRecord.save()
|
||||
await record.save()
|
||||
return { ticket: score }
|
||||
}
|
||||
/**
|
||||
* //TODO::开启地图
|
||||
* 开启地图
|
||||
*/
|
||||
@router('get /api/game/open')
|
||||
async openMap(req) {
|
||||
const user = req.user
|
||||
const gameInfo = await ActivityGame.insertOrUpdate({ user: user.id, activity: user.activity }, {})
|
||||
if (gameInfo.status === 1) {
|
||||
throw new ZError(11, 'already opened')
|
||||
}
|
||||
// TODO:: check condition
|
||||
gameInfo.status = 1
|
||||
await gameInfo.save()
|
||||
return {}
|
||||
}
|
||||
/**
|
||||
@ -121,6 +133,9 @@ class GameController extends BaseController {
|
||||
async gameStat(req, res) {
|
||||
const user = req.user
|
||||
const record = await ActivityGame.insertOrUpdate({ user: user.id, activity: user.activity }, {})
|
||||
if (MANUAL_OPEN_GAME && record.status === 0) {
|
||||
throw new ZError(12, 'map not open')
|
||||
}
|
||||
const signCfg = seqSignCfg
|
||||
const dateTag = formatDate(new Date())
|
||||
const checkRecord = await checkInToday(user.address, dateTag)
|
||||
@ -180,7 +195,7 @@ class GameController extends BaseController {
|
||||
step = parseInt(step)
|
||||
|
||||
const record = await ActivityGame.insertOrUpdate({ user: user.id, activity: user.activity }, {})
|
||||
if (record.status === 0) {
|
||||
if (MANUAL_OPEN_GAME && record.status === 0) {
|
||||
throw new ZError(12, 'map not open')
|
||||
}
|
||||
if (record.tickets < step) {
|
||||
|
@ -13,6 +13,9 @@ var ejson = require('mongodb-extended-json')
|
||||
const fs = require('fs') // Used to get all the files in a directory
|
||||
const list = fs.readdirSync(dir)
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (list[i].endsWith('.json') === false) {
|
||||
continue
|
||||
}
|
||||
// Remove the file extension
|
||||
const collection_name = list[i].replace('.json', '')
|
||||
const parsedJSON = require(dir + '/' + list[i])
|
||||
|
@ -44,7 +44,10 @@ class ActivityChestClass extends BaseModule {
|
||||
public level: number
|
||||
// 最大助力次数
|
||||
@prop()
|
||||
public maxBonus: number
|
||||
public maxBounsCount: number
|
||||
// 助力积分配置[min, max]
|
||||
@prop({ type: () => [Number], default: [] })
|
||||
public bounsCfg: number[]
|
||||
// 基础积分
|
||||
@prop({ default: 0 })
|
||||
public scoreInit: number
|
||||
@ -64,7 +67,7 @@ class ActivityChestClass extends BaseModule {
|
||||
stat: this.status,
|
||||
shareCode: this.shareCode,
|
||||
level: this.level,
|
||||
maxBonus: this.maxBonus,
|
||||
maxBounsCount: this.maxBounsCount,
|
||||
scoreInit: this.scoreInit,
|
||||
scoreBonus: this.scoreBonus,
|
||||
bounsCount: this.bonusUsers.length,
|
||||
|
60
src/models/chain/ChestRecord.ts
Normal file
60
src/models/chain/ChestRecord.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose'
|
||||
import { dbconn } from 'decorators/dbconn'
|
||||
import { BaseModule } from '../Base'
|
||||
import { hexToUtf8 } from 'zutils/utils/string.util'
|
||||
import logger from 'logger/logger'
|
||||
|
||||
@dbconn('chain')
|
||||
@index({ from: 1 }, { unique: false })
|
||||
@index({ from: 1, chestId: 1 }, { unique: true })
|
||||
@index({ from: 1, blockTime: 1 }, { unique: false })
|
||||
@modelOptions({
|
||||
schemaOptions: { collection: 'chest_open_record', timestamps: true },
|
||||
})
|
||||
export class ChestRecordClass extends BaseModule {
|
||||
@prop({ required: true })
|
||||
public from!: string
|
||||
@prop()
|
||||
public to: string
|
||||
@prop({ required: true })
|
||||
public hash: string
|
||||
@prop()
|
||||
public blockNumber: string
|
||||
@prop()
|
||||
public blockHash: string
|
||||
@prop()
|
||||
public blockTime: number
|
||||
@prop()
|
||||
public dateTag: string
|
||||
@prop()
|
||||
public chestId: string
|
||||
@prop()
|
||||
public value: string
|
||||
@prop()
|
||||
public input: string
|
||||
|
||||
public static async saveEvent(event: any) {
|
||||
const dataStr = hexToUtf8(event.input)
|
||||
const regexp = /data:,{\"p\":\"cf-20\",\"op\":\"chest_open\",\"id\":\"(.+?)\"}/
|
||||
const match = dataStr.match(regexp)
|
||||
if (!match) {
|
||||
logger.log('not a chest open event:', event.hash)
|
||||
return
|
||||
}
|
||||
event.chestId = match[1]
|
||||
logger.log('open chest with id:', event.chestId)
|
||||
return ChestRecord.insertOrUpdate({ hash: event.hash }, event)
|
||||
}
|
||||
|
||||
public toJson() {
|
||||
return {
|
||||
address: this.from,
|
||||
day: this.dateTag,
|
||||
time: this.blockTime,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const ChestRecord = getModelForClass(ChestRecordClass, {
|
||||
existingConnection: ChestRecordClass['db'],
|
||||
})
|
3
src/services/activity.svr.ts
Normal file
3
src/services/activity.svr.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const isActivityReady = (activity: any) => {
|
||||
return true
|
||||
}
|
@ -38,7 +38,7 @@ export const queryCheckInSeq = async (address: string) => {
|
||||
return record.toJson()
|
||||
}
|
||||
|
||||
export const queryBurnNftList = async (address: string, user: string, chain: number) => {
|
||||
export const queryBurnNftList = async (address: string, user: string, chain: string) => {
|
||||
address = address.toLowerCase()
|
||||
user = user.toLowerCase()
|
||||
|
||||
|
@ -12,7 +12,7 @@ export default class BurnNft extends ITask {
|
||||
const { task } = data
|
||||
let cfg = this.activity.tasks.find((t: TaskCfg) => t.id === task.id)
|
||||
const address = cfg.params.address.toLowerCase()
|
||||
const chain = parseInt(process.env.CHAIN)
|
||||
const chain = process.env.CHAIN
|
||||
const nftList = await queryBurnNftList(address, this.user.address, chain)
|
||||
const localNft = await NftBurnRecord.find({
|
||||
user: this.user.id,
|
||||
|
42
yarn.lock
42
yarn.lock
@ -659,15 +659,15 @@
|
||||
resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz"
|
||||
integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
|
||||
|
||||
"@typegoose/typegoose@^12.1.0":
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@typegoose/typegoose/-/typegoose-12.1.0.tgz#06da94152fef00e69978ecd5de6db83a7ae420b7"
|
||||
integrity sha512-RhqsFvTCTshtYxuzsHCGwPLJXgX1sc5aguZJ4w3ax6shVHaVQSG4VZddo/BowfP+0CSjp4J8XeCtrunkzkhJOg==
|
||||
"@typegoose/typegoose@^12.2.0":
|
||||
version "12.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@typegoose/typegoose/-/typegoose-12.2.0.tgz#c1aeba14f80ae94069000a9a2db0128c1e35b8fe"
|
||||
integrity sha512-6gC5aIfccXw4IZOMe3oSef63M6leDyMvuycfwzQdVi8M9C5UnpaV8tO1xzmxiOxUHDST0GdDW/aWCCX6MtOQxg==
|
||||
dependencies:
|
||||
lodash "^4.17.20"
|
||||
loglevel "^1.8.1"
|
||||
loglevel "^1.9.1"
|
||||
reflect-metadata "^0.2.1"
|
||||
semver "^7.5.4"
|
||||
semver "^7.6.0"
|
||||
tslib "^2.6.2"
|
||||
|
||||
"@types/bn.js@^4.11.3":
|
||||
@ -2998,10 +2998,10 @@ lodash@^4.17.20:
|
||||
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
loglevel@^1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4"
|
||||
integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==
|
||||
loglevel@^1.9.1:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.9.1.tgz#d63976ac9bcd03c7c873116d41c2a85bafff1be7"
|
||||
integrity sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==
|
||||
|
||||
long-timeout@0.1.1:
|
||||
version "0.1.1"
|
||||
@ -3232,10 +3232,10 @@ mongodb@6.3.0:
|
||||
bson "^6.2.0"
|
||||
mongodb-connection-string-url "^3.0.0"
|
||||
|
||||
mongoose@8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.1.0.tgz#25be9a39295c0cbffc971fdd4fb6302dceeb2ded"
|
||||
integrity sha512-kOA4Xnq2goqNpN9EmYElGNWfxA9H80fxcr7UdJKWi3UMflza0R7wpTihCpM67dE/0MNFljoa0sjQtlXVkkySAQ==
|
||||
mongoose@8.2.3:
|
||||
version "8.2.3"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.2.3.tgz#26c2074b0d65fa83fa2fd899d3327a2a820fd4c8"
|
||||
integrity sha512-ZB8K8AgbVgLCcqjtmZMxaQBEztwEEZCtAIPMx2Q56Uo4WWKmwf5Nu/EEIFo8d/17P946X0z6xzxwIqCxUMKxrA==
|
||||
dependencies:
|
||||
bson "^6.2.0"
|
||||
kareem "2.5.1"
|
||||
@ -3337,6 +3337,13 @@ node-addon-api@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz"
|
||||
integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==
|
||||
|
||||
node-fetch@2:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
|
||||
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-fetch@2.6.7:
|
||||
version "2.6.7"
|
||||
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz"
|
||||
@ -3937,6 +3944,13 @@ semver@^7.5.4:
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
semver@^7.6.0:
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d"
|
||||
integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
send@0.18.0:
|
||||
version "0.18.0"
|
||||
resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz"
|
||||
|
Loading…
x
Reference in New Issue
Block a user