Skip to content

Commit 929bfb2

Browse files
committed
feat: add forge support
1 parent d76e95b commit 929bfb2

File tree

12 files changed

+196
-84
lines changed

12 files changed

+196
-84
lines changed

forge/build.gradle.kts

+68-19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import net.fabricmc.loom.build.nesting.IncludedJarFactory
2+
import net.fabricmc.loom.task.AbstractRunTask
3+
14
val archives_name: String by rootProject
25
val mod_name: String by rootProject
36

@@ -6,23 +9,10 @@ architectury {
69
forge()
710
}
811

9-
loom {
10-
// mods {
11-
// register(archives_name) {
12-
// modFiles.from("../common/build/devlibs/${project(":common").base.archivesName.get()}-$version-dev.jar")
13-
// sourceSet(sourceSets.main.get())
14-
// }
15-
// }
16-
forge {
17-
// mixinConfig("$archives_name-common.mixins.json")
18-
mixinConfig("$archives_name.mixins.json")
19-
}
20-
21-
runs {
22-
named("client") {
23-
property("mixin.debug.export", "true")
24-
property("mixin.debug.verbose", "true")
25-
}
12+
sourceSets {
13+
val core by registering {
14+
compileClasspath += main.get().compileClasspath
15+
compileClasspath += main.get().output
2616
}
2717
}
2818

@@ -50,13 +40,45 @@ repositories {
5040
maven("https://maven.neoforged.net/releases")
5141
}
5242

43+
val modJar by tasks.registering(Jar::class) {
44+
archiveClassifier.set("core")
45+
from(sourceSets.named("core").get().output)
46+
destinationDirectory.set(project.buildDir.resolve("devlibs"))
47+
manifest {
48+
attributes(
49+
"MixinConfigs" to "$archives_name.mixins.json",
50+
)
51+
}
52+
}
53+
54+
loom {
55+
mods {
56+
named("main") {
57+
// modFiles.from(modJar)
58+
// sourceSet(project(":common").sourceSets.main.get())
59+
// sourceSet(sourceSets.named("core").get())
60+
}
61+
}
62+
63+
// forge {
64+
// mixinConfig("$archives_name-common.mixins.json")
65+
// mixinConfig("$archives_name.mixins.json")
66+
// }
67+
68+
runs {
69+
named("client") {
70+
property("mixin.debug.export", "true")
71+
property("mixin.debug.verbose", "true")
72+
}
73+
}
74+
}
75+
5376
dependencies {
54-
forge(libs.forge)
77+
forge(libs.neoforge)
5578

5679
implementation(project(path = ":common", configuration = "namedElements")) {
5780
isTransitive = false
5881
}
59-
include(project(path = ":common", configuration = "transformProductionForge"))
6082

6183
implementation(libs.kotlin.forge)
6284
modRuntimeOnly(libs.yacl.forge)
@@ -67,7 +89,34 @@ dependencies {
6789
}
6890

6991
tasks {
92+
remapJar {
93+
from(project(":common").sourceSets.main.get().output)
94+
forgeNestedJars.add(
95+
IncludedJarFactory.NestedFile(
96+
IncludedJarFactory.Metadata(
97+
"settingdust.modsets.forge",
98+
"service",
99+
version.toString(),
100+
"service"
101+
),
102+
modJar.get().outputs.files.singleFile
103+
),
104+
)
105+
}
106+
70107
processResources {
108+
exclude("META-INF/mods.toml")
109+
}
110+
111+
named<ProcessResources>("processCoreResources") {
71112
from(project(":common").sourceSets.main.get().resources)
72113
}
114+
115+
afterEvaluate {
116+
withType<AbstractRunTask> {
117+
classpath = classpath.filter { it !in sourceSets.main.get().output }
118+
classpath += files(jar)
119+
classpath += files(modJar)
120+
}
121+
}
73122
}

forge/src/main/kotlin/settingdust/modsets/forge/ModSetsModLocator.kt renamed to forge/src/core/kotlin/settingdust/modsets/forge/DummyModSetsModLocator.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package settingdust.modsets.forge
33
import net.minecraftforge.fml.loading.FMLPaths
44
import net.minecraftforge.fml.loading.moddiscovery.AbstractJarFileModLocator
55
import net.minecraftforge.forgespi.locating.IModLocator
6-
import settingdust.modsets.ModSets
6+
import org.slf4j.LoggerFactory
77
import java.nio.file.Path
88
import java.util.stream.Stream
99
import kotlin.io.path.div
@@ -12,7 +12,9 @@ import kotlin.io.path.listDirectoryEntries
1212
import kotlin.io.path.name
1313

1414
// Inspired by https://github.com/Chaos02/SubFolderLoader/blob/main/src/main/java/com/chaos02/structuredmodloader/StructuredModLoader.java
15-
class ModSetsModLocator : AbstractJarFileModLocator(), IModLocator {
15+
class DummyModSetsModLocator : AbstractJarFileModLocator(), IModLocator {
16+
private val logger = LoggerFactory.getLogger(javaClass)
17+
1618
companion object {
1719
val directoryModSet = mutableMapOf<String, MutableList<String>>()
1820
}
@@ -35,8 +37,8 @@ class ModSetsModLocator : AbstractJarFileModLocator(), IModLocator {
3537
override fun scanCandidates(): Stream<Path> {
3638
val modsDir = FMLPaths.GAMEDIR.get() / FMLPaths.MODSDIR.get()
3739
return modsDir.listDirectoryEntries().filter { it.isDirectory() }.also {
38-
ModSets.logger.info("Loading mods from {} sub dir in mods", it.size)
39-
ModSets.logger.debug(it.joinToString())
40+
logger.info("Loading mods from {} sub dir in mods", it.size)
41+
logger.debug(it.joinToString())
4042
}.flatMap {
4143
it.listDirectoryEntries("*.jar")
4244
}.stream()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package settingdust.modsets.forge
2+
3+
import kotlinx.coroutines.Dispatchers
4+
import kotlinx.coroutines.GlobalScope
5+
import kotlinx.coroutines.launch
6+
import net.minecraft.network.chat.Component
7+
import net.minecraftforge.client.ConfigScreenHandler.ConfigScreenFactory
8+
import net.minecraftforge.fml.ModList
9+
import net.minecraftforge.fml.common.Mod
10+
import net.minecraftforge.fml.loading.FMLPaths
11+
import net.minecraftforge.fml.loading.moddiscovery.BuiltinGameLibraryLocator
12+
import net.minecraftforge.fml.loading.moddiscovery.ClasspathLocator
13+
import net.minecraftforge.fml.loading.moddiscovery.JarInJarDependencyLocator
14+
import net.minecraftforge.fml.loading.moddiscovery.MinecraftLocator
15+
import settingdust.modsets.ModSet
16+
import settingdust.modsets.ModSets
17+
import settingdust.modsets.config
18+
import settingdust.modsets.forge.service.ModSetsModLocator
19+
import settingdust.modsets.rules
20+
import thedarkcolour.kotlinforforge.forge.LOADING_CONTEXT
21+
import kotlin.io.path.div
22+
23+
@Mod("mod_sets")
24+
class Entrypoint {
25+
init {
26+
// Take from https://github.com/isXander/YetAnotherConfigLib/blob/1.20.x/dev/test-forge/src/main/java/dev/isxander/yacl/test/forge/ForgeTest.java
27+
LOADING_CONTEXT.registerExtensionPoint(ConfigScreenFactory::class.java) {
28+
ConfigScreenFactory { _, parent ->
29+
ModSets.rules.createScreen(parent)
30+
}
31+
}
32+
33+
val gameDir = FMLPaths.GAMEDIR.get()
34+
val modsPath = FMLPaths.MODSDIR.get()
35+
val modSets = ModSets.rules.modSets
36+
37+
GlobalScope.launch(Dispatchers.IO) {
38+
ModSets.rules.ModSetsRegisterCallback.collect {
39+
for ((key, value) in ModSetsModLocator.directoryModSet.mapValues {
40+
ModSet(
41+
Component.literal(it.key),
42+
Component.literal(gameDir.relativize(modsPath / it.key).toString()),
43+
it.value.toMutableSet(),
44+
)
45+
}) {
46+
if (key in modSets) ModSets.logger.warn("Duplicate mod set with directory name: $key")
47+
modSets.putIfAbsent(key, value)
48+
}
49+
50+
for (mod in ModList.get().mods) {
51+
val provider = mod.owningFile.file.provider
52+
if (provider is MinecraftLocator || provider is BuiltinGameLibraryLocator || provider is JarInJarDependencyLocator || provider is ClasspathLocator) continue
53+
if (mod.modId in modSets) ModSets.logger.warn("Duplicate mod set with directory name: ${mod.modId}")
54+
modSets.putIfAbsent(
55+
mod.modId, ModSet(
56+
Component.literal(mod.displayName),
57+
Component.literal("${mod.modId}@${mod.version}"),
58+
mutableSetOf(mod.modId),
59+
)
60+
)
61+
}
62+
63+
ModSets.config.disabledMods.forEach {
64+
modSets.putIfAbsent(
65+
it, ModSet(
66+
Component.literal(it),
67+
Component.literal("$it@disabled"),
68+
mutableSetOf(it),
69+
)
70+
)
71+
}
72+
}
73+
}
74+
}
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
modLoader = "kotlinforforge"
2+
loaderVersion = "[4,]"
3+
license = "MIT"
4+
[[mods]]
5+
modId = "$id"
6+
version = "$version"
7+
displayName = "$name"
8+
logoFile = "assets/${id}/icon.png"
9+
authors = "$author"
10+
description = "$description"
11+
[[dependencies.$id]]
12+
modId = "forge"
13+
mandatory = true
14+
versionRange = "[${forge_version},)"
15+
ordering = "NONE"
16+
side = "BOTH"
17+
[[dependencies.$id]]
18+
modId = "minecraft"
19+
mandatory = true
20+
versionRange = "[${minecraft_version},)"
21+
ordering = "NONE"
22+
side = "BOTH"
23+
[[dependencies.$id]]
24+
modId = "kotlinforforge"
25+
mandatory = true
26+
versionRange = "[${kotlin_forge_version},)"
27+
ordering = "NONE"
28+
side = "BOTH"
29+
[[dependencies.$id]]
30+
modId = "yet_another_config_lib_v3"
31+
mandatory = true
32+
versionRange = "[${yacl_version},)"
33+
ordering = "NONE"
34+
side = "BOTH"

forge/src/main/java/settingdust/modsets/forge/DummyModSetsModLocator.java renamed to forge/src/main/java/settingdust/modsets/forge/service/ModSetsModLocator.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
package settingdust.modsets.forge;
1+
package settingdust.modsets.forge.service;
22

33
import com.google.common.collect.Streams;
44
import net.minecraftforge.fml.loading.FMLPaths;
55
import net.minecraftforge.fml.loading.moddiscovery.AbstractJarFileModLocator;
66
import net.minecraftforge.forgespi.language.IModInfo;
7-
import settingdust.modsets.ModSets;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
89

910
import java.io.IOException;
1011
import java.nio.file.Files;
@@ -16,10 +17,9 @@
1617
import java.util.stream.Stream;
1718

1819
// Inspired by https://github.com/Chaos02/SubFolderLoader/blob/main/src/main/java/com/chaos02/structuredmodloader/StructuredModLoader.java
19-
public class DummyModSetsModLocator extends AbstractJarFileModLocator {
20-
20+
public class ModSetsModLocator extends AbstractJarFileModLocator {
2121
public static Map<String, List<String>> directoryModSet = new HashMap<>();
22-
22+
private static Logger logger = LoggerFactory.getLogger(ModSetsModLocator.class);
2323
private List<Path> mods = new ArrayList<>();
2424

2525
@Override
@@ -37,8 +37,8 @@ public Stream<Path> scanCandidates() {
3737
var modsDir = FMLPaths.GAMEDIR.get().resolve(FMLPaths.MODSDIR.get());
3838
try (var dirs = Files.list(modsDir).filter(Files::isDirectory)) {
3939
var dirList = dirs.toList();
40-
ModSets.INSTANCE.getLogger().info("Loading mods from {} sub dir in mods", dirList.size());
41-
ModSets.INSTANCE.getLogger().debug(String.join(",", dirList.stream().map(it -> it.getFileName().toString()).toList()));
40+
logger.info("Loading mods from {} sub dir in mods", dirList.size());
41+
logger.debug(String.join(",", dirList.stream().map(it -> it.getFileName().toString()).toList()));
4242

4343
return dirList.stream().flatMap(it -> {
4444
try {

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

-19
This file was deleted.
+5-33
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,6 @@
1-
modLoader = "kotlinforforge"
2-
loaderVersion = "[4,]"
3-
license = "MIT"
1+
modLoader = "javafml"
2+
loaderVersion = "[46,)"
43
[[mods]]
5-
modId = "$id"
6-
version = "$version"
7-
displayName = "$name"
8-
logoFile = "assets/${id}/icon.png"
9-
authors = "$author"
10-
description = "$description"
11-
[[dependencies.$id]]
12-
modId = "forge"
13-
mandatory = true
14-
versionRange = "[${forge_version},)"
15-
ordering = "NONE"
16-
side = "BOTH"
17-
[[dependencies.$id]]
18-
modId = "minecraft"
19-
mandatory = true
20-
versionRange = "[${minecraft_version},)"
21-
ordering = "NONE"
22-
side = "BOTH"
23-
[[dependencies.$id]]
24-
modId = "kotlinforforge"
25-
mandatory = true
26-
versionRange = "[${kotlin_forge_version},)"
27-
ordering = "NONE"
28-
side = "BOTH"
29-
[[dependencies.$id]]
30-
modId = "yet_another_config_lib_v3"
31-
mandatory = true
32-
versionRange = "[${yacl_version},)"
33-
ordering = "NONE"
34-
side = "BOTH"
4+
modId = "dummy"
5+
version = "0.0.0"
6+
displayName = "dummy"
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
settingdust.modsets.forge.DummyModSetsModLocator
2-
settingdust.modsets.forge.ModSetsModLocator
1+
settingdust.modsets.forge.service.ModSetsModLocator

0 commit comments

Comments
 (0)