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)
}
}
+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 }
} 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
} while (!joinAcceptance)
val connectToken = receiveObject(GameReady.serializer()) { closeAndReturn { return@webSocket } }.connectToken
- Popup.GameReadyScreen(connectToken).display()
+ enterGame(connectToken)
}
}
}
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
}
}
- 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 {
}
enum class UserStatus {
- AVAILABLE, IN_MATCHMAKING, IN_BATTLE
+ AVAILABLE, IN_MATCHMAKING, READY_FOR_BATTLE, IN_BATTLE
}
@Serializable
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")
}
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}") {
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 }
gameEndpoint(user, token)
launch {
- val postGameUser = user.copy(status = UserStatus.AVAILABLE)
- User.put(postGameUser)
+ User.put(user.copy(status = UserStatus.AVAILABLE))
}
}
}