Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions src/main/kotlin/insight/generation/MinecraftClassCreateAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<PsiClass>(
Expand All @@ -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

Expand All @@ -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)
}
}

Expand Down Expand Up @@ -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 {
Expand Down
118 changes: 118 additions & 0 deletions src/main/kotlin/insight/generation/MinecraftResourceCreateAction.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
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.module.Module
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
val dir: PsiDirectory?
if (psi is PsiFile) {
dir = psi.containingDirectory
// MinecraftFacet.getInstance(module)?.findFile(psi. SourceType.RESOURCE) ?: return false
} else if(psi is PsiDirectory){
dir = psi
}else{
return false
}

val project = context.getData(CommonDataKeys.PROJECT) ?: return false
val underSourceRootOfType = ProjectRootManager.getInstance(project).fileIndex.isUnderSourceRootOfType(
dir.virtualFile,
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 && findModid(dir, module) != null && mcVersion != null && mcVersion >= MinecraftVersions.MC1_21
}

private fun findModid(dir: PsiDirectory, module: Module): String? {
val modids = MinecraftFacet.getInstance(module, ForgeModuleType)?.modIds ?: MinecraftFacet.getInstance(
module,
FabricModuleType
)?.modIds ?: MinecraftFacet.getInstance(module, NeoForgeModuleType)?.modIds ?: return null

return modids.firstOrNull { dir.virtualFile.path.split("/").contains(it) }
}

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 modid = findModid(dir, module) ?: return null

val template = FileTemplateManager.getInstance(dir.project)
.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")
}
}
21 changes: 21 additions & 0 deletions src/main/kotlin/platform/AbstractModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {

Expand Down Expand Up @@ -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
}
}
}
57 changes: 55 additions & 2 deletions src/main/kotlin/platform/fabric/FabricModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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<String> {
val jsonFile = PsiManager.getInstance(project).findFile(fabricJson ?: return emptyList()) as? JsonFile
Expand All @@ -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) = ""
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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") {
Expand Down
Loading