1
This commit is contained in:
52
tasks/tasks.controller.js
Normal file
52
tasks/tasks.controller.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const TasksModel = require("./tasks.model.js");
|
||||
|
||||
// Get all task configurations
|
||||
exports.getAllTasks = async (req, res) => {
|
||||
try {
|
||||
const tasks = await TasksModel.getAllTaskConfigs();
|
||||
res.status(200).send(tasks);
|
||||
} catch (error) {
|
||||
res.status(500).send({ error: "Internal server error" });
|
||||
}
|
||||
};
|
||||
|
||||
// Get player tasks
|
||||
exports.getPlayerTasks = async (req, res) => {
|
||||
try {
|
||||
const userId = req.params.userId;
|
||||
if (!userId) {
|
||||
return res.status(400).send({ error: "User ID is required" });
|
||||
}
|
||||
|
||||
const playerTasks = await TasksModel.getPlayerTasks(userId);
|
||||
if (!playerTasks) {
|
||||
return res.status(404).send({ error: "Player tasks not found" });
|
||||
}
|
||||
|
||||
res.status(200).send(playerTasks);
|
||||
} catch (error) {
|
||||
res.status(500).send({ error: "Internal server error" });
|
||||
}
|
||||
};
|
||||
|
||||
// Save player tasks
|
||||
exports.savePlayerTasks = async (req, res) => {
|
||||
try {
|
||||
const userId = req.params.userId;
|
||||
if (!userId) {
|
||||
return res.status(400).send({ error: "User ID is required" });
|
||||
}
|
||||
|
||||
const tasksData = req.body;
|
||||
tasksData.userId = userId;
|
||||
|
||||
const updatedTasks = await TasksModel.savePlayerTasks(tasksData);
|
||||
if (!updatedTasks) {
|
||||
return res.status(500).send({ error: "Failed to save player tasks" });
|
||||
}
|
||||
|
||||
res.status(200).send({ success: true });
|
||||
} catch (error) {
|
||||
res.status(500).send({ error: "Internal server error" });
|
||||
}
|
||||
};
|
||||
94
tasks/tasks.model.js
Normal file
94
tasks/tasks.model.js
Normal file
@@ -0,0 +1,94 @@
|
||||
const mongoose = require("mongoose");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
// Task data structure based on the documentation
|
||||
const playerTaskSchema = new Schema({
|
||||
taskId: { type: String, required: true },
|
||||
assignedTime: { type: Date, required: true },
|
||||
expireTime: { type: Date, required: true },
|
||||
status: { type: Number, required: true, default: 0 }, // 0: Active, 1: Completed, 2: Expired, 3: Claimed
|
||||
progress: { type: Number, required: true, default: 0 }
|
||||
});
|
||||
|
||||
const playerTaskDataSchema = new Schema({
|
||||
userId: { type: String, required: true, index: true },
|
||||
tasks: [playerTaskSchema],
|
||||
lastDailyTaskAssigned: { type: Date, default: null }
|
||||
});
|
||||
|
||||
playerTaskDataSchema.methods.toObj = function () {
|
||||
var elem = this.toObject();
|
||||
delete elem.__v;
|
||||
delete elem._id;
|
||||
return elem;
|
||||
};
|
||||
|
||||
const PlayerTaskData = mongoose.model("PlayerTaskData", playerTaskDataSchema);
|
||||
exports.PlayerTaskData = PlayerTaskData;
|
||||
|
||||
// Task configuration storage
|
||||
let taskConfigurations = [];
|
||||
|
||||
// Get all task configurations
|
||||
exports.getAllTaskConfigs = async () => {
|
||||
return taskConfigurations;
|
||||
};
|
||||
|
||||
// Get task configuration by ID
|
||||
exports.getTaskConfigById = async (taskId) => {
|
||||
return taskConfigurations.find(task => task.id === taskId);
|
||||
};
|
||||
|
||||
// Get player tasks
|
||||
exports.getPlayerTasks = async (userId) => {
|
||||
try {
|
||||
let playerTaskData = await PlayerTaskData.findOne({ userId: userId });
|
||||
if (!playerTaskData) {
|
||||
playerTaskData = new PlayerTaskData({
|
||||
userId: userId,
|
||||
tasks: [],
|
||||
lastDailyTaskAssigned: null
|
||||
});
|
||||
await playerTaskData.save();
|
||||
}
|
||||
return playerTaskData;
|
||||
} catch (e) {
|
||||
console.error("Error getting player tasks:", e);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Save player tasks
|
||||
exports.savePlayerTasks = async (playerTaskData) => {
|
||||
try {
|
||||
const updated = await PlayerTaskData.findOneAndUpdate(
|
||||
{ userId: playerTaskData.userId },
|
||||
playerTaskData,
|
||||
{ new: true, upsert: true }
|
||||
);
|
||||
return updated;
|
||||
} catch (e) {
|
||||
console.error("Error saving player tasks:", e);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize task configurations from file
|
||||
exports.initializeTaskConfig = (configPath) => {
|
||||
try {
|
||||
if (fs.existsSync(configPath)) {
|
||||
const configFile = fs.readFileSync(configPath, 'utf8');
|
||||
taskConfigurations = JSON.parse(configFile);
|
||||
console.log(`Loaded ${taskConfigurations.length} task configurations`);
|
||||
} else {
|
||||
console.log("Task configuration file not found, using empty configuration");
|
||||
taskConfigurations = [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error initializing task configuration:", e);
|
||||
taskConfigurations = [];
|
||||
}
|
||||
};
|
||||
30
tasks/tasks.routes.js
Normal file
30
tasks/tasks.routes.js
Normal file
@@ -0,0 +1,30 @@
|
||||
const TasksController = require('./tasks.controller.js');
|
||||
const AuthTool = require('../authorization/auth.tool.js');
|
||||
const config = require('../config.js');
|
||||
|
||||
const ADMIN = config.permissions.ADMIN; // Highest permission, can read and write all users
|
||||
const SERVER = config.permissions.SERVER; // Middle permission, can read all users
|
||||
const USER = config.permissions.USER; // Lowest permission, can only do things on same user
|
||||
|
||||
exports.route = (app) => {
|
||||
// Get all task configurations
|
||||
app.get('/api/tasks',
|
||||
AuthTool.isValidJWT,
|
||||
AuthTool.isPermissionLevel(SERVER),
|
||||
TasksController.getAllTasks
|
||||
);
|
||||
|
||||
// Get player tasks
|
||||
app.get('/api/tasks/:userId',
|
||||
AuthTool.isValidJWT,
|
||||
AuthTool.isSameUserOr(SERVER),
|
||||
TasksController.getPlayerTasks
|
||||
);
|
||||
|
||||
// Save player tasks
|
||||
app.post('/api/tasks/:userId',
|
||||
AuthTool.isValidJWT,
|
||||
AuthTool.isSameUserOr(SERVER),
|
||||
TasksController.savePlayerTasks
|
||||
);
|
||||
};
|
||||
111
tasks/tasks.tool.js
Normal file
111
tasks/tasks.tool.js
Normal file
@@ -0,0 +1,111 @@
|
||||
const TasksModel = require("./tasks.model.js");
|
||||
|
||||
// Task status constants
|
||||
const TASK_STATUS = {
|
||||
ACTIVE: 0,
|
||||
COMPLETED: 1,
|
||||
EXPIRED: 2,
|
||||
CLAIMED: 3
|
||||
};
|
||||
|
||||
// Task condition types
|
||||
const TASK_CONDITION_TYPES = {
|
||||
LOGIN_GAME: 1,
|
||||
PLAY_GAMES: 2,
|
||||
WIN_GAMES: 3,
|
||||
DEFEAT_HERO_WITH_ATTRIBUTES: 4,
|
||||
SUMMON_HERO_WITH_ATTRIBUTES: 5,
|
||||
USE_HERO_SKILL_WITH_ATTRIBUTES: 6
|
||||
};
|
||||
|
||||
// Task reward types
|
||||
const TASK_REWARD_TYPES = {
|
||||
COINS: 0
|
||||
};
|
||||
|
||||
// Check if a task is expired
|
||||
exports.isTaskExpired = (task) => {
|
||||
return new Date() > new Date(task.expireTime);
|
||||
};
|
||||
|
||||
// Check if a task is completed
|
||||
exports.isTaskCompleted = (task) => {
|
||||
return task.status === TASK_STATUS.COMPLETED;
|
||||
};
|
||||
|
||||
// Check if a task is claimed
|
||||
exports.isTaskClaimed = (task) => {
|
||||
return task.status === TASK_STATUS.CLAIMED;
|
||||
};
|
||||
|
||||
// Get a random task from the configuration
|
||||
exports.getRandomTask = async () => {
|
||||
const tasks = await TasksModel.getAllTaskConfigs();
|
||||
if (tasks.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const randomIndex = Math.floor(Math.random() * tasks.length);
|
||||
return tasks[randomIndex];
|
||||
};
|
||||
|
||||
// Create a new player task based on task configuration
|
||||
exports.createPlayerTask = async (taskConfig) => {
|
||||
const now = new Date();
|
||||
const expireTime = new Date(now.getTime() + (taskConfig.durationHours * 60 * 60 * 1000));
|
||||
|
||||
return {
|
||||
taskId: taskConfig.id,
|
||||
assignedTime: now,
|
||||
expireTime: expireTime,
|
||||
status: TASK_STATUS.ACTIVE,
|
||||
progress: 0
|
||||
};
|
||||
};
|
||||
|
||||
// Update task progress
|
||||
exports.updateTaskProgress = async (playerTask, taskConfig, increment = 1) => {
|
||||
// Check if task is already completed or claimed
|
||||
if (playerTask.status === TASK_STATUS.COMPLETED || playerTask.status === TASK_STATUS.CLAIMED) {
|
||||
return playerTask;
|
||||
}
|
||||
|
||||
// Update progress
|
||||
playerTask.progress += increment;
|
||||
|
||||
// Check if task is completed
|
||||
if (playerTask.progress >= taskConfig.value1) {
|
||||
playerTask.progress = taskConfig.value1; // Cap at the required value
|
||||
playerTask.status = TASK_STATUS.COMPLETED;
|
||||
}
|
||||
|
||||
return playerTask;
|
||||
};
|
||||
|
||||
// Give reward for completing a task
|
||||
exports.giveTaskReward = async (userId, taskConfig) => {
|
||||
// In a real implementation, this would integrate with the rewards system
|
||||
// For now, we'll just log the reward information
|
||||
console.log(`Giving reward to user ${userId} for task ${taskConfig.id}`);
|
||||
|
||||
for (let i = 0; i < taskConfig.rewardTypes.length; i++) {
|
||||
const rewardType = taskConfig.rewardTypes[i];
|
||||
const rewardNum = taskConfig.rewardNums[i];
|
||||
|
||||
switch (rewardType) {
|
||||
case TASK_REWARD_TYPES.COINS:
|
||||
console.log(`Rewarding ${rewardNum} coins to user ${userId}`);
|
||||
// Here we would call the rewards system to give coins to the user
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown reward type: ${rewardType}`);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Export constants
|
||||
exports.TASK_STATUS = TASK_STATUS;
|
||||
exports.TASK_CONDITION_TYPES = TASK_CONDITION_TYPES;
|
||||
exports.TASK_REWARD_TYPES = TASK_REWARD_TYPES;
|
||||
Reference in New Issue
Block a user