diff --git a/gradle.properties b/gradle.properties
index 47bd83b85..b46609575 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -14,7 +14,7 @@ kotlin.code.style=official
ideaVersion = 2021.1
ideaVersionName = 2021.1
-coreVersion = 1.5.13
+coreVersion = 1.5.14
downloadIdeaSources = true
pluginTomlVersion = 0.2.144.3766-211
diff --git a/readme.md b/readme.md
index 6137ee639..48bf6557b 100644
--- a/readme.md
+++ b/readme.md
@@ -32,7 +32,7 @@ Minecraft Development for IntelliJ
-Info and Documentation [](https://plugins.jetbrains.com/plugin/8327)
+Info and Documentation [](https://plugins.jetbrains.com/plugin/8327)
----------------------
diff --git a/src/main/kotlin/creator/BuildSystemWizardStep.kt b/src/main/kotlin/creator/BuildSystemWizardStep.kt
index d7bf772ea..10333e57b 100644
--- a/src/main/kotlin/creator/BuildSystemWizardStep.kt
+++ b/src/main/kotlin/creator/BuildSystemWizardStep.kt
@@ -35,6 +35,7 @@ class BuildSystemWizardStep(private val creator: MinecraftProjectCreator) : Modu
override fun getComponent() = panel
override fun updateStep() {
+ val previousBuildSystem = buildSystemBox.selectedItem
buildSystemBox.removeAllItems()
buildSystemBox.isEnabled = true
@@ -46,12 +47,18 @@ class BuildSystemWizardStep(private val creator: MinecraftProjectCreator) : Modu
buildSystemBox.addItem(type)
}
- buildSystemBox.selectedIndex = 0
if (buildSystemBox.itemCount == 1) {
buildSystemBox.isEnabled = false
return
}
+ if (previousBuildSystem != null) {
+ buildSystemBox.selectedItem = previousBuildSystem
+ return
+ }
+
+ buildSystemBox.selectedIndex = 0
+
// We prefer Gradle, so if it's included, choose it
// If Gradle is not included, luck of the draw
if (creator.configs.any { it.preferredBuildSystem == BuildSystemType.GRADLE }) {
diff --git a/src/main/kotlin/creator/MinecraftModuleBuilder.kt b/src/main/kotlin/creator/MinecraftModuleBuilder.kt
index 1f8bfd18c..c3de8405b 100644
--- a/src/main/kotlin/creator/MinecraftModuleBuilder.kt
+++ b/src/main/kotlin/creator/MinecraftModuleBuilder.kt
@@ -32,6 +32,7 @@ import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.roots.ui.configuration.ModulesProvider
import com.intellij.openapi.startup.StartupManager
import com.intellij.openapi.util.io.FileUtil
+import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import java.nio.file.Files
@@ -103,7 +104,7 @@ class MinecraftModuleBuilder : JavaModuleBuilder() {
wizardContext: WizardContext,
modulesProvider: ModulesProvider
): Array {
- return arrayOf(
+ val baseSteps = arrayOf(
BuildSystemWizardStep(creator),
BukkitProjectSettingsWizard(creator),
SpongeProjectSettingsWizard(creator),
@@ -113,6 +114,10 @@ class MinecraftModuleBuilder : JavaModuleBuilder() {
VelocityProjectSettingsWizard(creator),
BungeeCordProjectSettingsWizard(creator)
)
+ if (Registry.`is`("mcdev.wizard.finalizer")) {
+ return baseSteps + ProjectSetupFinalizerWizardStep(creator, wizardContext)
+ }
+ return baseSteps
}
override fun getCustomOptionsStep(context: WizardContext?, parentDisposable: Disposable?) =
diff --git a/src/main/kotlin/creator/MinecraftProjectCreator.kt b/src/main/kotlin/creator/MinecraftProjectCreator.kt
index 14624d600..7ffc5556a 100644
--- a/src/main/kotlin/creator/MinecraftProjectCreator.kt
+++ b/src/main/kotlin/creator/MinecraftProjectCreator.kt
@@ -16,6 +16,7 @@ import com.demonwav.mcdev.util.invokeAndWait
import com.demonwav.mcdev.util.invokeLater
import com.demonwav.mcdev.util.virtualFileOrError
import com.intellij.openapi.module.Module
+import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
@@ -159,6 +160,10 @@ class MinecraftProjectCreator {
VfsUtil.markDirtyAndRefresh(false, true, true, root.virtualFileOrError)
}
} catch (e: Exception) {
+ if (e is ProcessCanceledException || e.cause is ProcessCanceledException) {
+ // Do not log PCE. The second condition is there because LaterInvocator wraps PCEs in RuntimeExceptions
+ return
+ }
val workLogText = buildString {
appendLine("Build steps completed:")
for (workLogStep in workLog) {
diff --git a/src/main/kotlin/creator/PlatformVersion.kt b/src/main/kotlin/creator/PlatformVersion.kt
index e17bf630c..754de5020 100644
--- a/src/main/kotlin/creator/PlatformVersion.kt
+++ b/src/main/kotlin/creator/PlatformVersion.kt
@@ -14,12 +14,16 @@ import com.demonwav.mcdev.platform.PlatformType
import com.demonwav.mcdev.util.ProxyHttpConnectionFactory
import com.demonwav.mcdev.util.fromJson
import com.google.gson.Gson
+import com.intellij.openapi.diagnostic.Attachment
+import com.intellij.openapi.diagnostic.Logger
import java.io.IOException
import javax.swing.JComboBox
private const val cloudflareBaseUrl = "https://minecraftdev.org/versions/"
private const val githubBaseUrl = "https://raw.githubusercontent.com/minecraft-dev/minecraftdev.org/master/versions/"
+val PLATFORM_VERSION_LOGGER = Logger.getInstance("MDev.PlatformVersion")
+
fun getVersionSelector(type: PlatformType): PlatformVersion {
val versionJson = type.versionJson ?: throw UnsupportedOperationException("Incorrect platform type: $type")
return getVersionJson(versionJson)
@@ -27,7 +31,14 @@ fun getVersionSelector(type: PlatformType): PlatformVersion {
inline fun getVersionJson(path: String): T {
val text = getText(path)
- return Gson().fromJson(text)
+ try {
+ return Gson().fromJson(text)
+ } catch (e: Exception) {
+ val attachment = Attachment("JSON Document", text)
+ attachment.isIncluded = true
+ PLATFORM_VERSION_LOGGER.error("Failed to parse JSON document from '$path'", e, attachment)
+ throw e
+ }
}
fun getText(path: String): String {
@@ -35,8 +46,14 @@ fun getText(path: String): String {
// attempt cloudflare
doCall(cloudflareBaseUrl + path)
} catch (e: IOException) {
+ PLATFORM_VERSION_LOGGER.warn("Failed to reach cloudflare URL ${cloudflareBaseUrl + path}", e)
// if that fails, attempt github
- doCall(githubBaseUrl + path)
+ try {
+ doCall(githubBaseUrl + path)
+ } catch (e: IOException) {
+ PLATFORM_VERSION_LOGGER.warn("Failed to reach fallback GitHub URL ${githubBaseUrl + path}", e)
+ throw e
+ }
}
}
diff --git a/src/main/kotlin/creator/ProjectConfig.kt b/src/main/kotlin/creator/ProjectConfig.kt
index 2b77ca839..e3d33470c 100644
--- a/src/main/kotlin/creator/ProjectConfig.kt
+++ b/src/main/kotlin/creator/ProjectConfig.kt
@@ -13,6 +13,7 @@ package com.demonwav.mcdev.creator
import com.demonwav.mcdev.creator.buildsystem.BuildSystemType
import com.demonwav.mcdev.platform.PlatformType
import com.intellij.util.containers.isNullOrEmpty
+import com.intellij.util.lang.JavaVersion
private val bracketRegex = Regex("[\\[\\]]")
private val commaRegex = Regex("\\s*,\\s*")
@@ -37,6 +38,8 @@ abstract class ProjectConfig {
var description: String? = null
fun hasDescription() = description?.isNotBlank() == true
+ abstract val javaVersion: JavaVersion
+
protected fun commaSplit(string: String): List {
return if (!string.isBlank()) {
string.trim().replace(bracketRegex, "").split(commaRegex).toList()
diff --git a/src/main/kotlin/creator/ProjectSetupFinalizerWizardStep.kt b/src/main/kotlin/creator/ProjectSetupFinalizerWizardStep.kt
new file mode 100644
index 000000000..547b7dce6
--- /dev/null
+++ b/src/main/kotlin/creator/ProjectSetupFinalizerWizardStep.kt
@@ -0,0 +1,300 @@
+/*
+ * Minecraft Dev for IntelliJ
+ *
+ * https://minecraftdev.org
+ *
+ * Copyright (c) 2021 minecraft-dev
+ *
+ * MIT License
+ */
+
+package com.demonwav.mcdev.creator
+
+import com.demonwav.mcdev.creator.buildsystem.gradle.GradleBuildSystem
+import com.demonwav.mcdev.creator.buildsystem.gradle.GradleCreator
+import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
+import com.demonwav.mcdev.util.until
+import com.intellij.ide.util.projectWizard.ModuleWizardStep
+import com.intellij.ide.util.projectWizard.WizardContext
+import com.intellij.openapi.observable.properties.GraphPropertyImpl.Companion.graphProperty
+import com.intellij.openapi.observable.properties.PropertyGraph
+import com.intellij.openapi.projectRoots.JavaSdk
+import com.intellij.openapi.projectRoots.JavaSdkVersion
+import com.intellij.openapi.projectRoots.Sdk
+import com.intellij.openapi.roots.ui.configuration.JdkComboBox
+import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel
+import com.intellij.openapi.ui.MultiLineLabelUI
+import com.intellij.ui.SortedComboBoxModel
+import com.intellij.ui.components.Label
+import com.intellij.ui.layout.Row
+import com.intellij.ui.layout.RowBuilder
+import com.intellij.ui.layout.panel
+import com.intellij.util.ui.UIUtil
+import javax.swing.JComponent
+
+class ProjectSetupFinalizerWizardStep(
+ val creator: MinecraftProjectCreator,
+ val context: WizardContext
+) : ModuleWizardStep() {
+
+ private val finalizers: List =
+ listOf(JdkProjectSetupFinalizer(), GradleProjectSetupFinalizer())
+ private val finalizersWithRow: MutableMap = linkedMapOf()
+ private val applicableFinalizers: MutableSet = linkedSetOf()
+
+ private val panel by lazy {
+ panel {
+ row(Label("Project finalization")) {}
+ finalizers.forEach { finalizer ->
+ val row = titledRow("${finalizer.title}") {
+ with(finalizer) {
+ buildComponent(creator, context)
+ }
+ }
+ finalizersWithRow[finalizer] = row
+ }
+ }
+ }
+
+ override fun isStepVisible(): Boolean = true
+
+ override fun getComponent(): JComponent = panel
+
+ override fun updateStep() {
+ applicableFinalizers.clear()
+ for ((finalizer, row) in finalizersWithRow) {
+ if (finalizer.isApplicable(creator, context)) {
+ applicableFinalizers.add(finalizer)
+ finalizer.validateConfigs(creator, context)
+ row.visible = true
+ } else {
+ row.visible = false
+ }
+ }
+ }
+
+ override fun updateDataModel(): Unit = applicableFinalizers.forEach { it.apply(creator, context) }
+
+ override fun validate(): Boolean = applicableFinalizers.all { it.validateChanges(creator, context) }
+}
+
+/**
+ * Used to adjust project configurations before project creation begins, or simply display a summary.
+ * Can also block project creation if problems are found with the configurations (such as version incompatibilities.)
+ */
+interface ProjectSetupFinalizer {
+
+ val title: String
+
+ /**
+ * Builds the component to display in a titled row ([title])
+ */
+ fun RowBuilder.buildComponent(creator: MinecraftProjectCreator, context: WizardContext)
+
+ /**
+ * Whether this finalizer makes sense to appear in the given context.
+ *
+ * If `false` is returned the component of this finalizer will not be shown, and [validateConfigs],
+ * [validateChanges] and [apply] won't be called until it returns `true`.
+ *
+ * @return `true` if this finalizer applies to the given context, `false` otherwise
+ */
+ fun isApplicable(creator: MinecraftProjectCreator, context: WizardContext): Boolean
+
+ /**
+ * Validates the existing [ProjectConfig]s of this wizard. You can also initialize
+ *
+ * Finalizers are expected to display errors in their own component.
+ *
+ * @return `true` if the project setup is valid, `false` otherwise.
+ */
+ fun validateConfigs(creator: MinecraftProjectCreator, context: WizardContext): Boolean
+
+ /**
+ * Validates the changes made in this finalizer's component.
+ *
+ * @return `true` if the changes are valid, `false` otherwise.
+ */
+ fun validateChanges(creator: MinecraftProjectCreator, context: WizardContext): Boolean
+
+ /**
+ * Applies the changes validated in [validateChanges] to the project configuration.
+ */
+ fun apply(creator: MinecraftProjectCreator, context: WizardContext)
+}
+
+class JdkProjectSetupFinalizer : ProjectSetupFinalizer {
+
+ private val errorLabel = Label("", fontColor = UIUtil.FontColor.BRIGHTER)
+ .apply {
+ icon = UIUtil.getErrorIcon()
+ isVisible = false
+ }
+ private val sdksModel = ProjectSdksModel()
+ private lateinit var jdkBox: JdkComboBox
+ private var minimumVersion: JavaSdkVersion = JavaSdkVersion.JDK_1_8
+
+ private fun highestJDKVersionRequired(creator: MinecraftProjectCreator): JavaSdkVersion? {
+ val highestJavaVersionRequired = creator.configs.maxOfOrNull { it.javaVersion } ?: return null
+ return JavaSdkVersion.fromJavaVersion(highestJavaVersionRequired).also {
+ minimumVersion = it ?: JavaSdkVersion.JDK_1_8
+ }
+ }
+
+ private fun isUsingCompatibleJdk(creator: MinecraftProjectCreator, sdk: Sdk): Boolean {
+ val requiredJdkVersion = highestJDKVersionRequired(creator) ?: return false
+ return JavaSdk.getInstance().isOfVersionOrHigher(sdk, requiredJdkVersion)
+ }
+
+ override val title: String = "JDK"
+
+ override fun RowBuilder.buildComponent(creator: MinecraftProjectCreator, context: WizardContext) {
+ row(errorLabel) {}
+ jdkBox = JdkComboBox(
+ context.project,
+ sdksModel,
+ { it is JavaSdk },
+ { JavaSdk.getInstance().isOfVersionOrHigher(it, minimumVersion) },
+ null,
+ null,
+ )
+ reloadJdkBox(context)
+ if (jdkBox.itemCount > 0) {
+ jdkBox.selectedIndex = 0
+ }
+ row("JDK version:") {
+ component(jdkBox).constraints(grow)
+ }
+ }
+
+ override fun isApplicable(creator: MinecraftProjectCreator, context: WizardContext) = true
+
+ private fun reloadJdkBox(context: WizardContext) {
+ sdksModel.syncSdks()
+ sdksModel.reset(context.project)
+ jdkBox.reloadModel()
+ }
+
+ private fun updateUi(usingCompatibleJdk: Boolean) {
+ if (usingCompatibleJdk) {
+ errorLabel.text = ""
+ errorLabel.isVisible = false
+ return
+ }
+
+ errorLabel.text = "Project requires at least Java ${minimumVersion.description}"
+ errorLabel.isVisible = true
+ }
+
+ override fun validateConfigs(creator: MinecraftProjectCreator, context: WizardContext): Boolean {
+ val projectJdk = context.projectJdk ?: return true
+ val usingCompatibleJdk = isUsingCompatibleJdk(creator, projectJdk)
+ updateUi(usingCompatibleJdk)
+ return usingCompatibleJdk
+ }
+
+ override fun validateChanges(creator: MinecraftProjectCreator, context: WizardContext): Boolean {
+ return isUsingCompatibleJdk(creator, jdkBox.selectedJdk ?: return false)
+ }
+
+ override fun apply(creator: MinecraftProjectCreator, context: WizardContext) {
+ val selectedJdk = jdkBox.selectedJdk
+ if (selectedJdk != null) {
+ context.projectJdk = selectedJdk
+ }
+ }
+}
+
+class GradleProjectSetupFinalizer : ProjectSetupFinalizer {
+
+ private val errorLabel = Label("", fontColor = UIUtil.FontColor.BRIGHTER)
+ .apply {
+ icon = UIUtil.getErrorIcon()
+ setUI(MultiLineLabelUI())
+ isVisible = false
+ }
+ private val model = SortedComboBoxModel(Comparator.naturalOrder())
+
+ private val propertyGraph = PropertyGraph("GradleProjectSetupFinalizer graph")
+ var gradleVersion: SemanticVersion by propertyGraph.graphProperty { SemanticVersion.release() }
+ private var configs: Collection = emptyList()
+ private var incompatibleConfigs: List = emptyList()
+
+ private var gradleVersionRange: VersionRange? = null
+
+ override val title: String = "Gradle"
+
+ override fun RowBuilder.buildComponent(creator: MinecraftProjectCreator, context: WizardContext) {
+ row(errorLabel) {}
+ row("Gradle version:") {
+ comboBox(model, ::gradleVersion)
+ .enabled(false) // TODO load compatible Gradle versions list
+ }
+ }
+
+ override fun isApplicable(creator: MinecraftProjectCreator, context: WizardContext): Boolean {
+ val buildSystem = creator.buildSystem
+ return buildSystem is GradleBuildSystem
+ }
+
+ override fun validateConfigs(creator: MinecraftProjectCreator, context: WizardContext): Boolean {
+ configs = creator.configs
+ incompatibleConfigs = emptyList()
+
+ if (creator.buildSystem !is GradleBuildSystem) {
+ updateUi()
+ return true
+ }
+
+ val incompatibleConfigs = mutableListOf()
+ val range = creator.configs.fold(SemanticVersion.release() until null) { acc, config ->
+ val range = (config as? GradleCreator)?.compatibleGradleVersions ?: return@fold acc
+ val intersection = acc.intersect(range)
+ if (intersection == null) {
+ incompatibleConfigs.add(config)
+ return@fold acc
+ }
+ intersection
+ }
+ gradleVersionRange = range
+ this.incompatibleConfigs = incompatibleConfigs
+ updateUi()
+
+ // TODO get the compatible versions available if possible
+ gradleVersion = range.lower
+ model.clear()
+ model.add(gradleVersion)
+ model.selectedItem = gradleVersion
+ return this.incompatibleConfigs.isEmpty()
+ }
+
+ private fun updateUi() {
+ if (incompatibleConfigs.isEmpty()) {
+ errorLabel.text = ""
+ errorLabel.isVisible = false
+ return
+ }
+
+ val problemsList = incompatibleConfigs.joinToString(separator = "") { config ->
+ val configName = config.javaClass.simpleName.removeSuffix("ProjectConfig")
+ val compatibleGradleVersions = (config as GradleCreator).compatibleGradleVersions
+ "\n- $configName requires $compatibleGradleVersions"
+ }
+ val compatibleConfigsList = configs.subtract(incompatibleConfigs)
+ .joinToString { it.javaClass.simpleName.removeSuffix("ProjectConfig") }
+ errorLabel.text = "$compatibleConfigsList require Gradle $gradleVersionRange but:$problemsList"
+ errorLabel.isVisible = true
+ }
+
+ override fun validateChanges(creator: MinecraftProjectCreator, context: WizardContext): Boolean {
+ if (creator.buildSystem !is GradleBuildSystem) {
+ return true
+ }
+ return gradleVersionRange != null && incompatibleConfigs.isEmpty() && gradleVersion.parts.isNotEmpty()
+ }
+
+ override fun apply(creator: MinecraftProjectCreator, context: WizardContext) {
+ (creator.buildSystem as? GradleBuildSystem)?.gradleVersion = gradleVersion
+ }
+}
diff --git a/src/main/kotlin/creator/buildsystem/gradle/GradleBuildSystem.kt b/src/main/kotlin/creator/buildsystem/gradle/GradleBuildSystem.kt
index f0ce7e29f..fec7f89bc 100644
--- a/src/main/kotlin/creator/buildsystem/gradle/GradleBuildSystem.kt
+++ b/src/main/kotlin/creator/buildsystem/gradle/GradleBuildSystem.kt
@@ -18,6 +18,7 @@ import com.demonwav.mcdev.creator.buildsystem.BuildSystemTemplate
import com.demonwav.mcdev.creator.buildsystem.BuildSystemType
import com.demonwav.mcdev.platform.PlatformType
import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
import com.intellij.openapi.module.Module
import java.nio.file.Path
import java.util.Locale
@@ -95,6 +96,9 @@ class GradleBuildSystem(
* creating `Gradle` projects.
*/
interface GradleCreator {
+
+ val compatibleGradleVersions: VersionRange?
+
fun buildGradleCreator(rootDirectory: Path, module: Module, buildSystem: GradleBuildSystem): ProjectCreator
/**
diff --git a/src/main/kotlin/errorreporter/ErrorReporter.kt b/src/main/kotlin/errorreporter/ErrorReporter.kt
index caca175ba..e2256f7f3 100644
--- a/src/main/kotlin/errorreporter/ErrorReporter.kt
+++ b/src/main/kotlin/errorreporter/ErrorReporter.kt
@@ -24,11 +24,17 @@ import com.intellij.openapi.diagnostic.ErrorReportSubmitter
import com.intellij.openapi.diagnostic.IdeaLoggingEvent
import com.intellij.openapi.diagnostic.SubmittedReportInfo
import com.intellij.openapi.progress.EmptyProgressIndicator
+import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
+import com.intellij.openapi.progress.Task
import com.intellij.util.Consumer
import java.awt.Component
class ErrorReporter : ErrorReportSubmitter() {
+ private val ignoredErrorMessages = listOf(
+ "Key com.demonwav.mcdev.translations.TranslationFoldingSettings duplicated",
+ "Inspection #EntityConstructor has no description"
+ )
private val baseUrl = "https://github.com/minecraft-dev/MinecraftDev/issues"
override fun getReportActionText() = "Report to Minecraft Dev GitHub Issue Tracker"
@@ -38,9 +44,26 @@ class ErrorReporter : ErrorReportSubmitter() {
parentComponent: Component,
consumer: Consumer
): Boolean {
+ val dataContext = DataManager.getInstance().getDataContext(parentComponent)
+ val project = CommonDataKeys.PROJECT.getData(dataContext)
+
val event = events[0]
+ val errorMessage = event.throwableText
+ if (errorMessage.isNotBlank() && ignoredErrorMessages.any(errorMessage::contains)) {
+ val task = object : Task.Backgroundable(project, "Ignored error") {
+ override fun run(indicator: ProgressIndicator) {
+ consumer.consume(SubmittedReportInfo(null, null, SubmittedReportInfo.SubmissionStatus.DUPLICATE))
+ }
+ }
+ if (project == null) {
+ task.run(EmptyProgressIndicator())
+ } else {
+ ProgressManager.getInstance().run(task)
+ }
+ return true
+ }
+
val errorData = ErrorData(event.throwable, IdeaLogger.ourLastActionId)
- val dataContext = DataManager.getInstance().getDataContext(parentComponent)
errorData.description = additionalInfo
errorData.message = event.message
@@ -59,8 +82,6 @@ class ErrorReporter : ErrorReportSubmitter() {
val (reportValues, attachments) = errorData.formatErrorData()
- val project = CommonDataKeys.PROJECT.getData(dataContext)
-
val task = AnonymousFeedbackTask(
project,
"Submitting error report",
diff --git a/src/main/kotlin/facet/MinecraftFacet.kt b/src/main/kotlin/facet/MinecraftFacet.kt
index 57819c111..06bd4e63c 100644
--- a/src/main/kotlin/facet/MinecraftFacet.kt
+++ b/src/main/kotlin/facet/MinecraftFacet.kt
@@ -189,12 +189,13 @@ class MinecraftFacet(
val icon: Icon?
get() {
- val iconCount = moduleMap.keys.count { it.hasIcon }
- return when {
- iconCount == 0 -> null
- iconCount == 1 -> moduleMap.keys.firstOrNull { it.hasIcon }?.icon
- moduleMap.size > 0 -> PlatformAssets.MINECRAFT_ICON
- else -> null
+ val modulesWithIcon = moduleMap.keys.filter { it.hasIcon }
+ val candidateModules = modulesWithIcon.filter { !it.isIconSecondary }
+ .ifEmpty { modulesWithIcon }
+ return when (candidateModules.size) {
+ 0 -> null
+ 1 -> candidateModules.single().icon
+ else -> PlatformAssets.MINECRAFT_ICON
}
}
@@ -233,9 +234,12 @@ class MinecraftFacet(
companion object {
val ID = FacetTypeId(TYPE_ID)
- val facetType
+ val facetType: MinecraftFacetType
get() = FacetTypeRegistry.getInstance().findFacetType(ID) as MinecraftFacetType
+ val facetTypeOrNull: MinecraftFacetType?
+ get() = FacetTypeRegistry.getInstance().findFacetType(TYPE_ID) as? MinecraftFacetType
+
fun getInstance(module: Module) = FacetManager.getInstance(module).getFacetByType(ID)
fun getChildInstances(module: Module) = runReadAction run@{
diff --git a/src/main/kotlin/facet/MinecraftFacetDetector.kt b/src/main/kotlin/facet/MinecraftFacetDetector.kt
index f1018f490..e88fcebbd 100644
--- a/src/main/kotlin/facet/MinecraftFacetDetector.kt
+++ b/src/main/kotlin/facet/MinecraftFacetDetector.kt
@@ -62,7 +62,8 @@ class MinecraftFacetDetector : StartupActivity {
val configuration = MinecraftFacetConfiguration()
configuration.state.autoDetectTypes.addAll(platforms)
- val facet = facetManager.createFacet(MinecraftFacet.facetType, "Minecraft", configuration, null)
+ val facetType = MinecraftFacet.facetTypeOrNull ?: return
+ val facet = facetManager.createFacet(facetType, "Minecraft", configuration, null)
runWriteTaskLater {
// Only add the new facet if there isn't a Minecraft facet already - double check here since this
// task may run much later
@@ -120,7 +121,7 @@ class MinecraftFacetDetector : StartupActivity {
.withoutLibraries()
.withoutSdk()
.forEachModule forEach@{ m ->
- if (m.name.startsWith("SpongeAPI")) {
+ if (m.name.startsWith("SpongeAPI", ignoreCase = true)) {
// We don't want want to add parent modules in module groups
val moduleManager = ModuleManager.getInstance(m.project)
val groupPath = moduleManager.getModuleGroupPath(m)
diff --git a/src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt b/src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt
index c662499b6..e33f3fed0 100644
--- a/src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt
+++ b/src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt
@@ -17,18 +17,22 @@ import com.demonwav.mcdev.platform.fabric.FabricModuleType
import com.demonwav.mcdev.platform.forge.ForgeModuleType
import com.demonwav.mcdev.util.MinecraftTemplates
import com.demonwav.mcdev.util.findModule
+import com.intellij.codeInsight.daemon.JavaErrorBundle
+import com.intellij.codeInsight.daemon.impl.analysis.HighlightClassUtil
import com.intellij.ide.actions.CreateFileFromTemplateDialog
import com.intellij.ide.actions.CreateTemplateInPackageAction
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
+import com.intellij.openapi.ui.InputValidatorEx
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.JavaDirectoryService
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameHelper
+import com.intellij.psi.util.PsiUtil
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes
class MinecraftClassCreateAction :
@@ -44,6 +48,7 @@ class MinecraftClassCreateAction :
override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
builder.setTitle(CAPTION)
+ builder.setValidator(ClassInputValidator(project, directory))
val module = directory.findModule()
val isForge = module?.let { MinecraftFacet.getInstance(it, ForgeModuleType) } != null
@@ -90,6 +95,31 @@ class MinecraftClassCreateAction :
return JavaDirectoryService.getInstance().createClass(dir, className, templateName, false)
}
+ private class ClassInputValidator(
+ private val project: Project,
+ private val directory: PsiDirectory
+ ) : InputValidatorEx {
+ override fun getErrorText(inputString: String): String? {
+ if (inputString.isNotEmpty() && !PsiNameHelper.getInstance(project).isQualifiedName(inputString)) {
+ return JavaErrorBundle.message("create.class.action.this.not.valid.java.qualified.name")
+ }
+
+ val shortName = StringUtil.getShortName(inputString)
+ val languageLevel = PsiUtil.getLanguageLevel(directory)
+ return if (HighlightClassUtil.isRestrictedIdentifier(shortName, languageLevel)) {
+ JavaErrorBundle.message("restricted.identifier", shortName)
+ } else {
+ null
+ }
+ }
+
+ override fun checkInput(inputString: String): Boolean =
+ inputString.isNotBlank() && getErrorText(inputString) == null
+
+ override fun canClose(inputString: String): Boolean =
+ checkInput(inputString)
+ }
+
private companion object {
private const val CAPTION = "Minecraft Class"
}
diff --git a/src/main/kotlin/nbt/NbtVirtualFile.kt b/src/main/kotlin/nbt/NbtVirtualFile.kt
index 362dfa9df..aa3dd7c5a 100644
--- a/src/main/kotlin/nbt/NbtVirtualFile.kt
+++ b/src/main/kotlin/nbt/NbtVirtualFile.kt
@@ -100,7 +100,17 @@ class NbtVirtualFile(private val backingFile: VirtualFile, private val project:
VfsUtilCore.outputStreamAddingBOM(NbtOutputStream(this, requestor), this)
fun writeFile(requester: Any) {
- val nbttFile = PsiManager.getInstance(project).findFile(this) as NbttFile
+ val nbttFile = PsiManager.getInstance(project).findFile(this) as? NbttFile
+ if (nbttFile == null) {
+ Notification(
+ "NBT Save Error",
+ "Error Saving NBT File",
+ "The file is not recognised as a NBTT file. This might be caused by wrong file type associations.",
+ NotificationType.WARNING
+ ).notify(project)
+ return
+ }
+
val rootTag = nbttFile.getRootCompound()?.getRootCompoundTag()
if (rootTag == null) {
diff --git a/src/main/kotlin/nbt/editor/NbtFileEditorProvider.kt b/src/main/kotlin/nbt/editor/NbtFileEditorProvider.kt
index c3e3d3fb9..1f5aef8cc 100644
--- a/src/main/kotlin/nbt/editor/NbtFileEditorProvider.kt
+++ b/src/main/kotlin/nbt/editor/NbtFileEditorProvider.kt
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.components.JBLoadingPanel
+import com.intellij.util.IncorrectOperationException
import java.awt.BorderLayout
import java.beans.PropertyChangeListener
import javax.swing.JPanel
@@ -80,7 +81,15 @@ private class NbtFileEditor(
nbtFile.toolbar = toolbar
editor = editorProvider(nbtFile)
editor?.let { editor ->
- Disposer.register(this, editor)
+ try {
+ Disposer.register(this, editor)
+ } catch (e: IncorrectOperationException) {
+ // The editor can be disposed really quickly when opening a large number of NBT files
+ // Since everything happens basically at the same time, calling Disposer.isDisposed right before
+ // returns false but #dispose throws this IOE...
+ Disposer.dispose(this)
+ return@let
+ }
component.add(toolbar.panel, BorderLayout.NORTH)
component.add(editor.component, BorderLayout.CENTER)
}
diff --git a/src/main/kotlin/platform/AbstractModuleType.kt b/src/main/kotlin/platform/AbstractModuleType.kt
index dc7d551c6..7460fb332 100644
--- a/src/main/kotlin/platform/AbstractModuleType.kt
+++ b/src/main/kotlin/platform/AbstractModuleType.kt
@@ -33,6 +33,7 @@ abstract class AbstractModuleType(val groupId: String, v
abstract val icon: Icon?
open val hasIcon = true
+ open val isIconSecondary = false
abstract val id: String
diff --git a/src/main/kotlin/platform/MinecraftProjectViewNodeDecorator.kt b/src/main/kotlin/platform/MinecraftProjectViewNodeDecorator.kt
index ba73e7ac7..a68e9b981 100644
--- a/src/main/kotlin/platform/MinecraftProjectViewNodeDecorator.kt
+++ b/src/main/kotlin/platform/MinecraftProjectViewNodeDecorator.kt
@@ -44,13 +44,7 @@ class MinecraftProjectViewNodeDecorator : ProjectViewNodeDecorator {
val rootManager = ModuleRootManager.getInstance(module)
// Make sure there is at least a root to go off of
- if (rootManager.contentRoots.isEmpty()) {
- return
- }
-
- // Get the root and compare it to the node
- val root = rootManager.contentRoots[0]
- if (root != node.getVirtualFile()) {
+ if (node.virtualFile !in rootManager.contentRoots) {
return
}
diff --git a/src/main/kotlin/platform/adventure/AdventureModuleType.kt b/src/main/kotlin/platform/adventure/AdventureModuleType.kt
index d9923a1cf..6aff3f160 100644
--- a/src/main/kotlin/platform/adventure/AdventureModuleType.kt
+++ b/src/main/kotlin/platform/adventure/AdventureModuleType.kt
@@ -28,6 +28,7 @@ object AdventureModuleType : AbstractModuleType(
override val platformType = PlatformType.ADVENTURE
override val icon: Icon = PlatformAssets.ADVENTURE_ICON
+ override val isIconSecondary = true
override val ignoredAnnotations = emptyList()
override val listenerAnnotations = emptyList()
diff --git a/src/main/kotlin/platform/bukkit/creator/BukkitProjectConfig.kt b/src/main/kotlin/platform/bukkit/creator/BukkitProjectConfig.kt
index d1b45c877..92803cc99 100644
--- a/src/main/kotlin/platform/bukkit/creator/BukkitProjectConfig.kt
+++ b/src/main/kotlin/platform/bukkit/creator/BukkitProjectConfig.kt
@@ -20,7 +20,11 @@ import com.demonwav.mcdev.creator.buildsystem.maven.MavenCreator
import com.demonwav.mcdev.platform.PlatformType
import com.demonwav.mcdev.platform.bukkit.BukkitLikeConfiguration
import com.demonwav.mcdev.platform.bukkit.data.LoadOrder
+import com.demonwav.mcdev.util.MinecraftVersions
+import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
import com.intellij.openapi.module.Module
+import com.intellij.util.lang.JavaVersion
import java.nio.file.Path
class BukkitProjectConfig(override var type: PlatformType) :
@@ -29,7 +33,9 @@ class BukkitProjectConfig(override var type: PlatformType) :
override lateinit var mainClass: String
var loadOrder: LoadOrder = LoadOrder.POSTWORLD
- var minecraftVersion: String? = null
+ var minecraftVersion: String = ""
+ val semanticMinecraftVersion: SemanticVersion
+ get() = if (minecraftVersion.isBlank()) SemanticVersion.release() else SemanticVersion.parse(minecraftVersion)
var prefix: String? = null
fun hasPrefix() = prefix?.isNotBlank() == true
@@ -57,6 +63,11 @@ class BukkitProjectConfig(override var type: PlatformType) :
override val preferredBuildSystem = BuildSystemType.MAVEN
+ override val javaVersion: JavaVersion
+ get() = MinecraftVersions.requiredJavaVersion(semanticMinecraftVersion)
+
+ override val compatibleGradleVersions: VersionRange? = null
+
override fun buildMavenCreator(
rootDirectory: Path,
module: Module,
diff --git a/src/main/kotlin/platform/bukkit/creator/BukkitProjectCreator.kt b/src/main/kotlin/platform/bukkit/creator/BukkitProjectCreator.kt
index 671ca2e80..5a6c2a7ff 100644
--- a/src/main/kotlin/platform/bukkit/creator/BukkitProjectCreator.kt
+++ b/src/main/kotlin/platform/bukkit/creator/BukkitProjectCreator.kt
@@ -50,7 +50,7 @@ sealed class BukkitProjectCreator(
}
protected fun setupDependencyStep(): BukkitDependenciesStep {
- val mcVersion = config.minecraftVersion ?: throw IllegalStateException("No Minecraft version is set")
+ val mcVersion = config.minecraftVersion
return BukkitDependenciesStep(buildSystem, config.type, mcVersion)
}
diff --git a/src/main/kotlin/platform/bukkit/creator/BukkitProjectSettingsWizard.kt b/src/main/kotlin/platform/bukkit/creator/BukkitProjectSettingsWizard.kt
index 4ce1c75cf..dd14a40d1 100644
--- a/src/main/kotlin/platform/bukkit/creator/BukkitProjectSettingsWizard.kt
+++ b/src/main/kotlin/platform/bukkit/creator/BukkitProjectSettingsWizard.kt
@@ -58,6 +58,8 @@ class BukkitProjectSettingsWizard(private val creator: MinecraftProjectCreator)
private var config: BukkitProjectConfig? = null
+ private var versionsLoaded: Boolean = false
+
override fun getComponent(): JComponent {
return panel
}
@@ -92,6 +94,11 @@ class BukkitProjectSettingsWizard(private val creator: MinecraftProjectCreator)
}
}
+ if (versionsLoaded) {
+ return
+ }
+
+ versionsLoaded = true
CoroutineScope(Dispatchers.Swing).launch {
try {
withContext(Dispatchers.IO) { getVersionSelector(conf.type) }.set(minecraftVersionBox)
diff --git a/src/main/kotlin/platform/bukkit/creator/BukkitTemplate.kt b/src/main/kotlin/platform/bukkit/creator/BukkitTemplate.kt
index b2f024789..1c9336d6e 100644
--- a/src/main/kotlin/platform/bukkit/creator/BukkitTemplate.kt
+++ b/src/main/kotlin/platform/bukkit/creator/BukkitTemplate.kt
@@ -26,7 +26,6 @@ import com.demonwav.mcdev.util.MinecraftTemplates.Companion.BUKKIT_POM_TEMPLATE
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.BUKKIT_SETTINGS_GRADLE_TEMPLATE
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.BUKKIT_SUBMODULE_BUILD_GRADLE_TEMPLATE
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.BUKKIT_SUBMODULE_POM_TEMPLATE
-import com.demonwav.mcdev.util.SemanticVersion
import com.intellij.openapi.project.Project
object BukkitTemplate : BaseTemplate() {
@@ -126,11 +125,9 @@ object BukkitTemplate : BaseTemplate() {
// Plugins targeting 1.13 or newer need an explicit api declaration flag
// This is the major and minor version separated by a dot without the patch version. ex: 1.15 even for 1.15.2
- config.minecraftVersion?.let { mcVersion ->
- val semVer = SemanticVersion.parse(mcVersion)
- if (semVer >= BukkitModuleType.API_TAG_VERSION) {
- props["API_VERSION"] = semVer.take(2).toString()
- }
+ val mcVersion = config.semanticMinecraftVersion
+ if (mcVersion >= BukkitModuleType.API_TAG_VERSION) {
+ props["API_VERSION"] = mcVersion.take(2).toString()
}
return project.applyTemplate(BUKKIT_PLUGIN_YML_TEMPLATE, props)
diff --git a/src/main/kotlin/platform/bungeecord/creator/BungeeCordProjectConfig.kt b/src/main/kotlin/platform/bungeecord/creator/BungeeCordProjectConfig.kt
index 8723b7d5c..e466c0592 100644
--- a/src/main/kotlin/platform/bungeecord/creator/BungeeCordProjectConfig.kt
+++ b/src/main/kotlin/platform/bungeecord/creator/BungeeCordProjectConfig.kt
@@ -19,7 +19,11 @@ import com.demonwav.mcdev.creator.buildsystem.maven.MavenBuildSystem
import com.demonwav.mcdev.creator.buildsystem.maven.MavenCreator
import com.demonwav.mcdev.platform.PlatformType
import com.demonwav.mcdev.platform.bukkit.BukkitLikeConfiguration
+import com.demonwav.mcdev.util.MinecraftVersions
+import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
import com.intellij.openapi.module.Module
+import com.intellij.util.lang.JavaVersion
import java.nio.file.Path
class BungeeCordProjectConfig(override var type: PlatformType) :
@@ -28,6 +32,8 @@ class BungeeCordProjectConfig(override var type: PlatformType) :
override lateinit var mainClass: String
var minecraftVersion = ""
+ val semanticMinecraftVersion: SemanticVersion
+ get() = if (minecraftVersion.isBlank()) SemanticVersion.release() else SemanticVersion.parse(minecraftVersion)
override val dependencies = mutableListOf()
override fun hasDependencies() = listContainsAtLeastOne(dependencies)
@@ -45,6 +51,11 @@ class BungeeCordProjectConfig(override var type: PlatformType) :
override val preferredBuildSystem = BuildSystemType.MAVEN
+ override val javaVersion: JavaVersion
+ get() = MinecraftVersions.requiredJavaVersion(semanticMinecraftVersion)
+
+ override val compatibleGradleVersions: VersionRange? = null
+
override fun buildMavenCreator(
rootDirectory: Path,
module: Module,
diff --git a/src/main/kotlin/platform/bungeecord/creator/BungeeCordProjectSettingsWizard.kt b/src/main/kotlin/platform/bungeecord/creator/BungeeCordProjectSettingsWizard.kt
index aac557362..c6038e17f 100644
--- a/src/main/kotlin/platform/bungeecord/creator/BungeeCordProjectSettingsWizard.kt
+++ b/src/main/kotlin/platform/bungeecord/creator/BungeeCordProjectSettingsWizard.kt
@@ -56,6 +56,8 @@ class BungeeCordProjectSettingsWizard(
private var config: BungeeCordProjectConfig? = null
+ private var versionsLoaded: Boolean = false
+
override fun getComponent(): JComponent {
return panel
}
@@ -85,6 +87,11 @@ class BungeeCordProjectSettingsWizard(
else -> {}
}
+ if (versionsLoaded) {
+ return
+ }
+
+ versionsLoaded = true
CoroutineScope(Dispatchers.Swing).launch {
try {
withContext(Dispatchers.IO) { getVersionSelector(conf.type) }.set(minecraftVersionBox)
diff --git a/src/main/kotlin/platform/fabric/creator/FabricProjectConfig.kt b/src/main/kotlin/platform/fabric/creator/FabricProjectConfig.kt
index 166fd8563..a9c7da5b3 100644
--- a/src/main/kotlin/platform/fabric/creator/FabricProjectConfig.kt
+++ b/src/main/kotlin/platform/fabric/creator/FabricProjectConfig.kt
@@ -19,8 +19,11 @@ import com.demonwav.mcdev.platform.PlatformType
import com.demonwav.mcdev.platform.fabric.EntryPoint
import com.demonwav.mcdev.platform.forge.inspections.sideonly.Side
import com.demonwav.mcdev.util.License
+import com.demonwav.mcdev.util.MinecraftVersions
import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
import com.intellij.openapi.module.Module
+import com.intellij.util.lang.JavaVersion
import java.nio.file.Path
class FabricProjectConfig : ProjectConfig(), GradleCreator {
@@ -31,7 +34,6 @@ class FabricProjectConfig : ProjectConfig(), GradleCreator {
// Minecraft does not follow semver in the snapshots
var mcVersion = ""
var semanticMcVersion = SemanticVersion.release()
- var javaVersion = 8
var loaderVersion = SemanticVersion.release()
var apiVersion: SemanticVersion? = null
var apiMavenLocation: String? = null
@@ -48,6 +50,12 @@ class FabricProjectConfig : ProjectConfig(), GradleCreator {
override val preferredBuildSystem = BuildSystemType.GRADLE
+ override val javaVersion: JavaVersion
+ get() = MinecraftVersions.requiredJavaVersion(semanticMcVersion)
+
+ override val compatibleGradleVersions: VersionRange
+ get() = VersionRange.fixed(gradleVersion)
+
override fun buildGradleCreator(
rootDirectory: Path,
module: Module,
@@ -62,6 +70,7 @@ class FabricProjectConfig : ProjectConfig(), GradleCreator {
}
override fun configureRootGradle(rootDirectory: Path, buildSystem: GradleBuildSystem) {
- buildSystem.gradleVersion = gradleVersion
+ buildSystem.gradleVersion =
+ if (semanticMcVersion >= MinecraftVersions.MC1_17) SemanticVersion.release(7, 1, 1) else gradleVersion
}
}
diff --git a/src/main/kotlin/platform/fabric/creator/FabricProjectSettingsWizard.kt b/src/main/kotlin/platform/fabric/creator/FabricProjectSettingsWizard.kt
index c478c029e..ea4179106 100644
--- a/src/main/kotlin/platform/fabric/creator/FabricProjectSettingsWizard.kt
+++ b/src/main/kotlin/platform/fabric/creator/FabricProjectSettingsWizard.kt
@@ -21,7 +21,6 @@ import com.demonwav.mcdev.platform.fabric.EntryPoint
import com.demonwav.mcdev.platform.fabric.util.FabricConstants
import com.demonwav.mcdev.platform.forge.inspections.sideonly.Side
import com.demonwav.mcdev.util.License
-import com.demonwav.mcdev.util.MinecraftVersions
import com.demonwav.mcdev.util.SemanticVersion
import com.demonwav.mcdev.util.modUpdateStep
import com.demonwav.mcdev.util.toPackageName
@@ -237,7 +236,6 @@ class FabricProjectSettingsWizard(private val creator: MinecraftProjectCreator)
conf.mcVersion = mcVersion ?: ""
val normalizedMcVersion = dataProvider?.getNormalizedMinecraftVersion(mcVersion)?.normalized
conf.semanticMcVersion = normalizedMcVersion?.let { SemanticVersion.parse(it) } ?: SemanticVersion.release()
- conf.javaVersion = if (conf.semanticMcVersion >= MinecraftVersions.MC1_17) 16 else 8
val loaderVer = loaderVersion
if (loaderVer != null) {
conf.loaderVersion = SemanticVersion.parse(loaderVer)
diff --git a/src/main/kotlin/platform/fabric/creator/FabricTemplate.kt b/src/main/kotlin/platform/fabric/creator/FabricTemplate.kt
index 90549d421..353bb46ca 100644
--- a/src/main/kotlin/platform/fabric/creator/FabricTemplate.kt
+++ b/src/main/kotlin/platform/fabric/creator/FabricTemplate.kt
@@ -39,7 +39,7 @@ object FabricTemplate : BaseTemplate() {
"YARN_MAPPINGS" to config.yarnVersion,
"LOADER_VERSION" to config.loaderVersion.toString(),
"LOOM_VERSION" to config.loomVersion.toString(),
- "JAVA_VERSION" to config.javaVersion
+ "JAVA_VERSION" to config.javaVersion.feature
)
config.yarnClassifier?.let {
props["YARN_CLASSIFIER"] = it
@@ -110,7 +110,7 @@ object FabricTemplate : BaseTemplate() {
},
"LOADER_VERSION" to config.loaderVersion.toString(),
"MC_VERSION" to config.semanticMcVersion.toString(),
- "JAVA_VERSION" to config.javaVersion,
+ "JAVA_VERSION" to config.javaVersion.feature,
"LICENSE" to ((config.license ?: License.ALL_RIGHTS_RESERVED).id)
)
config.apiVersion?.let {
@@ -131,7 +131,7 @@ object FabricTemplate : BaseTemplate() {
val packageName = "${buildSystem.groupId.toPackageName()}.${buildSystem.artifactId.toPackageName()}.mixin"
val props = mapOf(
"PACKAGE_NAME" to packageName,
- "JAVA_VERSION" to config.javaVersion
+ "JAVA_VERSION" to config.javaVersion.feature
)
return project.applyTemplate(FABRIC_MIXINS_JSON_TEMPLATE, props)
}
diff --git a/src/main/kotlin/platform/forge/creator/ForgeProjectConfig.kt b/src/main/kotlin/platform/forge/creator/ForgeProjectConfig.kt
index 1080a1e6d..445c22012 100644
--- a/src/main/kotlin/platform/forge/creator/ForgeProjectConfig.kt
+++ b/src/main/kotlin/platform/forge/creator/ForgeProjectConfig.kt
@@ -19,8 +19,12 @@ import com.demonwav.mcdev.platform.PlatformType
import com.demonwav.mcdev.platform.forge.ForgeModuleType
import com.demonwav.mcdev.platform.mcp.McpVersionPair
import com.demonwav.mcdev.util.License
+import com.demonwav.mcdev.util.MinecraftVersions
import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
+import com.demonwav.mcdev.util.until
import com.intellij.openapi.module.Module
+import com.intellij.util.lang.JavaVersion
import java.nio.file.Path
class ForgeProjectConfig : ProjectConfig(), GradleCreator {
@@ -40,6 +44,15 @@ class ForgeProjectConfig : ProjectConfig(), GradleCreator {
override val preferredBuildSystem = BuildSystemType.GRADLE
+ override val javaVersion: JavaVersion
+ get() = MinecraftVersions.requiredJavaVersion(mcVersion)
+
+ override val compatibleGradleVersions: VersionRange
+ get() = when {
+ isFg3(mcVersion, forgeVersion) -> Fg3ProjectCreator.FG5_WRAPPER_VERSION until null
+ else -> VersionRange.fixed(Fg2ProjectCreator.FG_WRAPPER_VERSION)
+ }
+
override fun buildGradleCreator(
rootDirectory: Path,
module: Module,
diff --git a/src/main/kotlin/platform/forge/creator/ForgeProjectSettingsWizard.kt b/src/main/kotlin/platform/forge/creator/ForgeProjectSettingsWizard.kt
index acd7eca11..257490697 100644
--- a/src/main/kotlin/platform/forge/creator/ForgeProjectSettingsWizard.kt
+++ b/src/main/kotlin/platform/forge/creator/ForgeProjectSettingsWizard.kt
@@ -133,13 +133,13 @@ class ForgeProjectSettingsWizard(private val creator: MinecraftProjectCreator) :
minecraftVersionLabel.text = "Minecraft Version"
+ licenseBox.model = EnumComboBoxModel(License::class.java)
+ licenseBox.selectedItem = License.ALL_RIGHTS_RESERVED
+
if (versions != null || currentJob?.isActive == true) {
return
}
currentJob = updateVersions()
-
- licenseBox.model = EnumComboBoxModel(License::class.java)
- licenseBox.selectedItem = License.ALL_RIGHTS_RESERVED
}
private fun setForgeVersion(data: Data) {
diff --git a/src/main/kotlin/platform/liteloader/creator/LiteLoaderProjectConfig.kt b/src/main/kotlin/platform/liteloader/creator/LiteLoaderProjectConfig.kt
index 0de077b00..38856ac81 100644
--- a/src/main/kotlin/platform/liteloader/creator/LiteLoaderProjectConfig.kt
+++ b/src/main/kotlin/platform/liteloader/creator/LiteLoaderProjectConfig.kt
@@ -18,8 +18,11 @@ import com.demonwav.mcdev.creator.buildsystem.gradle.GradleCreator
import com.demonwav.mcdev.platform.PlatformType
import com.demonwav.mcdev.platform.forge.creator.Fg2ProjectCreator
import com.demonwav.mcdev.platform.mcp.McpVersionPair
+import com.demonwav.mcdev.util.MinecraftVersions
import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
import com.intellij.openapi.module.Module
+import com.intellij.util.lang.JavaVersion
import java.nio.file.Path
class LiteLoaderProjectConfig : ProjectConfig(), GradleCreator {
@@ -33,6 +36,11 @@ class LiteLoaderProjectConfig : ProjectConfig(), GradleCreator {
override val preferredBuildSystem = BuildSystemType.GRADLE
+ override val javaVersion: JavaVersion
+ get() = MinecraftVersions.requiredJavaVersion(mcVersion)
+
+ override val compatibleGradleVersions: VersionRange = VersionRange.fixed(Fg2ProjectCreator.FG_WRAPPER_VERSION)
+
override fun buildGradleCreator(
rootDirectory: Path,
module: Module,
diff --git a/src/main/kotlin/platform/mixin/action/CopyMixinTargetReferenceAction.kt b/src/main/kotlin/platform/mixin/action/CopyMixinTargetReferenceAction.kt
index 53c88b054..7b1798b3f 100644
--- a/src/main/kotlin/platform/mixin/action/CopyMixinTargetReferenceAction.kt
+++ b/src/main/kotlin/platform/mixin/action/CopyMixinTargetReferenceAction.kt
@@ -10,8 +10,10 @@
package com.demonwav.mcdev.platform.mixin.action
+import com.demonwav.mcdev.platform.mixin.reference.target.QualifiedMember
import com.demonwav.mcdev.platform.mixin.util.MixinMemberReference
import com.demonwav.mcdev.util.findReferencedMember
+import com.demonwav.mcdev.util.getQualifiedMemberReference
import com.demonwav.mcdev.util.qualifiedMemberReference
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
@@ -21,6 +23,7 @@ import com.intellij.openapi.ide.CopyPasteManager
import com.intellij.openapi.wm.WindowManager
import com.intellij.psi.PsiField
import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiQualifiedReference
import java.awt.datatransfer.StringSelection
class CopyMixinTargetReferenceAction : AnAction() {
@@ -32,10 +35,19 @@ class CopyMixinTargetReferenceAction : AnAction() {
val element = file.findElementAt(caret.offset) ?: return
val member = element.findReferencedMember() ?: return
+ val targetClass = (element.parent as? PsiQualifiedReference)?.let { QualifiedMember.resolveQualifier(it) }
val targetReference = when (member) {
- is PsiMethod -> member.qualifiedMemberReference
- is PsiField -> member.qualifiedMemberReference
+ is PsiMethod -> if (targetClass != null) {
+ member.getQualifiedMemberReference(targetClass)
+ } else {
+ member.qualifiedMemberReference
+ }
+ is PsiField -> if (targetClass != null) {
+ member.getQualifiedMemberReference(targetClass)
+ } else {
+ member.qualifiedMemberReference
+ }
else -> return
}
diff --git a/src/main/kotlin/platform/mixin/reference/target/TargetReference.kt b/src/main/kotlin/platform/mixin/reference/target/TargetReference.kt
index fd52a9ecd..95a90f21d 100644
--- a/src/main/kotlin/platform/mixin/reference/target/TargetReference.kt
+++ b/src/main/kotlin/platform/mixin/reference/target/TargetReference.kt
@@ -41,7 +41,6 @@ import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiQualifiedReference
import com.intellij.psi.PsiReference
import com.intellij.psi.PsiSubstitutor
-import com.intellij.psi.PsiThisExpression
import com.intellij.psi.ResolveResult
import com.intellij.psi.util.parentOfType
import com.intellij.util.ArrayUtil
@@ -218,10 +217,6 @@ data class QualifiedMember(val member: T, val qualifier: PsiClass
fun resolveQualifier(reference: PsiQualifiedReference): PsiClass? {
val qualifier = reference.qualifier ?: return null
- if (qualifier is PsiThisExpression) {
- return null
- }
-
((qualifier as? PsiReference)?.resolve() as? PsiClass)?.let { return it }
((qualifier as? PsiExpression)?.type as? PsiClassType)?.resolve()?.let { return it }
return null
diff --git a/src/main/kotlin/platform/sponge/creator/SpongeProjectConfig.kt b/src/main/kotlin/platform/sponge/creator/SpongeProjectConfig.kt
index 8d607dc01..855157b11 100644
--- a/src/main/kotlin/platform/sponge/creator/SpongeProjectConfig.kt
+++ b/src/main/kotlin/platform/sponge/creator/SpongeProjectConfig.kt
@@ -20,7 +20,10 @@ import com.demonwav.mcdev.creator.buildsystem.maven.MavenCreator
import com.demonwav.mcdev.platform.PlatformType
import com.demonwav.mcdev.platform.sponge.util.SpongeConstants
import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
+import com.demonwav.mcdev.util.until
import com.intellij.openapi.module.Module
+import com.intellij.util.lang.JavaVersion
import java.nio.file.Path
class SpongeProjectConfig : ProjectConfig(), MavenCreator, GradleCreator {
@@ -28,6 +31,8 @@ class SpongeProjectConfig : ProjectConfig(), MavenCreator, GradleCreator {
lateinit var mainClass: String
var spongeApiVersion = ""
+ val apiVersion: SemanticVersion
+ get() = if (spongeApiVersion.isBlank()) SemanticVersion.release() else SemanticVersion.parse(spongeApiVersion)
override var type = PlatformType.SPONGE
@@ -44,6 +49,12 @@ class SpongeProjectConfig : ProjectConfig(), MavenCreator, GradleCreator {
override val preferredBuildSystem = BuildSystemType.GRADLE
+ override val javaVersion: JavaVersion
+ get() = when {
+ apiVersion >= SpongeConstants.API9 -> JavaVersion.compose(16)
+ else -> JavaVersion.compose(8)
+ }
+
override fun buildMavenCreator(
rootDirectory: Path,
module: Module,
@@ -57,6 +68,12 @@ class SpongeProjectConfig : ProjectConfig(), MavenCreator, GradleCreator {
}
}
+ override val compatibleGradleVersions: VersionRange
+ get() = when {
+ apiVersion >= SpongeConstants.API9 -> SemanticVersion.release(7) until null
+ else -> SemanticVersion.release(6) until SemanticVersion.release(7)
+ }
+
override fun buildGradleCreator(
rootDirectory: Path,
module: Module,
diff --git a/src/main/kotlin/platform/sponge/creator/SpongeProjectSettingsWizard.kt b/src/main/kotlin/platform/sponge/creator/SpongeProjectSettingsWizard.kt
index 9bf60b794..63aba1577 100644
--- a/src/main/kotlin/platform/sponge/creator/SpongeProjectSettingsWizard.kt
+++ b/src/main/kotlin/platform/sponge/creator/SpongeProjectSettingsWizard.kt
@@ -54,6 +54,8 @@ class SpongeProjectSettingsWizard(private val creator: MinecraftProjectCreator)
private var config: SpongeProjectConfig? = null
+ private var versionsLoaded: Boolean = false
+
override fun getComponent(): JComponent {
return panel
}
@@ -77,6 +79,11 @@ class SpongeProjectSettingsWizard(private val creator: MinecraftProjectCreator)
title.icon = PlatformAssets.SPONGE_ICON_2X
}
+ if (versionsLoaded) {
+ return
+ }
+
+ versionsLoaded = true
CoroutineScope(Dispatchers.Swing).launch {
try {
withContext(Dispatchers.IO) { SpongeVersion.downloadData() }?.set(spongeApiVersionBox)
@@ -90,7 +97,7 @@ class SpongeProjectSettingsWizard(private val creator: MinecraftProjectCreator)
return creator.configs.any { it is SpongeProjectConfig }
}
- override fun onStepLeaving() {
+ override fun updateDataModel() {
val conf = this.config ?: return
conf.pluginName = this.pluginNameField.text
@@ -102,6 +109,4 @@ class SpongeProjectSettingsWizard(private val creator: MinecraftProjectCreator)
conf.setAuthors(this.authorsField.text)
conf.setDependencies(this.dependField.text)
}
-
- override fun updateDataModel() {}
}
diff --git a/src/main/kotlin/platform/sponge/util/SpongeConstants.kt b/src/main/kotlin/platform/sponge/util/SpongeConstants.kt
index fc0fdf318..d758aed1c 100644
--- a/src/main/kotlin/platform/sponge/util/SpongeConstants.kt
+++ b/src/main/kotlin/platform/sponge/util/SpongeConstants.kt
@@ -34,4 +34,5 @@ object SpongeConstants {
val ID_PATTERN = Pattern.compile(ID_PATTERN_STRING)
val API8 = SemanticVersion.release(8)
+ val API9 = SemanticVersion.release(8)
}
diff --git a/src/main/kotlin/platform/velocity/creator/VelocityProjectConfig.kt b/src/main/kotlin/platform/velocity/creator/VelocityProjectConfig.kt
index 4cb9363fe..d4742c795 100644
--- a/src/main/kotlin/platform/velocity/creator/VelocityProjectConfig.kt
+++ b/src/main/kotlin/platform/velocity/creator/VelocityProjectConfig.kt
@@ -17,7 +17,10 @@ import com.demonwav.mcdev.creator.buildsystem.gradle.GradleCreator
import com.demonwav.mcdev.creator.buildsystem.maven.MavenBuildSystem
import com.demonwav.mcdev.creator.buildsystem.maven.MavenCreator
import com.demonwav.mcdev.platform.PlatformType
+import com.demonwav.mcdev.util.SemanticVersion
+import com.demonwav.mcdev.util.VersionRange
import com.intellij.openapi.module.Module
+import com.intellij.util.lang.JavaVersion
import java.nio.file.Path
class VelocityProjectConfig : ProjectConfig(), MavenCreator, GradleCreator {
@@ -25,6 +28,9 @@ class VelocityProjectConfig : ProjectConfig(), MavenCreator, GradleCreator {
lateinit var mainClass: String
var velocityApiVersion = ""
+ val apiVersion: SemanticVersion
+ get() =
+ if (velocityApiVersion.isBlank()) SemanticVersion.release() else SemanticVersion.parse(velocityApiVersion)
override var type: PlatformType = PlatformType.VELOCITY
@@ -35,6 +41,12 @@ class VelocityProjectConfig : ProjectConfig(), MavenCreator, GradleCreator {
dependencies.addAll(commaSplit(string))
}
+ override val javaVersion: JavaVersion
+ get() = when {
+ apiVersion >= SemanticVersion.release(3) -> JavaVersion.compose(11)
+ else -> JavaVersion.compose(8)
+ }
+
override fun buildMavenCreator(
rootDirectory: Path,
module: Module,
@@ -43,6 +55,8 @@ class VelocityProjectConfig : ProjectConfig(), MavenCreator, GradleCreator {
return VelocityMavenCreator(rootDirectory, module, buildSystem, this)
}
+ override val compatibleGradleVersions: VersionRange? = null
+
override fun buildGradleCreator(
rootDirectory: Path,
module: Module,
diff --git a/src/main/kotlin/platform/velocity/creator/VelocityProjectCreator.kt b/src/main/kotlin/platform/velocity/creator/VelocityProjectCreator.kt
index 25a604dce..b687b104e 100644
--- a/src/main/kotlin/platform/velocity/creator/VelocityProjectCreator.kt
+++ b/src/main/kotlin/platform/velocity/creator/VelocityProjectCreator.kt
@@ -30,6 +30,7 @@ import com.demonwav.mcdev.creator.buildsystem.maven.BasicMavenStep
import com.demonwav.mcdev.creator.buildsystem.maven.CommonModuleDependencyStep
import com.demonwav.mcdev.creator.buildsystem.maven.MavenBuildSystem
import com.demonwav.mcdev.creator.buildsystem.maven.MavenGitignoreStep
+import com.demonwav.mcdev.platform.velocity.util.VelocityConstants
import com.demonwav.mcdev.util.SemanticVersion
import com.demonwav.mcdev.util.runWriteAction
import com.demonwav.mcdev.util.runWriteTaskInSmartMode
@@ -59,7 +60,7 @@ sealed class VelocityProjectCreator(
protected fun setupMainClassSteps(): Pair {
val mainClassStep = createJavaClassStep(config.mainClass) { packageName, className ->
- val version = SemanticVersion.parse(config.velocityApiVersion)
+ val version = config.apiVersion
VelocityTemplate.applyMainClass(project, packageName, className, config.hasDependencies(), version)
}
@@ -76,7 +77,7 @@ class VelocityMavenCreator(
override fun getSingleModuleSteps(): Iterable {
val (mainClassStep, modifyStep) = setupMainClassSteps()
- val pomText = VelocityTemplate.applyPom(project)
+ val pomText = VelocityTemplate.applyPom(project, config)
return listOf(
setupDependencyStep(),
@@ -93,7 +94,7 @@ class VelocityMavenCreator(
val commonDepStep = CommonModuleDependencyStep(buildSystem)
val (mainClassStep, modifyStep) = setupMainClassSteps()
- val pomText = VelocityTemplate.applySubPom(project)
+ val pomText = VelocityTemplate.applySubPom(project, config)
val mavenStep = BasicMavenStep(
project,
rootDirectory,
@@ -124,8 +125,8 @@ class VelocityGradleCreator(
override fun getSingleModuleSteps(): Iterable {
val (mainClassStep, modifyStep) = setupMainClassSteps()
- val buildText = VelocityTemplate.applyBuildGradle(project, buildSystem)
- val propText = VelocityTemplate.applyGradleProp(project)
+ val buildText = VelocityTemplate.applyBuildGradle(project, buildSystem, config)
+ val propText = VelocityTemplate.applyGradleProp(project, null)
val settingsText = VelocityTemplate.applySettingsGradle(project, buildSystem.artifactId)
val files = GradleFiles(buildText, propText, settingsText)
@@ -147,7 +148,8 @@ class VelocityGradleCreator(
val (mainClassStep, modifyStep) = setupMainClassSteps()
val buildText = VelocityTemplate.applySubBuildGradle(project, buildSystem)
- val files = GradleFiles(buildText, null, null)
+ val propText = VelocityTemplate.applyGradleProp(project, config.javaVersion.feature)
+ val files = GradleFiles(buildText, propText, null)
return listOf(
setupDependencyStep(),
@@ -258,11 +260,13 @@ class VelocityDependenciesSetup(
gradleConfiguration = "compileOnly"
)
)
+ val semanticApiVersion = SemanticVersion.parse(velocityApiVersion)
buildSystem.dependencies.add(
BuildDependency(
"com.velocitypowered",
- "velocity-api",
+ if (semanticApiVersion >= VelocityConstants.API_4) "velocity-annotation-processor" else "velocity-api",
velocityApiVersion,
+ mavenScope = if (semanticApiVersion >= VelocityConstants.API_4) "provided" else null,
gradleConfiguration = "annotationProcessor"
)
)
diff --git a/src/main/kotlin/platform/velocity/creator/VelocityProjectSettingsWizard.kt b/src/main/kotlin/platform/velocity/creator/VelocityProjectSettingsWizard.kt
index b9b9f5f39..4600dd988 100644
--- a/src/main/kotlin/platform/velocity/creator/VelocityProjectSettingsWizard.kt
+++ b/src/main/kotlin/platform/velocity/creator/VelocityProjectSettingsWizard.kt
@@ -51,6 +51,8 @@ class VelocityProjectSettingsWizard(private val creator: MinecraftProjectCreator
private var config: VelocityProjectConfig? = null
+ private var versionsLoaded: Boolean = false
+
override fun getComponent(): JComponent {
return panel
}
@@ -68,6 +70,11 @@ class VelocityProjectSettingsWizard(private val creator: MinecraftProjectCreator
basicUpdateStep(creator, conf, pluginNameField, mainClassField)
+ if (versionsLoaded) {
+ return
+ }
+
+ versionsLoaded = true
CoroutineScope(Dispatchers.Swing).launch {
try {
withContext(Dispatchers.IO) { getVersionSelector(conf.type) }.set(velocityApiVersionBox)
@@ -81,7 +88,7 @@ class VelocityProjectSettingsWizard(private val creator: MinecraftProjectCreator
return creator.configs.any { it is VelocityProjectConfig }
}
- override fun onStepLeaving() {
+ override fun updateDataModel() {
val conf = this.config ?: return
conf.pluginName = this.pluginNameField.text
@@ -93,6 +100,4 @@ class VelocityProjectSettingsWizard(private val creator: MinecraftProjectCreator
conf.setAuthors(this.authorsField.text)
conf.setDependencies(this.dependField.text)
}
-
- override fun updateDataModel() {}
}
diff --git a/src/main/kotlin/platform/velocity/creator/VelocityTemplate.kt b/src/main/kotlin/platform/velocity/creator/VelocityTemplate.kt
index aa8dabb1c..dd6841eb5 100644
--- a/src/main/kotlin/platform/velocity/creator/VelocityTemplate.kt
+++ b/src/main/kotlin/platform/velocity/creator/VelocityTemplate.kt
@@ -13,6 +13,7 @@ package com.demonwav.mcdev.platform.velocity.creator
import com.demonwav.mcdev.creator.buildsystem.BuildSystem
import com.demonwav.mcdev.creator.buildsystem.maven.BasicMavenStep
import com.demonwav.mcdev.platform.BaseTemplate
+import com.demonwav.mcdev.platform.velocity.util.VelocityConstants
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.VELOCITY_BUILD_CONSTANTS_TEMPLATE
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.VELOCITY_BUILD_GRADLE_TEMPLATE
import com.demonwav.mcdev.util.MinecraftTemplates.Companion.VELOCITY_GRADLE_PROPERTIES_TEMPLATE
@@ -27,13 +28,15 @@ import com.intellij.openapi.project.Project
object VelocityTemplate : BaseTemplate() {
- private val VELOCITY_2_SNAPSHOT = SemanticVersion.parse("2.0.0-SNAPSHOT")
-
- fun applyPom(project: Project): String =
- project.applyTemplate(VELOCITY_POM_TEMPLATE, BasicMavenStep.pluginVersions)
+ fun applyPom(project: Project, config: VelocityProjectConfig): String {
+ val props = BasicMavenStep.pluginVersions + ("JAVA_VERSION" to config.javaVersion.toFeatureString())
+ return project.applyTemplate(VELOCITY_POM_TEMPLATE, props)
+ }
- fun applySubPom(project: Project): String =
- project.applyTemplate(VELOCITY_SUBMODULE_POM_TEMPLATE, BasicMavenStep.pluginVersions)
+ fun applySubPom(project: Project, config: VelocityProjectConfig): String {
+ val props = BasicMavenStep.pluginVersions + ("JAVA_VERSION" to config.javaVersion.toFeatureString())
+ return project.applyTemplate(VELOCITY_SUBMODULE_POM_TEMPLATE, props)
+ }
fun applyMainClass(
project: Project,
@@ -51,10 +54,12 @@ object VelocityTemplate : BaseTemplate() {
props["HAS_DEPENDENCIES"] = "true"
}
- val template = if (version < VELOCITY_2_SNAPSHOT) {
- VELOCITY_MAIN_CLASS_TEMPLATE
+ val template = if (version < VelocityConstants.API_2 ||
+ (version >= VelocityConstants.API_3 && version < VelocityConstants.API_4)
+ ) {
+ VELOCITY_MAIN_CLASS_TEMPLATE // API 1 and 3
} else {
- VELOCITY_MAIN_CLASS_V2_TEMPLATE
+ VELOCITY_MAIN_CLASS_V2_TEMPLATE // API 2 and 4 (4+ maybe ?)
}
return project.applyTemplate(template, props)
@@ -68,17 +73,20 @@ object VelocityTemplate : BaseTemplate() {
return project.applyTemplate(VELOCITY_BUILD_CONSTANTS_TEMPLATE, props)
}
- fun applyBuildGradle(project: Project, buildSystem: BuildSystem): String {
+ fun applyBuildGradle(project: Project, buildSystem: BuildSystem, config: VelocityProjectConfig): String {
+ val javaVersion = config.javaVersion.feature
val props = mapOf(
"GROUP_ID" to buildSystem.groupId,
"PLUGIN_ID" to buildSystem.artifactId,
- "PLUGIN_VERSION" to buildSystem.version
+ "PLUGIN_VERSION" to buildSystem.version,
+ "JAVA_VERSION" to javaVersion
)
return project.applyTemplate(VELOCITY_BUILD_GRADLE_TEMPLATE, props)
}
- fun applyGradleProp(project: Project): String = project.applyTemplate(VELOCITY_GRADLE_PROPERTIES_TEMPLATE)
+ fun applyGradleProp(project: Project, javaVersion: Int?): String =
+ project.applyTemplate(VELOCITY_GRADLE_PROPERTIES_TEMPLATE, mapOf("JAVA_VERSION" to javaVersion))
fun applySettingsGradle(project: Project, artifactId: String): String {
val props = mapOf("ARTIFACT_ID" to artifactId)
diff --git a/src/main/kotlin/platform/velocity/framework/VelocityPresentationProvider.kt b/src/main/kotlin/platform/velocity/framework/VelocityPresentationProvider.kt
index 498650cf4..2b589f98a 100644
--- a/src/main/kotlin/platform/velocity/framework/VelocityPresentationProvider.kt
+++ b/src/main/kotlin/platform/velocity/framework/VelocityPresentationProvider.kt
@@ -14,6 +14,7 @@ import com.demonwav.mcdev.asset.PlatformAssets
import com.demonwav.mcdev.util.localFile
import com.intellij.framework.library.LibraryVersionProperties
import com.intellij.openapi.roots.libraries.LibraryPresentationProvider
+import com.intellij.openapi.util.io.JarUtil
import com.intellij.openapi.vfs.VirtualFile
import java.io.BufferedReader
import java.util.jar.JarFile
@@ -24,6 +25,10 @@ class VelocityPresentationProvider : LibraryPresentationProvider): LibraryVersionProperties? {
for (classesRoot in classesRoots) {
runCatching {
+ if (JarUtil.containsClass(classesRoot.localFile, "com.velocitypowered.api.proxy.ProxyServer")) {
+ return LibraryVersionProperties()
+ }
+
// Velocity API jar has no Manifest entries, so we search for their annotation processor instead
val registeredAPs = JarFile(classesRoot.localFile).use { jar ->
val aps = jar.getEntry("META-INF/services/javax.annotation.processing.Processor")
diff --git a/src/main/kotlin/platform/velocity/util/VelocityConstants.kt b/src/main/kotlin/platform/velocity/util/VelocityConstants.kt
index 1605c9e33..77a2d5d24 100644
--- a/src/main/kotlin/platform/velocity/util/VelocityConstants.kt
+++ b/src/main/kotlin/platform/velocity/util/VelocityConstants.kt
@@ -10,9 +10,15 @@
package com.demonwav.mcdev.platform.velocity.util
+import com.demonwav.mcdev.util.SemanticVersion
+
object VelocityConstants {
const val PLUGIN_ANNOTATION = "com.velocitypowered.api.plugin.Plugin"
const val SUBSCRIBE_ANNOTATION = "com.velocitypowered.api.event.Subscribe"
const val KYORI_TEXT_COLOR = "net.kyori.text.format.TextColor"
+
+ val API_2 = SemanticVersion.release(2)
+ val API_3 = SemanticVersion.release(3)
+ val API_4 = SemanticVersion.release(4)
}
diff --git a/src/main/kotlin/util/MinecraftVersions.kt b/src/main/kotlin/util/MinecraftVersions.kt
index bff2ca9c8..772c3480d 100644
--- a/src/main/kotlin/util/MinecraftVersions.kt
+++ b/src/main/kotlin/util/MinecraftVersions.kt
@@ -10,9 +10,16 @@
package com.demonwav.mcdev.util
+import com.intellij.util.lang.JavaVersion
+
object MinecraftVersions {
val MC1_12_2 = SemanticVersion.release(1, 12, 2)
val MC1_14_4 = SemanticVersion.release(1, 14, 4)
val MC1_16_1 = SemanticVersion.release(1, 16, 1)
val MC1_17 = SemanticVersion.release(1, 17)
+
+ fun requiredJavaVersion(minecraftVersion: SemanticVersion) = when {
+ minecraftVersion >= MC1_17 -> JavaVersion.compose(16)
+ else -> JavaVersion.compose(8)
+ }
}
diff --git a/src/main/kotlin/util/VersionRange.kt b/src/main/kotlin/util/VersionRange.kt
new file mode 100644
index 000000000..883226e01
--- /dev/null
+++ b/src/main/kotlin/util/VersionRange.kt
@@ -0,0 +1,71 @@
+/*
+ * Minecraft Dev for IntelliJ
+ *
+ * https://minecraftdev.org
+ *
+ * Copyright (c) 2021 minecraft-dev
+ *
+ * MIT License
+ */
+
+package com.demonwav.mcdev.util
+
+/**
+ * A [SemanticVersion] range whose [lower] bound is **inclusive** and [upper] bound is **exclusive** (uncapped if `null`)
+ */
+data class VersionRange(val lower: SemanticVersion, val upper: SemanticVersion? = null) {
+
+ /**
+ * Whether this range consists of only one specific version
+ */
+ val isFixed: Boolean = lower == upper
+
+ private val displayString: String by lazy { "[$lower,${upper ?: ""})" }
+
+ init {
+ if (upper != null && !isFixed) {
+ check(lower <= upper) { "Upper bound ($upper) must be greater than lower bound ($lower)" }
+ }
+ }
+
+ operator fun contains(version: SemanticVersion): Boolean {
+ if (isFixed) {
+ return version == lower
+ }
+ return version >= lower && (upper == null || version < upper)
+ }
+
+ /**
+ * Produces a [VersionRange] combining the highest [lower] bound and lowest [upper] bound of
+ * `this` and the [other] ranges.
+ *
+ * If this results in an empty intersection, `null` is returned.
+ *
+ * E.g. `[1.6,2)` and `[2.1,2.5)` because `2` in the first range is smaller than `2.1` in the second range
+ */
+ fun intersect(other: VersionRange): VersionRange? {
+ val highestLowerBound = maxOf(this.lower, other.lower)
+ val lowestUpperBound = minOf(this.upper, other.upper, Comparator.nullsLast(Comparator.naturalOrder()))
+ if (lowestUpperBound != null && highestLowerBound > lowestUpperBound) {
+ return null
+ }
+ return VersionRange(highestLowerBound, lowestUpperBound)
+ }
+
+ override fun toString(): String = displayString
+
+ companion object {
+
+ /**
+ * Creates a fixed range strictly consisting of the given [version]
+ * @see [isFixed]
+ */
+ fun fixed(version: SemanticVersion): VersionRange = VersionRange(version, version)
+ }
+}
+
+operator fun VersionRange?.contains(version: SemanticVersion): Boolean =
+ this == null || this.contains(version)
+
+infix fun SemanticVersion.until(upperExclusive: SemanticVersion?): VersionRange =
+ VersionRange(this, upperExclusive)
diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml
index c178d9d8f..f8b754010 100644
--- a/src/main/resources/META-INF/plugin.xml
+++ b/src/main/resources/META-INF/plugin.xml
@@ -93,6 +93,8 @@
+
+
@@ -788,6 +790,8 @@
implementationClass="com.demonwav.mcdev.platform.bungeecord.inspection.BungeeCordListenerImplementedInspection"/>
+
+
diff --git a/src/main/resources/fileTemplates/j2ee/multi/Multi-Module Base build.gradle.ft b/src/main/resources/fileTemplates/j2ee/multi/Multi-Module Base build.gradle.ft
index bd10acc91..352b9ad2e 100644
--- a/src/main/resources/fileTemplates/j2ee/multi/Multi-Module Base build.gradle.ft
+++ b/src/main/resources/fileTemplates/j2ee/multi/Multi-Module Base build.gradle.ft
@@ -12,7 +12,7 @@ subprojects {
group = parent.group
version = parent.version
- def targetJavaVersion = 8
+ def targetJavaVersion = property('javaVersion') as int
java {
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
sourceCompatibility = javaVersion
diff --git a/src/main/resources/fileTemplates/j2ee/multi/Multi-Module Base gradle.properties.ft b/src/main/resources/fileTemplates/j2ee/multi/Multi-Module Base gradle.properties.ft
index e69de29bb..752910940 100644
--- a/src/main/resources/fileTemplates/j2ee/multi/Multi-Module Base gradle.properties.ft
+++ b/src/main/resources/fileTemplates/j2ee/multi/Multi-Module Base gradle.properties.ft
@@ -0,0 +1 @@
+javaVersion=8
diff --git a/src/main/resources/fileTemplates/j2ee/velocity/Velocity Submodule pom.xml.ft b/src/main/resources/fileTemplates/j2ee/velocity/Velocity Submodule pom.xml.ft
index a17575bce..ebc5b3be3 100644
--- a/src/main/resources/fileTemplates/j2ee/velocity/Velocity Submodule pom.xml.ft
+++ b/src/main/resources/fileTemplates/j2ee/velocity/Velocity Submodule pom.xml.ft
@@ -16,7 +16,7 @@
- 1.8
+ ${JAVA_VERSION}
UTF-8
diff --git a/src/main/resources/fileTemplates/j2ee/velocity/Velocity build.gradle.ft b/src/main/resources/fileTemplates/j2ee/velocity/Velocity build.gradle.ft
index 34f7d045b..336743baa 100644
--- a/src/main/resources/fileTemplates/j2ee/velocity/Velocity build.gradle.ft
+++ b/src/main/resources/fileTemplates/j2ee/velocity/Velocity build.gradle.ft
@@ -13,7 +13,7 @@ repositories {
dependencies {
}
-def targetJavaVersion = 8
+def targetJavaVersion = ${JAVA_VERSION}
java {
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
sourceCompatibility = javaVersion
diff --git a/src/main/resources/fileTemplates/j2ee/velocity/Velocity gradle.properties.ft b/src/main/resources/fileTemplates/j2ee/velocity/Velocity gradle.properties.ft
index e69de29bb..bc215b8ea 100644
--- a/src/main/resources/fileTemplates/j2ee/velocity/Velocity gradle.properties.ft
+++ b/src/main/resources/fileTemplates/j2ee/velocity/Velocity gradle.properties.ft
@@ -0,0 +1,3 @@
+#if (${JAVA_VERSION})
+javaVersion=${JAVA_VERSION}
+#end
diff --git a/src/main/resources/fileTemplates/j2ee/velocity/Velocity pom.xml.ft b/src/main/resources/fileTemplates/j2ee/velocity/Velocity pom.xml.ft
index 0b7f2500a..876408862 100644
--- a/src/main/resources/fileTemplates/j2ee/velocity/Velocity pom.xml.ft
+++ b/src/main/resources/fileTemplates/j2ee/velocity/Velocity pom.xml.ft
@@ -12,7 +12,7 @@
- 1.8
+ ${JAVA_VERSION}
UTF-8