WIP: class search improvements

This commit is contained in:
embeddedt 2023-01-18 09:04:50 -05:00
parent c8a5d62e34
commit c01ea4fcc4
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
5 changed files with 104 additions and 45 deletions

View File

@ -147,6 +147,8 @@ dependencies {
runtimeOnly fg.deobf("curse.maven:spark-361579:3767277")
compileOnly fg.deobf("curse.maven:refinedstorage-243076:3807951")
implementation group: 'net.bytebuddy', name: 'byte-buddy', version: '1.12.22'
}
// Example for how to get properties into the manifest for reading at runtime.

View File

@ -0,0 +1,14 @@
package org.embeddedt.modernfix.classloading;
import net.minecraftforge.fml.loading.LoadingModList;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
public class ModernFixResourceFinder {
public static Enumeration<URL> findAllURLsForResource(String input) {
System.out.println(input);
return Collections.emptyEnumeration(); //LoadingModList.get().findAllURLsForResource(input);
}
}

View File

@ -1,44 +0,0 @@
package org.embeddedt.modernfix.service;
import cpw.mods.modlauncher.*;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import org.objectweb.asm.Type;
import java.lang.reflect.Field;
import java.nio.file.Path;
import java.util.EnumSet;
public class CachingTransformerService implements ILaunchPluginService {
@Override
public String name() {
return "modernfixcache";
}
@Override
public void initializeLaunch(ITransformerLoader transformerLoader, Path[] specialPaths) {
/* Swap the transformer for ours */
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(!(loader instanceof TransformingClassLoader)) {
throw new IllegalStateException("Expected a TransformingClassLoader");
}
try {
Field classTransformerField = TransformingClassLoader.class.getDeclaredField("classTransformer");
classTransformerField.setAccessible(true);
ClassTransformer t = (ClassTransformer)classTransformerField.get(loader);
TransformStore store = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "transformers");
LaunchPluginHandler pluginHandler = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "pluginHandler");
TransformerAuditTrail trail = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "auditTrail");
classTransformerField.set(loader, new ModernFixCachingClassTransformer(store, pluginHandler, (TransformingClassLoader)loader, trail));
} catch(ReflectiveOperationException e) {
e.printStackTrace();
}
}
private static final EnumSet<Phase> NEVER = EnumSet.noneOf(Phase.class);
@Override
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty) {
return NEVER;
}
}

View File

@ -0,0 +1,87 @@
package org.embeddedt.modernfix.service;
import com.electronwill.nightconfig.toml.TomlFormat;
import cpw.mods.modlauncher.*;
import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.TypesafeMap;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.config.ConfigFileTypeHandler;
import org.embeddedt.modernfix.classloading.ModernFixResourceFinder;
import org.embeddedt.modernfix.core.config.ModernFixConfig;
import org.objectweb.asm.Type;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Function;
public class ModernFixLaunchService implements ILaunchPluginService {
private static final boolean USE_TRANSFORMER_CACHE = false;
@Override
public String name() {
return "modernfix";
}
@Override
public void initializeLaunch(ITransformerLoader transformerLoader, Path[] specialPaths) {
/* Swap the transformer for ours */
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(!(loader instanceof TransformingClassLoader)) {
throw new IllegalStateException("Expected a TransformingClassLoader");
}
try {
if(USE_TRANSFORMER_CACHE) {
Field classTransformerField = TransformingClassLoader.class.getDeclaredField("classTransformer");
classTransformerField.setAccessible(true);
ClassTransformer t = (ClassTransformer)classTransformerField.get(loader);
TransformStore store = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "transformers");
LaunchPluginHandler pluginHandler = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "pluginHandler");
TransformerAuditTrail trail = ObfuscationReflectionHelper.getPrivateValue(ClassTransformer.class, t, "auditTrail");
classTransformerField.set(loader, new ModernFixCachingClassTransformer(store, pluginHandler, (TransformingClassLoader)loader, trail));
}
Field resourceFinderField = TransformingClassLoader.class.getDeclaredField("resourceFinder");
/* Construct a new list of resource finders, using similar logic to ML */
resourceFinderField.setAccessible(true);
Function<String, Enumeration<URL>> resourceFinder = constructResourceFinder();
resourceFinderField.set(loader, resourceFinder);
} catch(ReflectiveOperationException e) {
e.printStackTrace();
}
}
private Function<String, Enumeration<URL>> constructResourceFinder() throws ReflectiveOperationException {
Field servicesHandlerField = Launcher.class.getDeclaredField("transformationServicesHandler");
servicesHandlerField.setAccessible(true);
Object servicesHandler = servicesHandlerField.get(Launcher.INSTANCE);
Field serviceLookupField = servicesHandler.getClass().getDeclaredField("serviceLookup");
serviceLookupField.setAccessible(true);
Map<String, TransformationServiceDecorator> serviceLookup = (Map<String, TransformationServiceDecorator>)serviceLookupField.get(servicesHandler);
Method getClassLoaderMethod = TransformationServiceDecorator.class.getDeclaredMethod("getClassLoader");
getClassLoaderMethod.setAccessible(true);
Function<String, Enumeration<URL>> resourceEnumeratorLocator = ModernFixResourceFinder::findAllURLsForResource;
for(TransformationServiceDecorator decorator : serviceLookup.values()) {
Function<String, Optional<URL>> func = (Function<String, Optional<URL>>)getClassLoaderMethod.invoke(decorator);
if(func != null)
resourceEnumeratorLocator = EnumerationHelper.mergeFunctors(resourceEnumeratorLocator, EnumerationHelper.fromOptional(func));
}
System.out.println(EnumerationHelper.firstElementOrNull(resourceEnumeratorLocator.apply("net.minecraft.client.Minecraft")));
return resourceEnumeratorLocator;
}
private static final EnumSet<Phase> NEVER = EnumSet.noneOf(Phase.class);
@Override
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty) {
return NEVER;
}
}

View File

@ -1 +1 @@
org.embeddedt.modernfix.service.CachingTransformerService
org.embeddedt.modernfix.service.ModernFixLaunchService