From 9ba1b1251d16956fe3b9cd07f198577b63d4a486 Mon Sep 17 00:00:00 2001 From: joffrey-bion Date: Sat, 12 Dec 2020 02:03:45 +0100 Subject: Make ready button optional (server side) Resolves: https://github.com/joffrey-bion/seven-wonders/issues/63 --- .../kotlin/org/luxons/sevenwonders/model/Settings.kt | 1 + .../kotlin/org/luxons/sevenwonders/model/api/Lobby.kt | 2 ++ .../org/luxons/sevenwonders/server/api/Converters.kt | 1 + .../sevenwonders/server/controllers/GameController.kt | 17 ++++++++++++----- .../sevenwonders/server/controllers/LobbyController.kt | 15 ++++++++++++++- .../org/luxons/sevenwonders/server/SevenWondersTest.kt | 4 +++- .../server/controllers/LobbyControllerTest.kt | 2 +- 7 files changed, 34 insertions(+), 8 deletions(-) diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/Settings.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/Settings.kt index a6c949ea..d2ff40be 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/Settings.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/Settings.kt @@ -7,6 +7,7 @@ import kotlin.random.Random data class Settings( val randomSeedForTests: Long? = null, val timeLimitInSeconds: Int = 45, + val askForReadiness: Boolean = false, val initialGold: Int = 3, val discardedCardGold: Int = 3, val defaultTradingCost: Int = 2, diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt index 62bac3b1..5a06fa63 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt @@ -2,6 +2,7 @@ package org.luxons.sevenwonders.model.api import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import org.luxons.sevenwonders.model.Settings import org.luxons.sevenwonders.model.wonders.PreGameWonder const val SEVEN_WONDERS_WS_ENDPOINT = "/seven-wonders-websocket" @@ -45,6 +46,7 @@ data class LobbyDTO( val players: List, val allWonders: List, val state: State, + val settings: Settings, val hasEnoughPlayers: Boolean, val maxPlayersReached: Boolean, ) { diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt index 12f346a2..5689247b 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt @@ -13,6 +13,7 @@ fun Lobby.toDTO(): LobbyDTO = LobbyDTO( players = getPlayers().zip(getAssignedWonders()).map { (p, w) -> p.toDTO(w) }, allWonders = allWonders, state = state, + settings = settings, hasEnoughPlayers = hasEnoughPlayers(), maxPlayersReached = maxPlayersReached(), ) 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 51e8ba4f..94ebceab 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 @@ -31,14 +31,20 @@ class GameController( @MessageMapping("/game/sayReady") fun ready(principal: Principal) { val player = principal.player - player.isReady = true + val lobby = player.lobby + if (!lobby.settings.askForReadiness) { + logger.warn("Game {}: player {} is saying ready but readiness concept is disabled", lobby.id, player) + return + } + val game = player.game - logger.info("Game {}: player {} is ready for the next turn", game.id, player) + player.isReady = true - synchronized(player.lobby) { - val players = player.lobby.getPlayers() + synchronized(lobby) { + val players = lobby.getPlayers() sendPlayerReady(game.id, player) + logger.info("Game {}: player {} is ready for the next turn", game.id, player) val allReady = players.all { it.isReady } if (allReady) { @@ -58,6 +64,7 @@ class GameController( @MessageMapping("/game/prepareMove") fun prepareMove(action: PrepareMoveAction, principal: Principal) { val player = principal.player + val lobby = player.lobby val game = player.game synchronized(game) { val preparedCardBack = game.prepareMove(player.index, action.move) @@ -68,7 +75,7 @@ class GameController( if (game.allPlayersPreparedTheirMove()) { logger.info("Game {}: all players have prepared their move, executing turn...", game.id) game.playTurn() - sendTurnInfo(player.lobby.getPlayers(), game, true) + sendTurnInfo(player.lobby.getPlayers(), game, hideHands = lobby.settings.askForReadiness) if (game.endOfGameReached()) { player.lobby.setEndOfGame() } 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 6cc404e9..f73d5481 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 @@ -156,12 +156,25 @@ class LobbyController( val game = lobby.startGame() logger.info("Game {} successfully started", game.id) - game.getCurrentTurnInfo().hideHandsAndWaitForReadiness().forEach { + val currentTurnInfo = game.getCurrentTurnInfo().let { + if (lobby.settings.askForReadiness) it.hideHandsAndWaitForReadiness() else it + } + + // even if we don't care about ready state for business logic, the UI may use it nonetheless + lobby.initializePlayersReadyState() + + currentTurnInfo.forEach { val player = lobby.getPlayers()[it.playerIndex] template.convertAndSendToUser(player.username, "/queue/lobby/" + lobby.id + "/started", it) } } + private fun Lobby.initializePlayersReadyState() { + val players = getPlayers() + val initialReadyState = !settings.askForReadiness + players.forEach { it.isReady = initialReadyState } + } + companion object { private val logger = LoggerFactory.getLogger(LobbyController::class.java) } diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt index ccc2e548..3ed559b3 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt @@ -150,5 +150,7 @@ class SevenWondersTest { private suspend fun SevenWondersSession.createGameAndWaitLobby(gameName: String): LobbyDTO { val joinedLobbies = watchLobbyJoined() createGame(gameName) - return joinedLobbies.first() + val lobby = joinedLobbies.first() + updateSettings(lobby.settings.copy(askForReadiness = true)) + return lobby } diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt index 097e4792..351c2e9e 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt @@ -165,7 +165,7 @@ class LobbyControllerTest { assertEquals(Settings(), lobby.settings) - val newSettings = Settings(12L, 5, 5, 5, 4, 10, 2, HashMap()) + val newSettings = Settings(12L, 5, false, 5, 5, 4, 10, 2, HashMap()) val updateSettingsAction = UpdateSettingsAction(newSettings) val principal = TestPrincipal("testuser") -- cgit