diff options
Diffstat (limited to 'sw-server/src/main')
5 files changed, 59 insertions, 50 deletions
diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/ControllerUtils.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/ControllerUtils.kt new file mode 100644 index 00000000..41796bb6 --- /dev/null +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/ControllerUtils.kt @@ -0,0 +1,19 @@ +package org.luxons.sevenwonders.server.controllers + +import org.luxons.sevenwonders.model.api.events.GameEvent +import org.luxons.sevenwonders.model.api.events.GameListEvent +import org.luxons.sevenwonders.model.api.events.wrap +import org.luxons.sevenwonders.server.lobby.Player +import org.springframework.messaging.simp.SimpMessageSendingOperations + +internal fun SimpMessageSendingOperations.sendGameEvent(player: Player, event: GameEvent) { + convertAndSendToUser(player.username, "/queue/game/events", event.wrap()) +} + +internal fun SimpMessageSendingOperations.sendGameEvent(players: List<Player>, event: GameEvent) { + players.forEach { sendGameEvent(it, event) } +} + +internal fun SimpMessageSendingOperations.sendGameListEvent(event: GameListEvent) { + convertAndSend("/topic/games", event.wrap()) +} diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserController.kt index 8e90eb27..d3382c62 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserController.kt @@ -1,11 +1,11 @@ package org.luxons.sevenwonders.server.controllers -import org.luxons.sevenwonders.model.api.GameListEvent -import org.luxons.sevenwonders.model.api.GameListEventWrapper -import org.luxons.sevenwonders.model.api.LobbyDTO import org.luxons.sevenwonders.model.api.actions.CreateGameAction import org.luxons.sevenwonders.model.api.actions.JoinGameAction -import org.luxons.sevenwonders.model.api.wrap +import org.luxons.sevenwonders.model.api.events.GameEvent +import org.luxons.sevenwonders.model.api.events.GameListEvent +import org.luxons.sevenwonders.model.api.events.GameListEventWrapper +import org.luxons.sevenwonders.model.api.events.wrap import org.luxons.sevenwonders.server.ApiMisuseException import org.luxons.sevenwonders.server.api.toDTO import org.luxons.sevenwonders.server.lobby.Lobby @@ -14,8 +14,7 @@ import org.luxons.sevenwonders.server.repositories.LobbyRepository import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory import org.springframework.messaging.handler.annotation.MessageMapping -import org.springframework.messaging.simp.SimpMessagingTemplate -import org.springframework.messaging.simp.annotation.SendToUser +import org.springframework.messaging.simp.SimpMessageSendingOperations import org.springframework.messaging.simp.annotation.SubscribeMapping import org.springframework.stereotype.Controller import org.springframework.validation.annotation.Validated @@ -26,10 +25,10 @@ import java.security.Principal */ @Controller class GameBrowserController( + private val messenger: SimpMessageSendingOperations, private val lobbyController: LobbyController, private val lobbyRepository: LobbyRepository, private val playerRepository: PlayerRepository, - private val template: SimpMessagingTemplate, ) { /** * Gets the created or updated games. The list of existing games is received on this topic at once upon @@ -54,8 +53,7 @@ class GameBrowserController( * @return the newly created [Lobby] */ @MessageMapping("/lobby/create") - @SendToUser("/queue/lobby/joined") - fun createGame(@Validated action: CreateGameAction, principal: Principal): LobbyDTO { + fun createGame(@Validated action: CreateGameAction, principal: Principal) { checkThatUserIsNotInAGame(principal, "cannot create another game") val player = playerRepository.get(principal.name) @@ -65,8 +63,8 @@ class GameBrowserController( // notify everyone that a new game exists val lobbyDto = lobby.toDTO() - template.convertAndSend("/topic/games", GameListEvent.CreateOrUpdate(lobbyDto).wrap()) - return lobbyDto + messenger.sendGameListEvent(GameListEvent.CreateOrUpdate(lobbyDto)) + messenger.sendGameEvent(player, GameEvent.LobbyJoined(lobbyDto)) } /** @@ -78,8 +76,7 @@ class GameBrowserController( * @return the [Lobby] that has just been joined */ @MessageMapping("/lobby/join") - @SendToUser("/queue/lobby/joined") - fun joinGame(@Validated action: JoinGameAction, principal: Principal): LobbyDTO { + fun joinGame(@Validated action: JoinGameAction, principal: Principal) { checkThatUserIsNotInAGame(principal, "cannot join another game") val lobby = lobbyRepository.get(action.gameId) @@ -90,7 +87,7 @@ class GameBrowserController( logger.info("Player '{}' ({}) joined game {}", player.displayName, player.username, lobby.name) lobbyController.sendLobbyUpdateToPlayers(lobby) } - return lobby.toDTO() + messenger.sendGameEvent(player, GameEvent.LobbyJoined(lobby.toDTO())) } private fun checkThatUserIsNotInAGame(principal: Principal, impossibleActionDescription: String) { diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt index 70fb3220..17687e8b 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt @@ -2,11 +2,9 @@ package org.luxons.sevenwonders.server.controllers import io.micrometer.core.instrument.MeterRegistry import org.luxons.sevenwonders.engine.Game -import org.luxons.sevenwonders.model.api.GameListEvent import org.luxons.sevenwonders.model.api.actions.PrepareMoveAction import org.luxons.sevenwonders.model.api.events.GameEvent -import org.luxons.sevenwonders.model.api.events.wrap -import org.luxons.sevenwonders.model.api.wrap +import org.luxons.sevenwonders.model.api.events.GameListEvent import org.luxons.sevenwonders.model.cards.PreparedCard import org.luxons.sevenwonders.model.hideHandsAndWaitForReadiness import org.luxons.sevenwonders.server.api.toDTO @@ -16,7 +14,7 @@ import org.luxons.sevenwonders.server.repositories.LobbyRepository import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory import org.springframework.messaging.handler.annotation.MessageMapping -import org.springframework.messaging.simp.SimpMessagingTemplate +import org.springframework.messaging.simp.SimpMessageSendingOperations import org.springframework.stereotype.Controller import java.security.Principal @@ -25,7 +23,7 @@ import java.security.Principal */ @Controller class GameController( - private val template: SimpMessagingTemplate, + private val messenger: SimpMessageSendingOperations, private val playerRepository: PlayerRepository, private val lobbyRepository: LobbyRepository, private val meterRegistry: MeterRegistry, @@ -49,7 +47,7 @@ class GameController( synchronized(game) { player.isReady = true if (lobby.settings.askForReadiness) { - sendPlayerReady(game.id, player) + messenger.sendGameEvent(lobby.getPlayers(), GameEvent.PlayerIsReady(player.username)) } logger.info("Game {}: player {} is ready for the next turn", game.id, player) @@ -94,7 +92,7 @@ class GameController( logger.info("Game {}: player {} preparing move {}", game.id, player, action.move) val preparedCardBack = game.prepareMove(player.index, action.move) val preparedCard = PreparedCard(player.username, preparedCardBack) - sendPreparedCard(game.id, preparedCard) + messenger.sendGameEvent(lobby.getPlayers(), GameEvent.CardPrepared(preparedCard)) if (game.allPlayersPreparedTheirMove()) { logger.info("Game {}: all players have prepared their move, executing turn...", game.id) @@ -104,7 +102,7 @@ class GameController( handleEndOfGame(game, player, lobby) } } else { - template.convertAndSendToUser(player.username, "/queue/game/events", GameEvent.MovePrepared(action.move).wrap()) + messenger.sendGameEvent(player, GameEvent.MovePrepared(action.move)) } } } @@ -113,7 +111,7 @@ class GameController( meterRegistry.counter("games.finished").increment() logger.info("Game {}: end of game, displaying score board", game.id) player.lobby.setEndOfGame() - template.convertAndSend("/topic/games", GameListEvent.CreateOrUpdate(lobby.toDTO()).wrap()) + messenger.sendGameListEvent(GameListEvent.CreateOrUpdate(lobby.toDTO())) } @MessageMapping("/game/unprepareMove") @@ -128,24 +126,17 @@ class GameController( game.unprepareMove(player.index) val preparedCard = PreparedCard(player.username, null) logger.info("Game {}: player {} unprepared his move", game.id, player) - sendPreparedCard(game.id, preparedCard) + messenger.sendGameEvent(player.lobby.getPlayers(), GameEvent.CardPrepared(preparedCard)) + messenger.sendGameEvent(player, GameEvent.MoveUnprepared) } } - private fun sendPlayerReady(gameId: Long, player: Player) { - template.convertAndSend("/topic/game/$gameId/events", GameEvent.PlayerIsReady(player.username).wrap()) - } - - private fun sendPreparedCard(gameId: Long, preparedCard: PreparedCard) { - template.convertAndSend("/topic/game/$gameId/events", GameEvent.CardPrepared(preparedCard).wrap()) - } - private fun sendTurnInfo(players: List<Player>, game: Game, hideHands: Boolean) { val turns = game.getCurrentTurnInfo() val turnsToSend = if (hideHands) turns.hideHandsAndWaitForReadiness() else turns for (turnInfo in turnsToSend) { val player = players[turnInfo.playerIndex] - template.convertAndSendToUser(player.username, "/queue/game/events", GameEvent.NewTurnStarted(turnInfo).wrap()) + messenger.sendGameEvent(player, GameEvent.NewTurnStarted(turnInfo)) } } @@ -162,13 +153,13 @@ class GameController( synchronized(game) { lobby.removePlayer(player.username) logger.info("Game {}: player {} left the game", game.id, player) - template.convertAndSendToUser(player.username, "/queue/lobby/left", lobby.id) + messenger.sendGameEvent(player, GameEvent.LobbyLeft) // This could cause problems if the humans are faster than bots to leave a finished game, // but this case should be quite rare, so it does not matter much if (lobby.getPlayers().none { it.isHuman }) { lobbyRepository.remove(lobby.id) - template.convertAndSend("/topic/games", GameListEvent.Delete(lobby.id).wrap()) + messenger.sendGameListEvent(GameListEvent.Delete(lobby.id)) logger.info("Game {}: game deleted", game.id) } } diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt index 230623d8..59258e44 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt @@ -4,10 +4,11 @@ import io.micrometer.core.instrument.MeterRegistry import org.luxons.sevenwonders.model.api.ConnectedPlayer import org.luxons.sevenwonders.model.api.PlayerDTO import org.luxons.sevenwonders.model.api.actions.ChooseNameAction +import org.luxons.sevenwonders.model.api.events.GameEvent import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory import org.springframework.messaging.handler.annotation.MessageMapping -import org.springframework.messaging.simp.annotation.SendToUser +import org.springframework.messaging.simp.SimpMessageSendingOperations import org.springframework.stereotype.Controller import org.springframework.validation.annotation.Validated import java.security.Principal @@ -17,6 +18,7 @@ import java.security.Principal */ @Controller class HomeController( + private val messenger: SimpMessageSendingOperations, private val playerRepository: PlayerRepository, private val meterRegistry: MeterRegistry, ) { @@ -29,14 +31,14 @@ class HomeController( * @return the created [PlayerDTO] object */ @MessageMapping("/chooseName") - @SendToUser("/queue/nameChoice") - fun chooseName(@Validated action: ChooseNameAction, principal: Principal): ConnectedPlayer { + fun chooseName(@Validated action: ChooseNameAction, principal: Principal) { val username = principal.name val player = playerRepository.createOrUpdate(username, action.playerName, action.isHuman, action.icon) meterRegistry.counter("players.connections").increment() logger.info("Player '{}' chose the name '{}'", username, player.displayName) - return ConnectedPlayer(username, player.displayName, player.isHuman, player.icon) + val connectedPlayer = ConnectedPlayer(username, player.displayName, player.isHuman, player.icon) + messenger.sendGameEvent(player, GameEvent.NameChosen(connectedPlayer)) } companion object { diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt index 6a696d25..56e94493 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt @@ -7,12 +7,12 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeoutOrNull import org.luxons.sevenwonders.bot.connectBot import org.luxons.sevenwonders.client.SevenWondersClient -import org.luxons.sevenwonders.model.api.GameListEvent import org.luxons.sevenwonders.model.api.actions.AddBotAction import org.luxons.sevenwonders.model.api.actions.ReassignWondersAction import org.luxons.sevenwonders.model.api.actions.ReorderPlayersAction import org.luxons.sevenwonders.model.api.actions.UpdateSettingsAction -import org.luxons.sevenwonders.model.api.wrap +import org.luxons.sevenwonders.model.api.events.GameEvent +import org.luxons.sevenwonders.model.api.events.GameListEvent import org.luxons.sevenwonders.model.hideHandsAndWaitForReadiness import org.luxons.sevenwonders.server.api.toDTO import org.luxons.sevenwonders.server.lobby.Lobby @@ -23,7 +23,7 @@ import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value import org.springframework.messaging.handler.annotation.MessageMapping -import org.springframework.messaging.simp.SimpMessagingTemplate +import org.springframework.messaging.simp.SimpMessageSendingOperations import org.springframework.stereotype.Controller import org.springframework.validation.annotation.Validated import java.security.Principal @@ -34,9 +34,9 @@ import kotlin.time.milliseconds */ @Controller class LobbyController( + private val messenger: SimpMessageSendingOperations, private val lobbyRepository: LobbyRepository, private val playerRepository: PlayerRepository, - private val template: SimpMessagingTemplate, @Value("\${server.port}") private val serverPort: String, private val meterRegistry: MeterRegistry, ) { @@ -56,7 +56,7 @@ class LobbyController( synchronized(lobby) { lobby.removePlayer(principal.name) logger.info("Player {} left the lobby of game '{}'", player, lobby.name) - template.convertAndSendToUser(player.username, "/queue/lobby/left", lobby.id) + messenger.sendGameEvent(player, GameEvent.LobbyLeft) if (lobby.getPlayers().none { it.isHuman }) { deleteLobby(lobby) @@ -79,7 +79,7 @@ class LobbyController( synchronized(lobby) { lobby.getPlayers().forEach { it.leave() - template.convertAndSendToUser(it.username, "/queue/lobby/left", lobby.id) + messenger.sendGameEvent(it, GameEvent.LobbyLeft) } logger.info("Player {} disbanded game '{}'", player, lobby.name) deleteLobby(lobby) @@ -89,7 +89,7 @@ class LobbyController( private fun deleteLobby(lobby: Lobby) { lobbyRepository.remove(lobby.id) - template.convertAndSend("/topic/games", GameListEvent.Delete(lobby.id).wrap()) + messenger.sendGameListEvent(GameListEvent.Delete(lobby.id)) logger.info("Game '{}' removed", lobby.name) } @@ -147,9 +147,9 @@ class LobbyController( internal fun sendLobbyUpdateToPlayers(lobby: Lobby) { val lobbyDto = lobby.toDTO() lobby.getPlayers().forEach { - template.convertAndSendToUser(it.username, "/queue/lobby/updated", lobbyDto) + messenger.sendGameEvent(it, GameEvent.LobbyUpdated(lobbyDto)) } - template.convertAndSend("/topic/games", GameListEvent.CreateOrUpdate(lobbyDto).wrap()) + messenger.sendGameListEvent(GameListEvent.CreateOrUpdate(lobbyDto)) } @MessageMapping("/lobby/addBot") @@ -191,9 +191,9 @@ class LobbyController( currentTurnInfo.forEach { val player = lobby.getPlayers()[it.playerIndex] - template.convertAndSendToUser(player.username, "/queue/lobby/started", it) + messenger.sendGameEvent(player, GameEvent.GameStarted(it)) } - template.convertAndSend("/topic/games", GameListEvent.CreateOrUpdate(lobby.toDTO()).wrap()) + messenger.sendGameListEvent(GameListEvent.CreateOrUpdate(lobby.toDTO())) } private fun Lobby.resetPlayersReadyState() { |