314 lines
8.5 KiB
JavaScript
314 lines
8.5 KiB
JavaScript
import Match3Campaign from '../models/match3/campaign.js';
|
|
import Match3Level from '../models/match3/level.js';
|
|
import Match3Objective from '../models/match3/objective.js';
|
|
import Match3UserProgress from '../models/match3/userProgress.js';
|
|
import Match3UserLevelProgress from '../models/match3/userLevelProgress.js';
|
|
|
|
class Match3Service {
|
|
/**
|
|
* Lädt alle aktiven Kampagnen
|
|
*/
|
|
async getActiveCampaigns() {
|
|
try {
|
|
const campaigns = await Match3Campaign.findAll({
|
|
where: { isActive: true },
|
|
include: [
|
|
{
|
|
model: Match3Level,
|
|
as: 'levels',
|
|
where: { isActive: true },
|
|
required: false,
|
|
include: [
|
|
{
|
|
model: Match3Objective,
|
|
as: 'objectives',
|
|
required: false,
|
|
order: [['order', 'ASC']]
|
|
}
|
|
],
|
|
order: [['order', 'ASC']]
|
|
}
|
|
],
|
|
order: [['order', 'ASC']]
|
|
});
|
|
|
|
return campaigns;
|
|
} catch (error) {
|
|
console.error('Error loading active campaigns:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lädt eine spezifische Kampagne mit allen Leveln
|
|
*/
|
|
async getCampaign(campaignId) {
|
|
try {
|
|
const campaign = await Match3Campaign.findByPk(campaignId, {
|
|
include: [
|
|
{
|
|
model: Match3Level,
|
|
as: 'levels',
|
|
where: { isActive: true },
|
|
required: false,
|
|
include: [
|
|
{
|
|
model: Match3Objective,
|
|
as: 'objectives',
|
|
required: false,
|
|
order: [['order', 'ASC']]
|
|
}
|
|
],
|
|
order: [['order', 'ASC']]
|
|
}
|
|
]
|
|
});
|
|
|
|
return campaign;
|
|
} catch (error) {
|
|
console.error('Error loading campaign:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lädt den Benutzerfortschritt für eine Kampagne
|
|
*/
|
|
async getUserProgress(userId, campaignId) {
|
|
try {
|
|
let userProgress = await Match3UserProgress.findOne({
|
|
where: { userId, campaignId },
|
|
include: [
|
|
{
|
|
model: Match3UserLevelProgress,
|
|
as: 'levelProgress',
|
|
include: [
|
|
{
|
|
model: Match3Level,
|
|
as: 'level'
|
|
}
|
|
]
|
|
}
|
|
]
|
|
});
|
|
|
|
if (!userProgress) {
|
|
// Erstelle neuen Fortschritt wenn noch nicht vorhanden
|
|
userProgress = await Match3UserProgress.create({
|
|
userId,
|
|
campaignId,
|
|
totalScore: 0,
|
|
totalStars: 0,
|
|
levelsCompleted: 0,
|
|
currentLevel: 1,
|
|
isCompleted: false
|
|
});
|
|
} else {
|
|
// Validiere und korrigiere bestehende currentLevel-Werte
|
|
if (userProgress.currentLevel < 1 || userProgress.currentLevel > 1000) {
|
|
console.warn(`Invalid currentLevel detected for user ${userId}: ${userProgress.currentLevel}, correcting to ${userProgress.levelsCompleted + 1}`);
|
|
|
|
// Korrigiere den ungültigen Wert
|
|
await userProgress.update({
|
|
currentLevel: userProgress.levelsCompleted + 1
|
|
});
|
|
|
|
// Lade den aktualisierten Datensatz
|
|
userProgress = await Match3UserProgress.findByPk(userProgress.id, {
|
|
include: [
|
|
{
|
|
model: Match3UserLevelProgress,
|
|
as: 'levelProgress',
|
|
include: [
|
|
{
|
|
model: Match3Level,
|
|
as: 'level'
|
|
}
|
|
]
|
|
}
|
|
]
|
|
});
|
|
}
|
|
}
|
|
|
|
return userProgress;
|
|
} catch (error) {
|
|
console.error('Error loading user progress:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Aktualisiert den Level-Fortschritt eines Benutzers
|
|
*/
|
|
async updateLevelProgress(userId, campaignId, levelId, levelData) {
|
|
try {
|
|
// Lade oder erstelle Benutzerfortschritt
|
|
let userProgress = await Match3UserProgress.findOne({
|
|
where: { userId, campaignId }
|
|
});
|
|
|
|
if (!userProgress) {
|
|
userProgress = await Match3UserProgress.create({
|
|
userId,
|
|
campaignId,
|
|
totalScore: 0,
|
|
totalStars: 0,
|
|
levelsCompleted: 0,
|
|
currentLevel: 1,
|
|
isCompleted: false
|
|
});
|
|
}
|
|
|
|
// Lade oder erstelle Level-Fortschritt
|
|
let levelProgress = await Match3UserLevelProgress.findOne({
|
|
where: { userProgressId: userProgress.id, levelId }
|
|
});
|
|
|
|
if (!levelProgress) {
|
|
levelProgress = await Match3UserLevelProgress.create({
|
|
userProgressId: userProgress.id,
|
|
levelId,
|
|
score: 0,
|
|
moves: 0,
|
|
time: 0,
|
|
stars: 0,
|
|
isCompleted: false,
|
|
attempts: 0
|
|
});
|
|
}
|
|
|
|
// Aktualisiere Level-Fortschritt
|
|
const updateData = {
|
|
score: Math.max(levelProgress.bestScore, levelData.score),
|
|
moves: levelData.moves,
|
|
time: levelData.time || 0,
|
|
stars: Math.max(levelProgress.stars, levelData.stars),
|
|
isCompleted: levelData.isCompleted || false,
|
|
attempts: levelProgress.attempts + 1
|
|
};
|
|
|
|
if (levelData.isCompleted) {
|
|
updateData.completedAt = new Date();
|
|
}
|
|
|
|
await levelProgress.update(updateData);
|
|
|
|
// Aktualisiere Bestwerte
|
|
if (levelData.score > levelProgress.bestScore) {
|
|
await levelProgress.update({ bestScore: levelData.score });
|
|
}
|
|
if (levelData.moves < levelProgress.bestMoves || levelProgress.bestMoves === 0) {
|
|
await levelProgress.update({ bestMoves: levelData.moves });
|
|
}
|
|
if (levelData.time < levelProgress.bestTime || levelProgress.bestTime === 0) {
|
|
await levelProgress.update({ bestTime: levelData.time });
|
|
}
|
|
|
|
// Aktualisiere Kampagnen-Fortschritt
|
|
if (levelData.isCompleted) {
|
|
const totalScore = await Match3UserLevelProgress.sum('score', {
|
|
where: { userProgressId: userProgress.id, isCompleted: true }
|
|
});
|
|
|
|
const totalStars = await Match3UserLevelProgress.sum('stars', {
|
|
where: { userProgressId: userProgress.id, isCompleted: true }
|
|
});
|
|
|
|
const levelsCompleted = await Match3UserLevelProgress.count({
|
|
where: { userProgressId: userProgress.id, isCompleted: true }
|
|
});
|
|
|
|
// Korrigiere currentLevel: Es sollte immer levelsCompleted + 1 sein
|
|
const correctCurrentLevel = levelsCompleted + 1;
|
|
|
|
await userProgress.update({
|
|
totalScore,
|
|
totalStars,
|
|
levelsCompleted,
|
|
currentLevel: correctCurrentLevel, // Verwende den korrigierten Wert
|
|
lastPlayed: new Date()
|
|
});
|
|
|
|
// Prüfe ob Kampagne abgeschlossen ist
|
|
const totalLevels = await Match3Level.count({
|
|
where: { campaignId, isActive: true }
|
|
});
|
|
|
|
if (levelsCompleted >= totalLevels) {
|
|
await userProgress.update({ isCompleted: true });
|
|
}
|
|
}
|
|
|
|
return { userProgress, levelProgress };
|
|
} catch (error) {
|
|
console.error('Error updating level progress:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lädt die Bestenliste für eine Kampagne
|
|
*/
|
|
async getLeaderboard(campaignId, limit = 10) {
|
|
try {
|
|
const leaderboard = await Match3UserProgress.findAll({
|
|
where: { campaignId },
|
|
include: [
|
|
{
|
|
model: Match3UserLevelProgress,
|
|
as: 'levelProgress',
|
|
where: { isCompleted: true },
|
|
required: false
|
|
}
|
|
],
|
|
order: [
|
|
['totalScore', 'DESC'],
|
|
['totalStars', 'DESC'],
|
|
['levelsCompleted', 'DESC']
|
|
],
|
|
limit
|
|
});
|
|
|
|
return leaderboard;
|
|
} catch (error) {
|
|
console.error('Error loading leaderboard:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lädt Statistiken für einen Benutzer
|
|
*/
|
|
async getUserStats(userId) {
|
|
try {
|
|
const stats = await Match3UserProgress.findAll({
|
|
where: { userId },
|
|
include: [
|
|
{
|
|
model: Match3Campaign,
|
|
as: 'campaign'
|
|
},
|
|
{
|
|
model: Match3UserLevelProgress,
|
|
as: 'levelProgress',
|
|
include: [
|
|
{
|
|
model: Match3Level,
|
|
as: 'level'
|
|
}
|
|
]
|
|
}
|
|
]
|
|
});
|
|
|
|
return stats;
|
|
} catch (error) {
|
|
console.error('Error loading user stats:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
export default new Match3Service();
|