summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt4
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt7
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt7
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt11
4 files changed, 25 insertions, 4 deletions
diff --git a/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt b/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
index aff31a3f..39759fd0 100644
--- a/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
+++ b/sw-bot/src/main/kotlin/org/luxons/sevenwonders/bot/SevenWondersBot.kt
@@ -38,6 +38,10 @@ class SevenWondersBot(
private val config: BotConfig = BotConfig(),
private val session: SevenWondersSession,
) {
+ suspend fun disconnect() {
+ session.disconnect()
+ }
+
suspend fun createGameWithBotFriendsAndAutoPlay(
gameName: String,
otherBots: List<SevenWondersBot>,
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt
index 8d352402..48b26aa4 100644
--- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt
@@ -4,6 +4,8 @@ import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.model.PlayerMove
import org.luxons.sevenwonders.model.Settings
import org.luxons.sevenwonders.model.wonders.AssignedWonder
+import kotlin.time.ExperimentalTime
+import kotlin.time.hours
/**
* The action to choose the player's name. This is the first action that should be called.
@@ -101,12 +103,17 @@ class UpdateSettingsAction(
* The action to add a bot to the game. Can only be called in the lobby by the owner of the game.
*/
@Serializable
+@OptIn(ExperimentalTime::class)
class AddBotAction(
/**
* The display name for the bot to add.
*/
val botDisplayName: String,
/**
+ * The global timeout for the bot, after which it disconnects (whether the game is over or not).
+ */
+ val globalBotTimeoutMillis: Long = 6.hours.toLongMilliseconds(),
+ /**
* The configuration of the bot to add.
*/
val config: BotConfig = BotConfig(),
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 4f948ccf..60307962 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
@@ -1,7 +1,9 @@
package org.luxons.sevenwonders.server.controllers
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.wrap
import org.luxons.sevenwonders.model.cards.PreparedCard
import org.luxons.sevenwonders.model.hideHandsAndWaitForReadiness
import org.luxons.sevenwonders.server.lobby.Player
@@ -149,8 +151,11 @@ class GameController(
synchronized(game) {
lobby.removePlayer(player.username)
logger.info("Game {}: player {} left the game", game.id, player)
- if (lobby.getPlayers().isEmpty()) {
+ // 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())
logger.info("Game {}: game deleted", game.id)
}
}
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 732b9193..f2124009 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
@@ -3,7 +3,7 @@ package org.luxons.sevenwonders.server.controllers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withTimeout
+import kotlinx.coroutines.withTimeoutOrNull
import org.luxons.sevenwonders.bot.connectBot
import org.luxons.sevenwonders.client.SevenWondersClient
import org.luxons.sevenwonders.model.api.GameListEvent
@@ -26,7 +26,7 @@ import org.springframework.stereotype.Controller
import org.springframework.validation.annotation.Validated
import java.security.Principal
import kotlin.time.ExperimentalTime
-import kotlin.time.hours
+import kotlin.time.milliseconds
/**
* Handles actions in the game's lobby. The lobby is the place where players gather before a game.
@@ -158,9 +158,14 @@ class LobbyController(
}
logger.info("Starting bot {} in game '{}'", action.botDisplayName, lobby.name)
GlobalScope.launch {
- withTimeout(6.hours) {
+ val result = withTimeoutOrNull(action.globalBotTimeoutMillis) {
bot.joinAndAutoPlay(lobby.id)
}
+ if (result == null) {
+ val timeoutDuration = action.globalBotTimeoutMillis.milliseconds
+ logger.error("Bot {} timed out after {}", action.botDisplayName, timeoutDuration)
+ bot.disconnect()
+ }
}
}
bgstack15