change task id
This commit is contained in:
parent
ff41a769b7
commit
eb9ce07ff5
@ -101,12 +101,14 @@ SiweMessage的nonce说明(具体参考例子):
|
||||
"tasks": [ // 该活动需要完成的任务
|
||||
{
|
||||
"id": "任务id",
|
||||
"task": "任务类型",
|
||||
"title": "任务名",
|
||||
"desc": "任务描述",
|
||||
"type": 1, //任务类型, 1: 一次性任务, 2: 日常任务
|
||||
"pretasks": ["task id 1"], //前置任务
|
||||
"score": 0, // 完成任务可获得的积分
|
||||
"category": "", // 任务分类
|
||||
"data": {}, // 其他一些任务相关配置参数, 比如icon, 或者其他未考虑的参数
|
||||
"autoclaim": false // 任务完成后是否自动获取奖励
|
||||
}
|
||||
],
|
||||
|
@ -4,50 +4,108 @@
|
||||
"name": "First Activity1",
|
||||
"description": "This is the first test activity",
|
||||
"tasks": [{
|
||||
"id": "TwitterConnect",
|
||||
"id": "e2yhq2lj30vwcpedv7p",
|
||||
"task": "TwitterConnect",
|
||||
"title": "Connect Twitter",
|
||||
"type": 1,
|
||||
"desc": "",
|
||||
"score": 100,
|
||||
"category": "",
|
||||
"autoclaim": true,
|
||||
"data": {},
|
||||
"params": {}
|
||||
}, {
|
||||
"id": "TwitterFollow",
|
||||
"id": "e2fclylj30vwcpe0szl",
|
||||
"task": "TwitterFollow",
|
||||
"title": "Follow Twitter",
|
||||
"type": 1,
|
||||
"desc": "",
|
||||
"category": "",
|
||||
"desc": "Follow Counter Fire’s official X account",
|
||||
"category": "Social Tasks",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": ["TwitterConnect"],
|
||||
"data": {},
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"id": "OkxLogin",
|
||||
"title": "okx wallet login",
|
||||
"id": "e2feyflj30vwcpe0sjy",
|
||||
"task": "TwitterFollow",
|
||||
"title": "Follow Twitter",
|
||||
"type": 1,
|
||||
"desc": "",
|
||||
"category": "",
|
||||
"category": "Social Tasks",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"params": {}
|
||||
"pretasks": ["TwitterConnect"],
|
||||
"data": {},
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"id": "TwitterRetweet",
|
||||
"title": "ReTwitt",
|
||||
"id": "e2fuah0j30vwcpe0my7",
|
||||
"task": "TwitterRetweet",
|
||||
"title": "ReTwitter",
|
||||
"type": 2,
|
||||
"desc": "",
|
||||
"category": "Social Tasks",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": ["TwitterConnect"],
|
||||
"data": {},
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"id": "e2far3lj30vwcpe0mh7",
|
||||
"task": "DiscordConnect",
|
||||
"title": "Connect Discord",
|
||||
"type": 2,
|
||||
"desc": "",
|
||||
"category": "",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": ["TwitterConnect"],
|
||||
"pretasks": [],
|
||||
"data": {},
|
||||
"params": {}
|
||||
}, {
|
||||
"id": "e2far3lj30vwcpe0mf8",
|
||||
"task": "DiscordJoin",
|
||||
"title": "Join Discord",
|
||||
"type": 2,
|
||||
"desc": "",
|
||||
"category": "",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"data": {},
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"id": "UpdateScore",
|
||||
"id": "e2fak2lj30vwcpe0awc",
|
||||
"task": "DiscordRole",
|
||||
"title": "Discord Role",
|
||||
"type": 2,
|
||||
"desc": "",
|
||||
"category": "Social Tasks",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": ["DiscordJoin"],
|
||||
"data": {},
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"id": "e2f7fplj30vwcpe0l98",
|
||||
"task": "OkxLogin",
|
||||
"title": "okx wallet login",
|
||||
"type": 1,
|
||||
"desc": "",
|
||||
"category": "Special Quests",
|
||||
"score": 100,
|
||||
"autoclaim": false,
|
||||
"pretasks": [],
|
||||
"data": {},
|
||||
"params": {}
|
||||
}, {
|
||||
"id": "e2f7t4lj30vwcpe0ldr",
|
||||
"task": "ShareCode",
|
||||
"type": 1,
|
||||
"show": false,
|
||||
"autoclaim": false,
|
||||
"pretasks": ["TwitterConnect", "TwitterFollow"],
|
||||
"pretasks": [],
|
||||
"data": {},
|
||||
"params": {"score": [100, 20]}
|
||||
}],
|
||||
"startTime": 1702628292366,
|
||||
|
@ -63,7 +63,7 @@ export default class ActivityController extends BaseController {
|
||||
let user = await ActivityUser.findById(id)
|
||||
results.push({
|
||||
rank: start + i / 2 + 1,
|
||||
address: user.address,
|
||||
address: user?.address || 'unknow',
|
||||
score
|
||||
})
|
||||
}
|
||||
|
@ -44,20 +44,20 @@ export default class TasksController extends BaseController {
|
||||
let modified = false;
|
||||
let visibleTasks = new Set();
|
||||
for (let task of activity.tasks) {
|
||||
if (!allTasks.has(task.id)) {
|
||||
if (!allTasks.has(task.task)) {
|
||||
continue;
|
||||
}
|
||||
if (task.type === TaskTypeEnum.DAILY ) {
|
||||
let id = `${task.id}:${dateTag}`
|
||||
if (!taskAddedSet.has(id)) {
|
||||
modified = true;
|
||||
user.taskProgress.push({id, dateTag: dateTag, status: TaskStatusEnum.NOT_START})
|
||||
user.taskProgress.push({id, task:task.task ,dateTag: dateTag, status: TaskStatusEnum.NOT_START})
|
||||
}
|
||||
if (task.show) visibleTasks.add(id);
|
||||
} else if (task.type === TaskTypeEnum.ONCE ) {
|
||||
if (!taskAddedSet.has(task.id)) {
|
||||
modified = true;
|
||||
user.taskProgress.push({id: task.id, status: TaskStatusEnum.NOT_START})
|
||||
user.taskProgress.push({id: task.id, task: task.task, status: TaskStatusEnum.NOT_START})
|
||||
}
|
||||
if (task.show) visibleTasks.add(task.id);
|
||||
}
|
||||
@ -132,7 +132,7 @@ export default class TasksController extends BaseController {
|
||||
throw new ZError(11, 'task not begin');
|
||||
}
|
||||
if (currentTask.status === TaskStatusEnum.RUNNING) {
|
||||
let Task = require('../tasks/' + taskId);
|
||||
let Task = require('../tasks/' + currentTask.task);
|
||||
let taskInstance = new Task.default({user, activity});
|
||||
await taskInstance.execute({task: currentTask});
|
||||
}
|
||||
@ -155,7 +155,7 @@ export default class TasksController extends BaseController {
|
||||
throw new ZError(13, 'task not end')
|
||||
}
|
||||
|
||||
const Task = require('../tasks/' + task);
|
||||
const Task = require('../tasks/' + currentTask.task);
|
||||
const taskInstance = new Task.default({user, activity});
|
||||
await taskInstance.claimReward(currentTask);
|
||||
return currentTask
|
||||
|
@ -15,6 +15,8 @@ export class TaskCfg {
|
||||
@prop()
|
||||
id: string
|
||||
@prop()
|
||||
task: string
|
||||
@prop()
|
||||
title: string
|
||||
@prop({ enum: TaskTypeEnum, default: TaskTypeEnum.ONCE })
|
||||
type: TaskTypeEnum
|
||||
@ -31,6 +33,8 @@ export class TaskCfg {
|
||||
@prop({default: true})
|
||||
show: boolean
|
||||
@prop({ type: mongoose.Schema.Types.Mixed })
|
||||
data: any
|
||||
@prop({ type: mongoose.Schema.Types.Mixed })
|
||||
params: any
|
||||
}
|
||||
interface ActivityInfoClass extends Base, TimeStamps {}
|
||||
@ -68,6 +72,7 @@ class ActivityInfoClass extends BaseModule {
|
||||
if (task.show) {
|
||||
tasks.push({
|
||||
id: task.id,
|
||||
task: task.task,
|
||||
title: task.title,
|
||||
desc: task.desc,
|
||||
type: task.type,
|
||||
@ -75,6 +80,7 @@ class ActivityInfoClass extends BaseModule {
|
||||
score: task.score,
|
||||
category: task.category,
|
||||
autoclaim: task.autoclaim,
|
||||
data: task.data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ export enum TaskStatusEnum {
|
||||
export class TaskStatus {
|
||||
@prop()
|
||||
id: string
|
||||
@prop()
|
||||
task: string
|
||||
// 0: not start, 1: running, 2: success
|
||||
@prop({ enum: TaskStatusEnum, default: TaskStatusEnum.NOT_START })
|
||||
status: TaskStatusEnum
|
||||
|
44
src/tasks/DiscordConnect.ts
Normal file
44
src/tasks/DiscordConnect.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { checkDiscord } from "services/oauth.svr";
|
||||
import { ITask } from "./base/ITask";
|
||||
import { ZError } from "common/ZError";
|
||||
import { TaskStatusEnum } from "models/ActivityUser";
|
||||
import { TaskCfg } from "models/ActivityInfo";
|
||||
|
||||
export default class DiscordConnect extends ITask {
|
||||
static desc = 'join discord'
|
||||
static show: boolean = true
|
||||
|
||||
async execute(data: any) {
|
||||
const { address } = this.params.user
|
||||
const { task } = data
|
||||
const res = await checkDiscord(address)
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === task.id)
|
||||
if (res.status !== 200) {
|
||||
throw new ZError(11, 'discord check failed')
|
||||
}
|
||||
if (res.data.errcode) {
|
||||
throw new ZError(res.data.errcode, res.data.errmsg)
|
||||
}
|
||||
|
||||
if (res.data.data.userid && task.status === TaskStatusEnum.RUNNING) {
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.data = res.data.data
|
||||
task.discordId = res.data.data.userid
|
||||
try {
|
||||
await this.params.user.save()
|
||||
} catch(err) {
|
||||
throw new ZError(100, 'discord already binded')
|
||||
}
|
||||
if (cfg.autoclaim) {
|
||||
try {
|
||||
await this.claimReward(task);
|
||||
} catch(err) {
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
import { checkDiscord } from "services/oauth.svr";
|
||||
import { ITask } from "./base/ITask";
|
||||
import { ZError } from "common/ZError";
|
||||
import { TaskStatusEnum } from "models/ActivityUser";
|
||||
@ -9,32 +8,29 @@ export default class DiscordJoin extends ITask {
|
||||
static show: boolean = true
|
||||
|
||||
async execute(data: any) {
|
||||
const { address } = this.params.user
|
||||
const res = await checkDiscord(address)
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === this.constructor.name)
|
||||
if (res.status !== 200) {
|
||||
throw new ZError(11, 'discord check failed')
|
||||
}
|
||||
if (res.data.errcode) {
|
||||
throw new ZError(res.data.errcode, res.data.errmsg)
|
||||
}
|
||||
const { task } = data
|
||||
if (res.data.data.userid && task.status === TaskStatusEnum.RUNNING) {
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.data = res.data.data
|
||||
task.discordId = res.data.data.userid
|
||||
let cfg = this.params.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 discord join failed')
|
||||
}
|
||||
let num = Math.random() * 100
|
||||
if (num < cfg.params.failRate) {
|
||||
throw new ZError(12, 'check discord join failed')
|
||||
}
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.data = {}
|
||||
try {
|
||||
await this.params.user.save()
|
||||
} catch(err) {
|
||||
throw new ZError(100, 'already join discord')
|
||||
}
|
||||
if (cfg.autoclaim) {
|
||||
try {
|
||||
await this.params.user.save()
|
||||
await this.claimReward(task);
|
||||
} catch(err) {
|
||||
throw new ZError(100, 'discord already binded')
|
||||
}
|
||||
if (cfg.autoclaim) {
|
||||
try {
|
||||
await this.claimReward(task);
|
||||
} catch(err) {
|
||||
console.log(err)
|
||||
}
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
@ -8,7 +8,7 @@ export default class DiscordRole extends ITask {
|
||||
static show: boolean = true
|
||||
async execute(data: any) {
|
||||
const { task } = data
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === this.constructor.name)
|
||||
let cfg = this.params.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 discord role failed')
|
||||
|
@ -12,7 +12,7 @@ export default class OkxLogin extends ITask {
|
||||
async execute(data: any) {
|
||||
const { task } = data
|
||||
const { activity } = this.params.user
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === this.constructor.name)
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === task.id)
|
||||
let wallet = 'okx';
|
||||
let record = LoginRecord.findOne({ user: this.params.user.id, activity, wallet})
|
||||
if (!record ) {
|
||||
|
@ -29,8 +29,8 @@ export default class ShareCode extends ITask {
|
||||
static show: boolean = false
|
||||
|
||||
async execute(data: any) {
|
||||
let task = this.params.user.taskProgress.find((t: TaskStatus) => t.id === this.constructor.name)
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === this.constructor.name)
|
||||
let {task} = data
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === task.id)
|
||||
let scores = cfg.params.score;
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
@ -39,7 +39,7 @@ export default class ShareCode extends ITask {
|
||||
// According to configuration, add score to user who invite current user
|
||||
if (cfg.autoclaim) {
|
||||
try {
|
||||
await updateInviteScore(this.params.user, scores, 0, this.constructor.name)
|
||||
await updateInviteScore(this.params.user, scores, 0, task.task)
|
||||
} catch(err) {
|
||||
console.log(err)
|
||||
}
|
||||
@ -48,8 +48,8 @@ export default class ShareCode extends ITask {
|
||||
}
|
||||
|
||||
public async claimReward(task: TaskStatus) {
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === this.constructor.name)
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === task.id)
|
||||
let scores = cfg.params.score;
|
||||
await updateInviteScore(this.params.user, scores, 0, this.constructor.name)
|
||||
await updateInviteScore(this.params.user, scores, 0, task.task)
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ export default class TwitterConnect extends ITask {
|
||||
} catch(err) {
|
||||
throw new ZError(100, 'twitter already binded')
|
||||
}
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === this.constructor.name)
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === task.id)
|
||||
if (cfg.autoclaim) {
|
||||
try {
|
||||
await this.claimReward(task);
|
||||
|
@ -8,7 +8,7 @@ export default class TwitterFollow extends ITask {
|
||||
static show: boolean = true
|
||||
async execute(data: any) {
|
||||
const { task } = data
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.id === this.constructor.name)
|
||||
let cfg = this.params.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, 'follow failed')
|
||||
|
@ -7,7 +7,7 @@ export default class TwitterRetweet extends ITask {
|
||||
static show: boolean = true
|
||||
async execute(data: any) {
|
||||
const { task } = data
|
||||
let cfg = this.params.activity.tasks.find(t => t.id === this.constructor.name)
|
||||
let cfg = this.params.activity.tasks.find(t => t.id === task.id)
|
||||
let time = cfg.params.time;
|
||||
if (Date.now() - task.timeStart < time * 1000) {
|
||||
throw new ZError(11, 'retweet failed')
|
||||
|
@ -25,7 +25,7 @@ export abstract class ITask {
|
||||
user: user.id,
|
||||
score: cfg.score,
|
||||
activity: user.activity,
|
||||
scoreType: taskId,
|
||||
scoreType: cfg.task,
|
||||
scoreParams: {
|
||||
date: dateTag,
|
||||
taskId: task.id
|
||||
|
@ -136,4 +136,19 @@ export const base58ToHex = (base58String: string) => {
|
||||
num = num * BigInt(58) + BigInt(charIndex);
|
||||
}
|
||||
return num.toString(16);
|
||||
}
|
||||
|
||||
export const hexToBase32 = (hexString: string) => {
|
||||
const bytes = hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16));
|
||||
const base32Alphabet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
|
||||
let base32String = '';
|
||||
|
||||
let num = BigInt('0x' + hexString);
|
||||
while (num > BigInt(0)) {
|
||||
const remainder = num % BigInt(32);
|
||||
num = num / BigInt(32);
|
||||
base32String = base32Alphabet[Number(remainder)] + base32String;
|
||||
}
|
||||
|
||||
return base32String;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user