eros: mojang account adding

This commit is contained in:
Bixilon 2021-07-30 12:37:01 +02:00
parent 2451e4a5da
commit dc54c55aa1
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
8 changed files with 275 additions and 13 deletions

View File

@ -22,8 +22,10 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.gui.eros.controller.EmbeddedJavaFXController
import de.bixilon.minosoft.gui.eros.dialogs.SimpleErosConfirmationDialog
import de.bixilon.minosoft.gui.eros.main.account.add.MojangAddController
import de.bixilon.minosoft.gui.eros.main.account.add.OfflineAddController
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import de.bixilon.minosoft.util.KUtil.extend
import de.bixilon.minosoft.util.task.pool.DefaultThreadPool
import javafx.application.Platform
import javafx.fxml.FXML
@ -100,7 +102,7 @@ class AccountController : EmbeddedJavaFXController<Pane>() {
GridPane().let {
var row = 0
for ((key, property) in ACCOUNT_INFO_PROPERTIES) { // ToDo
for ((key, property) in ACCOUNT_INFO_PROPERTIES.extend(accountTypeListViewFX.selectionModel.selectedItem.additionalDetails)) { // ToDo
val propertyValue = property(account) ?: continue
it.add(Minosoft.LANGUAGE_MANAGER.translate(key).textFlow, 0, row)
@ -181,14 +183,18 @@ class AccountController : EmbeddedJavaFXController<Pane>() {
ErosAccountType<MojangAccount>(
resourceLocation = MojangAccount.RESOURCE_LOCATION,
translationKey = "minosoft:main.account.type.mojang".asResourceLocation(),
additionalDetails = listOf(
"minosoft:account.email".asResourceLocation() to { it.email },
"minosoft:account.uuid".asResourceLocation() to { it.uuid },
),
icon = FontAwesomeSolid.BUILDING,
addHandler = { TODO() }
addHandler = { MojangAddController(it).show() },
),
ErosAccountType<OfflineAccount>(
resourceLocation = OfflineAccount.RESOURCE_LOCATION,
translationKey = "minosoft:main.account.type.offline".asResourceLocation(),
icon = FontAwesomeSolid.MAP,
addHandler = { OfflineAddController(it).show() }
addHandler = { OfflineAddController(it).show() },
),
ErosAccountType<MicrosoftAccount>(
resourceLocation = MicrosoftAccount.RESOURCE_LOCATION,

View File

@ -23,6 +23,6 @@ data class ErosAccountType<T : Account>(
override val resourceLocation: ResourceLocation,
override val translationKey: ResourceLocation? = null,
val icon: Ikon,
val additionalDetails: Map<ResourceLocation, (account: T) -> Any?> = mapOf(),
val additionalDetails: List<Pair<ResourceLocation, (account: T) -> Any?>> = listOf(),
val addHandler: ((accountController: AccountController) -> Unit)? = null,
) : ResourceLocationAble, Translatable

View File

@ -0,0 +1,138 @@
/*
* Minosoft
* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.eros.main.account.add
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.accounts.types.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
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil.ctext
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil.placeholder
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil.text
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import de.bixilon.minosoft.util.KUtil.text
import de.bixilon.minosoft.util.task.pool.DefaultThreadPool
import javafx.application.Platform
import javafx.fxml.FXML
import javafx.scene.control.Button
import javafx.scene.control.PasswordField
import javafx.scene.control.TextField
import javafx.scene.text.TextFlow
import javafx.stage.Modality
class MojangAddController(
private val accountController: AccountController,
) : JavaFXWindowController() {
@FXML private lateinit var headerFX: TextFlow
@FXML private lateinit var descriptionFX: TextFlow
@FXML private lateinit var emailLabelFX: TextFlow
@FXML private lateinit var emailFX: TextField
@FXML private lateinit var passwordLabelFX: TextFlow
@FXML private lateinit var passwordFX: PasswordField
@FXML private lateinit var errorFX: TextFlow
@FXML private lateinit var loginButtonFX: Button
@FXML private lateinit var cancelButtonFX: Button
fun show() {
Platform.runLater {
JavaFXUtil.openModal(TITLE, LAYOUT, this, modality = Modality.APPLICATION_MODAL)
stage.show()
}
}
override fun init() {
super.init()
headerFX.text = HEADER
descriptionFX.text = DESCRIPTION
emailLabelFX.text = EMAIL_LABEL
emailFX.placeholder = EMAIL_PLACEHOLDER
passwordLabelFX.text = PASSWORD_LABEL
passwordFX.placeholder = PASSWORD_PLACEHOLDER
loginButtonFX.ctext = ADD_BUTTON
cancelButtonFX.ctext = CANCEL_BUTTON
errorFX.isVisible = false
emailFX.textProperty().addListener { _, _, _ ->
validate()
}
passwordFX.textProperty().addListener { _, _, _ ->
validate()
}
}
private fun validate() {
if (emailFX.text.isBlank()) {
loginButtonFX.isDisable = true
return
}
if (passwordFX.text.isEmpty()) {
loginButtonFX.isDisable = true
return
}
loginButtonFX.isDisable = false
}
@FXML
fun login() {
loginButtonFX.isDisable = true
errorFX.isVisible = false
DefaultThreadPool += {
try {
val account = MojangAccount.login(email = emailFX.text, password = passwordFX.text)
Minosoft.config.config.account.entries[account.id] = account
Minosoft.config.saveToFile()
Platform.runLater {
accountController.refreshList()
stage.hide()
}
} catch (exception: Exception) {
Platform.runLater {
exception.printStackTrace()
errorFX.text = exception.text
errorFX.isVisible = true
loginButtonFX.isDisable = false
}
}
}
}
@FXML
fun cancel() {
stage.hide()
}
companion object {
private val LAYOUT = "minosoft:eros/main/account/add/mojang.fxml".asResourceLocation()
private val TITLE = "minosoft:main.account.add.mojang.title".asResourceLocation()
private val HEADER = "minosoft:main.account.add.mojang.header".asResourceLocation()
private val DESCRIPTION = "minosoft:main.account.add.mojang.description".asResourceLocation()
private val EMAIL_LABEL = "minosoft:main.account.add.mojang.email.label".asResourceLocation()
private val EMAIL_PLACEHOLDER = "minosoft:main.account.add.mojang.email.placeholder".asResourceLocation()
private val PASSWORD_LABEL = "minosoft:main.account.add.mojang.password.label".asResourceLocation()
private val PASSWORD_PLACEHOLDER = "minosoft:main.account.add.mojang.password.placeholder".asResourceLocation()
private val ADD_BUTTON = "minosoft:main.account.add.mojang.add_button".asResourceLocation()
private val CANCEL_BUTTON = "minosoft:main.account.add.mojang.cancel_button".asResourceLocation()
}
}

View File

@ -15,9 +15,7 @@ package de.bixilon.minosoft.gui.eros.main.play.server.card
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.gui.eros.card.AbstractCard
import de.bixilon.minosoft.gui.eros.card.CardFactory
import de.bixilon.minosoft.gui.eros.modding.invoker.JavaFXEventInvoker
@ -28,7 +26,7 @@ import de.bixilon.minosoft.modding.event.events.connection.status.ServerStatusRe
import de.bixilon.minosoft.modding.event.events.connection.status.StatusConnectionStateChangeEvent
import de.bixilon.minosoft.modding.event.events.connection.status.StatusPongReceiveEvent
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import de.bixilon.minosoft.util.KUtil.realName
import de.bixilon.minosoft.util.KUtil.text
import de.bixilon.minosoft.util.KUtil.thousands
import javafx.fxml.FXML
import javafx.scene.image.Image
@ -108,7 +106,7 @@ class ServerCardController : AbstractCard<ServerCard>() {
if (lastServerCard != card) {
return@of
}
motdFX.text = TextComponent(it.exception::class.java.realName + ": " + it.exception.message).color(ChatColors.DARK_RED)
motdFX.text = it.exception.text
}
card.pongInvoker = JavaFXEventInvoker.of<StatusPongReceiveEvent> {

View File

@ -215,15 +215,26 @@ object KUtil {
return map.toMap()
}
fun <V> Collection<Any>.extend(vararg values: Any): List<V> {
fun <V> Collection<V>.extend(vararg values: Any): List<V> {
val list: MutableList<V> = mutableListOf()
for (value in this) {
list += value.unsafeCast<V>()
}
fun add(value: Any?) {
when (value) {
is Collection<*> -> {
for (element in value) {
add(element)
}
}
else -> list += value.unsafeCast<V>()
}
}
for (value in values) {
list += value.unsafeCast<V>()
add(value)
}
return list.toList()
}
@ -338,6 +349,9 @@ object KUtil {
}
}
val Throwable.text: TextComponent
get() = TextComponent(this::class.java.realName + ": " + this.message).color(ChatColors.DARK_RED)
fun Throwable.toStackTrace(): String {
val stringWriter = StringWriter()
this.printStackTrace(PrintWriter(stringWriter))

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<HBox xmlns:fx="http://javafx.com/fxml/1" fx:id="root" prefHeight="240.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/16"> <!--fx:controller="de.bixilon.minosoft.gui.eros.main.account.add.OfflineAddController" -->
<GridPane HBox.hgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS"/>
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="NEVER"/>
<RowConstraints vgrow="ALWAYS"/>
<RowConstraints vgrow="NEVER"/>
</rowConstraints>
<TextFlow fx:id="headerFX">
<GridPane.margin>
<Insets bottom="10.0" left="5.0" right="5.0" top="10.0"/>
</GridPane.margin>
<Text text="Add mojang account"/>
</TextFlow>
<TextFlow fx:id="descriptionFX" GridPane.rowIndex="1">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
<GridPane.margin>
<Insets bottom="15.0" right="5.0" top="5.0"/>
</GridPane.margin>
<Text text="Please enter your mojang email (or for legacy accounts their username) and your password to continue"/>
</TextFlow>
<GridPane GridPane.rowIndex="2">
<columnConstraints>
<ColumnConstraints hgrow="NEVER"/>
<ColumnConstraints hgrow="ALWAYS"/>
</columnConstraints>
<rowConstraints>
<RowConstraints valignment="CENTER" vgrow="NEVER"/>
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="CENTER" vgrow="NEVER"/>
</rowConstraints>
<TextFlow fx:id="emailLabelFX">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="30.0" top="5.0"/>
</GridPane.margin>
<Text text="Email"/>
</TextFlow>
<TextField fx:id="emailFX" promptText="user@example.org" GridPane.columnIndex="1">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</GridPane.margin>
</TextField>
<TextFlow fx:id="passwordLabelFX" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="30.0" top="5.0"/>
</GridPane.margin>
<Text text="Password"/>
</TextFlow>
<PasswordField fx:id="passwordFX" promptText="********" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</GridPane.margin>
</PasswordField>
</GridPane>
<GridPane GridPane.rowIndex="5">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS"/>
<ColumnConstraints hgrow="NEVER"/>
<ColumnConstraints hgrow="NEVER"/>
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="NEVER"/>
</rowConstraints>
<Button fx:id="cancelButtonFX" onAction="#cancel" text="Cancel" GridPane.columnIndex="1">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</GridPane.margin>
</Button>
<Button fx:id="loginButtonFX" disable="true" onAction="#login" text="Login" GridPane.columnIndex="2">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</GridPane.margin>
</Button>
</GridPane>
<TextFlow fx:id="errorFX" GridPane.rowIndex="3">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</GridPane.margin>
<Text text="Unknown exception: This is just a dummy"/>
</TextFlow>
</GridPane>
</HBox>

View File

@ -6,7 +6,7 @@
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<HBox xmlns:fx="http://javafx.com/fxml/1" fx:id="root" prefHeight="200.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/16"> <!--fx:controller="de.bixilon.minosoft.gui.eros.main.account.add.OfflineAddController" -->
<HBox xmlns:fx="http://javafx.com/fxml/1" fx:id="root" prefHeight="200.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/16"> <!--fx:controller="de.bixilon.minosoft.gui.eros.main.account.add.MojangAddController" -->
<GridPane HBox.hgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS"/>
@ -47,7 +47,7 @@
</GridPane.margin>
<Text text="Username"/>
</TextFlow>
<TextField fx:id="usernameFX" promptText="Username" GridPane.columnIndex="1">
<TextField fx:id="usernameFX" promptText="Testuser" GridPane.columnIndex="1">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</GridPane.margin>

View File

@ -70,6 +70,16 @@ minosoft:main.account.add.offline.title=Add offline account
minosoft:main.account.add.offline.header=Add offline account
minosoft:main.account.add.offline.description=Please enter the username of the account you want to add.
minosoft:main.account.add.offline.username.label=Username
minosoft:main.account.add.offline.username.placeholder=Username
minosoft:main.account.add.offline.username.placeholder=Test user
minosoft:main.account.add.offline.add_button=Add
minosoft:main.account.add.offline.cancel_button=Cancel
minosoft:main.account.add.mojang.title=Add mojang account
minosoft:main.account.add.mojang.header=Add mojang account
minosoft:main.account.add.mojang.description=Please enter your mojang email (or for legacy accounts their username) and your password to continue
minosoft:main.account.add.mojang.email.label=E-mail
minosoft:main.account.add.mojang.email.placeholder=user@example.org
minosoft:main.account.add.mojang.password.label=Password
minosoft:main.account.add.mojang.password.placeholder=********
minosoft:main.account.add.mojang.add_button=Add
minosoft:main.account.add.mojang.cancel_button=Cancel