183 lines
7.7 KiB
Kotlin
183 lines
7.7 KiB
Kotlin
package io.gitlab.jfronny.inceptum.gtk.window.create
|
|
|
|
import io.gitlab.jfronny.commons.StringFormatter
|
|
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.KDropDown
|
|
import io.gitlab.jfronny.inceptum.gtk.control.KEntry
|
|
import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant
|
|
import io.gitlab.jfronny.inceptum.gtk.schedule
|
|
import io.gitlab.jfronny.inceptum.gtk.util.I18n
|
|
import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray
|
|
import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog
|
|
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi
|
|
import io.gitlab.jfronny.inceptum.launcher.api.McApi
|
|
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo
|
|
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionsListInfo
|
|
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceNameTool
|
|
import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo
|
|
import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo
|
|
import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps
|
|
import org.gnome.glib.GLib
|
|
import org.gnome.gtk.*
|
|
import java.io.IOException
|
|
|
|
|
|
class NewInstanceWindow(app: Application) : KAssistant(app) {
|
|
companion object {
|
|
private val VERSIONS = McApi.getVersions()
|
|
}
|
|
|
|
init {
|
|
var gameVersion: VersionsListInfo? = null
|
|
var useFabric = false
|
|
var fabricVersion: FabricVersionLoaderInfo? = null
|
|
var name = "New Instance"
|
|
|
|
var failureMessage = "Unknown error, please look at the log!"
|
|
var isFailure = false
|
|
|
|
page("Welcome", AssistantPageType.INTRO) {
|
|
append(Label("This assistant will guide you through the process of setting up a Minecraft instance.\nTo begin, please choose the game version you want to use"))
|
|
|
|
val versions = VERSIONS.versions.stream()
|
|
.filter { InceptumConfig.snapshots || it.type == "release" }
|
|
.toTypedArray()
|
|
val def = versions.withIndex().firstOrNull { it.value.id == VERSIONS.latest.release }?.index ?: 0
|
|
gameVersion = versions[def]
|
|
|
|
append(KDropDown(versions, { it.id }, def).apply {
|
|
onChange { gameVersion = versions[it] }
|
|
})
|
|
|
|
setComplete(true)
|
|
}
|
|
page("Loader", AssistantPageType.CONTENT) {
|
|
append(Label("Select a mod loader if you want to use mods in this instance. This can be changed later."))
|
|
var lastGameVersion: VersionsListInfo? = null
|
|
var versions = arrayOf<FabricVersionLoaderInfo>()
|
|
var def = 0
|
|
|
|
val none = CheckButton.newWithLabel("None")
|
|
val fabric = CheckButton.newWithLabel("Fabric")
|
|
none.onToggled { useFabric = false }
|
|
none.onToggled { useFabric = true }
|
|
fabric.setGroup(none)
|
|
append(none)
|
|
val fabricVersionDropdown = KDropDown(versions, { it.loader.version }, def)
|
|
fabricVersionDropdown.onChange { fabricVersion = versions[it] }
|
|
append(Box(Orientation.HORIZONTAL, 8).apply {
|
|
append(fabric)
|
|
append(fabricVersionDropdown)
|
|
})
|
|
|
|
onOpen {
|
|
if (lastGameVersion == null || lastGameVersion != gameVersion) {
|
|
versions = FabricMetaApi.getLoaderVersions(gameVersion!!).toTypedArray()
|
|
def = versions.withIndex().firstOrNull { it.value.loader.stable }?.index ?: 0
|
|
fabricVersionDropdown.updateOptions(versions, def)
|
|
lastGameVersion = gameVersion
|
|
none.active = true
|
|
fabric.active = false
|
|
useFabric = false
|
|
}
|
|
|
|
if (versions.isEmpty()) {
|
|
none.active = true
|
|
fabric.active = false
|
|
useFabric = false
|
|
fabric.sensitive = false
|
|
}
|
|
}
|
|
|
|
setComplete(true)
|
|
}
|
|
page("Name", AssistantPageType.CONTENT) {
|
|
append(Label(I18n["instance.settings.general.name.placeholder"]))
|
|
val entry = KEntry(name)
|
|
entry.placeholderText = I18n["instance.settings.general.name.placeholder"]
|
|
entry.valign
|
|
entry.onChange { name = InstanceNameTool.getNextValid(it) }
|
|
append(entry)
|
|
onOpen {
|
|
name = InstanceNameTool.getDefaultName(gameVersion!!.id, useFabric)
|
|
entry.text = name
|
|
}
|
|
|
|
setComplete(true)
|
|
}
|
|
page("Creating", AssistantPageType.PROGRESS) {
|
|
append(Label("Creating Instance"))
|
|
val progress = ProgressBar()
|
|
append(progress)
|
|
val stage = Label("")
|
|
append(stage)
|
|
onOpen {
|
|
commit()
|
|
val pState = Steps.createProcessState()
|
|
val state = SetupStepInfo(
|
|
McApi.getVersionInfo(gameVersion),
|
|
if (useFabric) LoaderInfo(fabricVersion!!.loader) else LoaderInfo.NONE,
|
|
name,
|
|
pState
|
|
)
|
|
var finished = false
|
|
var cachedState: ProcessStateWatcherDialog.State? = null
|
|
addTickCallback { widget, _ ->
|
|
if (finished) return@addTickCallback GLib.SOURCE_REMOVE
|
|
val nc = ProcessStateWatcherDialog.State(pState)
|
|
if (nc != cachedState) {
|
|
cachedState = nc
|
|
stage.setMarkup(cachedState!!.msg)
|
|
progress.fraction = cachedState!!.progress.coerceAtMost(1f).toDouble()
|
|
widget.queueDraw()
|
|
}
|
|
GLib.SOURCE_CONTINUE
|
|
}
|
|
onClose { pState.cancel() }
|
|
onCancel { pState.cancel() }
|
|
pState.updateStep("Starting install process")
|
|
Thread {
|
|
try {
|
|
for (step in Steps.STEPS) {
|
|
if (state.isCancelled) {
|
|
try {
|
|
JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name))
|
|
} catch (e: IOException) {
|
|
Utils.LOGGER.error("Could not delete instance dir", e)
|
|
}
|
|
return@Thread
|
|
}
|
|
pState.incrementStep(step.name)
|
|
step.execute(state)
|
|
}
|
|
} catch (e: Throwable) {
|
|
pState.cancel()
|
|
Utils.LOGGER.error("Could not create instance")
|
|
failureMessage = StringFormatter.toString(e)
|
|
isFailure = true
|
|
} finally {
|
|
finished = true
|
|
schedule { setComplete(true) }
|
|
schedule { nextPage() }
|
|
}
|
|
}.start()
|
|
}
|
|
}
|
|
page("Done", AssistantPageType.SUMMARY) {
|
|
val status = Label("")
|
|
onOpen {
|
|
if (isFailure) {
|
|
status.setMarkup("Something went wrong while creating the instance.\n\n$failureMessage")
|
|
} else {
|
|
status.setMarkup("The instance was successfully created. You can now launch it using the main menu")
|
|
}
|
|
}
|
|
|
|
setComplete(true)
|
|
}
|
|
}
|
|
}
|