diff --git a/client/build.gradle.kts b/client/build.gradle.kts index e9065cf..7f223b5 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -29,17 +29,23 @@ korge { )) } +tasks.withType { + kotlinOptions { + jvmTarget = "17" + } +} + kotlin { jvm() sourceSets { val commonMain by getting { - kotlin.addSrcDir(File(project(":shared").projectDir, "src/commonMain/kotlin")) +// kotlin.addSrcDir(File(project(":shared").projectDir, "src/commonMain/kotlin")) dependencies { api("de.cketti.unicode:kotlin-codepoints-deluxe:0.6.1") api(project(":deps")) + api(project(":shared")) api(libs.kotlinx.uuid) api(libs.kotlinx.serialization) - api(libs.koin) api(libs.ktor.client.auth) api(libs.ktor.client.content.negotation) api(libs.ktor.serialization.kotlinx.protobuf) @@ -88,7 +94,6 @@ kotlin { ).contains(it.name) }.forEach { it.exclude(libs.kotlinx.uuid.asProvider()) it.exclude(libs.kotlinx.serialization) - it.exclude(libs.koin) it.exclude(libs.ktor.client.auth) it.exclude(libs.ktor.client.content.negotation) it.exclude(libs.ktor.serialization.kotlinx.json) diff --git a/client/src/androidMain/AndroidManifest.xml b/client/src/androidMain/AndroidManifest.xml deleted file mode 100644 index fe2871a..0000000 --- a/client/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/client/src/androidMain/kotlin/main.kt b/client/src/androidMain/kotlin/main.kt index 8244954..4a1f416 100644 --- a/client/src/androidMain/kotlin/main.kt +++ b/client/src/androidMain/kotlin/main.kt @@ -1,13 +1,5 @@ -import io.ktor.client.engine.cio.* import korlibs.io.file.std.resourcesVfs import korlibs.io.lang.readProperties -import network.ClientEngineFactory -import network.URLProvider -import org.koin.core.context.startKoin -import org.koin.core.qualifier.named -import org.koin.dsl.bind -import org.koin.dsl.module -import org.koin.mp.KoinPlatform class Main @@ -16,19 +8,7 @@ suspend fun runMain() { } suspend fun main() { val clientProps = resourcesVfs["client.properties"].readProperties() - val url = clientProps["server"]!! - val version = clientProps["version"]!! - startKoin {} - KoinPlatform.getKoin().loadModules(listOf(module { - single(named("version")) { version } - factory { - object : URLProvider { - override val url: String get() = url - } - } bind URLProvider::class - factory { - object : ClientEngineFactory { override fun getEngine() = CIO } - } bind ClientEngineFactory::class - })) + currentUrl = clientProps["server"]!! + version = clientProps["version"]!! startMain() } \ No newline at end of file diff --git a/client/src/commonMain/kotlin/MainScene.kt b/client/src/commonMain/kotlin/MainScene.kt index 5767d7d..9ac75f4 100644 --- a/client/src/commonMain/kotlin/MainScene.kt +++ b/client/src/commonMain/kotlin/MainScene.kt @@ -6,8 +6,6 @@ import korlibs.korge.scene.Scene import korlibs.korge.style.* import korlibs.korge.view.* import network.ServerClosedPacket -import org.koin.core.qualifier.named -import org.koin.mp.KoinPlatform.getKoin import ui.loadingMenu import ui.loginMenuView import util.ColorPalette @@ -15,7 +13,7 @@ import util.launchNow import util.transform val styler: ViewStyles.() -> Unit = { - textFont = getKoin().get() + textFont = font textAlignment = TextAlignment.MIDDLE_CENTER textSize = 100f textColor = ColorPalette.text @@ -38,7 +36,7 @@ class MainScene : Scene() { } screen.container { - text(getKoin().get(named("version")), textSize = 30f) { + text(version, textSize = 30f) { }.zIndex(100) zIndex(100) }.transform { diff --git a/client/src/commonMain/kotlin/const.kt b/client/src/commonMain/kotlin/const.kt new file mode 100644 index 0000000..aa463bd --- /dev/null +++ b/client/src/commonMain/kotlin/const.kt @@ -0,0 +1,7 @@ +import io.ktor.client.engine.* + +typealias KtorEngine = HttpClientEngineFactory + +lateinit var currentUrl: String +lateinit var version: String +lateinit var engine: KtorEngine diff --git a/shared/src/commonMain/kotlin/network/Client.kt b/client/src/commonMain/kotlin/network/Client.kt similarity index 89% rename from shared/src/commonMain/kotlin/network/Client.kt rename to client/src/commonMain/kotlin/network/Client.kt index 9d090a3..da72d11 100644 --- a/shared/src/commonMain/kotlin/network/Client.kt +++ b/client/src/commonMain/kotlin/network/Client.kt @@ -1,5 +1,7 @@ package network +import currentUrl +import engine import io.ktor.client.* import io.ktor.client.engine.* import io.ktor.client.plugins.contentnegotiation.* @@ -10,10 +12,9 @@ import io.ktor.serialization.kotlinx.* import io.ktor.serialization.kotlinx.protobuf.* import io.ktor.websocket.* import kotlinx.serialization.protobuf.ProtoBuf -import org.koin.mp.KoinPlatform +import sessionId +import username -val currentUrl get() = KoinPlatform.getKoin().get().url -val clientEngine get() = KoinPlatform.getKoin().get().getEngine() private var clientInst: HttpClient? = null suspend fun websocket(): WebSocketSession = client().webSocketSession(currentUrl.httpToWs()) @@ -45,7 +46,7 @@ suspend fun client(): HttpClient = run { suspend fun initializeClient() = run { - clientInst = HttpClient(clientEngine) { + clientInst = HttpClient(engine) { install(io.ktor.client.plugins.websocket.WebSockets) { contentConverter = converter } diff --git a/client/src/commonMain/kotlin/network/login.kt b/client/src/commonMain/kotlin/network/login.kt new file mode 100644 index 0000000..75c7cc8 --- /dev/null +++ b/client/src/commonMain/kotlin/network/login.kt @@ -0,0 +1,23 @@ +import io.ktor.client.call.* +import kotlinx.uuid.UUID +import kotlinx.uuid.generateUUID +import network.LoginRequest +import network.LoginResult +import network.LoginResultType +import network.sendHttp + +var username: String = generateUsername() +lateinit var sessionId: String +lateinit var sessionUUID: UUID +val usernameRegex = Regex("[ㄱ-ㅎ가-힣a-zA-Z0-9._]") +private fun generateUsername() = UUID.generateUUID().toString().substring(0, 4) + +suspend fun login(loginRequest: LoginRequest = LoginRequest(username)): LoginResultType { + val loginResult = runCatching { sendHttp("login", loginRequest, auth = false) } + .apply {println(this.exceptionOrNull()?.stackTraceToString())}.getOrNull()?.body() ?: return LoginResultType.SERVER_IS_NOT_AVAILABLE + if (loginResult.result == LoginResultType.SUCCESS) { + sessionUUID = loginResult.uuid!! + sessionId = sessionUUID.toString() + } + return loginResult.result +} \ No newline at end of file diff --git a/client/src/commonMain/kotlin/network/rooms.kt b/client/src/commonMain/kotlin/network/rooms.kt new file mode 100644 index 0000000..2c37ba2 --- /dev/null +++ b/client/src/commonMain/kotlin/network/rooms.kt @@ -0,0 +1,23 @@ +package network + +import currentUrl +import io.ktor.client.call.* +import io.ktor.client.request.* +import kotlinx.uuid.UUID +import sessionId +import username + +suspend fun createRoom(createRoom: CreateRoom) = sendHttp("rooms/create", createRoom).body() +suspend fun getViewedRooms() = runCatching { + client().post("$currentUrl/rooms") { + basicAuth(username, sessionId) + }.body>() +}.apply { this.exceptionOrNull()?.printStackTrace() }.getOrElse { listOf() } + +suspend fun joinRoom(uuid: UUID) = sendHttp("rooms/join", uuid).status + +suspend fun requestLeaveRoom(uuid: UUID) = sendHttp("rooms/leave", uuid).status + +suspend fun getRoomName(uuid: UUID) = sendHttp("rooms/name", uuid).body() + +suspend fun listPlayer() = sendHttp("rooms/players").body>() diff --git a/client/src/commonMain/kotlin/network/websocket.kt b/client/src/commonMain/kotlin/network/websocket.kt index 925f1ad..fb6dff8 100644 --- a/client/src/commonMain/kotlin/network/websocket.kt +++ b/client/src/commonMain/kotlin/network/websocket.kt @@ -10,7 +10,9 @@ import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.protobuf.ProtoBuf import network.ServerPacket.* import MainScene +import currentUrl import scene +import sessionUUID import ui.loadingMenu import util.launchNow diff --git a/client/src/commonMain/kotlin/start.kt b/client/src/commonMain/kotlin/start.kt index bf7f27e..802e893 100644 --- a/client/src/commonMain/kotlin/start.kt +++ b/client/src/commonMain/kotlin/start.kt @@ -1,4 +1,7 @@ +import korlibs.image.bitmap.Bitmap +import korlibs.image.bitmap.BmpSlice import korlibs.image.font.Font +import korlibs.image.font.WoffFont import korlibs.image.font.readWoffFont import korlibs.image.format.readBitmap import korlibs.image.format.readBitmapSlice @@ -10,30 +13,24 @@ import korlibs.korge.view.* import korlibs.math.geom.Anchor import korlibs.math.geom.ScaleMode import korlibs.math.geom.Size -import org.koin.core.qualifier.named -import org.koin.dsl.bind -import org.koin.dsl.module -import org.koin.mp.KoinPlatform.getKoin import util.ColorPalette +import kotlin.coroutines.CoroutineContext import kotlin.coroutines.coroutineContext lateinit var scene: SceneContainer lateinit var screen: FixedSizeContainer +lateinit var globalCoroutineContext: CoroutineContext +lateinit var logo: BmpSlice +lateinit var font: WoffFont +lateinit var boldFont: WoffFont +lateinit var profile: Bitmap suspend fun startMain() { - val coroutineContext = coroutineContext - val logo = resourcesVfs["images/logo.png"].readBitmapSlice() - val font = resourcesVfs["fonts/NanumSquareNeoTTF-dEb.woff"].readWoffFont() - val boldFont = resourcesVfs["fonts/NanumSquareNeoTTF-eHv.woff"].readWoffFont() - val profile = resourcesVfs["images/profile.png"].readBitmap() - getKoin().loadModules(listOf(module { - single { coroutineContext } - single(named("bold")) { boldFont } bind Font::class - single { font } bind Font::class - single(named("logo")) { logo } - single(named("profile")) { profile } - - })) + globalCoroutineContext = coroutineContext + logo = resourcesVfs["images/logo.png"].readBitmapSlice() + font = resourcesVfs["fonts/NanumSquareNeoTTF-dEb.woff"].readWoffFont() + boldFont = resourcesVfs["fonts/NanumSquareNeoTTF-eHv.woff"].readWoffFont() + profile = resourcesVfs["images/profile.png"].readBitmap() Korge( windowSize = Size(512, 512), title = "Skeep", @@ -47,6 +44,3 @@ suspend fun startMain() { scene.changeTo({ MainScene() }) } } - -inline fun > onAdd(hook: List) { -} diff --git a/client/src/commonMain/kotlin/ui/MainMenu.kt b/client/src/commonMain/kotlin/ui/MainMenu.kt index b6e14b6..f11dad4 100644 --- a/client/src/commonMain/kotlin/ui/MainMenu.kt +++ b/client/src/commonMain/kotlin/ui/MainMenu.kt @@ -17,9 +17,8 @@ import korlibs.math.geom.* import korlibs.time.DateTime import korlibs.time.milliseconds import korlibs.time.seconds +import logo import network.* -import org.koin.core.qualifier.named -import org.koin.mp.KoinPlatform.getKoin import scene import styler import screen @@ -145,7 +144,7 @@ fun MainMenuState.room(room: ViewedRoom) { rooms.customUiButton(size = buttonSize) button@{ transform { size(buttonSize) } isRoom = true - val logo = getKoin().get(named("logo")) + val logo = logo uiImage(size = logoSize, bitmap = logo, scaleMode = ScaleMode.FIT).transform { size(logoSize) .centerYOn(this@button) diff --git a/client/src/commonMain/kotlin/ui/createRoomMenu.kt b/client/src/commonMain/kotlin/ui/createRoomMenu.kt index d514d50..5e3ccfd 100644 --- a/client/src/commonMain/kotlin/ui/createRoomMenu.kt +++ b/client/src/commonMain/kotlin/ui/createRoomMenu.kt @@ -25,6 +25,7 @@ import styler import screen import ui.custom.* import ui.custom.UITextInput +import username import util.ColorPalette import util.launchNow import util.transform diff --git a/client/src/commonMain/kotlin/ui/newLoginMenu.kt b/client/src/commonMain/kotlin/ui/newLoginMenu.kt index aa20359..ae26a3a 100644 --- a/client/src/commonMain/kotlin/ui/newLoginMenu.kt +++ b/client/src/commonMain/kotlin/ui/newLoginMenu.kt @@ -15,16 +15,18 @@ import korlibs.korge.ui.* import korlibs.korge.view.Container import korlibs.korge.view.align.* import korlibs.korge.view.positionX -import korlibs.korge.view.solidRect import korlibs.korge.view.zIndex import korlibs.math.geom.RectCorners import korlibs.math.geom.Size +import login import network.* import styler import screen import ui.custom.UITextInput import ui.custom.customUiButton import ui.custom.customUiTextInput +import username +import usernameRegex import util.ColorPalette import util.launchNow import util.transform diff --git a/client/src/commonMain/kotlin/ui/waitingRoom.kt b/client/src/commonMain/kotlin/ui/waitingRoom.kt index d0e8677..c537056 100644 --- a/client/src/commonMain/kotlin/ui/waitingRoom.kt +++ b/client/src/commonMain/kotlin/ui/waitingRoom.kt @@ -28,10 +28,10 @@ import korlibs.math.geom.Size import korlibs.time.seconds import kotlinx.uuid.UUID import network.* -import org.koin.core.qualifier.named -import org.koin.mp.KoinPlatform.getKoin +import profile import styler import screen +import sessionUUID import ui.custom.* import ui.custom.UITextInput import util.ColorPalette @@ -177,7 +177,7 @@ fun WaitingRoomState.profileView(name: String, container: Container) { transform { size(profileSize) } // solidRect(size, color = Colors.WHITE) setExtra("profile", name) - val imageBitmap = getKoin().get(named("profile")).toBMP32().apply { + val imageBitmap = profile.toBMP32().apply { updateColors { if (it != Colors.TRANSPARENT) { val t = ColorPalette.hover diff --git a/client/src/commonMain/kotlin/util/coroutineUtil.kt b/client/src/commonMain/kotlin/util/coroutineUtil.kt index 259f69f..f651d80 100644 --- a/client/src/commonMain/kotlin/util/coroutineUtil.kt +++ b/client/src/commonMain/kotlin/util/coroutineUtil.kt @@ -1,8 +1,11 @@ package util +import globalCoroutineContext import korlibs.io.async.launchImmediately import kotlinx.coroutines.CoroutineScope -import org.koin.mp.KoinPlatform.getKoin +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope import kotlin.coroutines.CoroutineContext -fun launchNow(context: CoroutineContext = getKoin().get(), callback: suspend () -> Unit) = CoroutineScope(context).launchImmediately(callback) +@DelicateCoroutinesApi +fun launchNow(context: CoroutineContext = GlobalScope.coroutineContext, callback: suspend () -> Unit) = CoroutineScope(context).launchImmediately(callback) diff --git a/client/src/jsMain/kotlin/main.kt b/client/src/jsMain/kotlin/main.kt index a5869a8..30681a0 100644 --- a/client/src/jsMain/kotlin/main.kt +++ b/client/src/jsMain/kotlin/main.kt @@ -1,29 +1,11 @@ import io.ktor.client.engine.js.* import korlibs.io.file.std.resourcesVfs import korlibs.io.lang.readProperties -import network.ClientEngineFactory -import network.URLProvider -import org.koin.core.context.startKoin -import org.koin.core.qualifier.named -import org.koin.dsl.bind -import org.koin.dsl.module -import org.koin.mp.KoinPlatform suspend fun main() { val clientProps = resourcesVfs["client.properties"].readProperties() - val url = clientProps["server"]!! - val version = clientProps["version"]!! - startKoin {} - KoinPlatform.getKoin().loadModules(listOf(module { - single(named("version")) { version } - factory { - object : URLProvider { - override val url: String get() = url - } - } bind URLProvider::class - factory { - object : ClientEngineFactory { override fun getEngine() = Js } - } bind ClientEngineFactory::class - })) + currentUrl = clientProps["server"]!! + version = clientProps["version"]!! + engine = Js startMain() } \ No newline at end of file diff --git a/client/src/jvmMain/kotlin/main.kt b/client/src/jvmMain/kotlin/main.kt index 609848b..fa807ca 100644 --- a/client/src/jvmMain/kotlin/main.kt +++ b/client/src/jvmMain/kotlin/main.kt @@ -1,11 +1,4 @@ import io.ktor.client.engine.cio.* -import network.ClientEngineFactory -import network.URLProvider -import org.koin.core.context.startKoin -import org.koin.core.qualifier.named -import org.koin.dsl.bind -import org.koin.dsl.module -import org.koin.mp.KoinPlatform import java.util.* class Main @@ -14,19 +7,8 @@ suspend fun main() { val clientProps = Properties().apply { load(Main::class.java.getResourceAsStream("client.properties")) } - val url = clientProps["server"]!!.toString() - val version = clientProps["version"]!!.toString() - startKoin {} - KoinPlatform.getKoin().loadModules(listOf(module { - single(named("version")) { version } - factory { - object : URLProvider { - override val url: String get() = url - } - } bind URLProvider::class - factory { - object : ClientEngineFactory { override fun getEngine() = CIO } - } bind ClientEngineFactory::class - })) + currentUrl = clientProps["server"]!!.toString() + version = clientProps["version"]!!.toString() + engine = CIO startMain() } \ No newline at end of file diff --git a/client/src/macosArm64Main/kotlin/main.kt b/client/src/macosArm64Main/kotlin/main.kt index 3e8558a..d5dc9ff 100644 --- a/client/src/macosArm64Main/kotlin/main.kt +++ b/client/src/macosArm64Main/kotlin/main.kt @@ -1,34 +1,16 @@ -import io.ktor.client.engine.cio.* import korlibs.io.file.std.resourcesVfs import korlibs.io.lang.readProperties import kotlinx.coroutines.runBlocking -import network.ClientEngineFactory -import network.URLProvider -import org.koin.core.context.startKoin -import org.koin.core.qualifier.named -import org.koin.dsl.bind -import org.koin.dsl.module -import org.koin.mp.KoinPlatform +import io.ktor.client.engine.cio.* class Main fun runMain() = main() fun main() { runBlocking { val clientProps = resourcesVfs["client.properties"].readProperties() - val url = clientProps["server"]!! - val version = clientProps["version"]!! - startKoin {} - KoinPlatform.getKoin().loadModules(listOf(module { - single(named("version")) { version } - factory { - object : URLProvider { - override val url: String get() = url - } - } bind URLProvider::class - factory { - object : ClientEngineFactory { override fun getEngine() = CIO } - } bind ClientEngineFactory::class - })) + currentUrl = clientProps["server"]!! + version = clientProps["version"]!! + engine = CIO startMain() } } \ No newline at end of file diff --git a/client/src/mingwX64Main/kotlin/main.kt b/client/src/mingwX64Main/kotlin/main.kt index 0a432c0..a0cee88 100644 --- a/client/src/mingwX64Main/kotlin/main.kt +++ b/client/src/mingwX64Main/kotlin/main.kt @@ -2,33 +2,15 @@ import io.ktor.client.engine.winhttp.* import korlibs.io.file.std.resourcesVfs import korlibs.io.lang.readProperties import kotlinx.coroutines.runBlocking -import network.ClientEngineFactory -import network.URLProvider -import org.koin.core.context.startKoin -import org.koin.core.qualifier.named -import org.koin.dsl.bind -import org.koin.dsl.module -import org.koin.mp.KoinPlatform class Main fun runMain() = main() fun main() { runBlocking { val clientProps = resourcesVfs["client.properties"].readProperties() - val url = clientProps["server"]!! - val version = clientProps["version"]!! - startKoin {} - KoinPlatform.getKoin().loadModules(listOf(module { - single(named("version")) { version } - factory { - object : URLProvider { - override val url: String get() = url - } - } bind URLProvider::class - factory { - object : ClientEngineFactory { override fun getEngine() = WinHttp } - } bind ClientEngineFactory::class - })) + currentUrl = clientProps["server"]!! + version = clientProps["version"]!! + engine = WinHttp startMain() } } \ No newline at end of file diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 3d1ca9d..183e91a 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -1,16 +1,27 @@ +import korlibs.korge.gradle.KorgeGradlePlugin import korlibs.korge.gradle.KorgeLibraryGradlePlugin +import korlibs.korge.gradle.Orientation import korlibs.korge.gradle.korge +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +apply() apply(plugin = "org.jetbrains.kotlin.plugin.serialization") -apply(plugin = "org.jetbrains.kotlin.kapt") plugins { kotlin("multiplatform") - kotlin("kapt") + id("com.android.application") +} + +korge { + targetJvm() + targetJs() + targetDesktopCross() + targetDesktop() + targetAndroid() } tasks.withType { kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "17" } } @@ -21,7 +32,6 @@ kotlin { dependencies { api(libs.kotlinx.uuid) api(libs.kotlinx.serialization) - api(libs.koin) api(libs.ktor.client.auth) api(libs.ktor.client.content.negotation) api(libs.ktor.serialization.kotlinx.protobuf) diff --git a/shared/src/commonMain/kotlin/network/Login.kt b/shared/src/commonMain/kotlin/network/Login.kt index ca5843d..0df85a1 100644 --- a/shared/src/commonMain/kotlin/network/Login.kt +++ b/shared/src/commonMain/kotlin/network/Login.kt @@ -7,12 +7,6 @@ import kotlinx.uuid.generateUUID import network.LoginResultType.SERVER_IS_NOT_AVAILABLE import network.LoginResultType.SUCCESS -var username: String = generateUsername() -lateinit var sessionId: String -lateinit var sessionUUID: UUID -val usernameRegex = Regex("[ㄱ-ㅎ가-힣a-zA-Z0-9._]") -private fun generateUsername() = UUID.generateUUID().toString().substring(0, 4) - enum class LoginResultType { SUCCESS, ALREADY_JOINED, @@ -24,12 +18,4 @@ data class LoginResult( val result: LoginResultType, val uuid: UUID? = null, ) -suspend fun login(loginRequest: LoginRequest = LoginRequest(username)): LoginResultType { - val loginResult = runCatching { sendHttp("login", loginRequest, auth = false) } - .apply {println(this.exceptionOrNull()?.stackTraceToString())}.getOrNull()?.body() ?: return SERVER_IS_NOT_AVAILABLE - if (loginResult.result == SUCCESS) { - sessionUUID = loginResult.uuid!! - sessionId = sessionUUID.toString() - } - return loginResult.result -} \ No newline at end of file + diff --git a/shared/src/commonMain/kotlin/network/httpRequests.kt b/shared/src/commonMain/kotlin/network/httpRequests.kt index f4889e6..910c062 100644 --- a/shared/src/commonMain/kotlin/network/httpRequests.kt +++ b/shared/src/commonMain/kotlin/network/httpRequests.kt @@ -9,17 +9,3 @@ import kotlinx.uuid.UUID enum class CreateRoomResultType { CREATED, NOT_ALLOWED_MAX_PLAYERS_AMOUNT, NOT_ALlOWED_NAME } @Serializable data class CreateRoomResult(val type: CreateRoomResultType, val room: UUID = UUID()) -suspend fun createRoom(createRoom: CreateRoom) = sendHttp("rooms/create", createRoom).body() -suspend fun getViewedRooms() = runCatching { - client().post("$currentUrl/rooms") { - basicAuth(username, sessionId) - }.body>() -}.apply { this.exceptionOrNull()?.printStackTrace() }.getOrElse { listOf() } - -suspend fun joinRoom(uuid: UUID) = sendHttp("rooms/join", uuid).status - -suspend fun requestLeaveRoom(uuid: UUID) = sendHttp("rooms/leave", uuid).status - -suspend fun getRoomName(uuid: UUID) = sendHttp("rooms/name", uuid).body() - -suspend fun listPlayer() = sendHttp("rooms/players").body>()