Skip to content

Commit 0baa2b1

Browse files
committed
feat: ADD FORGE SUPPORT!
1 parent 54a5278 commit 0baa2b1

File tree

20 files changed

+380
-86
lines changed

20 files changed

+380
-86
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
This project heavily inspired by [ThatOrThis](https://github.com/EZForever/ThatOrThis)
11-
The mod is using for Minecraft Fabric/~~Quilt~~ for managing mod loading in game.
11+
The mod is using for Minecraft Fabric/Quilt/Forge for managing mod loading in game.
1212
And useful for modpack developer
1313

1414
## Feature

build.gradle.kts

+5
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,16 @@ val fabricIntermediaryJar by tasks.registering(Jar::class) {
151151
}
152152

153153
curseforge {
154+
options {
155+
debug = true
156+
}
154157
apiKey = env.CURSEFORGE_TOKEN.value // This should really be in a gradle.properties file
155158
project {
156159
id = "890349"
157160
mainArtifact(fabricIntermediaryJar.get()) {
158161
releaseType = "release"
162+
addGameVersion("fabric")
163+
addGameVersion("quilt")
159164
addGameVersion("1.19.4")
160165
addGameVersion("1.20")
161166
addGameVersion("1.20.1")

common/build.gradle.kts

+30
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,23 @@
66
"UnstableApiUsage",
77
)
88

9+
import dev.architectury.plugin.ModLoader
10+
import dev.architectury.plugin.TransformingTask
11+
import dev.architectury.plugin.loom.LoomInterface
12+
import net.fabricmc.loom.task.RemapJarTask
13+
14+
915
val archives_name: String by rootProject
1016

1117
architectury {
1218
common(rootProject.property("enabled_platforms").toString().split(","))
1319
}
1420

21+
val game by sourceSets.registering {
22+
compileClasspath += sourceSets.main.get().compileClasspath
23+
compileClasspath += sourceSets.main.get().output
24+
}
25+
1526
repositories {
1627
exclusiveContent {
1728
forRepository {
@@ -51,4 +62,23 @@ tasks {
5162
"FMLModType" to "LIBRARY",
5263
)
5364
}
65+
66+
val modJar by registering(Jar::class) {
67+
archiveClassifier.set("game")
68+
from(sourceSets.named("game").get().output)
69+
destinationDirectory.set(project.buildDir.resolve("devlibs"))
70+
manifest.attributes(
71+
"FMLModType" to "GAMELIBRARY",
72+
)
73+
}
74+
75+
val remapModJar by registering(RemapJarTask::class) {
76+
dependsOn(modJar)
77+
archiveClassifier.set("game")
78+
inputFile.convention(modJar.get().archiveFile)
79+
}
80+
81+
named<ProcessResources>("processGameResources") {
82+
exclude("META-INF/mods.toml")
83+
}
5484
}

common/gradle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.gradle.jvmargs=-Xmx2G
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
package settingdust.modsets
1+
package settingdust.modsets.game
22

33
import com.terraformersmc.modmenu.api.ConfigScreenFactory
44
import com.terraformersmc.modmenu.api.ModMenuApi
55

66
class ModSetsModMenu : ModMenuApi {
77
override fun getModConfigScreenFactory() = ConfigScreenFactory {
8-
ModSets.rules.createScreen(it)
8+
Rules.createScreen(it)
99
}
1010
}

common/src/main/kotlin/settingdust/modsets/Rule.kt renamed to common/src/game/kotlin/settingdust/modsets/game/Rule.kt

+18-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package settingdust.modsets
1+
package settingdust.modsets.game
22

33
import dev.isxander.yacl3.api.Binding
44
import dev.isxander.yacl3.api.Option
@@ -13,7 +13,9 @@ import kotlinx.serialization.Serializable
1313
import net.minecraft.network.chat.Component
1414
import net.minecraft.network.chat.HoverEvent
1515
import net.minecraft.network.chat.Style
16-
import settingdust.modsets.Rules.getOrThrow
16+
import settingdust.modsets.ModSets
17+
import settingdust.modsets.ModSetsConfig
18+
import settingdust.modsets.game.Rules.getOrThrow
1719

1820
interface Described {
1921
val text: Component
@@ -72,15 +74,15 @@ object LabelRule : OptionRule<Component> {
7274

7375
private val String.booleanBinding: Binding<Boolean>
7476
get() {
75-
val mods = ModSets.rules.modSets.getOrThrow(this).mods.toSet()
77+
val mods = Rules.modSets.getOrThrow(this).mods.toSet()
7678
return Binding.generic(
7779
true,
78-
{ mods.any { it !in ModSets.config.disabledMods } },
80+
{ mods.any { it !in ModSetsConfig.disabledMods } },
7981
{
8082
if (it) {
81-
ModSets.config.disabledMods.removeAll(mods)
83+
ModSetsConfig.disabledMods.removeAll(mods)
8284
} else {
83-
ModSets.config.disabledMods.addAll(mods)
85+
ModSetsConfig.disabledMods.addAll(mods)
8486
}
8587
},
8688
)
@@ -97,7 +99,7 @@ data class BooleanRule(val mod: String) : OptionRule<Boolean> {
9799
.apply {
98100
(
99101
rule.description
100-
?: ModSets.rules.modSets[mod]?.description
102+
?: Rules.modSets[mod]?.description
101103
)?.let { description(OptionDescription.of(it)) }
102104
}
103105
.instant(true)
@@ -122,7 +124,7 @@ data class CyclingRule(val mods: List<String>) : OptionRule<String> {
122124
CyclingListControllerBuilder.create(it)
123125
.values(mods)
124126
.valueFormatter { mod ->
125-
val modSet = ModSets.rules.modSets.getOrThrow(mod)
127+
val modSet = Rules.modSets.getOrThrow(mod)
126128
modSet.text.copy()
127129
.withStyle(
128130
Style.EMPTY.withHoverEvent(
@@ -142,31 +144,31 @@ data class CyclingRule(val mods: List<String>) : OptionRule<String> {
142144
Binding.generic(
143145
firstMod,
144146
{
145-
val modSets = ModSets.rules.modSets
147+
val modSets = Rules.modSets
146148
val enabledModSet = mods.asSequence()
147149
.filter { modSet ->
148150
val mods = modSets.getOrThrow(modSet).mods
149-
mods.isNotEmpty() && mods.none { it in ModSets.config.disabledMods }
151+
mods.isNotEmpty() && mods.none { it in ModSetsConfig.disabledMods }
150152
}
151153
.toList()
152154
if (enabledModSet.size > 1) {
153155
ModSets.logger.warn("More than one mod is enabled in cycling list: " + enabledModSet.joinToString() + ". Will take the first and disable the others")
154-
ModSets.config.disabledMods.addAll(
156+
ModSetsConfig.disabledMods.addAll(
155157
enabledModSet.drop(1).flatMap { modSets.getOrThrow(it).mods },
156158
)
157-
ModSets.config.disabledMods.removeAll(modSets.getOrThrow(enabledModSet.first()).mods.toSet())
159+
ModSetsConfig.disabledMods.removeAll(modSets.getOrThrow(enabledModSet.first()).mods.toSet())
158160
return@generic enabledModSet.first()
159161
}
160162
val currentSelected =
161163
enabledModSet.singleOrNull() ?: mods.firstOrNull { modSets.getOrThrow(it).mods.isEmpty() }
162164
?: firstMod
163165

164-
ModSets.config.disabledMods.removeAll(modSets.getOrThrow(currentSelected).mods.toSet())
166+
ModSetsConfig.disabledMods.removeAll(modSets.getOrThrow(currentSelected).mods.toSet())
165167
return@generic currentSelected
166168
},
167169
) { value: String ->
168-
ModSets.config.disabledMods.addAll(mods.flatMap { ModSets.rules.modSets.getOrThrow(it).mods })
169-
ModSets.config.disabledMods.removeAll(ModSets.rules.modSets.getOrThrow(value).mods.toSet())
170+
ModSetsConfig.disabledMods.addAll(mods.flatMap { Rules.modSets.getOrThrow(it).mods })
171+
ModSetsConfig.disabledMods.removeAll(Rules.modSets.getOrThrow(value).mods.toSet())
170172
},
171173
).build()
172174
}
@@ -185,7 +187,7 @@ data class ModsGroupRule(val mods: List<String>, val collapsed: Boolean = true)
185187
val group = OptionGroup.createBuilder().name(rule.text)
186188
rule.description?.let { group.description(OptionDescription.of(it)) }
187189
for (mod in mods) {
188-
val modSet = ModSets.rules.modSets.getOrThrow(mod)
190+
val modSet = Rules.modSets.getOrThrow(mod)
189191
val option = Option.createBuilder<Boolean>().name(modSet.text)
190192
modSet.description?.let { option.description(OptionDescription.of(it)) }
191193
group.option(

common/src/main/kotlin/settingdust/modsets/Rules.kt renamed to common/src/game/kotlin/settingdust/modsets/game/Rules.kt

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
package settingdust.modsets
1+
package settingdust.modsets.game
22

33
import dev.isxander.yacl3.api.*
44
import dev.isxander.yacl3.api.controller.StringControllerBuilder
5-
import kotlinx.coroutines.channels.BufferOverflow
65
import kotlinx.coroutines.flow.MutableSharedFlow
76
import kotlinx.coroutines.flow.asSharedFlow
87
import kotlinx.coroutines.runBlocking
@@ -16,6 +15,10 @@ import net.minecraft.client.gui.screens.Screen
1615
import net.minecraft.network.chat.Component
1716
import settingdust.kinecraft.serialization.ComponentSerializer
1817
import settingdust.kinecraft.serialization.GsonElementSerializer
18+
import settingdust.modsets.ModSets
19+
import settingdust.modsets.ModSetsConfig
20+
import settingdust.modsets.PlatformHelper
21+
import settingdust.modsets.config
1922
import kotlin.io.path.*
2023

2124
@OptIn(ExperimentalSerializationApi::class)
@@ -50,7 +53,7 @@ object Rules : MutableMap<String, RuleSet> by mutableMapOf() {
5053
get() {
5154
runBlocking { load() }
5255
val builder = YetAnotherConfigLib.createBuilder().title(Component.translatable("modsets.name"))
53-
if (ModSets.config.common.displayModSetsScreen && modSets.isNotEmpty()) {
56+
if (ModSetsConfig.common.displayModSetsScreen && modSets.isNotEmpty()) {
5457
builder.category(
5558
ConfigCategory.createBuilder().apply {
5659
name(Component.translatable("modsets.name"))
@@ -119,7 +122,7 @@ object Rules : MutableMap<String, RuleSet> by mutableMapOf() {
119122
ConfigCategory.createBuilder().name(Component.translatable("modsets.no_rules")).build(),
120123
)
121124
}
122-
return builder.save(::save).build()
125+
return builder.save(ModSets.rules::save).build()
123126
}
124127

125128
init {

common/src/main/kotlin/settingdust/modsets/Config.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ object ModSetsConfig {
3838
load()
3939
}
4040

41-
internal fun load() {
41+
fun load() {
4242
try {
4343
configDir.createDirectories()
4444
} catch (_: Exception) {
@@ -67,7 +67,7 @@ object ModSetsConfig {
6767
save()
6868
}
6969

70-
internal fun save() {
70+
fun save() {
7171
commonConfigPath.outputStream().use {
7272
json.encodeToStream(common, it)
7373
}

fabric/build.gradle.kts

+31-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
"UnstableApiUsage",
77
)
88

9+
import net.fabricmc.loom.build.nesting.IncludedJarFactory
10+
import net.fabricmc.loom.task.RemapJarTask
11+
912
plugins {
1013
alias(libs.plugins.minotaur)
1114
}
@@ -73,6 +76,8 @@ dependencies {
7376
}
7477
include(project(path = ":common", configuration = "transformProductionFabric"))
7578

79+
implementation(project.project(":common").sourceSets.named("game").get().output)
80+
7681
modImplementation(libs.fabric.loader)
7782
modRuntimeOnly(libs.fabric.languageKotlin) {
7883
exclude(module = "fabric-loader")
@@ -88,6 +93,31 @@ dependencies {
8893
include(kinecraft)
8994
}
9095

96+
tasks {
97+
remapJar {
98+
val factory = IncludedJarFactory(project)
99+
val getNestableJar = IncludedJarFactory::class.java.getDeclaredMethod(
100+
"getNestableJar",
101+
File::class.java,
102+
IncludedJarFactory.Metadata::class.java
103+
)
104+
getNestableJar.isAccessible = true
105+
val file = project.project(":common").tasks.named<RemapJarTask>("remapModJar").get().outputs.files.singleFile
106+
if (file.exists())
107+
nestedJars.from(
108+
getNestableJar.invoke(
109+
factory,
110+
project.project(":common").tasks.named<RemapJarTask>("remapModJar").get().outputs.files.singleFile,
111+
IncludedJarFactory.Metadata(
112+
"settingdust.modsets.common",
113+
"game",
114+
version.toString(),
115+
"game"
116+
)
117+
)
118+
)
119+
}
120+
}
91121

92122

93123
modrinth {
@@ -98,7 +128,7 @@ modrinth {
98128
uploadFile.set(rootProject.tasks.named("fabricIntermediaryJar")) // With Loom, this MUST be set to `remapJar` instead of `jar`!
99129
changelog.set(
100130
"""
101-
fix(common): calling save correctly with instant
131+
102132
""".trimIndent(),
103133
)
104134
gameVersions.addAll(

fabric/src/main/kotlin/settingdust/modsets/fabric/Entrypoint.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import net.fabricmc.loader.api.metadata.ModOrigin
1010
import net.fabricmc.loader.impl.FabricLoaderImpl
1111
import net.minecraft.client.resources.language.I18n
1212
import net.minecraft.network.chat.Component
13-
import settingdust.modsets.ModSet
13+
import settingdust.modsets.game.ModSet
1414
import settingdust.modsets.ModSets
15-
import settingdust.modsets.Rules.ModSetsRegisterCallback
15+
import settingdust.modsets.game.Rules.ModSetsRegisterCallback
1616
import settingdust.modsets.config
17-
import settingdust.modsets.rules
17+
import settingdust.modsets.game.rules
1818
import kotlin.io.path.div
1919

2020
object Entrypoint : ModInitializer {

0 commit comments

Comments
 (0)