Files
tcg-server/ladder/ladder.model.js
yaoyanwei e26f405ea8 1
2025-09-08 16:43:50 +08:00

122 lines
3.5 KiB
JavaScript

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ladderService = require('./ladder.service');
const leaderboardSchema = new Schema({
playerId: { type: String, index: true, required: true },
username: { type: String, required: true },
avatar: { type: String, default: "" },
rankId: { type: Number, default: 1 },
rankScore: { type: Number, default: 0 },
stars: { type: Number, default: 0 },
totalWins: { type: Number, default: 0 },
position: { type: Number, required: true },
lastWinDeck: { type: Object, default: null }, // 添加最后获胜牌组信息
lastUpdated: { type: Date, default: Date.now }
});
const Leaderboard = mongoose.model('Leaderboard', leaderboardSchema);
// Leaderboard functions
exports.generateLeaderboard = async () => {
try {
// Clear current leaderboard
await Leaderboard.deleteMany({});
// Get all users
const User = mongoose.model('Users');
const users = await User.find({});
// Sort users based on ranking criteria:
// 1. Rank level (higher is better)
// 2. Rank score (for King rank mechanism)
// 3. Stars
// 4. Total wins
const sortedUsers = users.sort((a, b) => {
const configA = ladderService.getRankConfig(a.rankId);
const configB = ladderService.getRankConfig(b.rankId);
// Compare rank levels
if (configA.Level !== configB.Level) {
return configB.Level - configA.Level;
}
// For players with rank score mechanism (King rank)
if (configA.RankScore === 1 && configB.RankScore === 1) {
if (a.rankScore !== b.rankScore) {
return b.rankScore - a.rankScore;
}
}
// Compare stars
if (a.stars !== b.stars) {
return b.stars - a.stars;
}
// Compare total wins
return b.totalWins - a.totalWins;
});
// Take top 100 players
const topPlayers = sortedUsers.slice(0, 100);
// Create leaderboard entries
const leaderboardEntries = [];
for (let i = 0; i < topPlayers.length; i++) {
const player = topPlayers[i];
const entry = new Leaderboard({
playerId: player._id,
username: player.username,
avatar: player.avatar,
rankId: player.rankId,
rankScore: player.rankScore,
stars: player.stars,
totalWins: player.totalWins,
lastWinDeck: player.lastWinDeck, // 包含最后获胜牌组
position: i + 1
});
leaderboardEntries.push(entry);
}
// Save all entries
if (leaderboardEntries.length > 0) {
await Leaderboard.insertMany(leaderboardEntries);
}
return leaderboardEntries;
} catch (error) {
console.error('Error generating leaderboard:', error);
return [];
}
};
exports.getLeaderboard = async () => {
try {
const leaderboard = await Leaderboard.find({}).sort({ position: 1 });
return leaderboard;
} catch (error) {
console.error('Error getting leaderboard:', error);
return [];
}
};
exports.getPlayerPosition = async (playerId) => {
try {
const entry = await Leaderboard.findOne({ playerId: playerId });
return entry ? entry.position : null;
} catch (error) {
console.error('Error getting player position:', error);
return null;
}
};
// Initialize the ladder for a new player
exports.initializePlayerLadder = (player) => {
player.rankId = 1;
player.stars = 0;
player.rankScore = 0;
player.winStreak = 0;
player.totalWins = 0;
player.lastWinDeck = null; // 初始化最后获胜牌组
return player;
};