diff --git a/arclight-forge/src/main/java/io/izzel/arclight/boot/mod/ModBootstrap.java b/arclight-forge/src/main/java/io/izzel/arclight/boot/mod/ModBootstrap.java index 73dfa5ca..17f93391 100644 --- a/arclight-forge/src/main/java/io/izzel/arclight/boot/mod/ModBootstrap.java +++ b/arclight-forge/src/main/java/io/izzel/arclight/boot/mod/ModBootstrap.java @@ -7,6 +7,7 @@ import cpw.mods.jarhandling.impl.Jar; import cpw.mods.modlauncher.LaunchPluginHandler; import cpw.mods.modlauncher.Launcher; import cpw.mods.modlauncher.serviceapi.ILaunchPluginService; +import cpw.mods.util.LambdaExceptionUtils; import io.izzel.arclight.api.Unsafe; import io.izzel.arclight.boot.AbstractBootstrap; import io.izzel.arclight.boot.asm.ArclightImplementer; @@ -15,14 +16,22 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.MarkerManager; import java.io.File; +import java.io.InputStream; import java.lang.invoke.MethodType; import java.lang.module.Configuration; +import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleFinder; import java.lang.module.ResolvedModule; +import java.net.URI; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.CodeSigner; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.jar.Manifest; public class ModBootstrap extends AbstractBootstrap { @@ -119,12 +128,50 @@ public class ModBootstrap extends AbstractBootstrap { var rootField = ModuleClassLoader.class.getDeclaredField("resolvedRoots"); var resolvedRoots = (Map) Unsafe.getObject(classLoader, Unsafe.objectFieldOffset(rootField)); var moduleRefCtor = Unsafe.lookup().findConstructor(Class.forName("cpw.mods.cl.JarModuleFinder$JarModuleReference"), - MethodType.methodType(void.class, Jar.class)); + MethodType.methodType(void.class, SecureJar.ModuleDataProvider.class)); for (var mod : conf.modules()) { for (var pk : mod.reference().descriptor().packages()) { packageLookup.put(pk, mod); } - resolvedRoots.put(mod.name(), moduleRefCtor.invokeWithArguments(secureJar)); + resolvedRoots.put(mod.name(), moduleRefCtor.invokeWithArguments(new JarModuleDataProvider((Jar) secureJar))); + } + } + + private record JarModuleDataProvider(Jar jar) implements SecureJar.ModuleDataProvider { + + @Override + public String name() { + return jar.name(); + } + + @Override + public ModuleDescriptor descriptor() { + return jar.computeDescriptor(); + } + + @Override + public URI uri() { + return jar.getURI(); + } + + @Override + public Optional findFile(final String name) { + return jar.findFile(name); + } + + @Override + public Optional open(final String name) { + return jar.findFile(name).map(Paths::get).map(LambdaExceptionUtils.rethrowFunction(Files::newInputStream)); + } + + @Override + public Manifest getManifest() { + return jar.getManifest(); + } + + @Override + public CodeSigner[] verifyAndGetSigners(final String cname, final byte[] bytes) { + return jar.verifyAndGetSigners(cname, bytes); } } }