From ebecc28455b8a6c651a660da8939eb9254fb8ab9 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Wed, 6 Jul 2022 11:43:19 -0500 Subject: [PATCH] Added remote status to right panel --- build.gradle.kts | 2 +- .../launcher/resources/data/LauncherData.kt | 2 +- .../data/login/LoginServerInstanceInfo.kt | 2 + .../launcher/resources/gui/ServerListView.kt | 24 +++++++++ .../services/data/RemoteDataService.kt | 52 +++++++++++++++++-- 5 files changed, 77 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a636c06..07cf5a1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,7 @@ subprojects { } group = "com.projectswg.launcher" -version = "2.0.1" +version = "2.1.0" application { mainModule.set("com.projectswg.launcher") diff --git a/src/main/java/com/projectswg/launcher/resources/data/LauncherData.kt b/src/main/java/com/projectswg/launcher/resources/data/LauncherData.kt index 56f18ca..34f1b4a 100644 --- a/src/main/java/com/projectswg/launcher/resources/data/LauncherData.kt +++ b/src/main/java/com/projectswg/launcher/resources/data/LauncherData.kt @@ -44,7 +44,7 @@ enum class LauncherData { get() = FX.application companion object { - const val VERSION = "2.0.1" + const val VERSION = "2.1.0" fun getApplicationDataDirectory(): File { return when (getOS()) { diff --git a/src/main/java/com/projectswg/launcher/resources/data/login/LoginServerInstanceInfo.kt b/src/main/java/com/projectswg/launcher/resources/data/login/LoginServerInstanceInfo.kt index 0285d12..15ebb6e 100644 --- a/src/main/java/com/projectswg/launcher/resources/data/login/LoginServerInstanceInfo.kt +++ b/src/main/java/com/projectswg/launcher/resources/data/login/LoginServerInstanceInfo.kt @@ -26,10 +26,12 @@ import tornadofx.setValue class LoginServerInstanceInfo { + val loginNameProperty = SimpleStringProperty("") val loginStatusProperty = SimpleStringProperty("") val updateStatusProperty = SimpleStringProperty("") val readyToPlayProperty = SimpleBooleanProperty(false) + var loginName: String by loginNameProperty var loginStatus: String by loginStatusProperty var updateStatus: String by updateStatusProperty var isReadyToPlay: Boolean by readyToPlayProperty diff --git a/src/main/java/com/projectswg/launcher/resources/gui/ServerListView.kt b/src/main/java/com/projectswg/launcher/resources/gui/ServerListView.kt index 669b8fd..0575622 100644 --- a/src/main/java/com/projectswg/launcher/resources/gui/ServerListView.kt +++ b/src/main/java/com/projectswg/launcher/resources/gui/ServerListView.kt @@ -20,6 +20,7 @@ package com.projectswg.launcher.resources.gui +import com.projectswg.common.data.encodables.galaxy.Galaxy import com.projectswg.launcher.resources.data.LauncherData import com.projectswg.launcher.resources.data.update.UpdateServer import com.projectswg.launcher.resources.game.GameInstance @@ -113,6 +114,29 @@ class ServerListView : View() { field(messages["servers.login.form.password"]) { passwordfield(LauncherData.INSTANCE.login.activeServerProperty.select { it.authenticationProperty }.select { it.passwordProperty }) } + field(messages["servers.column.remoteStatus"]) { + val loginName = LauncherData.INSTANCE.login.activeServerProperty.select { it.instanceInfo.loginNameProperty } + val loginStatus = LauncherData.INSTANCE.login.activeServerProperty.select { it.instanceInfo.loginStatusProperty } + val loginNameExists = loginName.select { ReadOnlyBooleanWrapper(it.isNotEmpty()) } + val loginStatusWithBrackets = loginStatus.select { ReadOnlyStringWrapper(if (loginNameExists.value) "[$it]" else it) } + val remoteStatus = loginName.stringBinding(loginStatusWithBrackets) { (if (loginNameExists.value) "$it " else "") + loginStatusWithBrackets.value } + + label(remoteStatus) { + maxWidth = Double.POSITIVE_INFINITY + isFillWidth = true + + textFillProperty().bind(loginStatus.select { when (it) { + Galaxy.GalaxyStatus.UP.name -> ReadOnlyObjectWrapper(Color.rgb(0, 255, 0)) + Galaxy.GalaxyStatus.DOWN.name -> ReadOnlyObjectWrapper(Color.RED) + Galaxy.GalaxyStatus.FULL.name -> ReadOnlyObjectWrapper(Color.YELLOW) + else -> ReadOnlyObjectWrapper(Color.WHITE) + } }) + + style { + fontWeight = FontWeight.BOLD + } + } + } field(messages["servers.column.localStatus"]) { val updateStatus = LauncherData.INSTANCE.login.activeServerProperty.select { it.updateServerProperty }.select { it.statusProperty } diff --git a/src/main/java/com/projectswg/launcher/services/data/RemoteDataService.kt b/src/main/java/com/projectswg/launcher/services/data/RemoteDataService.kt index e055184..a040818 100644 --- a/src/main/java/com/projectswg/launcher/services/data/RemoteDataService.kt +++ b/src/main/java/com/projectswg/launcher/services/data/RemoteDataService.kt @@ -20,24 +20,34 @@ package com.projectswg.launcher.services.data +import com.projectswg.common.data.encodables.galaxy.Galaxy +import com.projectswg.launcher.resources.data.LauncherData import com.projectswg.launcher.resources.intents.DownloadLauncherIntent import com.projectswg.launcher.resources.intents.RequestScanIntent import com.projectswg.launcher.resources.pipeline.LauncherConfigurationUpdater import com.projectswg.launcher.resources.pipeline.UpdateServerUpdater +import javafx.application.Platform import me.joshlarson.jlcommon.concurrency.ScheduledThreadPool import me.joshlarson.jlcommon.control.IntentHandler import me.joshlarson.jlcommon.control.Service +import me.joshlarson.jlcommon.log.Log +import me.joshlarson.json.JSONException +import me.joshlarson.json.JSONInputStream +import java.io.IOException +import java.net.URI +import java.net.URL import java.util.concurrent.TimeUnit class RemoteDataService : Service() { - private val executor: ScheduledThreadPool = ScheduledThreadPool(2, "remote-data-service") + private val executor: ScheduledThreadPool = ScheduledThreadPool(3, "remote-data-service") override fun start(): Boolean { executor.start() // Retrieves the latest file list for each update server executor.executeWithFixedDelay(0, TimeUnit.MINUTES.toMillis(30)) { this.updateUpdateServers() } executor.executeWithFixedDelay(0, TimeUnit.MINUTES.toMillis(30)) { this.updateRemoteVersion() } + executor.executeWithFixedDelay(0, TimeUnit.MINUTES.toMillis(1)) { this.updateLoginStatus() } return true } @@ -64,10 +74,46 @@ class RemoteDataService : Service() { LauncherConfigurationUpdater.update() } + private fun updateLoginStatus() { + for (server in loginData.servers) { + val serverUri = URI(server.connectionUri) + val protocol = if (serverUri.scheme == "ws") "http" else "https" + val port = if (serverUri.port < 0) 443 else serverUri.port + val statsUrl = URL(protocol, serverUri.host ?: continue, port, "/stats") + Log.t("Requesting server stats from %s", statsUrl.toExternalForm()) + + lateinit var loginName: String + lateinit var loginStatus: String + try { + JSONInputStream(statsUrl.openStream()).use { + val serverInfo = it.readObject() + val galaxyName = serverInfo["name"] as? String ?: return@use + val status = serverInfo["status"] as? String ?: return@use + + loginName = galaxyName + loginStatus = status + } + } catch (e: JSONException) { + Platform.runLater { + loginName = "" + loginStatus = "INVALID" + } + } catch (e: IOException) { + loginName = "" + loginStatus = Galaxy.GalaxyStatus.DOWN.name + } + + Platform.runLater { + server.instanceInfo.loginName = loginName + server.instanceInfo.loginStatus = loginStatus + } + } + } + companion object { - private val updateData: com.projectswg.launcher.resources.data.update.UpdateData - get() = com.projectswg.launcher.resources.data.LauncherData.INSTANCE.update + private val updateData = LauncherData.INSTANCE.update + private val loginData = LauncherData.INSTANCE.login } }