diff --git a/src/main/java/de/bixilon/minosoft/config/profile/ConnectionProfiles.kt b/src/main/java/de/bixilon/minosoft/config/profile/ConnectionProfiles.kt index 8668d3076..f3361fcf5 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/ConnectionProfiles.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/ConnectionProfiles.kt @@ -26,7 +26,7 @@ import de.bixilon.minosoft.data.registries.ResourceLocation class ConnectionProfiles( overrides: Map = mapOf(), - val eros: ErosProfile = overrides[ErosProfileManager.namespace]?.let { return@let ErosProfileManager.profiles[it] } ?: ErosProfileManager.selected, + val eros: ErosProfile = ErosProfileManager.selected, val particle: ParticleProfile = overrides[ParticleProfileManager.namespace]?.let { return@let ParticleProfileManager.profiles[it] } ?: ParticleProfileManager.selected, val audio: AudioProfile = overrides[AudioProfileManager.namespace]?.let { return@let AudioProfileManager.profiles[it] } ?: AudioProfileManager.selected, val entity: EntityProfile = overrides[EntityProfileManager.namespace]?.let { return@let EntityProfileManager.profiles[it] } ?: EntityProfileManager.selected, diff --git a/src/main/java/de/bixilon/minosoft/config/profile/GlobalProfileManager.kt b/src/main/java/de/bixilon/minosoft/config/profile/GlobalProfileManager.kt index ddfca0d75..96ddf2704 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/GlobalProfileManager.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/GlobalProfileManager.kt @@ -29,29 +29,35 @@ import de.bixilon.minosoft.util.task.time.TimeWorkerTask import java.io.File object GlobalProfileManager { - val DEFAULT_MANAGERS: List> = listOf( - ErosProfileManager, - ParticleProfileManager, - AudioProfileManager, - EntityProfileManager, - ResourcesProfileManager, - AccountProfileManager, - RenderingProfileManager, - BlockProfileManager, - ConnectionProfileManager, - HUDProfileManager, - ControlsProfileManager, - OtherProfileManager, - ) + val DEFAULT_MANAGERS: Map> private val SELECTED_PROFILES_TYPE: MapType = Jackson.MAPPER.typeFactory.constructMapType(HashMap::class.java, ResourceLocation::class.java, String::class.java) val CLASS_MAPPING: Map, ProfileManager<*>> init { + val map: MutableMap> = mutableMapOf() val classMapping: MutableMap, ProfileManager<*>> = mutableMapOf() - for (manager in DEFAULT_MANAGERS) { + val list = listOf( + ErosProfileManager, + ParticleProfileManager, + AudioProfileManager, + EntityProfileManager, + ResourcesProfileManager, + AccountProfileManager, + RenderingProfileManager, + BlockProfileManager, + ConnectionProfileManager, + HUDProfileManager, + ControlsProfileManager, + OtherProfileManager, + ) + + for (manager in list) { + map.put(manager.namespace, manager)?.let { throw IllegalStateException("Duplicate profile namespace: ${manager.namespace}") } classMapping[manager.profileClass] = manager } - CLASS_MAPPING = classMapping.toMap() + + this.DEFAULT_MANAGERS = map.toMap() + this.CLASS_MAPPING = classMapping.toMap() } private var initialized = false @@ -100,15 +106,15 @@ object GlobalProfileManager { throw IllegalStateException("Already initialized!") } loadSelectedProfiles() - for (manager in DEFAULT_MANAGERS) { - manager.load(selectedProfiles[manager.namespace]) + for ((namespace, manager) in DEFAULT_MANAGERS) { + manager.load(selectedProfiles[namespace]) } loading = false if (selectedProfilesChanges) { saveSelectedProfiles() } TimeWorker += TimeWorkerTask(1000) { - for (manager in DEFAULT_MANAGERS) { + for (manager in DEFAULT_MANAGERS.values) { for (profile in manager.profiles.values) { if (profile.saved) { continue @@ -136,4 +142,6 @@ object GlobalProfileManager { saveSelectedProfiles() } } + + operator fun get(resourceLocation: ResourceLocation): ProfileManager? = DEFAULT_MANAGERS[resourceLocation] } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/ProfileManager.kt b/src/main/java/de/bixilon/minosoft/config/profile/ProfileManager.kt index 229197d83..fdd6b1848 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/ProfileManager.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/ProfileManager.kt @@ -36,6 +36,8 @@ interface ProfileManager { val latestVersion: Int val saveLock: ReentrantLock val profileClass: Class + val profileSelectable: Boolean + get() = true val profiles: HashBiMap var selected: T @@ -99,10 +101,19 @@ interface ProfileManager { fun createDefaultProfile(name: String = DEFAULT_PROFILE_NAME): T - fun initDefaultProfile() { + fun initDefaultProfile(): T { + profiles[DEFAULT_PROFILE_NAME]?.let { return it } val profile = createDefaultProfile() + add(profile) this.selected = profile - saveAsync(profile) + return profile + } + + fun add(profile: T) { + save(profile) + if (RunConfiguration.PROFILES_HOT_RELOADING) { + watchProfile(DEFAULT_PROFILE_NAME, File(DEFAULT_PROFILE_NAME)) + } } @@ -150,12 +161,13 @@ interface ProfileManager { throw IOException("${baseDirectory.path} is not an directory!") } val profileNames = baseDirectory.list { current, name -> File(current, name).isDirectory }?.toMutableSet() ?: throw IOException("Can not create a list of profiles in ${baseDirectory.path}") - if (selected == null || profileNames.isEmpty()) { - profileNames += DEFAULT_PROFILE_NAME - } + for (profileName in profileNames) { val path = getPath(profileName, baseDirectory) val (saveFile, json) = readAndMigrate(path) + if (json == null) { + continue + } val profile: T try { profile = load(profileName, json) @@ -171,7 +183,7 @@ interface ProfileManager { } } - profiles[selected]?.let { this.selected = it } ?: selectDefault() + profiles[selected]?.let { this.selected = it } ?: initDefaultProfile() Log.log(LogMessageType.PROFILES, LogLevels.VERBOSE) { "Loaded ${profiles.size} $namespace profiles!" } } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/ListDelegateProfile.kt b/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/ListDelegateProfile.kt index ae5181b55..3e8cb8f47 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/ListDelegateProfile.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/ListDelegateProfile.kt @@ -33,7 +33,9 @@ open class ListDelegateProfile( if (StaticConfiguration.LOG_DELEGATE) { Log.log(LogMessageType.PROFILES, LogLevels.VERBOSE) { "Changed list entry $it in profile $profileName" } } - profileManager.profiles[profileName]?.saved = false + if (!profile.reloading) { + profileManager.profiles[profileName]?.saved = false + } ProfilesDelegateManager.onChange(profile, property.javaField ?: return@ListChangeListener, null, it) }) @@ -44,5 +46,8 @@ open class ListDelegateProfile( override fun set(value: MutableList) { this.value = FXCollections.synchronizedObservableList(FXCollections.observableList(value)) initListener() + if (!profile.reloading) { + profileManager.profiles[profileName]?.saved = false + } } } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/MapDelegateProfile.kt b/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/MapDelegateProfile.kt index 7499f0f04..b8bf68bf1 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/MapDelegateProfile.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/MapDelegateProfile.kt @@ -37,7 +37,9 @@ open class MapDelegateProfile( if (StaticConfiguration.LOG_DELEGATE) { Log.log(LogMessageType.PROFILES, LogLevels.VERBOSE) { "Changed map entry $it in profile $profileName" } } - profileManager.profiles[profileName]?.saved = false + if (!profile.reloading) { + profileManager.profiles[profileName]?.saved = false + } ProfilesDelegateManager.onChange(profile, property.javaField ?: return@MapChangeListener, null, it) }) @@ -54,6 +56,7 @@ open class MapDelegateProfile( if (!profileInitialized || profile.initializing || !profile.reloading) { this.value = FXCollections.synchronizedObservableMap(FXCollections.observableMap(value)) initListener() + profileManager.profiles[profileName]?.saved = false return } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/SetDelegateProfile.kt b/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/SetDelegateProfile.kt index 610dd1196..9fe504675 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/SetDelegateProfile.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/delegate/delegate/entry/SetDelegateProfile.kt @@ -34,7 +34,9 @@ open class SetDelegateProfile( if (StaticConfiguration.LOG_DELEGATE) { Log.log(LogMessageType.PROFILES, LogLevels.VERBOSE) { "Changed set entry $it in profile $profileName" } } - profileManager.profiles[profileName]?.saved = false + if (!profile.reloading) { + profileManager.profiles[profileName]?.saved = false + } ProfilesDelegateManager.onChange(profile, property.javaField ?: return@SetChangeListener, null, it) }) @@ -45,5 +47,8 @@ open class SetDelegateProfile( override fun set(value: MutableSet) { this.value = FXCollections.synchronizedObservableSet(FXCollections.observableSet(value)) initListener() + if (!profile.reloading) { + profileManager.profiles[profileName]?.saved = false + } } } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/ErosProfileManager.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/ErosProfileManager.kt index 9d46eeee9..180df3f48 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/ErosProfileManager.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/ErosProfileManager.kt @@ -22,6 +22,8 @@ object ErosProfileManager : ProfileManager { override val latestVersion = 1 override val saveLock = ReentrantLock() override val profileClass = ErosProfile::class.java + override val profileSelectable: Boolean + get() = false override var currentLoadingPath: String? = null diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/server/entries/Server.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/server/entries/Server.kt index c4da25bcf..3d989bdac 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/server/entries/Server.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/server/entries/Server.kt @@ -28,6 +28,7 @@ class Server( address: String, name: ChatComponent = ChatComponent.of(address), forcedVersion: Version? = null, + profiles: MutableMap = mutableMapOf(), ) { /** * Server-address as string. May contain the port @@ -44,7 +45,7 @@ class Server( * Changing profiles requires reconnect * If profile is unset, defaults to eros global profiles */ - var profiles: MutableMap by mapDelegate() + var profiles: MutableMap by mapDelegate(profiles) @get:JsonProperty("forced_version") @get:JsonInclude(JsonInclude.Include.NON_NULL) diff --git a/src/main/java/de/bixilon/minosoft/data/language/Language.kt b/src/main/java/de/bixilon/minosoft/data/language/Language.kt index 7b9cafd34..dddd9bec7 100644 --- a/src/main/java/de/bixilon/minosoft/data/language/Language.kt +++ b/src/main/java/de/bixilon/minosoft/data/language/Language.kt @@ -27,7 +27,13 @@ class Language( } override fun translate(key: ResourceLocation?, parent: TextComponent?, vararg data: Any?): ChatComponent { - val placeholder = this.data[key] ?: return ChatComponent.of(key.toString() + "->" + data.toString(), null, parent) + val placeholder = this.data[key] + if (placeholder == null) { + if (data.isEmpty()) { + return ChatComponent.of(key.toString(), null, parent) + } + return ChatComponent.of(key.toString() + "->" + data.contentToString(), null, parent) + } val ret = BaseComponent() diff --git a/src/main/java/de/bixilon/minosoft/data/language/LanguageManager.kt b/src/main/java/de/bixilon/minosoft/data/language/LanguageManager.kt index 2fced27ba..d4f88e222 100644 --- a/src/main/java/de/bixilon/minosoft/data/language/LanguageManager.kt +++ b/src/main/java/de/bixilon/minosoft/data/language/LanguageManager.kt @@ -46,7 +46,11 @@ class LanguageManager( } return language.translate(key, parent, *data) } - return ChatComponent.of("$key: ${data.contentToString()}") + + if (data.isEmpty()) { + return ChatComponent.of(key.toString(), null, parent) + } + return ChatComponent.of(key.toString() + "->" + data.contentToString(), null, parent) } companion object { diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/dialog/ProfileSelectDialog.kt b/src/main/java/de/bixilon/minosoft/gui/eros/dialog/ProfileSelectDialog.kt new file mode 100644 index 000000000..ecf6495a9 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/eros/dialog/ProfileSelectDialog.kt @@ -0,0 +1,228 @@ +/* + * 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.eros.dialog + +import de.bixilon.minosoft.Minosoft +import de.bixilon.minosoft.config.profile.GlobalProfileManager +import de.bixilon.minosoft.data.registries.ResourceLocation +import de.bixilon.minosoft.gui.eros.controller.DialogController +import de.bixilon.minosoft.gui.eros.util.JavaFXUtil +import de.bixilon.minosoft.gui.eros.util.JavaFXUtil.text +import de.bixilon.minosoft.util.KUtil.toResourceLocation +import javafx.fxml.FXML +import javafx.scene.control.* +import javafx.scene.input.KeyCode +import javafx.scene.input.KeyEvent +import javafx.scene.text.TextFlow +import javafx.stage.Modality + +class ProfileSelectDialog( + profiles: MutableMap, + private val onConfirm: (Map) -> Unit, + private val onCancel: () -> Unit, +) : DialogController() { + private val profiles = profiles.toMutableMap() + @FXML private lateinit var headerFX: TextFlow + + @FXML private lateinit var profilesFX: TableView + @FXML private lateinit var typeColumnFX: TableColumn + @FXML private lateinit var valueColumnFX: TableColumn + + @FXML private lateinit var createProfileButtonFX: Button + @FXML private lateinit var cancelButtonFX: Button + @FXML private lateinit var confirmButtonFX: Button + + fun show() { + JavaFXUtil.runLater { + JavaFXUtil.openModal(TITLE, LAYOUT, this, Modality.APPLICATION_MODAL) + stage.show() + } + } + + override fun init() { + headerFX.text = Minosoft.LANGUAGE_MANAGER.translate(HEADER) + + typeColumnFX.setCellFactory { ResourceLocationCell() } + valueColumnFX.setCellFactory { ProfileCell() } + + for ((type, profile) in profiles) { + profilesFX.items += ProfileEntry(type, profile) + } + profilesFX.items += ProfileEntry(null, "") + } + + override fun postInit() { + super.postInit() + + stage.setOnCloseRequest { cancel() } + + stage.scene.root.addEventFilter(KeyEvent.KEY_PRESSED) { + if (it.code == KeyCode.ENTER) { + cancel() + } + } + } + + @FXML + fun newProfile() { + } + + @FXML + fun confirm() { + stage.close() + val profiles: MutableMap = mutableMapOf() + for ((resourceLocation, profile) in this.profilesFX.items) { + if (profile.isBlank()) { + continue + } + profiles[resourceLocation ?: continue] = profile + } + onConfirm(profiles) + } + + @FXML + fun cancel() { + onCancel() + stage.close() + } + + + companion object { + private val LAYOUT = "minosoft:eros/dialog/profile_select.fxml".toResourceLocation() + private val TITLE = "minosoft:general.dialog.profile_select.title".toResourceLocation() + private val HEADER = "minosoft:general.dialog.profile_select.header".toResourceLocation() + } + + private data class ProfileEntry( + var resourceLocation: ResourceLocation?, + var profile: String = "", + ) + + private abstract inner class EditTableCell : TableCell() { + protected val label = Label() + protected val comboBox = ComboBox() + + init { + graphic = label + selectedProperty().addListener { _, _, _ -> cancelEdit() } + comboBox.selectionModel.selectedItemProperty().addListener { _, _, selected -> + commitEdit(selected) + } + } + + override fun updateItem(item: T, empty: Boolean) { + super.updateItem(item, empty) + graphic = label + isVisible = !empty + if (empty) { + return + } + update(tableRow.item) + } + + abstract fun update(entry: ProfileEntry) + abstract fun updateItem(item: T) + + override fun startEdit() { + super.startEdit() + graphic = comboBox + comboBox.show() + } + + override fun cancelEdit() { + super.cancelEdit() + graphic = label + } + + override fun commitEdit(newValue: T?) { + super.commitEdit(newValue) + updateItem(newValue ?: return) + graphic = label + } + } + + private inner class ResourceLocationCell : EditTableCell() { + init { + comboBox.selectionModel.selectedItemProperty().addListener { _, previous, selected -> + if (previous == null && selected != null) { + tableView.items += ProfileEntry(null, "") + tableView.refresh() + } + } + } + + override fun startEdit() { + val thisNamespace = tableRow.item.resourceLocation + if (comboBox.items.isEmpty()) { + val alreadyDisplayed: MutableSet = mutableSetOf() + for (entry in tableView.items) { + alreadyDisplayed += entry.resourceLocation ?: continue + } + for ((namespace, profileManager) in GlobalProfileManager.DEFAULT_MANAGERS) { + if (!profileManager.profileSelectable || (thisNamespace != namespace && namespace in alreadyDisplayed)) { + continue + } + comboBox.items += namespace + } + } + comboBox.selectionModel.select(thisNamespace) + super.startEdit() + } + + + override fun update(entry: ProfileEntry) = updateItem(entry.resourceLocation) + + + override fun updateItem(item: ResourceLocation?) { + label.text = item?.toString() ?: "Double click to select" + tableRow.item.resourceLocation = item + } + } + + private inner class ProfileCell : EditTableCell() { + + override fun startEdit() { + comboBox.items.clear() + comboBox.setCellFactory { + object : ListCell() { + override fun updateItem(item: String?, empty: Boolean) { + super.updateItem(item, empty) + text = if (item?.isBlank() == true && !empty) { + "" + } else { + item.toString() + } + } + } + } + comboBox.items += "" + GlobalProfileManager[tableRow.item.resourceLocation ?: return]?.let { + comboBox.items += it.profiles.keys + } + comboBox.selectionModel.select(this.tableRow.item.profile) + super.startEdit() + } + + override fun update(entry: ProfileEntry) = updateItem(entry.profile) + + override fun updateItem(item: String) { + if (item.isBlank()) { + label.text = "" + } else { + label.text = item + } + tableRow.item.profile = item + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/dialog/SimpleErosConfirmationDialog.kt b/src/main/java/de/bixilon/minosoft/gui/eros/dialog/SimpleErosConfirmationDialog.kt index 63ae32dee..7addea2d2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/dialog/SimpleErosConfirmationDialog.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/dialog/SimpleErosConfirmationDialog.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.eros.dialog import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.TranslatableComponents import de.bixilon.minosoft.gui.eros.controller.DialogController import de.bixilon.minosoft.gui.eros.util.JavaFXUtil import de.bixilon.minosoft.gui.eros.util.JavaFXUtil.text @@ -31,8 +32,8 @@ class SimpleErosConfirmationDialog( val title: Any = DEFAULT_TITLE_TEXT, val header: Any = DEFAULT_TITLE_TEXT, val description: Any? = null, - val cancelButtonText: Any = DEFAULT_CANCEL_TEXT, - val confirmButtonText: Any = DEFAULT_CONFIRM_TEXT, + val cancelButtonText: Any = TranslatableComponents.GENERAL_CANCEL, + val confirmButtonText: Any = TranslatableComponents.GENERAL_CONFIRM, val onCancel: () -> Unit = {}, val onConfirm: () -> Unit, val modality: Modality = Modality.WINDOW_MODAL, @@ -86,7 +87,5 @@ class SimpleErosConfirmationDialog( companion object { private val LAYOUT = "minosoft:eros/dialog/simple_confirmation.fxml".toResourceLocation() private val DEFAULT_TITLE_TEXT = "minosoft:general.dialog.are_you_sure".toResourceLocation() - private val DEFAULT_CANCEL_TEXT = "minosoft:general.cancel".toResourceLocation() - private val DEFAULT_CONFIRM_TEXT = "minosoft:general.confirm".toResourceLocation() } } diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/dialog/UpdateServerDialog.kt b/src/main/java/de/bixilon/minosoft/gui/eros/dialog/UpdateServerDialog.kt index 63a3226e2..470c0d12e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/dialog/UpdateServerDialog.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/dialog/UpdateServerDialog.kt @@ -15,8 +15,10 @@ package de.bixilon.minosoft.gui.eros.dialog import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.config.profile.delegate.watcher.SimpleProfileDelegateLWatcher.Companion.profileWatchFX +import de.bixilon.minosoft.config.profile.profiles.audio.AudioProfileManager import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager import de.bixilon.minosoft.config.profile.profiles.eros.server.entries.Server +import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.versions.Version import de.bixilon.minosoft.data.registries.versions.VersionTypes import de.bixilon.minosoft.data.registries.versions.Versions @@ -41,7 +43,7 @@ import javafx.scene.text.TextFlow */ class UpdateServerDialog( private val server: Server? = null, - val onUpdate: (name: String, address: String, forcedVersion: Version?) -> Unit, + val onUpdate: (name: String, address: String, forcedVersion: Version?, profiles: Map) -> Unit, ) : DialogController() { @FXML private lateinit var descriptionFX: TextFlow @FXML private lateinit var serverNameLabelFX: TextFlow @@ -54,10 +56,18 @@ class UpdateServerDialog( @FXML private lateinit var showReleasesFX: CheckBox @FXML private lateinit var showSnapshotsFX: CheckBox + @FXML private lateinit var profilesLabelFX: TextFlow + @FXML private lateinit var openProfileSelectDialogButtonFX: Button + @FXML private lateinit var updateServerButtonFX: Button @FXML private lateinit var cancelButtonFX: Button + private var profileSelectDialog: ProfileSelectDialog? = null + + private var profiles = server?.profiles ?: mutableMapOf(AudioProfileManager.namespace to "Default") // ToDo + + fun show() { JavaFXUtil.runLater { JavaFXUtil.openModal((server == null).decide(ADD_TITLE, EDIT_TITLE), LAYOUT, this) @@ -95,6 +105,8 @@ class UpdateServerDialog( serverAddressLabelFX.text = SERVER_ADDRESS_LABEL serverAddressFX.placeholder = SERVER_ADDRESS_PLACEHOLDER forcedVersionLabelFX.text = FORCED_VERSION_LABEL + profilesLabelFX.text = PROFILES_LABEL + openProfileSelectDialogButtonFX.ctext = PROFILES_OPEN_PROFILE_SELECT cancelButtonFX.ctext = TranslatableComponents.GENERAL_CANCEL @@ -176,7 +188,7 @@ class UpdateServerDialog( return } val forcedVersion = (forcedVersionFX.selectionModel.selectedItem == Versions.AUTOMATIC_VERSION).decide(null) { forcedVersionFX.selectionModel.selectedItem } - DefaultThreadPool += { onUpdate(serverNameFX.text.isBlank().decide({ serverAddressFX.text.toString() }, { serverNameFX.text.trim() }), serverAddressFX.text, forcedVersion) } + DefaultThreadPool += { onUpdate(serverNameFX.text.isBlank().decide({ serverAddressFX.text.toString() }, { serverNameFX.text.trim() }), serverAddressFX.text, forcedVersion, profiles) } stage.close() } @@ -185,6 +197,23 @@ class UpdateServerDialog( stage.close() } + @FXML + fun openProfileSelectDialog() { + profileSelectDialog?.let { it.show(); return } + val dialog = ProfileSelectDialog( + profiles = profiles, + onConfirm = { + this.profiles = it.toMutableMap() + this.profileSelectDialog = null + }, + onCancel = { + this.profileSelectDialog = null + }, + ) + this.profileSelectDialog = dialog + dialog.show() + } + companion object { private val LAYOUT = "minosoft:eros/dialog/update_server.fxml".toResourceLocation() @@ -197,6 +226,8 @@ class UpdateServerDialog( private val VERSION_AUTOMATIC = "minosoft:update_server.forced_version.automatic".toResourceLocation() private val SHOW_RELEASES = "minosoft:update_server.forced_version.releases".toResourceLocation() private val SHOW_SNAPSHOTS = "minosoft:update_server.forced_version.snapshots".toResourceLocation() + private val PROFILES_LABEL = "minosoft:update_server.profiles.label".toResourceLocation() + private val PROFILES_OPEN_PROFILE_SELECT = "minosoft:update_server.profiles.open_select_dialog".toResourceLocation() private val ADD_TITLE = "minosoft:update_server.add.title".toResourceLocation() private val ADD_DESCRIPTION = "minosoft:update_server.add.description".toResourceLocation() 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 df6b8ca82..005defe69 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 @@ -263,9 +263,10 @@ class ServerListController : EmbeddedJavaFXController(), Refreshable { it.add(Button("Edit").apply { setOnAction { val server = serverCard.server - UpdateServerDialog(server = server, onUpdate = { name, address, forcedVersion -> + UpdateServerDialog(server = server, onUpdate = { name, address, forcedVersion, profiles -> server.name = ChatComponent.of(name) server.forcedVersion = forcedVersion + server.profiles = profiles.toMutableMap() if (server.address != address) { serverCard.rawFavicon = null @@ -344,8 +345,8 @@ class ServerListController : EmbeddedJavaFXController(), Refreshable { @FXML fun addServer() { - UpdateServerDialog(onUpdate = { name, address, forcedVersion -> - serverType!!.servers += Server(name = ChatComponent.of(name), address = address, forcedVersion = forcedVersion) + UpdateServerDialog(onUpdate = { name, address, forcedVersion, profiles -> + serverType!!.servers += Server(name = ChatComponent.of(name), address = address, forcedVersion = forcedVersion, profiles = profiles.toMutableMap()) }).show() } diff --git a/src/main/java/de/bixilon/minosoft/util/KUtil.kt b/src/main/java/de/bixilon/minosoft/util/KUtil.kt index f208ea71b..c9d648a94 100644 --- a/src/main/java/de/bixilon/minosoft/util/KUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/KUtil.kt @@ -384,8 +384,8 @@ object KUtil { fun Any?.toLong(): Long { return when (this) { is Long -> this - is Number -> this.toLong() is Int -> this.toLong() + is Number -> this.toLong() else -> TODO() } } diff --git a/src/main/java/de/bixilon/minosoft/util/http/HTTP2.kt b/src/main/java/de/bixilon/minosoft/util/http/HTTP2.kt index 6f40983bc..11add9114 100644 --- a/src/main/java/de/bixilon/minosoft/util/http/HTTP2.kt +++ b/src/main/java/de/bixilon/minosoft/util/http/HTTP2.kt @@ -24,7 +24,6 @@ import java.net.http.HttpResponse object HTTP2 { - fun Map.headers(): Array { val headers: MutableList = mutableListOf() diff --git a/src/main/resources/assets/minosoft/eros/crash/crash_screen.fxml b/src/main/resources/assets/minosoft/eros/crash/crash_screen.fxml index 00ceea79c..ad11248df 100644 --- a/src/main/resources/assets/minosoft/eros/crash/crash_screen.fxml +++ b/src/main/resources/assets/minosoft/eros/crash/crash_screen.fxml @@ -56,7 +56,7 @@ - - + + + + + diff --git a/src/main/resources/assets/minosoft/eros/dialog/simple_confirmation.fxml b/src/main/resources/assets/minosoft/eros/dialog/simple_confirmation.fxml index a08f128a1..27af5b0a0 100644 --- a/src/main/resources/assets/minosoft/eros/dialog/simple_confirmation.fxml +++ b/src/main/resources/assets/minosoft/eros/dialog/simple_confirmation.fxml @@ -65,12 +65,12 @@ - - @@ -103,7 +119,7 @@ -