diff --git a/src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt b/src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt index f5efd0b54..bba3dddca 100644 --- a/src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt +++ b/src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt @@ -49,6 +49,7 @@ import com.intellij.psi.PsiNameHelper import com.intellij.psi.util.PsiTypesUtil import com.intellij.psi.util.PsiUtil import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes +import com.intellij.openapi.diagnostic.Logger class MinecraftClassCreateAction : CreateTemplateInPackageAction( @@ -69,9 +70,13 @@ class MinecraftClassCreateAction : val isForge = MinecraftFacet.getInstance(module, ForgeModuleType) != null val isNeoForge = MinecraftFacet.getInstance(module, NeoForgeModuleType) != null val isFabric = MinecraftFacet.getInstance(module, FabricModuleType) != null - val mcVersion = MinecraftFacet.getInstance(module, McpModuleType)?.getSettings() - ?.minecraftVersion?.let(SemanticVersion::parse) + + val mcVersion = MinecraftFacet.getInstance(module, NeoForgeModuleType)?.computeVersion()?: + MinecraftFacet.getInstance(module, McpModuleType)?.getSettings() + ?.minecraftVersion?.let(SemanticVersion::parse) ?: + MinecraftFacet.getInstance(module, FabricModuleType)?.computeVersion() + // LOG.info("VERSIONI: $neomcVersion, $mcVersion, $fabricMcVersion") if (isForge && mcVersion != null) { val icon = PlatformAssets.FORGE_ICON @@ -88,29 +93,39 @@ class MinecraftClassCreateAction : builder.addKind("Packet", icon, MinecraftTemplates.FORGE_1_17_PACKET_TEMPLATE) } else { builder.addKind("Block", icon, MinecraftTemplates.FORGE_1_17_BLOCK_TEMPLATE) - builder.addKind("Enchantment", icon, MinecraftTemplates.FORGE_1_17_ENCHANTMENT_TEMPLATE) builder.addKind("Item", icon, MinecraftTemplates.FORGE_1_17_ITEM_TEMPLATE) builder.addKind("Mob effect", icon, MinecraftTemplates.FORGE_1_17_MOB_EFFECT_TEMPLATE) builder.addKind("Packet", icon, MinecraftTemplates.FORGE_1_18_PACKET_TEMPLATE) } + if (mcVersion < MinecraftVersions.MC1_21) { + builder.addKind("Enchantment", icon, MinecraftTemplates.FORGE_1_17_ENCHANTMENT_TEMPLATE) + } } if (isNeoForge) { val icon = PlatformAssets.NEOFORGE_ICON builder.addKind("Block", icon, MinecraftTemplates.NEOFORGE_BLOCK_TEMPLATE) - builder.addKind("Enchantment", icon, MinecraftTemplates.NEOFORGE_ENCHANTMENT_TEMPLATE) builder.addKind("Item", icon, MinecraftTemplates.NEOFORGE_ITEM_TEMPLATE) builder.addKind("Mob effect", icon, MinecraftTemplates.NEOFORGE_MOB_EFFECT_TEMPLATE) builder.addKind("Packet", icon, MinecraftTemplates.NEOFORGE_PACKET_TEMPLATE) + if (mcVersion == null || mcVersion < MinecraftVersions.MC1_21) + builder.addKind("Enchantment", icon, MinecraftTemplates.NEOFORGE_ENCHANTMENT_TEMPLATE) } if (isFabric) { val icon = PlatformAssets.FABRIC_ICON + if (mcVersion != null && mcVersion >= MinecraftVersions.MC26_1) { + builder.addKind("Block", icon, MinecraftTemplates.FABRIC_26_1_BLOCK_TEMPLATE) + builder.addKind("Item", icon, MinecraftTemplates.FABRIC_26_1_ITEM_TEMPLATE) + builder.addKind("Mob effect", icon, MinecraftTemplates.FABRIC_26_1_MOB_EFFECT_TEMPLATE) - builder.addKind("Block", icon, MinecraftTemplates.FABRIC_BLOCK_TEMPLATE) - builder.addKind("Enchantment", icon, MinecraftTemplates.FABRIC_ENCHANTMENT_TEMPLATE) - builder.addKind("Item", icon, MinecraftTemplates.FABRIC_ITEM_TEMPLATE) - builder.addKind("Status effect", icon, MinecraftTemplates.FABRIC_STATUS_EFFECT_TEMPLATE) + } else { + builder.addKind("Block", icon, MinecraftTemplates.FABRIC_1_21_11_BLOCK_TEMPLATE) + builder.addKind("Item", icon, MinecraftTemplates.FABRIC_1_21_11_ITEM_TEMPLATE) + builder.addKind("Status effect", icon, MinecraftTemplates.FABRIC_1_21_11_STATUS_EFFECT_TEMPLATE) + } + if (mcVersion != null && mcVersion < MinecraftVersions.MC1_21) + builder.addKind("Enchantment", icon, MinecraftTemplates.FABRIC_1_21_11_ENCHANTMENT_TEMPLATE) } } @@ -140,7 +155,7 @@ class MinecraftClassCreateAction : return JavaDirectoryService.getInstance().createClass(dir, className, templateName, false) } - private class ClassInputValidator( + class ClassInputValidator( private val project: Project, private val directory: PsiDirectory, ) : InputValidatorEx { diff --git a/src/main/kotlin/insight/generation/MinecraftResourceCreateAction.kt b/src/main/kotlin/insight/generation/MinecraftResourceCreateAction.kt new file mode 100644 index 000000000..7905b66df --- /dev/null +++ b/src/main/kotlin/insight/generation/MinecraftResourceCreateAction.kt @@ -0,0 +1,99 @@ +package com.demonwav.mcdev.insight.generation + +import com.demonwav.mcdev.asset.GeneralAssets +import com.demonwav.mcdev.asset.MCDevBundle +import com.demonwav.mcdev.asset.PlatformAssets +import com.demonwav.mcdev.facet.MinecraftFacet +import com.demonwav.mcdev.insight.generation.MinecraftClassCreateAction.ClassInputValidator +import com.demonwav.mcdev.platform.fabric.FabricModuleType +import com.demonwav.mcdev.platform.forge.ForgeModuleType +import com.demonwav.mcdev.platform.mcp.McpModuleType +import com.demonwav.mcdev.platform.neoforge.NeoForgeModuleType +import com.demonwav.mcdev.util.MinecraftTemplates +import com.demonwav.mcdev.util.MinecraftVersions +import com.demonwav.mcdev.util.SemanticVersion +import com.demonwav.mcdev.util.findModule +import com.intellij.ide.actions.CreateFileFromTemplateAction +import com.intellij.ide.actions.CreateFileFromTemplateDialog +import com.intellij.ide.fileTemplates.FileTemplateManager +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectRootManager +import com.intellij.openapi.util.NlsContexts +import com.intellij.psi.PsiDirectory +import com.intellij.psi.PsiFile +import java.util.* +import org.jetbrains.annotations.NonNls +import org.jetbrains.jps.model.java.JavaResourceRootType + + +class MinecraftResourceCreateAction: CreateFileFromTemplateAction( + Const.CAPTION, + MCDevBundle("generate.class.description"), + GeneralAssets.MC_TEMPLATE +) { + override fun isAvailable(context: DataContext):Boolean { + val psi = context.getData(CommonDataKeys.PSI_ELEMENT) + val module = psi?.findModule() ?: return false + var dir: PsiDirectory? = null; + if(psi is PsiFile) { + dir = psi.containingDirectory + // MinecraftFacet.getInstance(module)?.findFile(psi. SourceType.RESOURCE) ?: return false + }else if(psi is PsiDirectory) { + dir = psi + } + val project = context.getData(CommonDataKeys.PROJECT) ?: return false + val underSourceRootOfType = ProjectRootManager.getInstance(project).fileIndex.isUnderSourceRootOfType( + dir?.virtualFile ?: return false, + setOf(JavaResourceRootType.RESOURCE) + ) + val mcVersion = MinecraftFacet.getInstance(module, McpModuleType)?.getSettings() + ?.minecraftVersion?.let(SemanticVersion::parse) ?: + MinecraftFacet.getInstance(module, FabricModuleType)?.computeVersion() ?: + MinecraftFacet.getInstance(module, NeoForgeModuleType)?.computeVersion() + + return underSourceRootOfType && mcVersion != null && mcVersion >= MinecraftVersions.MC1_21 + } + override fun buildDialog( + project: Project, + directory: PsiDirectory, + builder: CreateFileFromTemplateDialog.Builder + ) { + builder.setTitle(Const.CAPTION) + builder.setValidator(ClassInputValidator(project, directory)) + + val module = directory.findModule() ?: return + //For a possible update + // val mcVersion = MinecraftFacet.getInstance(module, McpModuleType)?.getSettings() + // ?.minecraftVersion?.let(SemanticVersion::parse) ?: + // MinecraftFacet.getInstance(module, FabricModuleType)?.computeVersion() ?: + // MinecraftFacet.getInstance(module, NeoForgeModuleType)?.computeVersion() + //if(mcVersion != null && mcVersion >= MinecraftVersions.MC1_21) { + val icon = PlatformAssets.MINECRAFT_ICON + builder.addKind("Enchantment", icon, MinecraftTemplates.JSON_ENCHANTMENT_TEMPLATE) + // } + } + override fun getActionName( + directory: PsiDirectory?, + newName: @NonNls String, + templateName: @NonNls String? + ): @NlsContexts.Command String = Const.CAPTION + + override fun createFile(name: String?, templateName: String?, dir: PsiDirectory?): PsiFile? { + val module = dir?.findModule() ?: return null + val modids = MinecraftFacet.getInstance(module, ForgeModuleType)?.modIds ?: + MinecraftFacet.getInstance(module, FabricModuleType)?.modIds ?: + MinecraftFacet.getInstance(module, NeoForgeModuleType)?.modIds ?: return null + val modid = modids[0] + + val template = FileTemplateManager.getInstance(dir?.project ?: return null).getInternalTemplate(templateName ?: return null) + return createFileFromTemplate(name, template, dir, defaultTemplateProperty,true, Collections.emptyMap(), mapOf(Pair("MODID", modid))) + + } + + private object Const { + val CAPTION + get() = MCDevBundle("generate.json.caption") + } +} diff --git a/src/main/kotlin/platform/AbstractModule.kt b/src/main/kotlin/platform/AbstractModule.kt index 43a81566b..30cc734ed 100644 --- a/src/main/kotlin/platform/AbstractModule.kt +++ b/src/main/kotlin/platform/AbstractModule.kt @@ -24,10 +24,12 @@ import com.demonwav.mcdev.facet.MinecraftFacet import com.demonwav.mcdev.insight.generation.EventListenerGenerationSupport import com.demonwav.mcdev.inspection.IsCancelled import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.util.Key import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiExpression +import com.intellij.psi.PsiManager import com.intellij.psi.PsiMethod import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiReferenceExpression @@ -36,6 +38,8 @@ import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker import javax.swing.Icon +import com.intellij.lang.properties.psi.PropertiesFile + abstract class AbstractModule(protected val facet: MinecraftFacet) { @@ -107,4 +111,21 @@ abstract class AbstractModule(protected val facet: MinecraftFacet) { open fun init() {} open fun dispose() {} open fun refresh() {} + + fun detectMinecraftVersionInProps(keyname: String): String? { + val contentRoots = ModuleRootManager.getInstance(module).contentRoots + var dir = contentRoots.firstOrNull() ?: return null + + val projectBase = project.basePath + while (true) { + val found = dir.findChild("gradle.properties") + if (found != null) { + val propsFile = PsiManager.getInstance(project).findFile(found) as? PropertiesFile ?: return null + return propsFile.findPropertyByKey(keyname)?.value + } + val parent = dir.parent ?: return null + if (dir.path == projectBase) return null + dir = parent + } + } } diff --git a/src/main/kotlin/platform/fabric/FabricModule.kt b/src/main/kotlin/platform/fabric/FabricModule.kt index 8481cc395..e190725fb 100644 --- a/src/main/kotlin/platform/fabric/FabricModule.kt +++ b/src/main/kotlin/platform/fabric/FabricModule.kt @@ -22,6 +22,7 @@ package com.demonwav.mcdev.platform.fabric import com.demonwav.mcdev.asset.PlatformAssets import com.demonwav.mcdev.facet.MinecraftFacet +import com.demonwav.mcdev.insight.generation.MinecraftClassCreateAction import com.demonwav.mcdev.platform.AbstractModule import com.demonwav.mcdev.platform.PlatformType import com.demonwav.mcdev.platform.fabric.reference.EntryPointReference @@ -30,11 +31,14 @@ import com.demonwav.mcdev.platform.mcp.fabricloom.FabricLoomData import com.demonwav.mcdev.platform.mcp.mappings.HardcodedYarnToMojmap import com.demonwav.mcdev.platform.mcp.mappings.HasCustomNamedMappings import com.demonwav.mcdev.platform.mcp.mappings.MappingsManager +import com.demonwav.mcdev.util.SemanticVersion import com.demonwav.mcdev.util.SourceType import com.demonwav.mcdev.util.nullable import com.demonwav.mcdev.util.runCatchingKtIdeaExceptions import com.intellij.json.JsonUtil +import com.intellij.json.psi.JsonArray import com.intellij.json.psi.JsonFile +import com.intellij.json.psi.JsonObject import com.intellij.json.psi.JsonStringLiteral import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement @@ -67,6 +71,7 @@ class FabricModule internal constructor(facet: MinecraftFacet) : AbstractModule( override val moduleType = FabricModuleType override val type = PlatformType.FABRIC override val icon = PlatformAssets.FABRIC_ICON + var fabricMinecraftVersion: SemanticVersion? = null; override fun computeModIds(): List { val jsonFile = PsiManager.getInstance(project).findFile(fabricJson ?: return emptyList()) as? JsonFile @@ -75,6 +80,51 @@ class FabricModule internal constructor(facet: MinecraftFacet) : AbstractModule( return listOfNotNull((jsonObj.findProperty("id")?.value as? JsonStringLiteral)?.value) } + fun computeVersion(): SemanticVersion? { + val jsonFile = PsiManager.getInstance(project).findFile(fabricJson ?: return null) as? JsonFile + ?: return null + val jsonObj = JsonUtil.getTopLevelObject(jsonFile) ?: return null; + val depends = jsonObj.findProperty("depends")?.value as? JsonObject + val range = depends?.findProperty("minecraft") + var value = (range?.value as? JsonStringLiteral)?.value; + val arrayValue = (range?.value as? JsonArray) + if (value != null) { + if (value.contains("\${")) { + val varName = value.substring(value.indexOf("\${") + 2, value.lastIndexOf("}")) + value = value.replace("\${${varName}}", detectMinecraftVersionInProps(varName) ?: return null) + } + val end = value.trimStart { !it.isDigit() } + val parse = try { + SemanticVersion.parse(end) + } catch (_: NumberFormatException) { + null + } + fabricMinecraftVersion = parse + return parse + } else if (arrayValue != null) { + var majorVersion: SemanticVersion? = null; + for (child in arrayValue.valueList) { + var string = (child as? JsonStringLiteral)?.value.toString() + if (string.contains("\${")) { + val varName = string.substring(string.indexOf("\${") + 2, string.lastIndexOf("}")) + string = string.replace("\${${varName}}", detectMinecraftVersionInProps(varName) ?: return null) + } + val end = string.trimStart { !it.isDigit() } + val value = try { + SemanticVersion.parse(end) + } catch (_: NumberFormatException) { + null + } + if (value != null) { + if (majorVersion == null || value > majorVersion) majorVersion = value + }; + } + fabricMinecraftVersion = majorVersion + return majorVersion + } + return null + } + override fun isEventClassValid(eventClass: PsiClass, method: PsiMethod?) = true override fun writeErrorMessageForEventParameter(eventClass: PsiClass, method: PsiMethod) = "" @@ -105,8 +155,10 @@ class FabricModule internal constructor(facet: MinecraftFacet) : AbstractModule( mappingNamespacesField = mappingDetection.namespaces } - private fun detectMappings(): MappingDetectionResult { + private fun + detectMappings(): MappingDetectionResult { val gradleData = GradleUtil.findGradleModuleData(facet.module) ?: return MappingDetectionResult.DEFAULT + val loomData = gradleData.children.find { it.key == FabricLoomData.KEY }?.data as? FabricLoomData ?: return MappingDetectionResult.DEFAULT val mappingsFile = loomData.tinyMappings ?: return MappingDetectionResult.DEFAULT @@ -147,7 +199,8 @@ class FabricModule internal constructor(facet: MinecraftFacet) : AbstractModule( override fun visitMethodArg(argPosition: Int, lvIndex: Int, srcName: String?) = false - override fun visitMethodVar(lvtRowIndex: Int, lvIndex: Int, startOpIdx: Int, endOpIdx: Int, srcName: String?) = false + override fun visitMethodVar(lvtRowIndex: Int, lvIndex: Int, startOpIdx: Int, endOpIdx: Int, srcName: String?) = + false override fun visitDstName(targetKind: MappedElementKind?, namespace: Int, name: String) { if (namespace == namedIndex && name == "net/minecraft/client/MinecraftClient") { diff --git a/src/main/kotlin/platform/neoforge/NeoForgeModule.kt b/src/main/kotlin/platform/neoforge/NeoForgeModule.kt index 19798ca2b..6dae19dc9 100644 --- a/src/main/kotlin/platform/neoforge/NeoForgeModule.kt +++ b/src/main/kotlin/platform/neoforge/NeoForgeModule.kt @@ -28,6 +28,8 @@ import com.demonwav.mcdev.platform.AbstractModule import com.demonwav.mcdev.platform.PlatformType import com.demonwav.mcdev.platform.forge.ForgeModule import com.demonwav.mcdev.platform.neoforge.util.NeoForgeConstants +import com.demonwav.mcdev.toml.stringValue +import com.demonwav.mcdev.util.SemanticVersion import com.demonwav.mcdev.util.SourceType import com.demonwav.mcdev.util.nullable import com.demonwav.mcdev.util.runCatchingKtIdeaExceptions @@ -35,15 +37,21 @@ import com.demonwav.mcdev.util.runWriteTaskLater import com.demonwav.mcdev.util.waitForAllSmart import com.intellij.json.JsonFileType import com.intellij.lang.jvm.JvmModifier +import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.fileTypes.FileTypeManager import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement +import com.intellij.psi.PsiManager import com.intellij.psi.PsiMethod import com.intellij.psi.PsiMethodCallExpression +import org.jetbrains.kotlin.util.removeSuffixIfPresent import org.jetbrains.uast.UClass import org.jetbrains.uast.UIdentifier import org.jetbrains.uast.toUElementOfType +import org.toml.lang.psi.TomlArrayTable +import org.toml.lang.psi.TomlFile +import org.toml.lang.psi.ext.name class NeoForgeModule internal constructor(facet: MinecraftFacet) : AbstractModule(facet) { @@ -57,7 +65,39 @@ class NeoForgeModule internal constructor(facet: MinecraftFacet) : AbstractModul override val icon = PlatformAssets.NEOFORGE_ICON override fun computeModIds() = ForgeModule.getModsFromModsToml(project, modsToml) - + fun computeVersion(): SemanticVersion? { + val tomlFile = PsiManager.getInstance(project).findFile(modsToml ?: return null) as? TomlFile + ?: return null + + for (child in tomlFile.children) { + if (child is TomlArrayTable && child.header.key?.name == "dependencies."+ computeModIds()[0]) { + var founded = false + for (entry in child.entries) { + if (entry.key.name == computeModIds()[0]) { + founded = true + } + } + if(!founded) continue + else{ + for (entry in child.entries) { + if (entry.key.name == "versionRange") { + val value = entry.value.toString() + var valueParsed = value; + if(value.contains("\${")) { + val varName = value.substring(value.indexOf("\${")+2, value.lastIndexOf("}")) + valueParsed = value.replace("\${${varName}}", detectMinecraftVersionInProps(varName)?: return null) + } + return SemanticVersion.parse(valueParsed.trim() + .removeSuffixIfPresent(")") + .removeSuffixIfPresent("]") + .substringAfter(",")) + } + } + } + } + } + return null + } override val eventListenerGenSupport: EventListenerGenerationSupport = NeoForgeEventListenerGenerationSupport() override fun init() { diff --git a/src/main/kotlin/util/MinecraftTemplates.kt b/src/main/kotlin/util/MinecraftTemplates.kt index f071706ea..1aac61ebe 100644 --- a/src/main/kotlin/util/MinecraftTemplates.kt +++ b/src/main/kotlin/util/MinecraftTemplates.kt @@ -161,13 +161,22 @@ class MinecraftTemplates : FileTemplateGroupDescriptorFactory { } FileTemplateGroupDescriptor("Fabric", PlatformAssets.FABRIC_ICON).let { fabricSkeletonGroup -> skeletonGroup.addTemplate(fabricSkeletonGroup) - fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_BLOCK_TEMPLATE)) - fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_ITEM_TEMPLATE)) - fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_ENCHANTMENT_TEMPLATE)) - fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_STATUS_EFFECT_TEMPLATE)) + fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_1_21_11_BLOCK_TEMPLATE)) + fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_1_21_11_ITEM_TEMPLATE)) + fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_1_21_11_ENCHANTMENT_TEMPLATE)) + fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_1_21_11_STATUS_EFFECT_TEMPLATE)) + + fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_26_1_BLOCK_TEMPLATE)) + fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_26_1_ITEM_TEMPLATE)) + fabricSkeletonGroup.addTemplate(FileTemplateDescriptor(FABRIC_26_1_MOB_EFFECT_TEMPLATE)) + } - } + } + FileTemplateGroupDescriptor("Json", PlatformAssets.MINECRAFT_ICON).let { jsonGroup -> + group.addTemplate(jsonGroup) + jsonGroup.addTemplate(JSON_ENCHANTMENT_TEMPLATE) + } FileTemplateGroupDescriptor("Licenses", null).let { licenseGroup -> group.addTemplate(licenseGroup) enumEntries().forEach { license -> @@ -268,10 +277,14 @@ class MinecraftTemplates : FileTemplateGroupDescriptorFactory { const val FORGE_1_18_PACKET_TEMPLATE = "ForgePacket (1.18+).java" - const val FABRIC_BLOCK_TEMPLATE = "FabricBlock.java" - const val FABRIC_ITEM_TEMPLATE = "FabricItem.java" - const val FABRIC_ENCHANTMENT_TEMPLATE = "FabricEnchantment.java" - const val FABRIC_STATUS_EFFECT_TEMPLATE = "FabricStatusEffect.java" + const val FABRIC_1_21_11_BLOCK_TEMPLATE = "FabricBlock (1.21.11-).java" + const val FABRIC_1_21_11_ITEM_TEMPLATE = "FabricItem (1.21.11-).java" + const val FABRIC_1_21_11_ENCHANTMENT_TEMPLATE = "FabricEnchantment (1.21.11-).java" + const val FABRIC_1_21_11_STATUS_EFFECT_TEMPLATE = "FabricStatusEffect (1.21.11-).java" + + const val FABRIC_26_1_BLOCK_TEMPLATE = "FabricBlock (26.1+).java" + const val FABRIC_26_1_ITEM_TEMPLATE = "FabricItem (26.1+).java" + const val FABRIC_26_1_MOB_EFFECT_TEMPLATE = "FabricMobEffect (26.1+).java" const val NEOFORGE_MIXINS_JSON_TEMPLATE = "NeoForge Mixins Config.json" const val NEOFORGE_MAIN_CLASS_TEMPLATE = "NeoForge Main Class.java" @@ -294,6 +307,8 @@ class MinecraftTemplates : FileTemplateGroupDescriptorFactory { const val NEOFORGE_PACKET_TEMPLATE = "NeoForgePacket.java" const val NEOFORGE_ENCHANTMENT_TEMPLATE = "NeoForgeEnchantment.java" const val NEOFORGE_MOB_EFFECT_TEMPLATE = "NeoForgeMobEffect.java" + + const val JSON_ENCHANTMENT_TEMPLATE = "JsonEnchantment.json" } private fun template(fileName: String, displayName: String? = null) = CustomDescriptor(fileName, displayName) diff --git a/src/main/kotlin/util/MinecraftVersions.kt b/src/main/kotlin/util/MinecraftVersions.kt index a5f77e609..193dbeb07 100644 --- a/src/main/kotlin/util/MinecraftVersions.kt +++ b/src/main/kotlin/util/MinecraftVersions.kt @@ -48,6 +48,7 @@ object MinecraftVersions { val MC1_21_1 = SemanticVersion.release(1, 21, 1) val MC1_21_11 = SemanticVersion.release(1, 21, 11) val MC26_1 = SemanticVersion.release(26, 1) + val MC26_2 = SemanticVersion.release(26, 2) fun requiredJavaVersion(minecraftVersion: SemanticVersion) = when { minecraftVersion <= MC1_16_5 -> JavaSdkVersion.JDK_1_8 diff --git a/src/main/kotlin/util/SemanticVersion.kt b/src/main/kotlin/util/SemanticVersion.kt index e93cc1084..12b2d7aa4 100644 --- a/src/main/kotlin/util/SemanticVersion.kt +++ b/src/main/kotlin/util/SemanticVersion.kt @@ -20,11 +20,14 @@ package com.demonwav.mcdev.util +import com.demonwav.mcdev.asset.MCDevBundle import com.demonwav.mcdev.creator.custom.model.TemplateApi import com.demonwav.mcdev.util.SemanticVersion.Companion.VersionPart.PreReleasePart import com.demonwav.mcdev.util.SemanticVersion.Companion.VersionPart.ReleasePart import com.demonwav.mcdev.util.SemanticVersion.Companion.VersionPart.TextPart import java.net.URLDecoder +import com.intellij.notification.Notification +import com.intellij.notification.NotificationType /** * Represents a comparable and generalised "semantic version". @@ -166,32 +169,32 @@ class SemanticVersion( listOf(mainPart), ) } - - parseMinecraftSnapshot(value)?.let { return it } - - val decodedValue = value.split('+').joinToString("+") { URLDecoder.decode(it, Charsets.UTF_8) } - val mainPartAndMetadata = decodedValue.split("+", limit = 2) - val mainPart = mainPartAndMetadata[0] - val metadata = mainPartAndMetadata.getOrNull(1) ?: "" - - val separator = SEPARATORS.find { it in mainPart } - val beforeSeparator = if (separator == null) mainPart else mainPart.substringBefore(separator) - val partCount = beforeSeparator.count { it == '.' } + 1 - val parts = mainPart.split('.', limit = partCount).map { part -> - if (separator != null && separator in part) { - val subParts = part.split(separator, limit = 2) - parsePreReleasePart(subParts[0], subParts[1], separator, part) - } else { - // Forge has a single version which should be 14.8.* but is actually 14.v8.* - val numberPart = if (part.startsWith('v')) { - part.substring(1) + parseMinecraftSnapshot(value)?.let { return it } + + val decodedValue = value.split('+').joinToString("+") { URLDecoder.decode(it, Charsets.UTF_8) } + val mainPartAndMetadata = decodedValue.split("+", limit = 2) + val mainPart = mainPartAndMetadata[0] + val metadata = mainPartAndMetadata.getOrNull(1) ?: "" + + val separator = SEPARATORS.find { it in mainPart } + val beforeSeparator = if (separator == null) mainPart else mainPart.substringBefore(separator) + val partCount = beforeSeparator.count { it == '.' } + 1 + val parts = mainPart.split('.', limit = partCount).map { part -> + if (separator != null && separator in part) { + val subParts = part.split(separator, limit = 2) + parsePreReleasePart(subParts[0], subParts[1], separator, part) } else { - part + // Forge has a single version which should be 14.8.* but is actually 14.v8.* + val numberPart = if (part.startsWith('v')) { + part.substring(1) + } else { + part + } + ReleasePart(parseInt(numberPart), part) } - ReleasePart(parseInt(numberPart), part) } - } - return SemanticVersion(parts, metadata) + return SemanticVersion(parts, metadata) + } sealed class VersionPart : Comparable { diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 8aec3d25e..3aa046780 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -1751,6 +1751,10 @@ text="Minecraft Class" description="Create skeleton classes used in Minecraft Mods"> + + + diff --git a/src/main/resources/fileTemplates/j2ee/json/JsonEnchantment.json.ft b/src/main/resources/fileTemplates/j2ee/json/JsonEnchantment.json.ft new file mode 100644 index 000000000..ab4722c25 --- /dev/null +++ b/src/main/resources/fileTemplates/j2ee/json/JsonEnchantment.json.ft @@ -0,0 +1,22 @@ +{ + "description": { + "translate": "enchantment.${MODID}.${NAME}" + }, + "supported_items": "#yourtag", + "weight": 1, + "max_level": 3, + "min_cost": { + "base": 5, + "per_level_above_first": 8 + }, + "max_cost": { + "base": 25, + "per_level_above_first": 8 + }, + "slots": [ + "mainhand" + ], + "anvil_cost": 2, + "effects": { + } +} \ No newline at end of file diff --git a/src/main/resources/fileTemplates/j2ee/json/JsonEnchantment.json.html b/src/main/resources/fileTemplates/j2ee/json/JsonEnchantment.json.html new file mode 100644 index 000000000..2c8eda21c --- /dev/null +++ b/src/main/resources/fileTemplates/j2ee/json/JsonEnchantment.json.html @@ -0,0 +1,25 @@ + + + + +

This is an example enchantment template for minecraft 1.21+

+ + \ No newline at end of file diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock.java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (1.21.11-).java.ft similarity index 100% rename from src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock.java.ft rename to src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (1.21.11-).java.ft diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment.java.html b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (1.21.11-).java.html similarity index 93% rename from src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment.java.html rename to src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (1.21.11-).java.html index 3d9b2f8b9..f5667c727 100644 --- a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment.java.html +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (1.21.11-).java.html @@ -20,6 +20,6 @@ - A basic enchantment class for fabric. + A basic block class for fabric 1.21.11-. diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (26.1+).java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (26.1+).java.ft new file mode 100644 index 000000000..671f8f4d1 --- /dev/null +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (26.1+).java.ft @@ -0,0 +1,10 @@ +#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end +#parse("File Header.java") + +import net.minecraft.world.level.block.Block; + +public class ${NAME} extends Block { + public ${NAME}(Properties properties) { + super(properties); + } +} diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock.java.html b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (26.1+).java.html similarity index 94% rename from src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock.java.html rename to src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (26.1+).java.html index 85250ce6e..c4a8f96b0 100644 --- a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock.java.html +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricBlock (26.1+).java.html @@ -20,6 +20,6 @@ - A basic block class for fabric. + A basic block class for fabric 26.1+. diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment.java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment (1.21.11-).java.ft similarity index 100% rename from src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment.java.ft rename to src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment (1.21.11-).java.ft diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment (1.21.11-).java.html b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment (1.21.11-).java.html new file mode 100644 index 000000000..f20134053 --- /dev/null +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricEnchantment (1.21.11-).java.html @@ -0,0 +1,25 @@ + + + + + A basic enchantment class for fabric 1.21.11-. + + diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem.java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (1.21.11-).java.ft similarity index 100% rename from src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem.java.ft rename to src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (1.21.11-).java.ft diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem.java.html b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (1.21.11-).java.html similarity index 93% rename from src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem.java.html rename to src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (1.21.11-).java.html index dcbeee1a6..11bef898f 100644 --- a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem.java.html +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (1.21.11-).java.html @@ -20,6 +20,6 @@ - An empty Fabric item class. + An empty Fabric item class for 1.21.11-. diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (26.1+).java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (26.1+).java.ft new file mode 100644 index 000000000..df9bace43 --- /dev/null +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (26.1+).java.ft @@ -0,0 +1,10 @@ +#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end +#parse("File Header.java") + +import net.minecraft.world.item.Item; + +public class ${NAME} extends Item { + public ${NAME}(Properties props) { + super(props); + } +} diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect.java.html b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (26.1+).java.html similarity index 93% rename from src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect.java.html rename to src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (26.1+).java.html index 12f4b6bb2..11bef898f 100644 --- a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect.java.html +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricItem (26.1+).java.html @@ -20,6 +20,6 @@ - An empty Fabric status effect class. + An empty Fabric item class for 1.21.11-. diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricMobEffect (26.1+).java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricMobEffect (26.1+).java.ft new file mode 100644 index 000000000..67d1d3355 --- /dev/null +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricMobEffect (26.1+).java.ft @@ -0,0 +1,10 @@ +#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end +#parse("File Header.java") + +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +public class ${NAME} extends MobEffect { + public ${NAME}(MobEffectCategory mobEffectCategory, int color) { + super(mobEffectCategory, color); + } +} \ No newline at end of file diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricMobEffect (26.1+).java.html b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricMobEffect (26.1+).java.html new file mode 100644 index 000000000..a75911573 --- /dev/null +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricMobEffect (26.1+).java.html @@ -0,0 +1,25 @@ + + + + +An empty Fabric status effect class for 1.21.11- . + + diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect.java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect (1.21.11-).java.ft similarity index 100% rename from src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect.java.ft rename to src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect (1.21.11-).java.ft diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect (1.21.11-).java.html b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect (1.21.11-).java.html new file mode 100644 index 000000000..a7e4a9a18 --- /dev/null +++ b/src/main/resources/fileTemplates/j2ee/skeleton/fabric/FabricStatusEffect (1.21.11-).java.html @@ -0,0 +1,25 @@ + + + + + An empty Fabric status effect class for 1.21.11- . + + diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/forge/ForgeEnchantment (1.17+).java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/forge/ForgeEnchantment (1.17+).java.ft index c4ae0bd57..cf383cca6 100644 --- a/src/main/resources/fileTemplates/j2ee/skeleton/forge/ForgeEnchantment (1.17+).java.ft +++ b/src/main/resources/fileTemplates/j2ee/skeleton/forge/ForgeEnchantment (1.17+).java.ft @@ -4,9 +4,8 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.EnchantmentCategory; - public class ${NAME} extends Enchantment { - public ${NAME}(Rarity rarity, EnchantmentCategory category, EquipmentSlot[] slots) { - super(rarity, category, slots); + public ${NAME}(Rarity rarity, EnchantmentCategory category, EquipmentSlot[] slots){ + super(rarity, category, slots); } } diff --git a/src/main/resources/fileTemplates/j2ee/skeleton/neoforge/NeoForgeEnchantment.java.ft b/src/main/resources/fileTemplates/j2ee/skeleton/neoforge/NeoForgeEnchantment.java.ft index c4ae0bd57..2e911bce0 100644 --- a/src/main/resources/fileTemplates/j2ee/skeleton/neoforge/NeoForgeEnchantment.java.ft +++ b/src/main/resources/fileTemplates/j2ee/skeleton/neoforge/NeoForgeEnchantment.java.ft @@ -1,6 +1,5 @@ #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") - import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.EnchantmentCategory; diff --git a/src/main/resources/messages/MinecraftDevelopment.properties b/src/main/resources/messages/MinecraftDevelopment.properties index 84e6d428a..45b659ebd 100644 --- a/src/main/resources/messages/MinecraftDevelopment.properties +++ b/src/main/resources/messages/MinecraftDevelopment.properties @@ -180,6 +180,10 @@ generate.event_listener.ignore_if_canceled=Ignore if event is canceled generate.class.caption=Minecraft Class generate.class.description=Class generation for modders +#In future is going to be Minecraft Json or similar +generate.json.caption=Minecraft Enchantment +generate.json.description=Enchantment generation for modders + generate.color.change_action=Change Color generate.color.change_error=Can''t change colors in {0} generate.color.choose_action=Choose Color diff --git a/src/main/resources/messages/MinecraftDevelopment_fr.properties b/src/main/resources/messages/MinecraftDevelopment_fr.properties index 7015adb16..959e17774 100644 --- a/src/main/resources/messages/MinecraftDevelopment_fr.properties +++ b/src/main/resources/messages/MinecraftDevelopment_fr.properties @@ -20,3 +20,5 @@ generate.event_listener.title=Event Listener generate.event_listener.settings=Configuration du Listener +generate.json.description=Génération de JSON pour les moddeurs +generate.json.caption=JSON de Minecraft diff --git a/src/main/resources/messages/MinecraftDevelopment_zh.properties b/src/main/resources/messages/MinecraftDevelopment_zh.properties index d4812a8b0..261aa2216 100644 --- a/src/main/resources/messages/MinecraftDevelopment_zh.properties +++ b/src/main/resources/messages/MinecraftDevelopment_zh.properties @@ -188,3 +188,5 @@ minecraft.settings.show_chat_color_underlines=显示聊天颜色下划线 minecraft.settings.chat_color_underline_style=聊天颜色下划线样式: minecraft.settings.mixin=Mixin minecraft.settings.mixin.shadow_annotation_same_line=@Shadow 注解在同一行 +generate.json.description=面向模组制作者的 JSON 生成 +generate.json.caption=Minecraft JSON