summaryrefslogtreecommitdiff
path: root/sw-server
diff options
context:
space:
mode:
authorjoffrey-bion <joffrey.bion@gmail.com>2021-02-03 02:37:38 +0100
committerjoffrey-bion <joffrey.bion@gmail.com>2021-02-03 23:29:16 +0100
commit7c2371766b940742f3986d7904d4c20a4127ea70 (patch)
tree294d0c80b2590b69d032a37bcc78b3ce15be012a /sw-server
parentCleanup (diff)
downloadseven-wonders-7c2371766b940742f3986d7904d4c20a4127ea70.tar.gz
seven-wonders-7c2371766b940742f3986d7904d4c20a4127ea70.tar.bz2
seven-wonders-7c2371766b940742f3986d7904d4c20a4127ea70.zip
Add auto-game with bots only
Resolves: https://github.com/joffrey-bion/seven-wonders/issues/82
Diffstat (limited to 'sw-server')
-rw-r--r--sw-server/build.gradle.kts5
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSecurityConfig.kt4
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/AutoGameController.kt52
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt18
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt15
5 files changed, 80 insertions, 14 deletions
diff --git a/sw-server/build.gradle.kts b/sw-server/build.gradle.kts
index 38d48d9c..a129f952 100644
--- a/sw-server/build.gradle.kts
+++ b/sw-server/build.gradle.kts
@@ -12,7 +12,10 @@ dependencies {
implementation(project(":sw-engine"))
implementation(project(":sw-bot"))
implementation(kotlin("reflect")) // required by Spring 5
- implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1")
+
+ val coroutinesVersion = "1.4.2"
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$coroutinesVersion") // for Spring
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
implementation("org.springframework.boot:spring-boot-starter-websocket")
diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSecurityConfig.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSecurityConfig.kt
index 9557ba1a..aa080189 100644
--- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSecurityConfig.kt
+++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSecurityConfig.kt
@@ -8,5 +8,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
class WebSecurityConfig : WebSecurityConfigurerAdapter() {
// this disables default authentication settings
- override fun configure(httpSecurity: HttpSecurity) = Unit
+ override fun configure(httpSecurity: HttpSecurity) {
+ http.cors().and().csrf().disable()
+ }
}
diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/AutoGameController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/AutoGameController.kt
new file mode 100644
index 00000000..4acdc3be
--- /dev/null
+++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/AutoGameController.kt
@@ -0,0 +1,52 @@
+package org.luxons.sevenwonders.server.controllers
+
+import kotlinx.coroutines.withTimeout
+import org.luxons.sevenwonders.bot.connectBot
+import org.luxons.sevenwonders.bot.connectBots
+import org.luxons.sevenwonders.client.SevenWondersClient
+import org.luxons.sevenwonders.model.api.AutoGameAction
+import org.luxons.sevenwonders.model.api.AutoGameResult
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RestController
+import java.security.Principal
+import kotlin.time.ExperimentalTime
+import kotlin.time.minutes
+
+/**
+ * Handles actions in the game's lobby. The lobby is the place where players gather before a game.
+ */
+@RestController
+class AutoGameController(
+ @Value("\${server.port}") private val serverPort: String,
+) {
+ @OptIn(ExperimentalTime::class)
+ @PostMapping("/autoGame")
+ suspend fun autoGame(@RequestBody action: AutoGameAction, principal: Principal): AutoGameResult {
+ logger.info("Starting auto-game {}", action.gameName)
+ val client = SevenWondersClient()
+ val serverUrl = "ws://localhost:$serverPort"
+
+ val lastTurn = withTimeout(5.minutes) {
+ val otherBotNames = List(action.nbPlayers - 1) { "JoinerBot${it + 1}" }
+ val owner = client.connectBot(serverUrl, "OwnerBot", action.config)
+ val joiners = client.connectBots(serverUrl, otherBotNames, action.config)
+
+ owner.createGameWithBotFriendsAndAutoPlay(
+ gameName = action.gameName,
+ otherBots = joiners,
+ customWonders = action.customWonders,
+ customSettings = action.customSettings,
+ )
+ }
+
+ val scoreBoard = lastTurn.scoreBoard ?: error("Last turn info doesn't have scoreboard")
+ return AutoGameResult(scoreBoard, lastTurn.table)
+ }
+
+ companion object {
+ private val logger = LoggerFactory.getLogger(AutoGameController::class.java)
+ }
+}
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 aa01a23a..557a1714 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
@@ -2,7 +2,10 @@ package org.luxons.sevenwonders.server.controllers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
-import org.luxons.sevenwonders.bot.SevenWondersBot
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeout
+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
@@ -22,6 +25,8 @@ import org.springframework.messaging.simp.SimpMessagingTemplate
import org.springframework.stereotype.Controller
import org.springframework.validation.annotation.Validated
import java.security.Principal
+import kotlin.time.ExperimentalTime
+import kotlin.time.hours
/**
* Handles actions in the game's lobby. The lobby is the place where players gather before a game.
@@ -144,14 +149,19 @@ class LobbyController(
template.convertAndSend("/topic/games", GameListEvent.CreateOrUpdate(lobbyDto).wrap())
}
+ @OptIn(ExperimentalTime::class)
@MessageMapping("/lobby/addBot")
fun addBot(@Validated action: AddBotAction, principal: Principal) {
val lobby = principal.player.ownedLobby
- val bot = SevenWondersBot(action.botDisplayName)
+ val bot = runBlocking {
+ SevenWondersClient().connectBot("ws://localhost:$serverPort", action.botDisplayName, action.config)
+ }
+ logger.info("Starting bot {} in game '{}'", action.botDisplayName, lobby.name)
GlobalScope.launch {
- bot.play("ws://localhost:$serverPort", lobby.id)
+ withTimeout(6.hours) {
+ bot.joinAndAutoPlay(lobby.id)
+ }
}
- logger.info("Added bot {} to game '{}'", action.botDisplayName, lobby.name)
}
/**
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 02f43fcf..7c830140 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
@@ -9,6 +9,7 @@ import kotlinx.coroutines.withTimeoutOrNull
import org.junit.runner.RunWith
import org.luxons.sevenwonders.client.SevenWondersClient
import org.luxons.sevenwonders.client.SevenWondersSession
+import org.luxons.sevenwonders.client.createGameAndWaitLobby
import org.luxons.sevenwonders.client.joinGameAndWaitLobby
import org.luxons.sevenwonders.model.Action
import org.luxons.sevenwonders.model.api.GameListEvent
@@ -60,7 +61,7 @@ class SevenWondersTest {
val session2 = newPlayer("Player2")
val gameName = "Test Game"
- val lobby = ownerSession.createGameAndWaitLobby(gameName)
+ val lobby = ownerSession.createGameWithLegacySettingsAndWaitLobby(gameName)
session1.joinGameAndWaitLobby(lobby.id)
session2.joinGameAndWaitLobby(lobby.id)
@@ -80,7 +81,7 @@ class SevenWondersTest {
val ownerSession = newPlayer("GameOwner")
val gameName = "Test Game"
- val lobby = ownerSession.createGameAndWaitLobby(gameName)
+ val lobby = ownerSession.createGameWithLegacySettingsAndWaitLobby(gameName)
assertEquals(gameName, lobby.name)
disconnect(ownerSession)
@@ -97,7 +98,7 @@ class SevenWondersTest {
val ownerSession = newPlayer("GameOwner")
val gameName = "Test Game"
- val createdLobby = ownerSession.createGameAndWaitLobby(gameName)
+ val createdLobby = ownerSession.createGameWithLegacySettingsAndWaitLobby(gameName)
val afterGameListEvent = withTimeout(500) { games.receive() }
assertTrue(afterGameListEvent is GameListEvent.CreateOrUpdate)
@@ -114,7 +115,7 @@ class SevenWondersTest {
val session2 = newPlayer("Player2")
val startEvents1 = session1.watchGameStarted()
- val lobby = session1.createGameAndWaitLobby("Test Game")
+ val lobby = session1.createGameWithLegacySettingsAndWaitLobby("Test Game")
val startEvents2 = session2.watchGameStarted()
session2.joinGameAndWaitLobby(lobby.id)
@@ -146,10 +147,8 @@ class SevenWondersTest {
}
}
-private suspend fun SevenWondersSession.createGameAndWaitLobby(gameName: String): LobbyDTO {
- val joinedLobbies = watchLobbyJoined()
- createGame(gameName)
- val lobby = joinedLobbies.first()
+private suspend fun SevenWondersSession.createGameWithLegacySettingsAndWaitLobby(gameName: String): LobbyDTO {
+ val lobby = createGameAndWaitLobby(gameName)
updateSettings(lobby.settings.copy(askForReadiness = true))
return lobby
}
bgstack15