mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-15 10:21:45 -04:00
Remove @Optional annotations that specify our lowercase mod ID (#2661)
Fixes #2649. Explanation: * Other mods can integrate with us by implementing the SimpleComponent interface. They annotate its methods with @Optional to avoid a hard dependency on us. * Our mod ID changed from "OpenComputers" in 1.10 to "opencomputers" in 1.11. * Some mods (like RFTools) can't refer to our mod by the right-case mod ID, because the same .jar works on both 1.10 and 1.11. * In most cases, using the wrong-case mod ID would just mean that integration wouldn't work, but for us, it causes a crash. * The crash is because we use ASM to inject some extra methods and make the class implement a different interface. This means that if the @Optional mod ID is wrong, our new interface will still be there but some of the original methods won't, which leads to AbstractMethodErrors like McJty/RFTools#1466. * Forge looks for the @Optional annotations before our coremod can do anything, so we can't just remove them from the class. Instead, we need to remove them from Forge's internal list.
This commit is contained in:
parent
2279b734a8
commit
673facee90
@ -1,10 +1,13 @@
|
||||
package li.cil.oc.common.asm
|
||||
|
||||
import com.google.common.collect.ListMultimap
|
||||
import li.cil.oc.common.asm.template.SimpleComponentImpl
|
||||
import li.cil.oc.integration.Mods
|
||||
import net.minecraft.launchwrapper.IClassTransformer
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader
|
||||
import net.minecraftforge.fml.common.asm.transformers.ModAPITransformer
|
||||
import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.objectweb.asm.ClassReader
|
||||
import org.objectweb.asm.ClassWriter
|
||||
@ -42,6 +45,19 @@ class ClassTransformer extends IClassTransformer {
|
||||
private val loader = classOf[ClassTransformer].getClassLoader.asInstanceOf[LaunchClassLoader]
|
||||
private val log = LogManager.getLogger("OpenComputers")
|
||||
|
||||
// Stuff to help us remove the @Optional annotations below. We set
|
||||
// this up outside of the method so that it only has to be done once.
|
||||
private val optionalsField = classOf[ModAPITransformer].getDeclaredField("optionals")
|
||||
optionalsField.setAccessible(true)
|
||||
private val transformers = loader.getTransformers()
|
||||
private var foundModAPITransformer = false
|
||||
// If these weren't lazy, they'd run before the ModAPITransformer gets added.
|
||||
private lazy val modAPITransformer = {
|
||||
foundModAPITransformer = true
|
||||
transformers.find(_.isInstanceOf[ModAPITransformer]).get
|
||||
}
|
||||
private lazy val optionals = optionalsField.get(modAPITransformer).asInstanceOf[ListMultimap[String, ASMData]]
|
||||
|
||||
override def transform(name: String, transformedName: String, basicClass: Array[Byte]): Array[Byte] = {
|
||||
if (basicClass == null || name.startsWith("scala.")) return basicClass
|
||||
var transformedClass = basicClass
|
||||
@ -146,6 +162,17 @@ class ClassTransformer extends IClassTransformer {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(foundModAPITransformer || transformers.find(_.isInstanceOf[ModAPITransformer]).isDefined) {
|
||||
// Forge makes the list of @Optional annotations before we can remove
|
||||
// them from the class, so we need to remove them from its list instead.
|
||||
val lookupName = if(name.endsWith("$class")) name.substring(0, name.length() - 6) else name
|
||||
val ourOptionals = optionals.get(lookupName)
|
||||
val filteredOptionals = ourOptionals.filter(_.getAnnotationInfo().get("modid") == "opencomputers")
|
||||
if(!filteredOptionals.isEmpty) {
|
||||
filteredOptionals.foreach(ourOptionals.remove)
|
||||
log.info(s"Successfully removed our lowercase @Optional annotations from class $name.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inject some code into the EntityLiving classes recreateLeash method to allow
|
||||
|
Loading…
x
Reference in New Issue
Block a user