From 2361c206e43e66eadcc602186c463befea190516 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Tue, 20 Oct 2020 13:19:38 +0800 Subject: [PATCH] Implement plugin patcher (#63) --- .../mod/util/remapper/ArclightRemapper.java | 2 + .../mod/util/remapper/PluginTransformer.java | 4 + .../patcher/ArclightPluginPatcher.java | 73 +++++++++++++++++++ .../main/resources/META-INF/i18n/en_us.conf | 5 ++ .../main/resources/META-INF/i18n/zh_cn.conf | 5 ++ 5 files changed, 89 insertions(+) create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/patcher/ArclightPluginPatcher.java 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 136ca8f6..24bb7f25 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 @@ -4,6 +4,7 @@ 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 io.izzel.arclight.common.mod.util.remapper.patcher.ArclightPluginPatcher; import net.md_5.specialsource.InheritanceMap; import net.md_5.specialsource.JarMapping; import net.md_5.specialsource.provider.ClassLoaderProvider; @@ -56,6 +57,7 @@ public class ArclightRemapper { this.transformerList.add(ArclightInterfaceInvokerGen.INSTANCE); this.transformerList.add(ArclightRedirectAdapter.INSTANCE); this.transformerList.add(ClassLoaderAdapter.INSTANCE); + ArclightPluginPatcher.load(this.transformerList); } public static ClassLoaderRemapper createClassLoaderRemapper(ClassLoader classLoader) { 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 index 01731554..fcc85982 100644 --- 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 @@ -5,4 +5,8 @@ import org.objectweb.asm.tree.ClassNode; public interface PluginTransformer { void handleClass(ClassNode node, ClassLoaderRemapper remapper); + + default int priority() { + return 0; + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/patcher/ArclightPluginPatcher.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/patcher/ArclightPluginPatcher.java new file mode 100644 index 00000000..ae209261 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/patcher/ArclightPluginPatcher.java @@ -0,0 +1,73 @@ +package io.izzel.arclight.common.mod.util.remapper.patcher; + +import io.izzel.arclight.common.mod.ArclightMod; +import io.izzel.arclight.common.mod.util.remapper.ClassLoaderRemapper; +import io.izzel.arclight.common.mod.util.remapper.PluginTransformer; +import org.bukkit.configuration.file.YamlConfiguration; +import org.objectweb.asm.tree.ClassNode; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; + +public class ArclightPluginPatcher implements PluginTransformer { + + private final List list; + + public ArclightPluginPatcher(List list) { + this.list = list; + } + + @Override + public void handleClass(ClassNode node, ClassLoaderRemapper remapper) { + for (PluginTransformer transformer : list) { + transformer.handleClass(node, remapper); + } + } + + public static void load(List transformerList) { + File pluginFolder = new File("plugins"); + if (pluginFolder.exists()) { + ArclightMod.LOGGER.info("patcher.loading"); + ArrayList list = new ArrayList<>(); + for (File file : pluginFolder.listFiles()) { + if (file.isFile() && file.getName().endsWith(".jar")) { + loadFromJar(file.toPath()).ifPresent(list::add); + } + } + if (!list.isEmpty()) { + list.sort(Comparator.comparing(PluginTransformer::priority)); + ArclightMod.LOGGER.info("patcher.loaded", list.size()); + transformerList.add(new ArclightPluginPatcher(list)); + } + } + } + + private static Optional loadFromJar(Path path) { + try { + FileSystem fileSystem = FileSystems.newFileSystem(path, ArclightPluginPatcher.class.getClassLoader()); + Path pluginYml = fileSystem.getPath("plugin.yml"); + if (Files.exists(pluginYml)) { + YamlConfiguration configuration = YamlConfiguration.loadConfiguration(Files.newBufferedReader(pluginYml)); + String name = configuration.getString("arclight.patcher"); + if (name != null) { + URLClassLoader loader = new URLClassLoader(new URL[]{path.toUri().toURL()}, ArclightPluginPatcher.class.getClassLoader()); + Class clazz = Class.forName(name, false, loader); + PluginTransformer transformer = clazz.asSubclass(PluginTransformer.class).newInstance(); + return Optional.of(transformer); + } + } + } catch (Exception e) { + ArclightMod.LOGGER.error("patcher.load-error", e); + } + return Optional.empty(); + } +} diff --git a/i18n-config/src/main/resources/META-INF/i18n/en_us.conf b/i18n-config/src/main/resources/META-INF/i18n/en_us.conf index e04d0e3b..18fa6f57 100644 --- a/i18n-config/src/main/resources/META-INF/i18n/en_us.conf +++ b/i18n-config/src/main/resources/META-INF/i18n/en_us.conf @@ -40,6 +40,11 @@ mixin-load { optimization = "Arclight optimization mixin added." } mod-load = "Arclight Mod loaded." +patcher { + loading = "Loading plugin patchers ..." + loaded = "Loaded {} patchers" + load-error = "Error occurred while loading patcher" +} registry { forge-event = "Arclight events registered." begin = "Regitring for Bukkit ..." diff --git a/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf b/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf index 70c35bea..7e632d78 100644 --- a/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf +++ b/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf @@ -44,6 +44,11 @@ mixin-load { optimization = "服务端优化 Mixin 配置已加载" } mod-load = "Arclight Mod 已加载" +patcher { + loading = "正在加载 Plugin Patcher ..." + loaded = "加载了 {} 个 Patcher" + load-error = "加载 Patcher 时发生错误" +} registry { forge-event = "Arclight 事件系统已注册" begin = "正在向 Bukkit 注册 ..."