fix: Isolate mixins in alternative source sets
This commit is contained in:
12
src/compat/jade/java/moe/nea/firmament/compat/jade/Compat.kt
Normal file
12
src/compat/jade/java/moe/nea/firmament/compat/jade/Compat.kt
Normal file
@@ -0,0 +1,12 @@
|
||||
package moe.nea.firmament.compat.jade
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||
|
||||
@CompatMeta
|
||||
object Compat : ICompatMeta {
|
||||
override fun shouldLoad(): Boolean {
|
||||
return FabricLoader.getInstance().isModLoaded("jade")
|
||||
}
|
||||
}
|
||||
12
src/compat/rei/java/moe/nea/firmament/compat/rei/Compat.kt
Normal file
12
src/compat/rei/java/moe/nea/firmament/compat/rei/Compat.kt
Normal file
@@ -0,0 +1,12 @@
|
||||
package moe.nea.firmament.compat.rei
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||
|
||||
@CompatMeta
|
||||
object Compat : ICompatMeta {
|
||||
override fun shouldLoad(): Boolean {
|
||||
return FabricLoader.getInstance().isModLoaded("roughlyenoughitems")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package moe.nea.firmament.compat.gender
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||
|
||||
@CompatMeta
|
||||
object Compat : ICompatMeta {
|
||||
override fun shouldLoad(): Boolean {
|
||||
return FabricLoader.getInstance().isModLoaded("wildfire_gender")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package moe.nea.firmament.init;
|
||||
|
||||
|
||||
import moe.nea.firmament.util.ErrorUtil;
|
||||
import moe.nea.firmament.util.compatloader.ICompatMeta;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
@@ -94,7 +97,7 @@ public class AutoDiscoveryPlugin {
|
||||
String norm = (className.substring(0, className.length() - ".class".length()))
|
||||
.replace("\\", "/")
|
||||
.replace("/", ".");
|
||||
if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".")) {
|
||||
if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".") && ICompatMeta.Companion.shouldLoad(norm)) {
|
||||
mixins.add(norm.substring(getMixinPackage().length() + 1));
|
||||
}
|
||||
}
|
||||
@@ -125,24 +128,25 @@ public class AutoDiscoveryPlugin {
|
||||
*/
|
||||
public List<String> getMixins() {
|
||||
if (mixins != null) return mixins;
|
||||
System.out.println("Trying to discover mixins");
|
||||
mixins = new ArrayList<>();
|
||||
URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
|
||||
System.out.println("Found classes at " + classUrl);
|
||||
tryDiscoverFromContentFile(classUrl);
|
||||
var classRoots = System.getProperty("firmament.classroots");
|
||||
if (classRoots != null && !classRoots.isBlank()) {
|
||||
System.out.println("Found firmament class roots: " + classRoots);
|
||||
for (String s : classRoots.split(File.pathSeparator)) {
|
||||
if (s.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
try {
|
||||
System.out.println("Trying to discover mixins");
|
||||
mixins = new ArrayList<>();
|
||||
URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
|
||||
System.out.println("Found classes at " + classUrl);
|
||||
tryDiscoverFromContentFile(classUrl);
|
||||
var classRoots = System.getProperty("firmament.classroots");
|
||||
if (classRoots != null && !classRoots.isBlank()) {
|
||||
System.out.println("Found firmament class roots: " + classRoots);
|
||||
for (String s : classRoots.split(File.pathSeparator)) {
|
||||
if (s.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
tryDiscoverFromContentFile(new File(s).toURI().toURL());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
return mixins;
|
||||
}
|
||||
|
||||
11
src/main/kotlin/Compat.kt
Normal file
11
src/main/kotlin/Compat.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package moe.nea.firmament
|
||||
|
||||
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||
|
||||
@CompatMeta
|
||||
object Compat : ICompatMeta {
|
||||
override fun shouldLoad(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import moe.nea.firmament.features.mining.PickaxeAbility
|
||||
import moe.nea.firmament.features.mining.PristineProfitTracker
|
||||
import moe.nea.firmament.features.world.FairySouls
|
||||
import moe.nea.firmament.features.world.Waypoints
|
||||
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||
import moe.nea.firmament.util.data.DataHolder
|
||||
|
||||
object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "features", ::Config) {
|
||||
@@ -83,17 +84,18 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
|
||||
|
||||
fun subscribeEvents() {
|
||||
SubscriptionList.allLists.forEach { list ->
|
||||
runCatching {
|
||||
list.provideSubscriptions {
|
||||
it.owner.javaClass.classes.forEach {
|
||||
runCatching { it.getDeclaredField("INSTANCE").get(null) }
|
||||
if (ICompatMeta.shouldLoad(list.javaClass.name))
|
||||
runCatching {
|
||||
list.provideSubscriptions {
|
||||
it.owner.javaClass.classes.forEach {
|
||||
runCatching { it.getDeclaredField("INSTANCE").get(null) }
|
||||
}
|
||||
subscribeSingleEvent(it)
|
||||
}
|
||||
subscribeSingleEvent(it)
|
||||
}.getOrElse {
|
||||
// TODO: allow annotating source sets to specifically opt out of loading for mods, maybe automatically
|
||||
Firmament.logger.info("Ignoring events from $list, likely due to a missing compat mod.", it)
|
||||
}
|
||||
}.getOrElse {
|
||||
// TODO: allow annotating source sets to specifically opt out of loading for mods, maybe automatically
|
||||
Firmament.logger.info("Ignoring events from $list, likely due to a missing compat mod.", it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import kotlin.reflect.KClass
|
||||
import kotlin.streams.asSequence
|
||||
import moe.nea.firmament.Firmament
|
||||
|
||||
abstract class CompatLoader<T : Any>(val kClass: Class<T>) {
|
||||
open class CompatLoader<T : Any>(val kClass: Class<T>) {
|
||||
constructor(kClass: KClass<T>) : this(kClass.java)
|
||||
|
||||
val loader: ServiceLoader<T> = ServiceLoader.load(kClass)
|
||||
|
||||
48
src/main/kotlin/util/compatloader/CompatMeta.kt
Normal file
48
src/main/kotlin/util/compatloader/CompatMeta.kt
Normal file
@@ -0,0 +1,48 @@
|
||||
package moe.nea.firmament.util.compatloader
|
||||
|
||||
import java.util.ServiceLoader
|
||||
import moe.nea.firmament.events.subscription.SubscriptionList
|
||||
import moe.nea.firmament.init.AutoDiscoveryPlugin
|
||||
import moe.nea.firmament.util.ErrorUtil
|
||||
|
||||
/**
|
||||
* Declares the compat meta interface for the current source set.
|
||||
* This is used by [CompatLoader], [SubscriptionList], and [AutoDiscoveryPlugin]. Annotate a [ICompatMeta] object with
|
||||
* this.
|
||||
*/
|
||||
annotation class CompatMeta
|
||||
|
||||
interface ICompatMetaGen {
|
||||
fun owns(className: String): Boolean
|
||||
val meta: ICompatMeta
|
||||
}
|
||||
|
||||
interface ICompatMeta {
|
||||
fun shouldLoad(): Boolean
|
||||
|
||||
companion object {
|
||||
val allMetas = ServiceLoader
|
||||
.load(ICompatMetaGen::class.java)
|
||||
.toList()
|
||||
|
||||
fun shouldLoad(className: String): Boolean {
|
||||
// TODO: replace this with a more performant package lookup
|
||||
val meta = if (ErrorUtil.aggressiveErrors) {
|
||||
val fittingMetas = allMetas.filter { it.owns(className) }
|
||||
require(fittingMetas.size == 1) { "Orphaned or duplicate owned class $className (${fittingMetas.map { it.meta }}). Consider adding a @CompatMeta object." }
|
||||
fittingMetas.single()
|
||||
} else {
|
||||
allMetas.firstOrNull { it.owns(className) }
|
||||
}
|
||||
return meta?.meta?.shouldLoad() ?: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CompatHelper {
|
||||
fun isOwnedByPackage(className: String, vararg packages: String): Boolean {
|
||||
// TODO: create package lookup structure once
|
||||
val packageName = className.substringBeforeLast('.')
|
||||
return packageName in packages
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package moe.nea.firmament.features.texturepack
|
||||
|
||||
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||
|
||||
@CompatMeta
|
||||
object Compat : ICompatMeta {
|
||||
override fun shouldLoad(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user