diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/ArclightMain.java b/arclight-common/src/main/java/io/izzel/arclight/common/ArclightMain.java index 3257730e..93151c66 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/ArclightMain.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/ArclightMain.java @@ -6,7 +6,6 @@ import io.izzel.arclight.api.EnumHelper; import io.izzel.arclight.api.Unsafe; import io.izzel.arclight.common.mod.util.log.ArclightI18nLogger; import io.izzel.arclight.common.mod.util.log.ArclightLazyLogManager; -import io.izzel.arclight.common.mod.util.remapper.ArclightRemapper; import io.izzel.arclight.common.util.EnumTypeFactory; import io.izzel.arclight.i18n.ArclightConfig; import io.izzel.arclight.i18n.ArclightLocale; @@ -14,7 +13,6 @@ import net.minecraftforge.server.ServerMain; import java.io.InputStream; import java.lang.reflect.Field; -import java.util.Objects; import java.util.jar.Attributes; import java.util.jar.Manifest; @@ -38,8 +36,6 @@ public abstract class ArclightMain { } try { printLogo(); - ArclightI18nLogger.getLogger("Arclight").info("loading-mapping"); - Objects.requireNonNull(ArclightRemapper.INSTANCE); this.beforeStart(); this.dirtyHacks(); ServerMain.main(args); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/PluginClassLoaderMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/PluginClassLoaderMixin.java index 46ea333f..ad9f3880 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/PluginClassLoaderMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/PluginClassLoaderMixin.java @@ -4,7 +4,7 @@ import com.google.common.io.ByteStreams; import io.izzel.arclight.common.asm.SwitchTableFixer; import io.izzel.arclight.common.bridge.bukkit.JavaPluginLoaderBridge; import io.izzel.arclight.common.mod.util.remapper.ArclightRemapper; -import io.izzel.arclight.common.mod.util.remapper.PluginRemapper; +import io.izzel.arclight.common.mod.util.remapper.ClassLoaderRemapper; import org.bukkit.Bukkit; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPluginLoader; @@ -36,7 +36,7 @@ public class PluginClassLoaderMixin extends URLClassLoader { @Shadow @Final private URL url; // @formatter:on - private PluginRemapper remapper; + private ClassLoaderRemapper remapper; public PluginClassLoaderMixin(URL[] urls) { super(urls); @@ -74,7 +74,7 @@ public class PluginClassLoaderMixin extends URLClassLoader { classBytes = SwitchTableFixer.INSTANCE.processClass(classBytes); classBytes = Bukkit.getUnsafe().processClass(description, path, classBytes); if (remapper == null) { - remapper = ArclightRemapper.INSTANCE.createPluginRemapper(this.loader, this); + remapper = ArclightRemapper.INSTANCE.createClassLoaderRemapper(this); } classBytes = remapper.remapClass(classBytes); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightInterfaceInvokerGen.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightInterfaceInvokerGen.java index 915dd310..e583dba4 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightInterfaceInvokerGen.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightInterfaceInvokerGen.java @@ -16,14 +16,20 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -public class ArclightInterfaceInvokerGen { +public class ArclightInterfaceInvokerGen implements PluginTransformer { + public static final ArclightInterfaceInvokerGen INSTANCE = new ArclightInterfaceInvokerGen(); private static final String PREFIX = "net/minecraft/"; - public static void generate(ClassNode classNode, ClassRepo classRepo, PluginRemapper remapper, InheritanceProvider inheritanceProvider) { + @Override + public void handleClass(ClassNode node, ClassLoaderRemapper remapper) { + generate(node, remapper, GlobalClassRepo.inheritanceProvider()); + } + + private static void generate(ClassNode classNode, ClassLoaderRemapper remapper, InheritanceProvider inheritanceProvider) { if (shouldGenerate(classNode.name, inheritanceProvider)) { HashSet> set = new HashSet<>(); - interfaceMethods(classNode.name, set, classRepo); + interfaceMethods(classNode.name, set, GlobalClassRepo.INSTANCE); for (Map.Entry entry : set) { String name = entry.getKey(); String desc = entry.getValue(); @@ -47,7 +53,7 @@ public class ArclightInterfaceInvokerGen { } } - private static MethodNode generateSynthetic(String name, String desc, MethodInsnNode node, PluginRemapper remapper) { + private static MethodNode generateSynthetic(String name, String desc, MethodInsnNode node, ClassLoaderRemapper remapper) { name = remapper.mapType(name); MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, name, desc, null, null); methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightRedirectAdapter.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightRedirectAdapter.java index fe9ac3d2..eaf4467e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightRedirectAdapter.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightRedirectAdapter.java @@ -17,10 +17,11 @@ import java.util.ListIterator; import java.util.Map; import java.util.Objects; -public class ArclightRedirectAdapter { +public class ArclightRedirectAdapter implements PluginTransformer { - private static String REPLACED_NAME = Type.getInternalName(ArclightReflectionHandler.class); - private static Map methodRedirects = ImmutableMap + public static final ArclightRedirectAdapter INSTANCE = new ArclightRedirectAdapter(); + private static final String REPLACED_NAME = Type.getInternalName(ArclightReflectionHandler.class); + private static final Map METHOD_REDIRECTS = ImmutableMap .builder() .put( method(Opcodes.INVOKEVIRTUAL, Field.class, "getName"), @@ -104,14 +105,19 @@ public class ArclightRedirectAdapter { ) .build(); - public static void redirect(ClassNode classNode, String generatedOwner) { + @Override + public void handleClass(ClassNode node, ClassLoaderRemapper remapper) { + redirect(node, remapper.getGeneratedHandler()); + } + + private static void redirect(ClassNode classNode, String generatedOwner) { for (MethodNode methodNode : classNode.methods) { ListIterator iterator = methodNode.instructions.iterator(); while (iterator.hasNext()) { AbstractInsnNode insnNode = iterator.next(); if (insnNode instanceof MethodInsnNode) { MethodInsnNode from = (MethodInsnNode) insnNode; - for (Map.Entry entry : methodRedirects.entrySet()) { + for (Map.Entry entry : METHOD_REDIRECTS.entrySet()) { MethodInsnNode key = entry.getKey(); if ( key.getOpcode() == from.getOpcode() && @@ -151,5 +157,4 @@ public class ArclightRedirectAdapter { String desc = Type.getMethodDescriptor(method); return new MethodInsnNode(opcode, owner, name, desc); } - } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightRemapper.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightRemapper.java index 195fcd1c..d6224f86 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightRemapper.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ArclightRemapper.java @@ -3,21 +3,23 @@ package io.izzel.arclight.common.mod.util.remapper; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import io.izzel.arclight.api.Unsafe; +import io.izzel.arclight.common.mod.util.log.ArclightI18nLogger; import net.md_5.specialsource.InheritanceMap; import net.md_5.specialsource.JarMapping; import net.md_5.specialsource.provider.ClassLoaderProvider; import net.md_5.specialsource.provider.JointProvider; -import org.bukkit.plugin.java.JavaPluginLoader; import java.io.BufferedReader; import java.io.InputStreamReader; -import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; public class ArclightRemapper { public static final ArclightRemapper INSTANCE; static { + ArclightI18nLogger.getLogger("Arclight").info("loading-mapping"); try { INSTANCE = new ArclightRemapper(); } catch (Exception e) { @@ -28,6 +30,7 @@ public class ArclightRemapper { private final JarMapping toNmsMapping; private final JarMapping toBukkitMapping; public final InheritanceMap inheritanceMap; + private final List transformerList = new ArrayList<>(); public ArclightRemapper() throws Exception { this.toNmsMapping = new JarMapping(); @@ -50,10 +53,16 @@ public class ArclightRemapper { inheritanceProvider.add(new ClassLoaderProvider(ClassLoader.getSystemClassLoader())); this.toNmsMapping.setFallbackInheritanceProvider(inheritanceProvider); this.toBukkitMapping.setFallbackInheritanceProvider(inheritanceProvider); + this.transformerList.add(ArclightInterfaceInvokerGen.INSTANCE); + this.transformerList.add(ArclightRedirectAdapter.INSTANCE); } - public PluginRemapper createPluginRemapper(JavaPluginLoader loader, URLClassLoader plugin) { - return new PluginRemapper(copyOf(toNmsMapping), copyOf(toBukkitMapping), loader, plugin); + public ClassLoaderRemapper createClassLoaderRemapper(ClassLoader classLoader) { + return new ClassLoaderRemapper(copyOf(toNmsMapping), copyOf(toBukkitMapping), classLoader); + } + + public List getTransformerList() { + return transformerList; } private static long pkgOffset, clOffset, mdOffset, fdOffset, mapOffset; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginRemapper.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRemapper.java similarity index 88% rename from arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginRemapper.java rename to arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRemapper.java index d2e3b232..a01d5ba3 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginRemapper.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRemapper.java @@ -4,15 +4,14 @@ import com.google.common.base.Preconditions; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.Maps; -import io.izzel.arclight.common.mod.util.remapper.generated.ArclightReflectionHandler; import io.izzel.arclight.api.Unsafe; +import io.izzel.arclight.common.mod.util.remapper.generated.ArclightReflectionHandler; import net.md_5.specialsource.JarMapping; import net.md_5.specialsource.JarRemapper; import net.md_5.specialsource.RemappingClassAdapter; import net.md_5.specialsource.repo.ClassRepo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bukkit.plugin.java.JavaPluginLoader; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; @@ -27,7 +26,6 @@ import org.spongepowered.asm.service.MixinService; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.net.URLClassLoader; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; @@ -36,33 +34,30 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -public class PluginRemapper extends JarRemapper { +public class ClassLoaderRemapper extends JarRemapper { private static final Logger LOGGER = LogManager.getLogger("Arclight"); private static final String PREFIX = "net/minecraft/"; - private final PluginInheritanceProvider inheritanceProvider; - private final ClassRepo classRepo; private final JarMapping toBukkitMapping; private final JarRemapper toBukkitRemapper; - private final URLClassLoader plugin; + private final ClassLoader classLoader; private final String generatedHandler; - public PluginRemapper(JarMapping jarMapping, JarMapping toBukkitMapping, JavaPluginLoader loader, URLClassLoader plugin) { + public ClassLoaderRemapper(JarMapping jarMapping, JarMapping toBukkitMapping, ClassLoader classLoader) { super(jarMapping); this.toBukkitMapping = toBukkitMapping; - this.plugin = plugin; - this.classRepo = SharedClassRepo.get(loader, plugin); - this.inheritanceProvider = new PluginInheritanceProvider(this.classRepo); + this.classLoader = classLoader; this.jarMapping.setInheritanceMap(ArclightRemapper.INSTANCE.inheritanceMap); - this.jarMapping.setFallbackInheritanceProvider(this.inheritanceProvider); - this.toBukkitMapping.setFallbackInheritanceProvider(this.inheritanceProvider); + this.jarMapping.setFallbackInheritanceProvider(GlobalClassRepo.inheritanceProvider()); + this.toBukkitMapping.setFallbackInheritanceProvider(GlobalClassRepo.inheritanceProvider()); this.toBukkitRemapper = new JarRemapper(this.toBukkitMapping); this.generatedHandler = generateReflectionHandler(); + GlobalClassRepo.INSTANCE.addRepo(new ClassLoaderRepo(this.classLoader)); } - public URLClassLoader getPluginClassLoader() { - return plugin; + public ClassLoader getClassLoader() { + return classLoader; } public JarMapping toBukkitMapping() { @@ -77,8 +72,8 @@ public class PluginRemapper extends JarRemapper { return toBukkitRemapper; } - public ClassRepo getClassRepo() { - return classRepo; + public String getGeneratedHandler() { + return generatedHandler; } // BiMap: srg -> bukkit @@ -204,7 +199,7 @@ public class PluginRemapper extends JarRemapper { private boolean shouldRemap(String internalName) { Boolean b = cacheRemap.get(internalName); if (b != null) return b; - for (String s : inheritanceProvider.getAll(internalName)) { + for (String s : GlobalClassRepo.inheritanceProvider().getAll(internalName)) { if (s.startsWith(PREFIX)) { cacheRemap.put(internalName, true); return true; @@ -230,7 +225,7 @@ public class PluginRemapper extends JarRemapper { if (ArclightRemapper.INSTANCE.inheritanceMap.hasParents(owner)) { parents = ArclightRemapper.INSTANCE.inheritanceMap.getParents(owner); } else { - parents = this.inheritanceProvider.getParents(owner); + parents = GlobalClassRepo.inheritanceProvider().getParents(owner); ArclightRemapper.INSTANCE.inheritanceMap.setParents(owner, parents); } @@ -249,7 +244,7 @@ public class PluginRemapper extends JarRemapper { } public byte[] remapClass(byte[] arr) { - return remapClassFile(arr, classRepo); + return remapClassFile(arr, GlobalClassRepo.INSTANCE); } @Override @@ -262,8 +257,9 @@ public class PluginRemapper extends JarRemapper { RemappingClassAdapter mapper = new RemappingClassAdapter(node, this, repo); reader.accept(mapper, ClassReader.SKIP_FRAMES); - ArclightRedirectAdapter.redirect(node, generatedHandler); - ArclightInterfaceInvokerGen.generate(node, this.classRepo, this, this.inheritanceProvider); + for (PluginTransformer transformer : ArclightRemapper.INSTANCE.getTransformerList()) { + transformer.handleClass(node, this); + } // 有的插件的编译器奇奇怪怪的,所以在这里要重新计算 frame ClassWriter wr = new PluginClassWriter(ClassWriter.COMPUTE_FRAMES); @@ -272,14 +268,14 @@ public class PluginRemapper extends JarRemapper { return wr.toByteArray(); } - private static AtomicInteger atomicInteger = new AtomicInteger(); + private static final AtomicInteger COUNTER = new AtomicInteger(); private String generateReflectionHandler() { try { ClassNode node = MixinService.getService().getBytecodeProvider().getClassNode(Type.getInternalName(ArclightReflectionHandler.class)); Preconditions.checkNotNull(node, "node"); ClassWriter writer = new ClassWriter(0); - String name = Type.getInternalName(ArclightReflectionHandler.class) + "_" + atomicInteger.getAndIncrement(); + String name = Type.getInternalName(ArclightReflectionHandler.class) + "_" + COUNTER.getAndIncrement(); ClassVisitor visitor = new ClassRemapper(writer, new NameRemapper(name)); node.accept(visitor); byte[] bytes = writer.toByteArray(); @@ -296,7 +292,7 @@ public class PluginRemapper extends JarRemapper { private static class NameRemapper extends Remapper { - private static String origin = Type.getInternalName(ArclightReflectionHandler.class); + private static final String ORIGIN = Type.getInternalName(ArclightReflectionHandler.class); private final String internal; @@ -306,14 +302,14 @@ public class PluginRemapper extends JarRemapper { @Override public String mapType(String internalName) { - if (internalName.equals(origin)) { + if (internalName.equals(ORIGIN)) { return internal; } return super.mapType(internalName); } } - private class PluginClassWriter extends ClassWriter { + private static class PluginClassWriter extends ClassWriter { public PluginClassWriter(int flags) { super(flags); @@ -321,11 +317,11 @@ public class PluginRemapper extends JarRemapper { @Override protected String getCommonSuperClass(String type1, String type2) { - Collection parents = inheritanceProvider.getAll(type2); + Collection parents = GlobalClassRepo.inheritanceProvider().getAll(type2); if (parents.contains(type1)) { return type1; } - if (inheritanceProvider.getAll(type1).contains(type2)) { + if (GlobalClassRepo.inheritanceProvider().getAll(type1).contains(type2)) { return type2; } do { @@ -335,7 +331,7 @@ public class PluginRemapper extends JarRemapper { } private String getSuper(final String typeName) { - ClassNode node = classRepo.findClass(typeName); + ClassNode node = GlobalClassRepo.INSTANCE.findClass(typeName); if (node == null) return "java/lang/Object"; return node.superName; } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRepo.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRepo.java new file mode 100644 index 00000000..a3d1cadb --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRepo.java @@ -0,0 +1,36 @@ +package io.izzel.arclight.common.mod.util.remapper; + +import net.md_5.specialsource.repo.ClassRepo; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.ClassNode; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; + +public class ClassLoaderRepo implements ClassRepo { + + private final ClassLoader classLoader; + + public ClassLoaderRepo(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public ClassNode findClass(String internalName) { + URL url = classLoader.getResource(internalName + ".class"); + if (url == null) return null; + try { + URLConnection connection = url.openConnection(); + try (InputStream inputStream = connection.getInputStream()) { + ClassReader reader = new ClassReader(inputStream); + ClassNode classNode = new ClassNode(); + reader.accept(classNode, ClassReader.SKIP_CODE); + return classNode; + } + } catch (IOException ignored) { + } + return null; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/GlobalClassRepo.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/GlobalClassRepo.java new file mode 100644 index 00000000..b431d639 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/GlobalClassRepo.java @@ -0,0 +1,62 @@ +package io.izzel.arclight.common.mod.util.remapper; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import net.md_5.specialsource.repo.ClassRepo; +import org.objectweb.asm.tree.ClassNode; +import org.spongepowered.asm.service.MixinService; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class GlobalClassRepo implements ClassRepo { + + public static final GlobalClassRepo INSTANCE = new GlobalClassRepo(); + private static final PluginInheritanceProvider PROVIDER = new PluginInheritanceProvider(INSTANCE); + + private final LoadingCache cache = CacheBuilder.newBuilder().maximumSize(65536).build(CacheLoader.from(this::findParallel)); + private final Set repos = Collections.newSetFromMap(new ConcurrentHashMap<>()); + + private GlobalClassRepo() { + } + + @Override + public ClassNode findClass(String internalName) { + try { + return cache.get(internalName); + } catch (Throwable e) { + return null; + } + } + + private ClassNode findParallel(String internalName) { + return this.repos.parallelStream() + .map(it -> it.findClass(internalName)) + .filter(Objects::nonNull) + .findAny() + .orElseGet(() -> this.findMinecraft(internalName)); + } + + private ClassNode findMinecraft(String internalName) { + try { + return MixinService.getService().getBytecodeProvider().getClassNode(internalName); + } catch (Exception e) { + throw new RuntimeException(internalName, e); + } + } + + public void addRepo(ClassRepo repo) { + this.repos.add(repo); + } + + public void removeRepo(ClassRepo repo) { + this.repos.remove(repo); + } + + public static PluginInheritanceProvider inheritanceProvider() { + return PROVIDER; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginClassRepo.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginClassRepo.java deleted file mode 100644 index 756ff7ac..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginClassRepo.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.izzel.arclight.common.mod.util.remapper; - -import io.izzel.arclight.common.bridge.bukkit.JavaPluginLoaderBridge; -import net.md_5.specialsource.repo.ClassRepo; -import org.bukkit.plugin.java.JavaPluginLoader; -import org.objectweb.asm.tree.ClassNode; - -import java.net.URLClassLoader; - -public class PluginClassRepo implements ClassRepo { - - private final SharedClassRepo shared; - private JavaPluginLoaderBridge loader; - private URLClassLoader plugin; - - protected PluginClassRepo(SharedClassRepo shared, JavaPluginLoader loader, URLClassLoader plugin) { - this.shared = shared; - this.loader = (JavaPluginLoaderBridge) (Object) loader; - this.plugin = plugin; - } - - @Override - public ClassNode findClass(String internalName) { - if (plugin == null) return shared.findClass(internalName); - if (loader.bridge$getLoaders().contains(plugin)) { - plugin = null; - } - ClassNode node = shared.findClass(internalName); - if (node == null && plugin != null) { - return shared.findIn(plugin, internalName + ".class"); - } - return node; - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginInheritanceProvider.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginInheritanceProvider.java index 4578eb51..2bf0003e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginInheritanceProvider.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginInheritanceProvider.java @@ -12,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap; public class PluginInheritanceProvider implements InheritanceProvider { - private static Map> sharedInheritanceMap = new ConcurrentHashMap<>(); + private static final Map> SHARED_INHERITANCE_MAP = new ConcurrentHashMap<>(); private final ClassRepo classRepo; @@ -34,7 +34,7 @@ public class PluginInheritanceProvider implements InheritanceProvider { } public Collection getAll(String className) { - Collection collection = sharedInheritanceMap.get(className); + Collection collection = SHARED_INHERITANCE_MAP.get(className); if (collection != null) return collection; ClassNode node = classRepo.findClass(className); @@ -48,7 +48,7 @@ public class PluginInheritanceProvider implements InheritanceProvider { parents.add("java/lang/Object"); } - sharedInheritanceMap.put(className, parents); + SHARED_INHERITANCE_MAP.put(className, parents); return parents; } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginTransformer.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginTransformer.java new file mode 100644 index 00000000..01731554 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/PluginTransformer.java @@ -0,0 +1,8 @@ +package io.izzel.arclight.common.mod.util.remapper; + +import org.objectweb.asm.tree.ClassNode; + +public interface PluginTransformer { + + void handleClass(ClassNode node, ClassLoaderRemapper remapper); +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/SharedClassRepo.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/SharedClassRepo.java deleted file mode 100644 index 7cb703b6..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/SharedClassRepo.java +++ /dev/null @@ -1,93 +0,0 @@ -package io.izzel.arclight.common.mod.util.remapper; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import io.izzel.arclight.common.bridge.bukkit.JavaPluginLoaderBridge; -import net.md_5.specialsource.repo.ClassRepo; -import org.bukkit.plugin.java.JavaPluginLoader; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.tree.ClassNode; -import org.spongepowered.asm.service.MixinService; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLConnection; - -public class SharedClassRepo implements ClassRepo { - - private static SharedClassRepo classRepo; - - protected final JavaPluginLoaderBridge loader; - private final Cache cache = CacheBuilder.newBuilder().maximumSize(65536).build(); - - protected SharedClassRepo(JavaPluginLoader loader) { - this.loader = ((JavaPluginLoaderBridge) (Object) loader); - } - - @Override - public ClassNode findClass(String internalName) { - ClassNode ret = cache.getIfPresent(internalName); - if (ret != null) { - return ret; - } - try { - ret = MixinService.getService().getBytecodeProvider().getClassNode(internalName); - } catch (Exception ignored) { - } - if (ret == null) { - ret = findPlugins(internalName + ".class"); - } - if (ret != null) { - cache.put(internalName, ret); - } - return ret; - } - - private ClassNode findPlugins(String name) { - for (URLClassLoader classLoader : loader.bridge$getLoaders()) { - ClassNode node = findIn(classLoader, name); - if (node != null) return node; - } - return null; - } - - protected ClassNode findIn(URLClassLoader classLoader, String name) { - URL url = HelperClassLoader.find(classLoader, name); - if (url == null) return null; - try { - URLConnection connection = url.openConnection(); - try (InputStream inputStream = connection.getInputStream()) { - ClassReader reader = new ClassReader(inputStream); - ClassNode classNode = new ClassNode(); - reader.accept(classNode, ClassReader.SKIP_CODE); - return classNode; - } - } catch (IOException ignored) { - } - return null; - } - - public static ClassRepo get(JavaPluginLoader loader, URLClassLoader plugin) { - if (classRepo == null) { - synchronized (SharedClassRepo.class) { - if (classRepo == null) { - classRepo = new SharedClassRepo(loader); - } - } - } - return new PluginClassRepo(classRepo, loader, plugin); - } - - private static class HelperClassLoader extends URLClassLoader { - - public HelperClassLoader(URL[] urls) { - super(urls); - } - - static URL find(URLClassLoader classLoader, String resource) { - return classLoader.findResource(resource); // search local - } - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/generated/ArclightReflectionHandler.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/generated/ArclightReflectionHandler.java index 38169b5e..61039052 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/generated/ArclightReflectionHandler.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/generated/ArclightReflectionHandler.java @@ -1,7 +1,7 @@ package io.izzel.arclight.common.mod.util.remapper.generated; +import io.izzel.arclight.common.mod.util.remapper.ClassLoaderRemapper; import org.objectweb.asm.Type; -import io.izzel.arclight.common.mod.util.remapper.PluginRemapper; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -14,11 +14,11 @@ public class ArclightReflectionHandler { private static final String PREFIX = "net.minecraft."; - public static PluginRemapper remapper; + public static ClassLoaderRemapper remapper; // bukkit -> srg public static Class redirectForName(String cl) throws ClassNotFoundException { - return redirectForName(cl, true, remapper.getPluginClassLoader()); + return redirectForName(cl, true, remapper.getClassLoader()); } // bukkit -> srg diff --git a/build.gradle b/build.gradle index 4eada321..47a0d31f 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ import java.nio.file.attribute.BasicFileAttributes allprojects { group 'io.izzel.arclight' - version '1.0.2' + version '1.0.3-SNAPSHOT' ext { agpVersion = '1.7'