diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/Account.kt b/src/main/java/de/bixilon/minosoft/data/accounts/Account.kt index 5975096b3..faa76951f 100644 --- a/src/main/java/de/bixilon/minosoft/data/accounts/Account.kt +++ b/src/main/java/de/bixilon/minosoft/data/accounts/Account.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -18,9 +18,9 @@ import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf import de.bixilon.minosoft.config.profile.profiles.eros.server.entries.Server -import de.bixilon.minosoft.data.accounts.types.MicrosoftAccount -import de.bixilon.minosoft.data.accounts.types.MojangAccount -import de.bixilon.minosoft.data.accounts.types.OfflineAccount +import de.bixilon.minosoft.data.accounts.types.microsoft.MicrosoftAccount +import de.bixilon.minosoft.data.accounts.types.mojang.MojangAccount +import de.bixilon.minosoft.data.accounts.types.offline.OfflineAccount import de.bixilon.minosoft.data.player.properties.PlayerProperties import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection @@ -37,6 +37,8 @@ abstract class Account( abstract val id: String abstract val type: ResourceLocation abstract val properties: PlayerProperties? + @JsonIgnore open var state: AccountStates = AccountStates.UNCHECKED + @JsonIgnore open var error: Throwable? = null @Transient @JsonIgnore @@ -45,5 +47,18 @@ abstract class Account( abstract fun join(serverId: String) abstract fun logout(clientToken: String) - abstract fun verify(clientToken: String) + abstract fun check(clientToken: String) + + @Synchronized + open fun tryCheck(clientToken: String) { + if (state == AccountStates.CHECKING || state == AccountStates.REFRESHING) { + // already checking + return + } + if (state == AccountStates.WORKING) { + // Nothing to do + return + } + check(clientToken) + } } diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/AccountStates.kt b/src/main/java/de/bixilon/minosoft/data/accounts/AccountStates.kt new file mode 100644 index 000000000..e4eaf0bc6 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/accounts/AccountStates.kt @@ -0,0 +1,53 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.accounts + +import de.bixilon.minosoft.data.language.Translatable +import de.bixilon.minosoft.data.registries.ResourceLocation +import de.bixilon.minosoft.util.KUtil.toResourceLocation + +enum class AccountStates : Translatable { + /** + * The account might work + */ + UNCHECKED, + + /** + * It is just being checked, it might fail + */ + CHECKING, + + /** + * The session key is not working anymore, but it can be refreshed + */ + REFRESHING, + + /** + * The session key is working + */ + WORKING, + + /** + * The account is expired and credentials needs to be provided again + */ + EXPIRED, + + /** + * The account is invalid because of some other reason + */ + ERRORED, + ; + + override val translationKey: ResourceLocation = "minosoft:main.account.state.${name.lowercase()}".toResourceLocation() +} diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/types/MicrosoftAccount.kt b/src/main/java/de/bixilon/minosoft/data/accounts/types/microsoft/MicrosoftAccount.kt similarity index 73% rename from src/main/java/de/bixilon/minosoft/data/accounts/types/MicrosoftAccount.kt rename to src/main/java/de/bixilon/minosoft/data/accounts/types/microsoft/MicrosoftAccount.kt index e0c688be7..9d26ec905 100644 --- a/src/main/java/de/bixilon/minosoft/data/accounts/types/MicrosoftAccount.kt +++ b/src/main/java/de/bixilon/minosoft/data/accounts/types/microsoft/MicrosoftAccount.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -11,11 +11,12 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.accounts.types +package de.bixilon.minosoft.data.accounts.types.microsoft import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonProperty import de.bixilon.minosoft.data.accounts.Account +import de.bixilon.minosoft.data.accounts.AccountStates import de.bixilon.minosoft.data.player.properties.PlayerProperties import de.bixilon.minosoft.data.registries.CompanionResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation @@ -35,20 +36,30 @@ class MicrosoftAccount( override val id: String = uuid.toString() override val type: ResourceLocation = RESOURCE_LOCATION + @Synchronized override fun join(serverId: String) { AccountUtil.joinMojangServer(username, accessToken!!, uuid, serverId) } override fun logout(clientToken: String) = Unit - override fun verify(@Nullable clientToken: String) { + @Synchronized + override fun check(@Nullable clientToken: String) { if (accessToken != null) { return } - val (xboxLiveToken, userHash) = MicrosoftOAuthUtils.getXboxLiveToken(authorizationToken) - val xstsToken = MicrosoftOAuthUtils.getXSTSToken(xboxLiveToken) + try { + state = AccountStates.REFRESHING + val (xboxLiveToken, userHash) = MicrosoftOAuthUtils.getXboxLiveToken(authorizationToken) + val xstsToken = MicrosoftOAuthUtils.getXSTSToken(xboxLiveToken) - accessToken = MicrosoftOAuthUtils.getMinecraftBearerAccessToken(userHash, xstsToken) + accessToken = MicrosoftOAuthUtils.getMinecraftBearerAccessToken(userHash, xstsToken) + state = AccountStates.WORKING + } catch (exception: Throwable) { + this.error = exception + this.state = AccountStates.ERRORED + throw exception + } } override fun toString(): String { diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/types/MojangAccount.kt b/src/main/java/de/bixilon/minosoft/data/accounts/types/mojang/MojangAccount.kt similarity index 88% rename from src/main/java/de/bixilon/minosoft/data/accounts/types/MojangAccount.kt rename to src/main/java/de/bixilon/minosoft/data/accounts/types/mojang/MojangAccount.kt index 5167b1425..f497aa0c2 100644 --- a/src/main/java/de/bixilon/minosoft/data/accounts/types/MojangAccount.kt +++ b/src/main/java/de/bixilon/minosoft/data/accounts/types/mojang/MojangAccount.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -11,7 +11,7 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.accounts.types +package de.bixilon.minosoft.data.accounts.types.mojang import com.fasterxml.jackson.annotation.JsonProperty import de.bixilon.kutil.cast.CastUtil.nullCast @@ -19,6 +19,7 @@ import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.json.JsonUtil.asJsonObject import de.bixilon.kutil.uuid.UUIDUtil.toUUID import de.bixilon.minosoft.data.accounts.Account +import de.bixilon.minosoft.data.accounts.AccountStates import de.bixilon.minosoft.data.player.properties.PlayerProperties import de.bixilon.minosoft.data.registries.CompanionResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation @@ -58,18 +59,26 @@ class MojangAccount( if (response.statusCode != 200) { throw AuthenticationException(response.statusCode) } - + state = AccountStates.EXPIRED Log.log(LogMessageType.AUTHENTICATION, LogLevels.VERBOSE) { "Mojang account login successful (username=$username)" } } - override fun verify(clientToken: String) { + override fun check(clientToken: String) { if (refreshed) { return } - refresh(clientToken) + try { + refresh(clientToken) + } catch (exception: Throwable) { + this.error = exception + state = AccountStates.ERRORED + throw exception + } } + @Synchronized fun refresh(clientToken: String) { + state = AccountStates.REFRESHING val response = mutableMapOf( "accessToken" to accessToken, "clientToken" to clientToken, @@ -84,6 +93,7 @@ class MojangAccount( this.accessToken = response.body["accessToken"].unsafeCast() refreshed = true + state = AccountStates.WORKING Log.log(LogMessageType.AUTHENTICATION, LogLevels.VERBOSE) { "Mojang account refresh successful (username=$username)" } } @@ -118,7 +128,7 @@ class MojangAccount( Log.log(LogMessageType.AUTHENTICATION, LogLevels.VERBOSE) { "Mojang login successful (email=$email)" } val uuid = response.body["selectedProfile"].asJsonObject()["id"].toString().toUUID() - return MojangAccount( + val account = MojangAccount( id = response.body["user"].asJsonObject()["id"].unsafeCast(), username = response.body["selectedProfile"].asJsonObject()["name"].unsafeCast(), uuid = uuid, @@ -126,6 +136,8 @@ class MojangAccount( accessToken = response.body["accessToken"].unsafeCast(), properties = PlayerProperties.fetch(uuid), ) + account.state = AccountStates.WORKING + return account } } } diff --git a/src/main/java/de/bixilon/minosoft/data/accounts/types/OfflineAccount.kt b/src/main/java/de/bixilon/minosoft/data/accounts/types/offline/OfflineAccount.kt similarity index 84% rename from src/main/java/de/bixilon/minosoft/data/accounts/types/OfflineAccount.kt rename to src/main/java/de/bixilon/minosoft/data/accounts/types/offline/OfflineAccount.kt index 3e2ef9b81..d1b169d17 100644 --- a/src/main/java/de/bixilon/minosoft/data/accounts/types/OfflineAccount.kt +++ b/src/main/java/de/bixilon/minosoft/data/accounts/types/offline/OfflineAccount.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -11,10 +11,11 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.accounts.types +package de.bixilon.minosoft.data.accounts.types.offline import com.fasterxml.jackson.annotation.JsonIgnore import de.bixilon.minosoft.data.accounts.Account +import de.bixilon.minosoft.data.accounts.AccountStates import de.bixilon.minosoft.data.player.properties.PlayerProperties import de.bixilon.minosoft.data.registries.CompanionResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation @@ -23,6 +24,9 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation class OfflineAccount(username: String) : Account(username) { override val id: String = username override val type: ResourceLocation = RESOURCE_LOCATION + override var state: AccountStates + get() = AccountStates.WORKING + set(value) {} @JsonIgnore override val properties: PlayerProperties? = null @@ -31,7 +35,7 @@ class OfflineAccount(username: String) : Account(username) { override fun logout(clientToken: String) = Unit - override fun verify(clientToken: String) = Unit + override fun check(clientToken: String) = Unit override fun toString(): String { return "OfflineAccount{$username}" diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/main/MainErosController.kt b/src/main/java/de/bixilon/minosoft/gui/eros/main/MainErosController.kt index 810851430..ae11517bd 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/main/MainErosController.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/main/MainErosController.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -18,6 +18,7 @@ import de.bixilon.minosoft.ShutdownReasons import de.bixilon.minosoft.config.profile.delegate.watcher.SimpleProfileDelegateWatcher.Companion.profileWatchFX import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager import de.bixilon.minosoft.data.accounts.Account +import de.bixilon.minosoft.data.accounts.AccountStates import de.bixilon.minosoft.gui.eros.controller.EmbeddedJavaFXController import de.bixilon.minosoft.gui.eros.controller.JavaFXWindowController import de.bixilon.minosoft.gui.eros.util.JavaFXAccountUtil.avatar @@ -133,6 +134,7 @@ class MainErosController : JavaFXWindowController() { } } + @Synchronized fun verifyAccount(account: Account? = null, onSuccess: (Account) -> Unit) { val profile = ErosProfileManager.selected.general.accountProfile val account = account ?: profile.selected @@ -140,10 +142,17 @@ class MainErosController : JavaFXWindowController() { activity = ErosMainActivities.ACCOUNT return } + if (account.state == AccountStates.WORKING) { + DefaultThreadPool += { onSuccess(account) } + return + } + if (account.state == AccountStates.CHECKING || account.state == AccountStates.REFRESHING) { + return + } DefaultThreadPool += { try { - account.verify(profile.clientToken) + account.tryCheck(profile.clientToken) onSuccess(account) } catch (exception: Throwable) { exception.printStackTrace() diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/main/account/AccountCardController.kt b/src/main/java/de/bixilon/minosoft/gui/eros/main/account/AccountCardController.kt index 55d2b5240..f2237ce0d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/main/account/AccountCardController.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/main/account/AccountCardController.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -51,7 +51,7 @@ class AccountCardController : AbstractCardController() { avatarFX.image = item.avatar accountNameFX.text = item.username - stateFX.text = "Unchecked" + stateFX.text = item.state connectionCountFX.text = TranslatableComponents.ACCOUNT_CARD_CONNECTION_COUNT(item.connections.size) } diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/main/account/AccountController.kt b/src/main/java/de/bixilon/minosoft/gui/eros/main/account/AccountController.kt index 19a3a681e..00a9501fd 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/main/account/AccountController.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/main/account/AccountController.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -20,13 +20,15 @@ import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.config.profile.delegate.watcher.entry.MapProfileDelegateWatcher.Companion.profileWatchMapFX import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager import de.bixilon.minosoft.data.accounts.Account -import de.bixilon.minosoft.data.accounts.types.MicrosoftAccount -import de.bixilon.minosoft.data.accounts.types.MojangAccount -import de.bixilon.minosoft.data.accounts.types.OfflineAccount +import de.bixilon.minosoft.data.accounts.AccountStates +import de.bixilon.minosoft.data.accounts.types.microsoft.MicrosoftAccount +import de.bixilon.minosoft.data.accounts.types.mojang.MojangAccount +import de.bixilon.minosoft.data.accounts.types.offline.OfflineAccount import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.TranslatableComponents import de.bixilon.minosoft.gui.eros.controller.EmbeddedJavaFXController +import de.bixilon.minosoft.gui.eros.dialog.ErosErrorReport.Companion.report import de.bixilon.minosoft.gui.eros.dialog.SimpleErosConfirmationDialog import de.bixilon.minosoft.gui.eros.main.account.add.MicrosoftAddController import de.bixilon.minosoft.gui.eros.main.account.add.MojangAddController @@ -106,6 +108,21 @@ class AccountController : EmbeddedJavaFXController() { } } + private fun checkAccount(account: Account, select: Boolean) { + val profile = ErosProfileManager.selected.general.accountProfile + DefaultThreadPool += { + try { + account.tryCheck(profile.clientToken) // ToDo: Show error + if (select) { + profile.selected = account + } + } catch (exception: Throwable) { + exception.report() + } + JavaFXUtil.runLater { refreshList() } + } + } + private fun setAccountInfo(account: Account?) { if (account == null) { @@ -156,25 +173,20 @@ class AccountController : EmbeddedJavaFXController() { ctext = TranslatableComponents.GENERAL_DELETE }, 1, 0) - it.add(Button("Verify").apply { + it.add(Button("Check").apply { setOnAction { isDisable = true - DefaultThreadPool += { - account.verify(profile.clientToken) - JavaFXUtil.runLater { refreshList() } - } + checkAccount(account, false) + } + ctext = CHECK + if (account.state == AccountStates.WORKING || account.state == AccountStates.CHECKING || account.state == AccountStates.REFRESHING) { + isDisable = true } - ctext = VERIFY }, 3, 0) it.add(Button("Use").apply { setOnAction { isDisable = true - - DefaultThreadPool += { - account.verify(profile.clientToken) // ToDo: Show error - profile.selected = account - JavaFXUtil.runLater { refreshList() } - } + checkAccount(account, true) } isDisable = profile.selected == account ctext = USE @@ -194,12 +206,13 @@ class AccountController : EmbeddedJavaFXController() { companion object { val LAYOUT = "minosoft:eros/main/account/account.fxml".toResourceLocation() - private val VERIFY = "minosoft:main.account.list.info.button.verify".toResourceLocation() + private val CHECK = "minosoft:main.account.list.info.button.check".toResourceLocation() private val USE = "minosoft:main.account.list.info.button.use".toResourceLocation() private val ADD = "minosoft:main.account.list.info.button.add".toResourceLocation() private val ACCOUNT_INFO_PROPERTIES: List Any?>> = listOf( "minosoft:main.account.account_info.id".toResourceLocation() to { it.id }, + "minosoft:main.account.account_info.state".toResourceLocation() to { it.state }, ) val ACCOUNT_TYPES = listOf( diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/main/account/add/MojangAddController.kt b/src/main/java/de/bixilon/minosoft/gui/eros/main/account/add/MojangAddController.kt index 631ab5b2f..36eedcec5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/main/account/add/MojangAddController.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/main/account/add/MojangAddController.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -15,7 +15,7 @@ package de.bixilon.minosoft.gui.eros.main.account.add import de.bixilon.kutil.concurrent.pool.DefaultThreadPool import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager -import de.bixilon.minosoft.data.accounts.types.MojangAccount +import de.bixilon.minosoft.data.accounts.types.mojang.MojangAccount import de.bixilon.minosoft.gui.eros.controller.JavaFXWindowController import de.bixilon.minosoft.gui.eros.main.account.AccountController import de.bixilon.minosoft.gui.eros.util.JavaFXUtil diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/main/account/add/OfflineAddController.kt b/src/main/java/de/bixilon/minosoft/gui/eros/main/account/add/OfflineAddController.kt index 63862e3dc..7859940b8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/main/account/add/OfflineAddController.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/main/account/add/OfflineAddController.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -14,7 +14,7 @@ package de.bixilon.minosoft.gui.eros.main.account.add import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager -import de.bixilon.minosoft.data.accounts.types.OfflineAccount +import de.bixilon.minosoft.data.accounts.types.offline.OfflineAccount import de.bixilon.minosoft.gui.eros.controller.JavaFXWindowController import de.bixilon.minosoft.gui.eros.main.account.AccountController import de.bixilon.minosoft.gui.eros.util.JavaFXUtil diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/main/play/server/ServerListController.kt b/src/main/java/de/bixilon/minosoft/gui/eros/main/play/server/ServerListController.kt index cae8253cf..9ecd9facc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/main/play/server/ServerListController.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/main/play/server/ServerListController.kt @@ -13,7 +13,6 @@ package de.bixilon.minosoft.gui.eros.main.play.server -import de.bixilon.kutil.concurrent.pool.DefaultThreadPool import de.bixilon.kutil.latch.CountUpAndDownLatch import de.bixilon.kutil.primitive.BooleanUtil.decide import de.bixilon.kutil.primitive.IntUtil.thousands @@ -126,46 +125,44 @@ class ServerListController : EmbeddedJavaFXController(), Refreshable { val ping = serverCard.ping val pingVersion = serverCard.ping.serverVersion ?: return Eros.mainErosController.verifyAccount { account -> - DefaultThreadPool += { - val connection = PlayConnection( - address = ping.tryAddress ?: DNSUtil.getServerAddress(server.address), - account = account, - version = serverCard.server.forcedVersion ?: pingVersion, - profiles = ConnectionProfiles(ErosProfileManager.selected.general.profileOverrides.toMutableMap().apply { putAll(server.profiles) }) - ) - account.connections[server] = connection - serverCard.connections += connection + val connection = PlayConnection( + address = ping.tryAddress ?: DNSUtil.getServerAddress(server.address), + account = account, + version = serverCard.server.forcedVersion ?: pingVersion, + profiles = ConnectionProfiles(ErosProfileManager.selected.general.profileOverrides.toMutableMap().apply { putAll(server.profiles) }) + ) + account.connections[server] = connection + serverCard.connections += connection - connection::state.observeFX(this) { - if (it.disconnected) { - account.connections -= server - serverCard.connections -= connection - } - JavaFXUtil.runLater { updateServer(server) } + connection::state.observeFX(this) { + if (it.disconnected) { + account.connections -= server + serverCard.connections -= connection } - - connection.registerEvent(JavaFXEventInvoker.of { event -> - KickDialog( - title = "minosoft:connection.kick.title".toResourceLocation(), - header = "minosoft:connection.kick.header".toResourceLocation(), - description = TranslatableComponents.CONNECTION_KICK_DESCRIPTION(server, account), - reason = event.reason, - ).show() - }) - connection.registerEvent(JavaFXEventInvoker.of { event -> - KickDialog( - title = "minosoft:connection.login_kick.title".toResourceLocation(), - header = "minosoft:connection.login_kick.header".toResourceLocation(), - description = TranslatableComponents.CONNECTION_LOGIN_KICK_DESCRIPTION(server, account), - reason = event.reason, - ).show() - }) - val latch = CountUpAndDownLatch(0) - val assetsDialog = VerifyAssetsDialog(latch = latch).apply { show() } - connection::state.observeFX(this) { if (it.disconnected) assetsDialog.close() } - ConnectingDialog(connection).show() - connection.connect(latch) + JavaFXUtil.runLater { updateServer(server) } } + + connection.registerEvent(JavaFXEventInvoker.of { event -> + KickDialog( + title = "minosoft:connection.kick.title".toResourceLocation(), + header = "minosoft:connection.kick.header".toResourceLocation(), + description = TranslatableComponents.CONNECTION_KICK_DESCRIPTION(server, account), + reason = event.reason, + ).show() + }) + connection.registerEvent(JavaFXEventInvoker.of { event -> + KickDialog( + title = "minosoft:connection.login_kick.title".toResourceLocation(), + header = "minosoft:connection.login_kick.header".toResourceLocation(), + description = TranslatableComponents.CONNECTION_LOGIN_KICK_DESCRIPTION(server, account), + reason = event.reason, + ).show() + }) + val latch = CountUpAndDownLatch(0) + val assetsDialog = VerifyAssetsDialog(latch = latch).apply { show() } + connection::state.observeFX(this) { if (it.disconnected) assetsDialog.close() } + ConnectingDialog(connection).show() + connection.connect(latch) } } diff --git a/src/main/java/de/bixilon/minosoft/util/account/microsoft/MicrosoftOAuthUtils.kt b/src/main/java/de/bixilon/minosoft/util/account/microsoft/MicrosoftOAuthUtils.kt index aa8a2d73f..df87b11c4 100644 --- a/src/main/java/de/bixilon/minosoft/util/account/microsoft/MicrosoftOAuthUtils.kt +++ b/src/main/java/de/bixilon/minosoft/util/account/microsoft/MicrosoftOAuthUtils.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -18,7 +18,7 @@ import de.bixilon.kutil.json.JsonUtil.asJsonList import de.bixilon.kutil.json.JsonUtil.asJsonObject import de.bixilon.kutil.primitive.LongUtil.toLong import de.bixilon.kutil.uuid.UUIDUtil.toUUID -import de.bixilon.minosoft.data.accounts.types.MicrosoftAccount +import de.bixilon.minosoft.data.accounts.types.microsoft.MicrosoftAccount import de.bixilon.minosoft.data.player.properties.PlayerProperties import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.account.AccountUtil @@ -53,7 +53,7 @@ object MicrosoftOAuthUtils { ) account.accessToken = accessToken - account.verify("") + account.check("") // client token does not exist for microsoft accounts Log.log(LogMessageType.AUTHENTICATION, LogLevels.INFO) { "Microsoft account login successful (uuid=${account.uuid})" } diff --git a/src/main/resources/assets/minosoft/language/en_us.lang b/src/main/resources/assets/minosoft/language/en_us.lang index 33f613553..def8598f2 100644 --- a/src/main/resources/assets/minosoft/language/en_us.lang +++ b/src/main/resources/assets/minosoft/language/en_us.lang @@ -84,7 +84,7 @@ minosoft:server_list.refresh.text2=information -minosoft:main.account.list.info.button.verify=Verify +minosoft:main.account.list.info.button.check=Check minosoft:main.account.list.info.button.use=Use minosoft:main.account.list.info.button.add=Add account minosoft:main.account.no_account_selected=No account selected @@ -92,6 +92,13 @@ minosoft:main.account.type.mojang=Mojang minosoft:main.account.type.microsoft=Microsoft minosoft:main.account.type.offline=Offline +minosoft:main.account.state.unchecked=Unchecked +minosoft:main.account.state.checking=Checking... +minosoft:main.account.state.refreshing=Refreshing... +minosoft:main.account.state.working=Working +minosoft:main.account.state.expired=Expired +minosoft:main.account.state.errored=Errored + minosoft:main.account.card.connection_count=%1$s connections