114 lines
5.1 KiB
Java
114 lines
5.1 KiB
Java
package eric.Roullette.service;
|
|
|
|
import eric.Roullette.dto.PlayersMessage;
|
|
import eric.Roullette.util.JsonUtil;
|
|
import io.javalin.websocket.WsContext;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import java.util.*;
|
|
import java.util.concurrent.*;
|
|
|
|
public class GameService {
|
|
private static final Logger log = LoggerFactory.getLogger(GameService.class);
|
|
private final SpotifyAuthService authService;
|
|
private final Map<String, Set<WsContext>> sessions = new ConcurrentHashMap<>();
|
|
private final Map<String, Game> games = new ConcurrentHashMap<>();
|
|
|
|
public GameService(SpotifyAuthService authService) { // <-- Konstruktor
|
|
this.authService = authService;
|
|
}
|
|
|
|
public Map<String, List<String>> getTrackInfos(Map<String, List<String>> allPlayerTracks) {
|
|
// für jeden String Spieler in allPlayerTracks die Liste der Tracks an authservice übergeben
|
|
Map<String, List<String>> trackInfos = new ConcurrentHashMap<>();
|
|
for (Map.Entry<String, List<String>> entry : allPlayerTracks.entrySet()) {
|
|
String player = entry.getKey();
|
|
List<String> tracks = entry.getValue();
|
|
if (tracks.isEmpty()) continue; // Keine Tracks, skip
|
|
try {
|
|
List<String> trackInfo = authService.getTrackInfos(tracks);
|
|
trackInfos.put(player, trackInfo);
|
|
} catch (Exception e) {
|
|
log.error("Fehler beim Abrufen der Track-Infos für Spieler {}: {}", player, e.getMessage());
|
|
}
|
|
}
|
|
return trackInfos;
|
|
}
|
|
|
|
|
|
public record Game(String id, List<String> players, Map<String,Integer> scores, String currentOwner,
|
|
String currentSong, List<String> allTracks, Map<String, List<String>> playerTracks) {
|
|
public static Game create(String id) {
|
|
return new Game(id, new CopyOnWriteArrayList<>(), new ConcurrentHashMap<>(), null, null, new ArrayList<>(), new ConcurrentHashMap<>());
|
|
}
|
|
|
|
}
|
|
|
|
public Game getOrCreateGame(String gameId) {
|
|
return games.computeIfAbsent(gameId, Game::create);
|
|
}
|
|
|
|
public void addPlayer(String gameId, String user) throws InterruptedException {
|
|
Game g = getOrCreateGame(gameId);
|
|
if (user != null && !g.players().contains(user)) {
|
|
g.players().add(user);
|
|
g.scores().putIfAbsent(user, 0);
|
|
// Songs einmalig laden und speichern
|
|
List<String> tracks = authService.getRecentTracks(user);
|
|
g.playerTracks().put(user, tracks);
|
|
}
|
|
}
|
|
|
|
public void registerSession(String gameId, WsContext ctx) {
|
|
sessions
|
|
.computeIfAbsent(gameId, id -> ConcurrentHashMap.newKeySet())
|
|
.add(ctx);
|
|
broadcastPlayers(gameId);
|
|
}
|
|
|
|
public void removeSession(String gameId, WsContext ctx) {
|
|
sessions.getOrDefault(gameId, Collections.emptySet()).remove(ctx);
|
|
broadcastPlayers(gameId);
|
|
}
|
|
|
|
public void broadcastPlayers(String gameId) {
|
|
Game game = games.get(gameId);
|
|
if (game == null) return;
|
|
PlayersMessage msg = new PlayersMessage(new ArrayList<>(game.players()));
|
|
sessions.getOrDefault(gameId, Collections.emptySet())
|
|
.forEach(ctx -> ctx.send(JsonUtil.toJson(msg)));
|
|
}
|
|
|
|
public void createGame(String gameId) {
|
|
Game game = new Game(gameId, new CopyOnWriteArrayList<>(), new ConcurrentHashMap<>(), null, null, new ArrayList<>(), new ConcurrentHashMap<>());
|
|
games.put(gameId, game);
|
|
}
|
|
|
|
public boolean gameExists(String gameId) {
|
|
return games.containsKey(gameId);
|
|
}
|
|
|
|
public Game startRound(String gameId, List<String> uris) {
|
|
Game g = getOrCreateGame(gameId);
|
|
if (g.players().isEmpty()) throw new IllegalStateException("No players");
|
|
String owner = g.players().get(ThreadLocalRandom.current().nextInt(g.players().size()));
|
|
List<String> ownerTracks = g.playerTracks().getOrDefault(owner, List.of());
|
|
if (ownerTracks.isEmpty()) throw new IllegalStateException("Owner hat keine Tracks");
|
|
String song = ownerTracks.get(ThreadLocalRandom.current().nextInt(ownerTracks.size()));
|
|
|
|
//String song = uris.get(ThreadLocalRandom.current().nextInt(uris.size()));
|
|
Game updated = new Game(gameId, g.players(), g.scores(), owner, song, uris, g.playerTracks());
|
|
games.put(gameId, updated);
|
|
return updated;
|
|
}
|
|
|
|
public Set<WsContext> getSessions(String gameId) {
|
|
return sessions.getOrDefault(gameId, Collections.emptySet());
|
|
}
|
|
// Map<Player, List<Track>>
|
|
public Map<String, List<String>> getPlayerTracks(String gameId) {
|
|
Game game = games.get(gameId);
|
|
if (game == null) return Collections.emptyMap();
|
|
return game.playerTracks();
|
|
}
|
|
} |