Files
mindflux/src/main/java/com/example/mindflux/service/AchievementServiceImpl.java
T
AliceDarkest 3f32fcd6c1
mindflux-ci / build (push) Successful in 22s
Add ServiceClash game
2026-07-13 23:06:14 +02:00

104 lines
5.4 KiB
Java

package com.example.mindflux.service;
import com.example.mindflux.model.Achievement;
import com.example.mindflux.repository.AchievementRepository;
import com.example.mindflux.repository.GameScoreRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class AchievementServiceImpl implements AchievementService {
/** Katalog aller Achievements (Titel -> Beschreibung), in Anzeige-Reihenfolge. */
static final Map<String, String> CATALOG = new LinkedHashMap<>();
static {
CATALOG.put("Erster Sieg", "Schließe dein erstes Spiel ab.");
CATALOG.put("1000er-Club", "Erziele 1000 Punkte in einer einzigen Runde.");
CATALOG.put("Highscore-Jäger", "Verbessere deinen eigenen Highscore.");
CATALOG.put("Dauerbrenner", "Spiele dasselbe Spiel zehnmal.");
CATALOG.put("Punktesammler", "Sammle insgesamt 5000 Punkte.");
CATALOG.put("Allrounder", "Spiele vier verschiedene Spiele.");
CATALOG.put("Gedächtnis-Impuls", "Schließe eine MindMatch-Runde mit Punkten ab.");
CATALOG.put("Quiz-Kapitän", "Schließe eine TechTacular-Runde mit Punkten ab.");
CATALOG.put("Werkbank aktiv", "Schließe eine DevLab-Runde mit Punkten ab.");
CATALOG.put("Syntax-Spur", "Schließe eine SyntaxSaga-Runde mit Punkten ab.");
CATALOG.put("Fluchtprotokoll", "Schließe eine SystemEscape-Runde mit Punkten ab.");
CATALOG.put("Erste Fallakte", "Schließe eine BugHunter-Akte mit Punkten ab.");
CATALOG.put("Leitstand-Einsatz", "Schließe eine ServiceClash-Schicht mit Punkten ab.");
CATALOG.put("Incident Commander", "Löse eine ServiceClash-Schicht ohne Fehler oder Aufdecken.");
CATALOG.put("Netzwerk-Neustart", "Schließe eine NetWorker-Welt mit Punkten ab.");
}
private final AchievementRepository achievementRepository;
private final GameScoreRepository gameScoreRepository;
public AchievementServiceImpl(AchievementRepository achievementRepository,
GameScoreRepository gameScoreRepository) {
this.achievementRepository = achievementRepository;
this.gameScoreRepository = gameScoreRepository;
}
@Override
public List<Achievement> getAchievementsForUser(String username) {
List<Achievement> earned = achievementRepository.findByUsername(username);
Map<String, Achievement> earnedByTitle = earned.stream()
.collect(Collectors.toMap(Achievement::getTitle, a -> a, (a, b) -> a));
List<Achievement> result = new ArrayList<>();
// Katalog in fester Reihenfolge: verdient mit Datum, sonst als gesperrte Karte.
CATALOG.forEach((title, description) -> {
Achievement achievement = earnedByTitle.remove(title);
result.add(achievement != null ? achievement
: new Achievement(title, description, null, false));
});
// Ältere/zusätzliche verdiente Achievements außerhalb des Katalogs behalten.
result.addAll(earnedByTitle.values());
return result;
}
@Override
@Transactional
public void checkAndAward(String username, String game, int score, boolean newHighscore, long playsInGame) {
Set<String> existing = achievementRepository.findByUsername(username).stream()
.map(Achievement::getTitle)
.collect(Collectors.toSet());
award(existing, username, "Erster Sieg",
gameScoreRepository.countByUsername(username) >= 1);
award(existing, username, "1000er-Club", score >= 1000);
award(existing, username, "Highscore-Jäger", newHighscore && playsInGame > 1);
award(existing, username, "Dauerbrenner", playsInGame >= 10);
award(existing, username, "Punktesammler",
gameScoreRepository.sumScoreByUsername(username) >= 5000);
award(existing, username, "Allrounder",
gameScoreRepository.countDistinctGamesByUsername(username) >= 4);
String gameAchievement = Map.of(
"mindmatch", "Gedächtnis-Impuls", "techtacular", "Quiz-Kapitän", "devlab", "Werkbank aktiv",
"syntax-saga", "Syntax-Spur", "codeescape", "Fluchtprotokoll", "bughunter", "Erste Fallakte",
"serviceclash", "Leitstand-Einsatz", "networker", "Netzwerk-Neustart").get(game);
if (gameAchievement != null) award(existing, username, gameAchievement, score > 0);
}
@Override @Transactional
public void awardSpecial(String username, String title, String description) {
Set<String> existing = achievementRepository.findByUsername(username).stream().map(Achievement::getTitle).collect(Collectors.toSet());
if (!existing.contains(title)) { Achievement achievement = new Achievement(title, description, null, true); achievement.setUsername(username); achievementRepository.save(achievement); }
}
private void award(Set<String> existing, String username, String title, boolean condition) {
if (!condition || existing.contains(title)) {
return;
}
Achievement achievement = new Achievement(title, CATALOG.get(title), null, true);
achievement.setUsername(username);
achievementRepository.save(achievement);
}
}