User: strokkur24
Date: 11 Jan 26 21:39
Revision: 83a5cc6cead962b3becede3f8f1559802d2f043a
Summary:
feat: add automatic Paper version fetching
TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=10392&personal=false
Index: .editorconfig
===================================================================
--- .editorconfig (revision 64b86aa7bdd5a928c4ab568848df7963e70251e4)
+++ .editorconfig (revision 83a5cc6cead962b3becede3f8f1559802d2f043a)
@@ -1,6 +1,10 @@
+root = true
+
[*.{kt,kts}]
+indent_size = 4
+indent_style = space
-max_line_length=120
+max_line_length = 120
-ij_kotlin_imports_layout=*
+ij_kotlin_imports_layout = *
ij_kotlin_name_count_to_use_star_import = 2147483647
ij_kotlin_name_count_to_use_star_import_for_members = 2147483647
insert_final_newline = true
Index: src/main/kotlin/creator/custom/types/PaperVersionCreatorProperty.kt
===================================================================
--- src/main/kotlin/creator/custom/types/PaperVersionCreatorProperty.kt (revision 83a5cc6cead962b3becede3f8f1559802d2f043a)
+++ src/main/kotlin/creator/custom/types/PaperVersionCreatorProperty.kt (revision 83a5cc6cead962b3becede3f8f1559802d2f043a)
@@ -0,0 +1,82 @@
+/*
+ * Minecraft Development for IntelliJ
+ *
+ * https://mcdev.io/
+ *
+ * Copyright (C) 2025 minecraft-dev
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, version 3.0 only.
+ *
+ * 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 Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.demonwav.mcdev.creator.custom.types
+
+import com.demonwav.mcdev.creator.custom.CreatorContext
+import com.demonwav.mcdev.creator.custom.TemplatePropertyDescriptor
+import com.demonwav.mcdev.util.MinecraftVersions
+import com.demonwav.mcdev.util.SemanticVersion
+import com.intellij.ui.dsl.builder.Panel
+import io.ktor.client.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.jsonArray
+import kotlinx.serialization.json.jsonObject
+import kotlinx.serialization.json.jsonPrimitive
+
+open class PaperVersionCreatorProperty(
+ descriptor: TemplatePropertyDescriptor,
+ context: CreatorContext
+) : SemanticVersionCreatorProperty(descriptor, context) {
+
+ @OptIn(DelicateCoroutinesApi::class)
+ companion object {
+ val paperVersions: Map? = loadPaperVersions()?.associate { it to it.toString() }
+
+ fun loadPaperVersions(): List? {
+ val client = HttpClient()
+ return runBlocking {
+ val response = client.get("https://fill.papermc.io/v3/projects/paper")
+ if (response.status.isSuccess()) {
+ val element = Json.parseToJsonElement(response.bodyAsText())
+ return@runBlocking element.jsonObject["versions"]?.jsonObject?.values
+ ?.asSequence()
+ ?.flatMap { it.jsonArray }
+ ?.map { it.jsonPrimitive.content }
+ ?.mapNotNull { SemanticVersion.tryParse(it) }
+ // only release versions
+ ?.filter { ver -> ver.parts.all { it is SemanticVersion.Companion.VersionPart.ReleasePart } }
+ // nothing lower than 1.18.2 should be selectable
+ ?.filter { it >= MinecraftVersions.MC1_18_2 }
+ ?.toList()
+ ?.sortedDescending()
+ } else {
+ return@runBlocking null
+ }
+ }
+ }
+ }
+
+ override fun buildUi(panel: Panel) {
+ super.buildDropdownMenu(panel, paperVersions)
+ }
+
+ class Factory : CreatorPropertyFactory {
+ override fun create(
+ descriptor: TemplatePropertyDescriptor,
+ context: CreatorContext
+ ): CreatorProperty<*> = PaperVersionCreatorProperty(descriptor, context)
+ }
+}
Index: src/main/kotlin/creator/custom/types/SimpleCreatorProperty.kt
===================================================================
--- src/main/kotlin/creator/custom/types/SimpleCreatorProperty.kt (revision 64b86aa7bdd5a928c4ab568848df7963e70251e4)
+++ src/main/kotlin/creator/custom/types/SimpleCreatorProperty.kt (revision 83a5cc6cead962b3becede3f8f1559802d2f043a)
@@ -38,7 +38,7 @@
valueType: Class
) : CreatorProperty(descriptor, context, valueType) {
- private val options: Map? = makeOptionsList()
+ val options: Map? = makeOptionsList()
private fun makeOptionsList(): Map? {
val map = when (val options = descriptor.options) {
@@ -78,37 +78,41 @@
override val graphProperty: GraphProperty by lazy { graph.property(defaultValue) }
- override fun buildUi(panel: Panel) {
- if (isDropdown) {
+ protected fun buildDropdownMenu(panel: Panel, options: Map?) {
- if (graphProperty.get() !in options!!.keys) {
- graphProperty.set(defaultValue)
- }
+ if (graphProperty.get() !in options!!.keys) {
+ graphProperty.set(defaultValue)
+ }
- panel.row(descriptor.translatedLabel) {
- if (descriptor.forceDropdown == true) {
- comboBox(options.keys, DropdownAutoRenderer())
- .bindItem(graphProperty)
- .enabled(descriptor.editable != false)
- .also {
- val component = it.component
- ComboboxSpeedSearch.installOn(component)
- val validation =
- BuiltinValidations.isAnyOf(component::getSelectedItem, options.keys, component)
- it.validationOnInput(validation)
- it.validationOnApply(validation)
- }
- } else {
- segmentedButton(options.keys) { text = options[it] ?: it.toString() }
- .bind(graphProperty)
- .enabled(descriptor.editable != false)
- .maxButtonsCount(4)
- .validation {
- val message = MCDevBundle("creator.validation.invalid_option")
- addInputRule(message) { it.selectedItem !in options.keys }
- addApplyRule(message) { it.selectedItem !in options.keys }
- }
- }
- }.propertyVisibility()
+ panel.row(descriptor.translatedLabel) {
+ if (descriptor.forceDropdown == true) {
+ comboBox(options.keys, DropdownAutoRenderer())
+ .bindItem(graphProperty)
+ .enabled(descriptor.editable != false)
+ .also {
+ val component = it.component
+ ComboboxSpeedSearch.installOn(component)
+ val validation =
+ BuiltinValidations.isAnyOf(component::getSelectedItem, options.keys, component)
+ it.validationOnInput(validation)
+ it.validationOnApply(validation)
+ }
+ } else {
+ segmentedButton(options.keys) { text = options[it] ?: it.toString() }
+ .bind(graphProperty)
+ .enabled(descriptor.editable != false)
+ .maxButtonsCount(4)
+ .validation {
+ val message = MCDevBundle("creator.validation.invalid_option")
+ addInputRule(message) { it.selectedItem !in options.keys }
+ addApplyRule(message) { it.selectedItem !in options.keys }
+ }
+ }
+ }.propertyVisibility()
+ }
+
+ override fun buildUi(panel: Panel) {
+ if (isDropdown) {
+ buildDropdownMenu(panel, options)
} else {
buildSimpleUi(panel)
}
@@ -125,7 +129,7 @@
isSelected: Boolean,
cellHasFocus: Boolean
): Component {
- val label = options!![value] ?: value.toString()
+ val label = options?.get(value) ?: value.toString()
return super.getListCellRendererComponent(list, label, index, isSelected, cellHasFocus)
}
}
Index: src/main/resources/META-INF/plugin.xml
===================================================================
--- src/main/resources/META-INF/plugin.xml (revision 64b86aa7bdd5a928c4ab568848df7963e70251e4)
+++ src/main/resources/META-INF/plugin.xml (revision 83a5cc6cead962b3becede3f8f1559802d2f043a)
@@ -214,6 +214,9 @@
+