Skip to content

Commit dac286b

Browse files
committed
Add support for ForgeGradle patcher projects
1 parent 9999285 commit dac286b

File tree

11 files changed

+288
-1
lines changed

11 files changed

+288
-1
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Minecraft Dev for IntelliJ
3+
*
4+
* https://minecraftdev.org
5+
*
6+
* Copyright (c) 2017 minecraft-dev
7+
*
8+
* MIT License
9+
*/
10+
11+
package com.demonwav.mcdev.platform.forge.gradle.tooling
12+
13+
import com.demonwav.mcdev.platform.mcp.gradle.tooling.McpModelBuilderImpl
14+
import org.gradle.api.Project
15+
import org.jetbrains.annotations.NotNull
16+
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
17+
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
18+
19+
final class ForgePatcherModelBuilderImpl implements ModelBuilderService {
20+
21+
@Override
22+
boolean canBuild(String modelName) {
23+
return ForgePatcherModel.name == modelName
24+
}
25+
26+
@Override
27+
Object buildAll(String modelName, Project project) {
28+
def extension = project.extensions.findByName("minecraft")
29+
if (extension == null) {
30+
// No ForgeGradle
31+
return null
32+
}
33+
34+
if (project.plugins.findPlugin("net.minecraftforge.gradle.patcher") == null) {
35+
// Not using the patcher plugin
36+
return null
37+
}
38+
39+
def mcpModel = new McpModelBuilderImpl().buildAll(modelName, project)
40+
41+
def set = new HashSet<String>()
42+
for (p in extension.projects) {
43+
set.add(p.capName)
44+
}
45+
46+
return new ForgePatcherModelImpl(mcpModel, set)
47+
}
48+
49+
@Override
50+
ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) {
51+
return ErrorMessageBuilder.create(
52+
project, e, "MinecraftDev import errors"
53+
).withDescription("Unable to build MinecraftDev Forge patcher project configuration")
54+
}
55+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Minecraft Dev for IntelliJ
3+
*
4+
* https://minecraftdev.org
5+
*
6+
* Copyright (c) 2017 minecraft-dev
7+
*
8+
* MIT License
9+
*/
10+
11+
package com.demonwav.mcdev.platform.forge.gradle.tooling
12+
13+
import com.demonwav.mcdev.platform.mcp.gradle.tooling.McpModel
14+
import groovy.transform.CompileStatic
15+
16+
@CompileStatic
17+
final class ForgePatcherModelImpl implements ForgePatcherModel, Serializable {
18+
19+
final McpModel mcpModel
20+
final Set<String> projects
21+
22+
ForgePatcherModelImpl(McpModel mcpModel, Set<String> projects) {
23+
this.mcpModel = mcpModel
24+
this.projects = projects
25+
}
26+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Minecraft Dev for IntelliJ
3+
*
4+
* https://minecraftdev.org
5+
*
6+
* Copyright (c) 2017 minecraft-dev
7+
*
8+
* MIT License
9+
*/
10+
11+
package com.demonwav.mcdev.platform.forge.gradle.tooling;
12+
13+
import com.demonwav.mcdev.platform.mcp.gradle.tooling.McpModel;
14+
import java.util.Set;
15+
16+
public interface ForgePatcherModel {
17+
McpModel getMcpModel();
18+
Set<String> getProjects();
19+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
com.demonwav.mcdev.platform.mcp.gradle.tooling.McpModelBuilderImpl
2+
com.demonwav.mcdev.platform.forge.gradle.tooling.ForgePatcherModelBuilderImpl

src/main/kotlin/com/demonwav/mcdev/facet/MinecraftFacetConfiguration.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,7 @@ data class MinecraftFacetConfigurationData(
4444
var userChosenTypes: MutableMap<PlatformType, Boolean> = mutableMapOf(),
4545
@Tag("autoDetectTypes")
4646
@AbstractCollection(surroundWithTag = false, elementTag = "platformType", elementValueAttribute = "")
47-
var autoDetectTypes: MutableSet<PlatformType> = mutableSetOf()
47+
var autoDetectTypes: MutableSet<PlatformType> = mutableSetOf(),
48+
@Tag("forgePatcher")
49+
var forgePatcher: Boolean = false
4850
)

src/main/kotlin/com/demonwav/mcdev/facet/MinecraftFacetDetector.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ class MinecraftFacetDetector(project: Project) : AbstractProjectComponent(projec
9393
val types = facet.configuration.state.autoDetectTypes
9494
types.clear()
9595
types.addAll(platforms)
96+
97+
if (facet.configuration.state.forgePatcher) {
98+
// make sure Forge and MCP are present
99+
types.add(PlatformType.FORGE)
100+
types.add(PlatformType.MCP)
101+
}
102+
96103
facet.refresh()
97104
}
98105

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Minecraft Dev for IntelliJ
3+
*
4+
* https://minecraftdev.org
5+
*
6+
* Copyright (c) 2017 minecraft-dev
7+
*
8+
* MIT License
9+
*/
10+
11+
package com.demonwav.mcdev.platform.forge.gradle
12+
13+
import com.demonwav.mcdev.facet.MinecraftFacet
14+
import com.demonwav.mcdev.facet.MinecraftFacetConfiguration
15+
import com.demonwav.mcdev.platform.PlatformType
16+
import com.demonwav.mcdev.platform.mcp.McpModuleSettings
17+
import com.demonwav.mcdev.platform.mcp.McpModuleType
18+
import com.demonwav.mcdev.util.findChildren
19+
import com.intellij.openapi.externalSystem.model.DataNode
20+
import com.intellij.openapi.externalSystem.model.project.ProjectData
21+
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
22+
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
23+
import com.intellij.openapi.module.Module
24+
import com.intellij.openapi.module.ModuleManager
25+
import com.intellij.openapi.project.Project
26+
27+
class ForgePatcherDataService : AbstractProjectDataService<ForgePatcherModelData, Module>() {
28+
29+
override fun getTargetDataKey() = ForgePatcherModelData.KEY
30+
31+
override fun importData(toImport: Collection<DataNode<ForgePatcherModelData>>,
32+
projectData: ProjectData?,
33+
project: Project,
34+
modelsProvider: IdeModifiableModelsProvider) {
35+
if (projectData == null || toImport.isEmpty()) {
36+
return
37+
}
38+
39+
for (node in toImport) {
40+
val data = node.data
41+
42+
val moduleManager = ModuleManager.getInstance(project)
43+
44+
for (name in data.model.projects) {
45+
val rootModule = moduleManager.findModuleByName(name) ?: continue
46+
var children = rootModule.findChildren()
47+
48+
if (children.isEmpty()) {
49+
children = setOf(rootModule)
50+
}
51+
52+
children.forEach { register(it, modelsProvider) }
53+
for (m in moduleManager.modules) {
54+
if (m !in children) {
55+
MinecraftFacet.getInstance(m)?.apply {
56+
configuration.state.forgePatcher = false
57+
refresh()
58+
}
59+
}
60+
}
61+
62+
for (child in children) {
63+
val mcpModule = MinecraftFacet.getInstance(child, McpModuleType) ?: continue
64+
val mcp = data.model.mcpModel
65+
mcpModule.updateSettings(McpModuleSettings.State(mcp.minecraftVersion, mcp.mcpVersion, mcp.mappingFiles))
66+
}
67+
}
68+
}
69+
}
70+
71+
fun register(module: Module, modelsProvider: IdeModifiableModelsProvider) {
72+
val model = modelsProvider.getModifiableFacetModel(module)
73+
val facet = model.getFacetByType(MinecraftFacet.ID)
74+
75+
if (facet == null) {
76+
val configuration = MinecraftFacetConfiguration()
77+
configuration.state.autoDetectTypes.addAll(platforms)
78+
configuration.state.forgePatcher = true
79+
80+
model.addFacet(MinecraftFacet.facetType.createFacet(module, "Minecraft", configuration, null))
81+
} else {
82+
val types = facet.configuration.state.autoDetectTypes
83+
facet.configuration.state.forgePatcher = true
84+
types.clear()
85+
types.addAll(platforms)
86+
facet.refresh()
87+
}
88+
}
89+
90+
companion object {
91+
private val platforms = setOf(PlatformType.FORGE, PlatformType.MCP)
92+
}
93+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Minecraft Dev for IntelliJ
3+
*
4+
* https://minecraftdev.org
5+
*
6+
* Copyright (c) 2017 minecraft-dev
7+
*
8+
* MIT License
9+
*/
10+
11+
package com.demonwav.mcdev.platform.forge.gradle
12+
13+
import com.demonwav.mcdev.platform.forge.gradle.tooling.ForgePatcherModel
14+
import com.intellij.openapi.externalSystem.model.Key
15+
import com.intellij.openapi.externalSystem.model.ProjectKeys
16+
import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData
17+
import com.intellij.openapi.externalSystem.model.project.ModuleData
18+
19+
class ForgePatcherModelData(val module: ModuleData, val model: ForgePatcherModel) : AbstractExternalEntityData(module.owner) {
20+
21+
companion object {
22+
val KEY = Key.create(ForgePatcherModelData::class.java, ProjectKeys.TASK.processingWeight + 1)
23+
}
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Minecraft Dev for IntelliJ
3+
*
4+
* https://minecraftdev.org
5+
*
6+
* Copyright (c) 2017 minecraft-dev
7+
*
8+
* MIT License
9+
*/
10+
11+
package com.demonwav.mcdev.platform.forge.gradle
12+
13+
import com.demonwav.mcdev.platform.forge.gradle.tooling.ForgePatcherModel
14+
import com.intellij.openapi.externalSystem.model.DataNode
15+
import com.intellij.openapi.externalSystem.model.project.ModuleData
16+
import org.gradle.tooling.model.idea.IdeaModule
17+
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
18+
19+
class ForgePatcherProjectResolverExtension : AbstractProjectResolverExtension() {
20+
21+
override fun getExtraProjectModelClasses() = setOf(ForgePatcherModel::class.java)
22+
override fun getToolingExtensionsClasses() = extraProjectModelClasses
23+
24+
override fun populateModuleExtraModels(gradleModule: IdeaModule, ideModule: DataNode<ModuleData>) {
25+
val model = resolverCtx.getExtraProject(gradleModule, ForgePatcherModel::class.java)
26+
if (model != null) {
27+
ideModule.createChild(ForgePatcherModelData.KEY, ForgePatcherModelData(ideModule.data, model))
28+
}
29+
30+
super.populateModuleExtraModels(gradleModule, ideModule)
31+
}
32+
}

src/main/kotlin/com/demonwav/mcdev/util/Util.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ package com.demonwav.mcdev.util
1212

1313
import com.intellij.openapi.application.ApplicationManager
1414
import com.intellij.openapi.application.ModalityState
15+
import com.intellij.openapi.module.Module
16+
import com.intellij.openapi.module.ModuleManager
1517
import org.jetbrains.annotations.Contract
1618

1719
inline fun <T> runInlineReadAction(func: () -> T): T {
@@ -104,3 +106,27 @@ fun <T : Any> Array<T?>.castNotNull(): Array<T> {
104106
@Suppress("UNCHECKED_CAST")
105107
return this as Array<T>
106108
}
109+
110+
fun Module.findChildren(): Set<Module> {
111+
runInlineReadAction {
112+
val manager = ModuleManager.getInstance(project)
113+
val result = mutableSetOf<Module>()
114+
115+
for (m in manager.modules) {
116+
if (m === this) {
117+
continue
118+
}
119+
120+
val path = manager.getModuleGroupPath(m) ?: continue
121+
val namedModule = manager.findModuleByName(path.last()) ?: continue
122+
123+
if (namedModule != this) {
124+
continue
125+
}
126+
127+
result.add(m)
128+
}
129+
130+
return result
131+
}
132+
}

0 commit comments

Comments
 (0)