Various changes to game joining
authorTheSaminator <TheSaminator@users.noreply.github.com>
Thu, 10 Feb 2022 16:42:04 +0000 (11:42 -0500)
committerTheSaminator <TheSaminator@users.noreply.github.com>
Thu, 10 Feb 2022 16:42:04 +0000 (11:42 -0500)
src/jsMain/kotlin/starshipfights/game/client_matchmaking.kt
src/jsMain/kotlin/starshipfights/game/popup.kt
src/jvmMain/kotlin/starshipfights/data/auth/user_sessions.kt
src/jvmMain/kotlin/starshipfights/game/endpoints_game.kt

index 1f4988de2ffbe41704ab9770105c2e6e2891a27e..9c30999013e0dc15d75a3e810df181cc044c7e16 100644 (file)
@@ -6,8 +6,14 @@ import externals.threejs.WebGLRenderer
 import io.ktor.client.features.websocket.*
 import kotlinx.browser.document
 import kotlinx.browser.window
+import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
+import kotlinx.html.FormEncType
+import kotlinx.html.FormMethod
+import kotlinx.html.dom.create
+import kotlinx.html.hiddenInput
+import kotlinx.html.js.form
 
 suspend fun setupBackground() {
        val camera = PerspectiveCamera(69, window.aspectRatio, 0.01, 1_000)
@@ -37,6 +43,16 @@ suspend fun setupBackground() {
        }
 }
 
+private suspend fun enterGame(connectToken: String): Nothing {
+       document.create.form(action = "/play", method = FormMethod.post, encType = FormEncType.applicationXWwwFormUrlEncoded) {
+               hiddenInput {
+                       name = "token"
+                       value = connectToken
+               }
+       }.submit()
+       awaitCancellation()
+}
+
 private suspend fun usePlayerLogin(admirals: List<InGameAdmiral>) {
        val playerLogin = Popup.getPlayerLogin(admirals)
        val admiral = admirals.single { it.id == playerLogin.admiral }
@@ -66,7 +82,7 @@ private suspend fun usePlayerLogin(admirals: List<InGameAdmiral>) {
                                        } while (!joinConnected)
                                        
                                        val connectToken = receiveObject(GameReady.serializer()) { closeAndReturn { return@webSocket } }.connectToken
-                                       Popup.GameReadyScreen(connectToken).display()
+                                       enterGame(connectToken)
                                }
                                GlobalSide.GUEST -> {
                                        val listOfHosts = receiveObject(JoinListing.serializer()) { closeAndReturn { return@webSocket } }.openGames
@@ -86,7 +102,7 @@ private suspend fun usePlayerLogin(admirals: List<InGameAdmiral>) {
                                        } while (!joinAcceptance)
                                        
                                        val connectToken = receiveObject(GameReady.serializer()) { closeAndReturn { return@webSocket } }.connectToken
-                                       Popup.GameReadyScreen(connectToken).display()
+                                       enterGame(connectToken)
                                }
                        }
                }
index cac0087aa00a925f4cb5ef29a08214d99365b475..a22aea17fc042487afd1aed0ba7f0035c69eb94f 100644 (file)
@@ -14,7 +14,6 @@ import kotlinx.html.*
 import kotlinx.html.dom.append
 import kotlinx.html.js.onClickFunction
 import org.w3c.dom.HTMLDivElement
-import org.w3c.dom.HTMLFormElement
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.resume
 
@@ -363,36 +362,6 @@ sealed class Popup<out T> {
                }
        }
        
-       class GameReadyScreen(private val connectToken: String) : Popup<Nothing>() {
-               override fun TagConsumer<*>.render(context: CoroutineContext, callback: (Nothing) -> Unit) {
-                       p {
-                               style = "text-align:center"
-                               
-                               +"Your battle is ready for you to enter!"
-                       }
-                       
-                       form(action = "/play", method = FormMethod.post, encType = FormEncType.applicationXWwwFormUrlEncoded) {
-                               id = "battle-entry"
-                               style = "display:none"
-                               hiddenInput {
-                                       name = "token"
-                                       value = connectToken
-                               }
-                       }
-                       
-                       div(classes = "button-set row") {
-                               button {
-                                       +"Enter Battle"
-                                       onClickFunction = { e ->
-                                               e.preventDefault()
-                                               
-                                               document.getElementById("battle-entry").unsafeCast<HTMLFormElement>().submit()
-                                       }
-                               }
-                       }
-               }
-       }
-       
        class LoadingScreen<T>(private val loadingText: String, private val loadAction: suspend () -> T) : Popup<T>() {
                override fun TagConsumer<*>.render(context: CoroutineContext, callback: (T) -> Unit) {
                        p {
index bc4d7b97ac77322611a52907e9fe87ea169b3d3b..b56100994357dcb214e08b655193fe3c531d74fd 100644 (file)
@@ -32,7 +32,7 @@ data class User(
 }
 
 enum class UserStatus {
-       AVAILABLE, IN_MATCHMAKING, IN_BATTLE
+       AVAILABLE, IN_MATCHMAKING, READY_FOR_BATTLE, IN_BATTLE
 }
 
 @Serializable
index 970b898277c940c527a92c8947e013d94b3d0939..0af46ef3e165996a223767f913fc517d32285eb3 100644 (file)
@@ -29,7 +29,8 @@ fun Routing.installGame() {
                
                val clientMode = when (user.status) {
                        UserStatus.AVAILABLE -> ClientMode.Error("You must use the matchmaking interface to enter a game")
-                       UserStatus.IN_MATCHMAKING -> call.getGameClientMode()
+                       UserStatus.IN_MATCHMAKING -> ClientMode.Error("You must start a game in the matchmaking interface")
+                       UserStatus.READY_FOR_BATTLE -> call.getGameClientMode()
                        UserStatus.IN_BATTLE -> ClientMode.Error("You cannot play in multiple battles at the same time")
                }
                
@@ -42,11 +43,13 @@ fun Routing.installGame() {
                        closeAndReturn("You cannot play in multiple battles at the same time") { return@webSocket }
                
                val user = oldUser.copy(status = UserStatus.IN_MATCHMAKING)
-               launch {
-                       User.put(user)
-               }
+               User.put(user)
                
                matchmakingEndpoint(user)
+               
+               launch {
+                       User.put(user.copy(status = UserStatus.READY_FOR_BATTLE))
+               }
        }
        
        webSocket("/game/{token}") {
@@ -56,6 +59,8 @@ fun Routing.installGame() {
                
                if (oldUser.status == UserStatus.IN_BATTLE)
                        closeAndReturn("You cannot play in multiple battles at the same time") { return@webSocket }
+               if (oldUser.status == UserStatus.IN_MATCHMAKING)
+                       closeAndReturn("You must start a game in the matchmaking interface") { return@webSocket }
                if (oldUser.status == UserStatus.AVAILABLE)
                        closeAndReturn("You must use the matchmaking interface to enter a game") { return@webSocket }
                
@@ -65,8 +70,7 @@ fun Routing.installGame() {
                gameEndpoint(user, token)
                
                launch {
-                       val postGameUser = user.copy(status = UserStatus.AVAILABLE)
-                       User.put(postGameUser)
+                       User.put(user.copy(status = UserStatus.AVAILABLE))
                }
        }
 }