From e9ea337ef97f34240030569097c3674ee68ad68d Mon Sep 17 00:00:00 2001 From: eric <3024947@stud.hs-mannheim.de> Date: Fri, 8 Aug 2025 04:07:12 +0200 Subject: [PATCH] Darkmode beta --- src/main/java/eric/Roullette/App.java | 3 +- .../eric/Roullette/service/GameService.java | 137 +++++++++--------- .../websocket/GameWebSocketHandler.java | 13 +- src/main/resources/public/game.html | 15 +- src/main/resources/public/js/game.js | 18 ++- .../Roullette/service/GameServiceTest.java | 22 +-- 6 files changed, 112 insertions(+), 96 deletions(-) diff --git a/src/main/java/eric/Roullette/App.java b/src/main/java/eric/Roullette/App.java index 723777b..282d686 100644 --- a/src/main/java/eric/Roullette/App.java +++ b/src/main/java/eric/Roullette/App.java @@ -23,12 +23,13 @@ public class App { if (cfg.spotifyClientId == null || cfg.spotifyClientSecret == null || cfg.spotifyRedirectUri == null) { throw new IllegalStateException("Spotify-Konfiguration fehlt: Bitte stelle sicher, dass ClientId, ClientSecret und RedirectUri gesetzt sind."); } - GameService gs = new GameService(); + SpotifyAuthService sas = new SpotifyAuthService( cfg.spotifyClientId, cfg.spotifyClientSecret, cfg.spotifyRedirectUri ); + GameService gs = new GameService(sas); Javalin app = Javalin.create(config -> { config.showJavalinBanner = false; diff --git a/src/main/java/eric/Roullette/service/GameService.java b/src/main/java/eric/Roullette/service/GameService.java index 8fbd73b..b1aea36 100644 --- a/src/main/java/eric/Roullette/service/GameService.java +++ b/src/main/java/eric/Roullette/service/GameService.java @@ -1,78 +1,85 @@ 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.*; + 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 Map> sessions = new ConcurrentHashMap<>(); - private final Map games = new ConcurrentHashMap<>(); + public class GameService { + private static final Logger log = LoggerFactory.getLogger(GameService.class); + private final SpotifyAuthService authService; + private final Map> sessions = new ConcurrentHashMap<>(); + private final Map games = new ConcurrentHashMap<>(); - public record Game(String id, List players, Map scores,String currentOwner, - String currentSong,List allTracks) { - public static Game create(String id) { - return new Game(id, new CopyOnWriteArrayList<>(), new ConcurrentHashMap<>(), null, null, new ArrayList<>()); + public GameService(SpotifyAuthService authService) { // <-- Konstruktor + this.authService = authService; } - } - - public Game getOrCreateGame(String gameId) { - return games.computeIfAbsent(gameId, id -> Game.create(id)); - } - - public void addPlayer(String gameId, String user) { - Game g = getOrCreateGame(gameId); - if (user != null && !g.players().contains(user)) { - g.players().add(user); - g.scores().putIfAbsent(user, 0); + public record Game(String id, List players, Map scores, String currentOwner, + String currentSong, List allTracks, Map> playerTracks) { + public static Game create(String id) { + return new Game(id, new CopyOnWriteArrayList<>(), new ConcurrentHashMap<>(), null, null, new ArrayList<>(), new ConcurrentHashMap<>()); + } } - } - public void registerSession(String gameId, WsContext ctx) { - sessions - .computeIfAbsent(gameId, id -> ConcurrentHashMap.newKeySet()) - .add(ctx); - broadcastPlayers(gameId); - } + public Game getOrCreateGame(String gameId) { + return games.computeIfAbsent(gameId, id -> Game.create(id)); + } - public void removeSession(String gameId, WsContext ctx) { - sessions.getOrDefault(gameId, Collections.emptySet()).remove(ctx); - broadcastPlayers(gameId); - } + public void addPlayer(String gameId, String user) { + 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 tracks = authService.getRecentTracks(user); + g.playerTracks().put(user, tracks); + } + } - 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 registerSession(String gameId, WsContext ctx) { + sessions + .computeIfAbsent(gameId, id -> ConcurrentHashMap.newKeySet()) + .add(ctx); + broadcastPlayers(gameId); + } - public void createGame(String gameId) { - Game game = new Game(gameId, new CopyOnWriteArrayList<>(), new ConcurrentHashMap<>(), null, null, new ArrayList<>()); - games.put(gameId, game); - } + public void removeSession(String gameId, WsContext ctx) { + sessions.getOrDefault(gameId, Collections.emptySet()).remove(ctx); + broadcastPlayers(gameId); + } - public boolean gameExists(String gameId) { - return games.containsKey(gameId); - } - public Game startRound(String gameId, List 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())); - String song = uris.get(ThreadLocalRandom.current().nextInt(uris.size())); - Game updated = new Game(gameId, g.players(), g.scores(), owner, song, uris); - games.put(gameId, updated); - return updated; - } - // In GameService.java - public Set getSessions(String gameId) { - return sessions.getOrDefault(gameId, Collections.emptySet()); - } + 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 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())); + 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 getSessions(String gameId) { + return sessions.getOrDefault(gameId, Collections.emptySet()); + } + } \ No newline at end of file diff --git a/src/main/java/eric/Roullette/websocket/GameWebSocketHandler.java b/src/main/java/eric/Roullette/websocket/GameWebSocketHandler.java index b98b534..32d1fd1 100644 --- a/src/main/java/eric/Roullette/websocket/GameWebSocketHandler.java +++ b/src/main/java/eric/Roullette/websocket/GameWebSocketHandler.java @@ -78,7 +78,7 @@ public class GameWebSocketHandler { // Songs von allen Spielern sammeln List allTracks = new ArrayList<>(); for (String player : game.players()) { - allTracks.addAll(authService.getRecentTracks(player)); + allTracks.addAll(game.playerTracks().getOrDefault(player, List.of())); } if (allTracks.isEmpty()) { // TODO: Fehler an Client senden, dass keine Songs da sind @@ -90,6 +90,17 @@ public class GameWebSocketHandler { // Jetzt Broadcast mit den aktuellen Daten broadcastRoundStart(gameId); } + case "next-round" -> { + var currentGame = service.getOrCreateGame(gameId); + List allTracks = new ArrayList<>(); + for (String player : currentGame.players()) { + allTracks.addAll(authService.getRecentTracks(player)); + } + if (!allTracks.isEmpty()) { + service.startRound(gameId, allTracks); + } + broadcastRoundStart(gameId); + } } }); } diff --git a/src/main/resources/public/game.html b/src/main/resources/public/game.html index 0e221fd..e27eafc 100644 --- a/src/main/resources/public/game.html +++ b/src/main/resources/public/game.html @@ -7,12 +7,13 @@