Skip to content

Commit

Permalink
Remap plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Mgazul committed Jan 4, 2025
1 parent 6ee1726 commit a228369
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -10,18 +15,21 @@
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;
import java.util.Collections;
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;
Expand All @@ -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<String, Class<?>> classes = new ConcurrentHashMap<String, Class<?>>();
private final PluginDescriptionFile description;
Expand All @@ -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");
Expand Down Expand Up @@ -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<byte[]> 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<byte[], CodeSource> classBytes = this.getRemapper().remapClass(name, byteSource, connection);


int dot = name.lastIndexOf('.');
if (dot != -1) {
Expand All @@ -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) {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/mohistmc/banner/BannerGameProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<FabricLauncher>) ctor.newInstance()).accept(launcher);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private String getBannerVersion() throws Exception {
Expand Down

0 comments on commit a228369

Please sign in to comment.