244 lines
12 KiB
Kotlin
244 lines
12 KiB
Kotlin
package io.gitlab.jfronny.inceptum.gtk.window.settings.instance
|
|
|
|
import io.github.jwharm.javagi.base.GErrorException
|
|
import io.gitlab.jfronny.commons.ArgumentsTokenizer
|
|
import io.gitlab.jfronny.commons.io.JFiles
|
|
import io.gitlab.jfronny.inceptum.common.InceptumConfig
|
|
import io.gitlab.jfronny.inceptum.common.MetaHolder
|
|
import io.gitlab.jfronny.inceptum.common.Utils
|
|
import io.gitlab.jfronny.inceptum.gtk.control.ILabel
|
|
import io.gitlab.jfronny.inceptum.gtk.control.settings.SectionedSettingsTab
|
|
import io.gitlab.jfronny.inceptum.gtk.util.*
|
|
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi
|
|
import io.gitlab.jfronny.inceptum.launcher.api.McApi
|
|
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList
|
|
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceNameTool
|
|
import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser
|
|
import org.gnome.gio.File
|
|
import org.gnome.gobject.BindingFlags
|
|
import org.gnome.gtk.*
|
|
import java.io.IOException
|
|
import java.nio.file.Files
|
|
import java.nio.file.Path
|
|
import java.util.*
|
|
|
|
class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab<InstanceSettingsWindow>(window) {
|
|
companion object {
|
|
private val VERSIONS = McApi.getVersions()
|
|
}
|
|
|
|
init {
|
|
val instance = window.instance
|
|
section(null) {
|
|
row("instance.settings.general.name", "instance.settings.general.name.placeholder") {
|
|
val apply = Button.newWithLabel(I18n["instance.settings.apply"])
|
|
val entry = setEntry(instance.name) { s: String -> apply.sensitive = s != instance.name }
|
|
entry.placeholderText = I18n["instance.settings.general.name.placeholder"]
|
|
apply.valign = Align.CENTER
|
|
apply.onClicked {
|
|
try {
|
|
val newPath = MetaHolder.INSTANCE_DIR.resolve(InstanceNameTool.getNextValid(entry.text))
|
|
Files.move(instance.path, newPath)
|
|
window.close()
|
|
InstanceSettingsWindow(window.application, InstanceList.read(newPath)).visible = true
|
|
} catch (e: IOException) {
|
|
showError("Could not rename", e)
|
|
}
|
|
}
|
|
apply.sensitive = false
|
|
append(apply)
|
|
}
|
|
}
|
|
section("instance.settings.general.game") {
|
|
run {
|
|
var fabricEnabled: Switch? = null
|
|
var versionChanged: (() -> Unit)? = null
|
|
var fabricVersion: DropDown? = null
|
|
var defaultFabric: String? = null
|
|
var fabricVersions: Array<String>? = null
|
|
|
|
val versions = VERSIONS.versions.stream()
|
|
.filter { InceptumConfig.snapshots || it.type == "release" }
|
|
.map { it.id }
|
|
.toTypedArray()
|
|
val def = versions.withIndex().firstOrNull { it.value == instance.gameVersion }?.index ?: 0
|
|
|
|
row("instance.settings.general.game.version", "instance.settings.general.game.version.subtitle") {
|
|
setDropdown(versions, def) { i ->
|
|
instance.meta.gameVersion = if (instance.isFabric) GameVersionParser.createVersionWithFabric(
|
|
versions[i], instance.loaderVersion
|
|
) else versions[i]
|
|
instance.writeMeta()
|
|
versionChanged!!()
|
|
}.enableSearch = true
|
|
}
|
|
|
|
val fabricRow = row("instance.settings.general.game.fabric.enabled", "instance.settings.general.game.fabric.enabled.subtitle")
|
|
val loaderRow = row("instance.settings.general.game.fabric.version", "instance.settings.general.game.fabric.version.subtitle")
|
|
|
|
loaderRow.visible = instance.isFabric
|
|
fabricEnabled = fabricRow.setSwitch(instance.isFabric) { bl: Boolean ->
|
|
if (bl) {
|
|
if (fabricVersions != null && fabricVersions!!.isNotEmpty() && defaultFabric != null) {
|
|
instance.meta.gameVersion =
|
|
GameVersionParser.createVersionWithFabric(instance.gameVersion, defaultFabric)
|
|
instance.writeMeta()
|
|
} else {
|
|
fabricEnabled!!.active = false
|
|
}
|
|
} else {
|
|
instance.meta.gameVersion = instance.gameVersion
|
|
instance.writeMeta()
|
|
}
|
|
}
|
|
fabricEnabled.bindProperty("active", loaderRow, "visible", BindingFlags.DEFAULT)
|
|
|
|
versionChanged = {
|
|
val ver = VERSIONS.versions.stream()
|
|
.filter { it.id == instance.gameVersion }
|
|
.findFirst()
|
|
.map { FabricMetaApi.getLoaderVersions(it) }
|
|
.map { it.toTypedArray() }
|
|
defaultFabric = if (instance.isFabric) instance.loaderVersion else ver
|
|
.map { Arrays.stream(it) }
|
|
.map { it.filter { l -> l.loader.stable } }
|
|
.flatMap { it.findFirst() }
|
|
.map { it.loader.version }
|
|
.orElse(null)
|
|
fabricVersions = ver.map { Arrays.stream(it) }
|
|
.map { it.map { l -> l.loader.version }.toTypedArray() }
|
|
.orElse(null)
|
|
if (fabricVersions == null || fabricVersions!!.isEmpty()) {
|
|
fabricEnabled.active = false
|
|
} else if (fabricVersion != null) fabricVersion!!.model = StringList(fabricVersions)
|
|
}
|
|
versionChanged()
|
|
fabricVersion =
|
|
loaderRow.setDropdown(fabricVersions!!, fabricVersions!!.indexOf(defaultFabric)) { i: Int ->
|
|
instance.meta.gameVersion =
|
|
if (i == -1) instance.gameVersion
|
|
else GameVersionParser.createVersionWithFabric(instance.gameVersion, fabricVersions!![i])
|
|
instance.writeMeta()
|
|
}
|
|
fabricVersion.enableSearch = true
|
|
}
|
|
row("instance.settings.general.game.java", "instance.settings.general.game.java.subtitle") {
|
|
val entry = setEntry(instance.meta.java) { s: String ->
|
|
instance.meta.java = s.ifBlank { null }
|
|
instance.writeMeta()
|
|
}
|
|
val btn = Button.newFromIconName("folder-symbolic")
|
|
btn.valign = Align.CENTER
|
|
btn.onClicked {
|
|
val dialog = FileChooserNative(
|
|
I18n["instance.settings.general.game.java"],
|
|
window,
|
|
FileChooserAction.OPEN,
|
|
"_" + I18n["select"],
|
|
"_" + I18n["cancel"]
|
|
)
|
|
if (instance.meta.java != null && Files.exists(Path.of(instance.meta.java))) {
|
|
try {
|
|
dialog.setFile(File.newForPath(instance.meta.java))
|
|
} catch (e: GErrorException) {
|
|
Log.error("Could not set starting point", e)
|
|
}
|
|
}
|
|
dialog.onResponse { responseId: Int ->
|
|
if (responseId == ResponseType.ACCEPT.value) {
|
|
val file = dialog.file!!.path
|
|
if (file != null) entry.text = file
|
|
}
|
|
}
|
|
dialog.show()
|
|
}
|
|
append(btn)
|
|
}
|
|
row("instance.settings.general.game.memory.min", "instance.settings.general.game.memory.min.subtitle") {
|
|
setSpinButton(
|
|
(if (instance.meta.minMem == null) 512 else instance.meta.minMem / Memory.MB).toDouble(),
|
|
512.0,
|
|
Memory.maxMBForInstance.toDouble(),
|
|
128.0
|
|
) { v: Double ->
|
|
instance.meta.minMem = (v * Memory.MB).toLong()
|
|
if (instance.meta.minMem == Memory.GB / 2) instance.meta.minMem = null
|
|
instance.writeMeta()
|
|
}
|
|
}
|
|
row("instance.settings.general.game.memory.max", "instance.settings.general.game.memory.max.subtitle") {
|
|
setSpinButton(
|
|
(if (instance.meta.maxMem == null) 1024 else instance.meta.maxMem / Memory.MB).toDouble(),
|
|
1024.0,
|
|
Memory.maxMBForInstance.toDouble(),
|
|
128.0
|
|
) { v: Double ->
|
|
instance.meta.maxMem = (v * Memory.MB).toLong()
|
|
if (instance.meta.maxMem == Memory.GB) instance.meta.maxMem = null
|
|
instance.writeMeta()
|
|
}
|
|
}
|
|
}
|
|
section("instance.settings.general.args") {
|
|
instance.meta.checkArguments()
|
|
row("instance.settings.general.args.jvm", "instance.settings.general.args.jvm.subtitle") {
|
|
setEntry(ArgumentsTokenizer.join(instance.meta.arguments.jvm.toTypedArray())) {
|
|
instance.meta.arguments = instance.meta.arguments.withJvm(listOf(*ArgumentsTokenizer.tokenize(it)))
|
|
instance.writeMeta()
|
|
}
|
|
}
|
|
row("instance.settings.general.args.client", "instance.settings.general.args.client.subtitle") {
|
|
setEntry(ArgumentsTokenizer.join(instance.meta.arguments.client.toTypedArray())) {
|
|
instance.meta.arguments = instance.meta.arguments.withClient(listOf(*ArgumentsTokenizer.tokenize(it)))
|
|
instance.writeMeta()
|
|
}
|
|
}
|
|
row("instance.settings.general.args.server", "instance.settings.general.args.server.subtitle") {
|
|
setEntry(ArgumentsTokenizer.join(instance.meta.arguments.server.toTypedArray())) {
|
|
instance.meta.arguments = instance.meta.arguments.withServer(listOf(*ArgumentsTokenizer.tokenize(it)))
|
|
instance.writeMeta()
|
|
}
|
|
}
|
|
}
|
|
section("instance.settings.general.manage") {
|
|
row("instance.delete", "instance.delete.subtitle") {
|
|
setButton("instance.delete") {
|
|
val dialog = MessageDialog(
|
|
window,
|
|
DialogFlags.MODAL.or(DialogFlags.DESTROY_WITH_PARENT),
|
|
MessageType.WARNING,
|
|
ButtonsType.OK_CANCEL,
|
|
null
|
|
)
|
|
dialog.markup = I18n["instance.delete.confirm"]
|
|
dialog.title = I18n["instance.delete.confirm.title"]
|
|
dialog.onResponse { responseId: Int ->
|
|
when (ResponseType.of(responseId)) {
|
|
ResponseType.OK -> {
|
|
try {
|
|
JFiles.deleteRecursive(instance.path)
|
|
dialog.close()
|
|
window.close()
|
|
} catch (e: IOException) {
|
|
showError(I18n["instance.delete.fail"], e)
|
|
}
|
|
dialog.close()
|
|
}
|
|
|
|
ResponseType.CLOSE, ResponseType.CANCEL -> dialog.close()
|
|
ResponseType.DELETE_EVENT -> dialog.destroy()
|
|
else -> {}
|
|
}
|
|
}
|
|
dialog.show()
|
|
}
|
|
}
|
|
row("instance.directory", "instance.directory.subtitle") {
|
|
setButton("instance.directory") { Utils.openFile(instance.path.toFile()) }
|
|
}
|
|
}
|
|
val timestamp = if (instance.meta.lastLaunched == null) 0 else instance.meta.lastLaunched
|
|
append(ILabel("instance.settings.general.last-launched", ILabel.Mode.SUBTITLE, Date(timestamp * 1000).toString()))
|
|
}
|
|
}
|