diff --git a/modules/banner-api/src/main/java/com/mohistmc/banner/bukkit/pluginfix/PluginFixManager.java b/modules/banner-api/src/main/java/com/mohistmc/banner/bukkit/pluginfix/PluginFixManager.java index edac92854..3aba1f8b3 100644 --- a/modules/banner-api/src/main/java/com/mohistmc/banner/bukkit/pluginfix/PluginFixManager.java +++ b/modules/banner-api/src/main/java/com/mohistmc/banner/bukkit/pluginfix/PluginFixManager.java @@ -18,7 +18,7 @@ public class PluginFixManager { - public static byte[] injectPluginFix(String className, byte[] clazz) { + public static byte[] injectPluginFix(String mainClass, String className, byte[] clazz) { if (className.endsWith("PaperLib")) { return patch(clazz, PluginFixManager::removePaper); } diff --git a/modules/banner-api/src/main/java/com/mohistmc/banner/bukkit/remapping/Remapper.java b/modules/banner-api/src/main/java/com/mohistmc/banner/bukkit/remapping/Remapper.java index 3f5b6c367..aedf650d8 100644 --- a/modules/banner-api/src/main/java/com/mohistmc/banner/bukkit/remapping/Remapper.java +++ b/modules/banner-api/src/main/java/com/mohistmc/banner/bukkit/remapping/Remapper.java @@ -47,6 +47,7 @@ public Remapper() throws Exception { // this.toNmsMapping.packages.put("org/yaml/snakeyaml/", "com/mohistmc/org/yaml/snakeyaml/"); // this.toNmsMapping.packages.put("javax/inject/", "com/mohistmc/javax/inject/"); // this.toNmsMapping.classes.put("io/netty/util/Version", "com/mohistmc/bukkit/pluginfix/ScriptBlockPlus"); + this.toNmsMapping.packages.put("org/bukkit/craftbukkit/v1_21_R1/", "org/bukkit/craftbukkit/"); this.toBukkitMapping = new JarMapping(); this.inheritanceMap = new InheritanceMap(); this.toNmsMapping.loadMappings( diff --git a/modules/banner-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/modules/banner-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java index 64a294aeb..3e276e248 100644 --- a/modules/banner-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/modules/banner-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -2,6 +2,11 @@ import com.google.common.base.Preconditions; import com.google.common.io.ByteStreams; +import com.mohistmc.banner.bukkit.pluginfix.PluginFixManager; +import com.mohistmc.banner.bukkit.remapping.ClassLoaderRemapper; +import com.mohistmc.banner.bukkit.remapping.Remapper; +import com.mohistmc.banner.bukkit.remapping.RemappingClassLoader; +import io.izzel.tools.product.Product2; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -10,6 +15,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.net.URLConnection; import java.security.CodeSigner; import java.security.CodeSource; import java.util.Collection; @@ -17,11 +23,13 @@ import java.util.Enumeration; import java.util.Map; import java.util.Set; +import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.logging.Level; +import org.bukkit.Bukkit; import org.bukkit.plugin.InvalidPluginException; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.SimplePluginManager; @@ -31,7 +39,7 @@ /** * A ClassLoader for plugins, to allow shared classes across multiple plugins */ -final class PluginClassLoader extends URLClassLoader { +final class PluginClassLoader extends URLClassLoader implements RemappingClassLoader { private final JavaPluginLoader loader; private final Map> classes = new ConcurrentHashMap>(); private final PluginDescriptionFile description; @@ -50,6 +58,16 @@ final class PluginClassLoader extends URLClassLoader { ClassLoader.registerAsParallelCapable(); } + private ClassLoaderRemapper remapper; + + @Override + public ClassLoaderRemapper getRemapper() { + if (remapper == null) { + remapper = Remapper.createClassLoaderRemapper(this); + } + return remapper; + } + PluginClassLoader(@NotNull final JavaPluginLoader loader, @Nullable final ClassLoader parent, @NotNull final PluginDescriptionFile description, @NotNull final File dataFolder, @NotNull final File file, @Nullable ClassLoader libraryLoader) throws IOException, InvalidPluginException, MalformedURLException { super(new URL[] {file.toURI().toURL()}, parent); Preconditions.checkArgument(loader != null, "Loader cannot be null"); @@ -169,18 +187,29 @@ protected Class findClass(String name) throws ClassNotFoundException { if (result == null) { String path = name.replace('.', '/').concat(".class"); - JarEntry entry = jar.getJarEntry(path); - - if (entry != null) { - byte[] classBytes; - - try (InputStream is = jar.getInputStream(entry)) { - classBytes = ByteStreams.toByteArray(is); - } catch (IOException ex) { - throw new ClassNotFoundException(name, ex); + URL url = this.findResource(path); + + if (url != null) { + + URLConnection connection; + Callable byteSource; + try { + connection = url.openConnection(); + connection.connect(); + byteSource = () -> { + try (InputStream is = connection.getInputStream()) { + byte[] classBytes = ByteStreams.toByteArray(is); + classBytes = Bukkit.getUnsafe().processClass(description, path, classBytes); + classBytes = PluginFixManager.injectPluginFix(description.getMain(), name, classBytes); // Mohist - Inject plugin fix + return classBytes; + } + }; + } catch (IOException e) { + throw new ClassNotFoundException(name, e); } - classBytes = loader.server.getUnsafe().processClass(description, path, classBytes); + Product2 classBytes = this.getRemapper().remapClass(name, byteSource, connection); + int dot = name.lastIndexOf('.'); if (dot != -1) { @@ -200,10 +229,7 @@ protected Class findClass(String name) throws ClassNotFoundException { } } - CodeSigner[] signers = entry.getCodeSigners(); - CodeSource source = new CodeSource(url, signers); - - result = defineClass(name, classBytes, 0, classBytes.length, source); + result = defineClass(name, classBytes._1, 0, classBytes._1.length, classBytes._2); } if (result == null) { diff --git a/src/main/java/com/mohistmc/banner/BannerGameProvider.java b/src/main/java/com/mohistmc/banner/BannerGameProvider.java index bc174d195..313d5572d 100644 --- a/src/main/java/com/mohistmc/banner/BannerGameProvider.java +++ b/src/main/java/com/mohistmc/banner/BannerGameProvider.java @@ -4,6 +4,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.function.Consumer; import java.util.jar.Attributes; import java.util.jar.Manifest; import net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider; @@ -56,6 +57,15 @@ public Arguments getArguments() { @Override public void unlockClassPath(FabricLauncher launcher) { super.unlockClassPath(launcher); + try { + var field = launcher.getClass().getDeclaredField("unlocked"); + field.setAccessible(true); + field.set(launcher, true); + var ctor = launcher.loadIntoTarget("com.mohistmc.banner.boot.FabricBootstrap").getConstructor(); + ((Consumer) ctor.newInstance()).accept(launcher); + } catch (Exception e) { + throw new RuntimeException(e); + } } private String getBannerVersion() throws Exception {