Bereinigen und Entfernen von nicht mehr benötigten TinyMCE-Dateien und -Plugins; Aktualisierung der Internationalisierung für Deutsch und Englisch in den Falukant- und Navigationsmodulen; Verbesserung der Statusleiste und Router-Implementierung.
This commit is contained in:
313
backend/services/match3Service.js
Normal file
313
backend/services/match3Service.js
Normal file
@@ -0,0 +1,313 @@
|
||||
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();
|
||||
Reference in New Issue
Block a user