Skip to content

Commit d76e95b

Browse files
committed
feat: add quilt support
1 parent be740f5 commit d76e95b

File tree

14 files changed

+116
-57
lines changed

14 files changed

+116
-57
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ bin/
4545
*/run
4646

4747
.env
48+
*.log

build.gradle.kts

+7-32
Original file line numberDiff line numberDiff line change
@@ -138,21 +138,23 @@ subprojects {
138138
}
139139
}
140140

141-
142-
val finalJar by tasks.registering(Jar::class) {
143-
dependsOn(":fabric:remapJar")
141+
val fabricIntermediaryJar by tasks.registering(Jar::class) {
142+
dependsOn(":fabric:remapJar", ":quilt:remapJar")
144143
from(zipTree(project(":fabric").tasks.named("remapJar").get().outputs.files.first()))
145-
// from(project(":quilt").tasks.getByName("remapJar"))
144+
from(zipTree(project(":quilt").tasks.named("remapJar").get().outputs.files.first()))
146145

147146
archiveBaseName.set(archives_name)
148147
archiveVersion.set("${project.version}")
148+
archiveClassifier.set("fabric-intermediary")
149+
150+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
149151
}
150152

151153
curseforge {
152154
apiKey = env.CURSEFORGE_TOKEN.value // This should really be in a gradle.properties file
153155
project {
154156
id = "890349"
155-
mainArtifact(finalJar.get()) {
157+
mainArtifact(fabricIntermediaryJar.get()) {
156158
releaseType = "release"
157159
addGameVersion("1.19.4")
158160
addGameVersion("1.20")
@@ -165,30 +167,3 @@ curseforge {
165167
}
166168
}
167169
}
168-
169-
modrinth {
170-
token.set(env.MODRINTH_TOKEN.value) // This is the default. Remember to have the MODRINTH_TOKEN environment variable set or else this will fail, or set it to whatever you want - just make sure it stays private!
171-
projectId.set("mod-sets") // This can be the project ID or the slug. Either will work!
172-
syncBodyFrom.set(rootProject.file("README.md").readText())
173-
versionType.set("release") // This is the default -- can also be `beta` or `alpha`
174-
uploadFile.set(finalJar) // With Loom, this MUST be set to `remapJar` instead of `jar`!
175-
changelog.set(
176-
"""
177-
fix(common): calling save correctly with instant
178-
""".trimIndent(),
179-
)
180-
gameVersions.addAll(
181-
"1.19.4",
182-
"1.20",
183-
"1.20.1",
184-
) // Must be an array, even with only one version
185-
loaders.add("fabric") // Must also be an array - no need to specify this if you're using Loom or ForgeGradle
186-
dependencies {
187-
required.project("fabric-language-kotlin")
188-
// https://modrinth.com/mod/yacl
189-
required.project("yacl")
190-
// https://modrinth.com/mod/kinecraft-serialization
191-
embedded.version("kinecraft-serialization", "${libs.versions.kinecraft.serialization.get()}-fabric")
192-
optional.project("modmenu")
193-
}
194-
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package settingdust.modsets
22

3-
import com.mojang.logging.LogUtils
3+
import org.slf4j.LoggerFactory
44

55
object ModSets {
6-
val logger by lazy { LogUtils.getLogger()!! }
6+
val logger by lazy { LoggerFactory.getLogger(javaClass)!! }
77
}
88

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

+7-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import dev.isxander.yacl3.api.controller.StringControllerBuilder
55
import kotlinx.coroutines.channels.BufferOverflow
66
import kotlinx.coroutines.flow.MutableSharedFlow
77
import kotlinx.coroutines.flow.asSharedFlow
8+
import kotlinx.coroutines.runBlocking
89
import kotlinx.serialization.ExperimentalSerializationApi
910
import kotlinx.serialization.json.Json
1011
import kotlinx.serialization.json.decodeFromStream
@@ -24,7 +25,7 @@ object Rules : MutableMap<String, RuleSet> by mutableMapOf() {
2425

2526
val modSets = mutableMapOf<String, ModSet>()
2627
private val _ModSetsRegisterCallback =
27-
MutableSharedFlow<Unit>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
28+
MutableSharedFlow<Unit>()
2829
val ModSetsRegisterCallback = _ModSetsRegisterCallback.asSharedFlow()
2930

3031
private val definedModSets = mutableMapOf<String, ModSet>()
@@ -47,9 +48,9 @@ object Rules : MutableMap<String, RuleSet> by mutableMapOf() {
4748

4849
private val config: YetAnotherConfigLib
4950
get() {
50-
load()
51+
runBlocking { load() }
5152
val builder = YetAnotherConfigLib.createBuilder().title(Component.translatable("modsets.name"))
52-
if (ModSets.config.common.displayModSetsScreen) {
53+
if (ModSets.config.common.displayModSetsScreen && modSets.isNotEmpty()) {
5354
builder.category(
5455
ConfigCategory.createBuilder().apply {
5556
name(Component.translatable("modsets.name"))
@@ -122,10 +123,10 @@ object Rules : MutableMap<String, RuleSet> by mutableMapOf() {
122123
}
123124

124125
init {
125-
load()
126+
runBlocking { load() }
126127
}
127128

128-
private fun load() {
129+
private suspend fun load() {
129130
ModSets.config.load()
130131
try {
131132
configDir.createDirectories()
@@ -141,7 +142,7 @@ object Rules : MutableMap<String, RuleSet> by mutableMapOf() {
141142
definedModSets.putAll(json.decodeFromStream(it))
142143
}
143144
modSets.putAll(definedModSets)
144-
_ModSetsRegisterCallback.tryEmit(Unit)
145+
_ModSetsRegisterCallback.emit(Unit)
145146

146147
clear()
147148
rulesDir.listDirectoryEntries("*.json").forEach {

fabric/build.gradle.kts

+34
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
"UnstableApiUsage",
77
)
88

9+
plugins {
10+
alias(libs.plugins.minotaur)
11+
}
12+
913
val archives_name: String by rootProject
1014
val mod_name: String by rootProject
1115

@@ -83,3 +87,33 @@ dependencies {
8387
modRuntimeOnly(kinecraft)
8488
include(kinecraft)
8589
}
90+
91+
92+
93+
modrinth {
94+
token.set(env.MODRINTH_TOKEN.value) // This is the default. Remember to have the MODRINTH_TOKEN environment variable set or else this will fail, or set it to whatever you want - just make sure it stays private!
95+
projectId.set("mod-sets") // This can be the project ID or the slug. Either will work!
96+
syncBodyFrom.set(rootProject.file("README.md").readText())
97+
versionType.set("release") // This is the default -- can also be `beta` or `alpha`
98+
uploadFile.set(rootProject.tasks.named("fabricIntermediaryJar")) // With Loom, this MUST be set to `remapJar` instead of `jar`!
99+
changelog.set(
100+
"""
101+
fix(common): calling save correctly with instant
102+
""".trimIndent(),
103+
)
104+
gameVersions.addAll(
105+
"1.19.4",
106+
"1.20",
107+
"1.20.1",
108+
) // Must be an array, even with only one version
109+
loaders.add("fabric") // Must also be an array - no need to specify this if you're using Loom or ForgeGradle
110+
loaders.add("quilt")
111+
dependencies {
112+
required.project("fabric-language-kotlin")
113+
// https://modrinth.com/mod/yacl
114+
required.project("yacl")
115+
// https://modrinth.com/mod/kinecraft-serialization
116+
embedded.version("kinecraft-serialization", "${libs.versions.kinecraft.serialization.get()}-fabric")
117+
optional.project("modmenu")
118+
}
119+
}

fabric/src/main/java/settingdust/modsets/FilteredDirectoryModCandidateFinder.java renamed to fabric/src/main/java/settingdust/modsets/fabric/FilteredDirectoryModCandidateFinder.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package settingdust.modsets;
1+
package settingdust.modsets.fabric;
22

33
import net.fabricmc.loader.api.FabricLoader;
44
import net.fabricmc.loader.impl.FabricLoaderImpl;
@@ -7,6 +7,8 @@
77
import net.fabricmc.loader.impl.discovery.ModDiscoverer;
88
import net.fabricmc.loader.impl.metadata.DependencyOverrides;
99
import net.fabricmc.loader.impl.metadata.VersionOverrides;
10+
import settingdust.modsets.ConfigKt;
11+
import settingdust.modsets.ModSets;
1012

1113
import java.lang.reflect.Constructor;
1214
import java.lang.reflect.InvocationTargetException;

fabric/src/main/java/settingdust/modsets/ModContainerModCandidateFinder.java renamed to fabric/src/main/java/settingdust/modsets/fabric/ModContainerModCandidateFinder.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
package settingdust.modsets;
1+
package settingdust.modsets.fabric;
22

33
import net.fabricmc.loader.api.metadata.ModOrigin;
44
import net.fabricmc.loader.impl.ModContainerImpl;
55
import net.fabricmc.loader.impl.discovery.ClasspathModCandidateFinder;
6+
import settingdust.modsets.ConfigKt;
7+
import settingdust.modsets.ModSets;
68

79
import java.util.List;
810

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

+29-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package settingdust.modsets.fabric
22

3+
import kotlinx.coroutines.DelicateCoroutinesApi
34
import kotlinx.coroutines.Dispatchers
45
import kotlinx.coroutines.GlobalScope
56
import kotlinx.coroutines.launch
@@ -9,19 +10,22 @@ import net.fabricmc.loader.api.metadata.ModOrigin
910
import net.fabricmc.loader.impl.FabricLoaderImpl
1011
import net.minecraft.client.resources.language.I18n
1112
import net.minecraft.network.chat.Component
12-
import settingdust.modsets.FilteredDirectoryModCandidateFinder
1313
import settingdust.modsets.ModSet
1414
import settingdust.modsets.ModSets
15+
import settingdust.modsets.Rules.ModSetsRegisterCallback
16+
import settingdust.modsets.config
1517
import settingdust.modsets.rules
1618
import kotlin.io.path.div
1719

1820
object Entrypoint : ModInitializer {
21+
@OptIn(DelicateCoroutinesApi::class)
1922
override fun onInitialize() {
2023
val gameDir = FabricLoaderImpl.INSTANCE.gameDir
2124
val modsPath = FabricLoaderImpl.INSTANCE.modsDirectory.toPath()
25+
val modSets = ModSets.rules.modSets
2226

2327
GlobalScope.launch(Dispatchers.IO) {
24-
ModSets.rules.ModSetsRegisterCallback.collect {
28+
ModSetsRegisterCallback.collect {
2529
for ((key, value) in FilteredDirectoryModCandidateFinder.directoryModSets
2630
.mapValues {
2731
ModSet(
@@ -30,17 +34,17 @@ object Entrypoint : ModInitializer {
3034
it.value.toMutableSet(),
3135
)
3236
}) {
33-
if (key in ModSets.rules.modSets) ModSets.logger.warn("Duplicate mod set with directory name: $key")
34-
ModSets.rules.modSets.putIfAbsent(key, value)
37+
if (key in modSets) ModSets.logger.warn("Duplicate mod set with directory name: $key")
38+
modSets.putIfAbsent(key, value)
3539
}
3640

3741
for (mod in FabricLoader.getInstance().allMods) {
3842
if (mod.origin.kind.equals(ModOrigin.Kind.NESTED)) continue
3943
val metadata = mod.metadata
4044
if (metadata.type.equals("builtin")) continue
41-
if (metadata.id in ModSets.rules.modSets) ModSets.logger.warn("Duplicate mod set with mod id: ${metadata.id}")
45+
if (metadata.id in modSets) ModSets.logger.warn("Duplicate mod set with mod id: ${metadata.id}")
4246
val nameKey = "modmenu.nameTranslation.${metadata.id}"
43-
ModSets.rules.modSets.putIfAbsent(
47+
modSets.putIfAbsent(
4448
metadata.id,
4549
ModSet(
4650
if (try {
@@ -58,6 +62,25 @@ object Entrypoint : ModInitializer {
5862
),
5963
)
6064
}
65+
66+
ModSets.config.disabledMods.forEach {
67+
modSets.putIfAbsent(
68+
it, ModSet(
69+
if (try {
70+
I18n.exists("modmenu.nameTranslation.$it")
71+
} catch (e: Exception) {
72+
false
73+
}
74+
) {
75+
Component.translatable("modmenu.nameTranslation.$it")
76+
} else {
77+
Component.literal(it)
78+
},
79+
Component.literal("$it@disabled"),
80+
mutableSetOf(it),
81+
)
82+
)
83+
}
6184
}
6285
}
6386
}

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ import net.fabricmc.loader.impl.metadata.VersionOverrides
1616
import net.fabricmc.loader.impl.util.SystemProperties
1717
import net.fabricmc.loader.impl.util.log.Log
1818
import net.fabricmc.loader.impl.util.log.LogCategory
19-
import settingdust.modsets.FilteredDirectoryModCandidateFinder
20-
import settingdust.modsets.ModContainerModCandidateFinder
2119
import settingdust.modsets.ModSets
2220
import settingdust.modsets.config
2321
import java.nio.file.Path
@@ -103,7 +101,9 @@ object ModSetsInjector {
103101

104102
private fun discoverMods(): Collection<ModCandidate> {
105103
val discoverer = ModDiscoverer(VersionOverrides(), DependencyOverrides(loader.configDir))
106-
addCandidateFinderFunction.call(discoverer, ModContainerModCandidateFinder(mods))
104+
addCandidateFinderFunction.call(discoverer,
105+
ModContainerModCandidateFinder(mods)
106+
)
107107
val modsDir = loader.modsDirectory.toPath()
108108
modsDir
109109
.listDirectoryEntries()

gradle.properties

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
kotlin.code.style=official
22
kotlin.stdlib.default.dependency=false
33
# Gradle Properties
4-
org.gradle.jvmargs=-Xmx2G
5-
org.gradle.parallel=true
4+
org.gradle.jvmargs=-Xmx4G
5+
#org.gradle.parallel=true
66
# Mod Properties
7-
mod_version=1.1.2
7+
mod_version=1.2.0
88
maven_group=settingdust.modsets
99
archives_name=mod_sets
1010
mod_name=Mod Sets

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

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package settingdust.modsets.quilt
22

3+
import kotlinx.coroutines.DelicateCoroutinesApi
34
import kotlinx.coroutines.Dispatchers
45
import kotlinx.coroutines.GlobalScope
56
import kotlinx.coroutines.launch
@@ -13,10 +14,12 @@ import org.quiltmc.loader.impl.QuiltLoaderImpl
1314
import org.quiltmc.qsl.base.api.entrypoint.ModInitializer
1415
import settingdust.modsets.ModSet
1516
import settingdust.modsets.ModSets
17+
import settingdust.modsets.config
1618
import settingdust.modsets.rules
1719
import kotlin.io.path.name
1820

1921
class Entrypoint : ModInitializer {
22+
@OptIn(DelicateCoroutinesApi::class)
2023
override fun onInitialize(container: ModContainer) {
2124
val modSets = ModSets.rules.modSets
2225
val modDir = QuiltLoaderImpl.INSTANCE.modsDir
@@ -29,10 +32,11 @@ class Entrypoint : ModInitializer {
2932
// I can't find the real case of muleiple quilt source paths. So, just use the first
3033
val paths = mod.sourcePaths.singleOrNull() ?: continue
3134
// Quilt will be writing the path like [path in system, path in jar] etc.
32-
val pathInSystem = paths.first()
33-
if (pathInSystem.startsWith(modDir)) {
35+
val pathInSystem = paths.singleOrNull() ?: continue
36+
if (pathInSystem.startsWith(modDir) && modDir != pathInSystem.parent) {
3437
val subDir = pathInSystem.parent.name
35-
if (subDir in modSets) ModSets.logger.warn("Duplicate mod set with directory name: $subDir")
38+
ModSets.logger.debug("Add {} to {}", pathInSystem, subDir)
39+
if (subDir in modSets) ModSets.logger.warn("Duplicate mod set with directory name: $subDir")
3640
modSets.getOrPut(subDir) {
3741
ModSet(
3842
Component.literal(subDir),
@@ -44,6 +48,23 @@ class Entrypoint : ModInitializer {
4448
if (metadata.id() in modSets) ModSets.logger.warn("Duplicate mod set with mod id: ${metadata.id()}")
4549
modSets.putIfAbsent(metadata.id(), ModSet(metadata))
4650
}
51+
52+
ModSets.config.disabledMods.forEach {
53+
modSets.putIfAbsent(it, ModSet(
54+
if (try {
55+
I18n.exists("modmenu.nameTranslation.$it")
56+
} catch (e: Exception) {
57+
false
58+
}
59+
) {
60+
Component.translatable("modmenu.nameTranslation.$it")
61+
} else {
62+
Component.literal(it)
63+
},
64+
Component.literal("$it@disabled"),
65+
mutableSetOf(it),
66+
))
67+
}
4768
}
4869
}
4970
}

0 commit comments

Comments
 (0)