From b82f1bbcf1f98e9b233e82754c0995375c2193ca Mon Sep 17 00:00:00 2001 From: Diogo Correia Date: Tue, 25 Jun 2024 18:03:50 +0100 Subject: [PATCH] feat: conditionally relocate adventure across all platforms --- build.gradle | 4 + core/build.gradle | 1 + .../triton/loader/utils/CommonLoader.java | 40 ++++++ .../loader/utils/JarInJarClassLoader.java | 12 +- .../triton/loader/utils/LoaderFlag.java | 5 + .../triton/dependencies/Dependency.java | 136 +++++++++++++----- .../triton/dependencies/Repository.java | 5 + .../triton/plugin/PluginLoader.java | 16 +++ triton-bungeecord/build.gradle | 10 +- triton-bungeecord/loader/build.gradle | 2 +- .../triton/loader/BungeeLoader.java | 24 ++-- .../packetinterceptor/BungeeListener.java | 4 +- .../bungeecord/plugin/BungeePlugin.java | 36 +++-- .../triton/loader/SpigotLoader.java | 33 ++--- .../triton/spigot/plugin/SpigotPlugin.java | 36 +++-- triton-velocity/build.gradle | 2 + .../triton/loader/VelocityLoader.java | 35 +++-- .../triton/velocity/VelocityTriton.java | 18 ++- .../velocity/plugin/VelocityPlugin.java | 35 ++++- 19 files changed, 325 insertions(+), 129 deletions(-) create mode 100644 core/loader/src/main/java/com/rexcantor64/triton/loader/utils/CommonLoader.java create mode 100644 core/loader/src/main/java/com/rexcantor64/triton/loader/utils/LoaderFlag.java create mode 100644 core/src/main/java/com/rexcantor64/triton/dependencies/Repository.java diff --git a/build.gradle b/build.gradle index 1ab23def..2be13653 100644 --- a/build.gradle +++ b/build.gradle @@ -59,6 +59,7 @@ subprojects { dependencies { implementation project(':api') implementation project(':core:triton-core-loader') + implementation project(':triton-bungeecord:triton-bungeecord-loader') implementation project(':triton-spigot:triton-spigot-loader') implementation project(':triton-velocity:triton-velocity-loader') @@ -74,6 +75,9 @@ shadowJar { from { project(':core').tasks.shadowJar.archiveFile } + from { + project(':triton-bungeecord').tasks.shadowJar.archiveFile + } from { project(':triton-spigot').tasks.shadowJar.archiveFile } diff --git a/core/build.gradle b/core/build.gradle index 1bef5e61..0c6ebdaa 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -10,6 +10,7 @@ test { } dependencies { + compileOnly project(':core:triton-core-loader') compileOnly project(":api") // Adventure / MiniMessage diff --git a/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/CommonLoader.java b/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/CommonLoader.java new file mode 100644 index 00000000..256aa752 --- /dev/null +++ b/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/CommonLoader.java @@ -0,0 +1,40 @@ +package com.rexcantor64.triton.loader.utils; + +import lombok.Builder; +import lombok.Singular; +import me.lucko.jarrelocator.Relocation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +@Builder +public class CommonLoader { + private static final String CORE_JAR_NAME = "triton-core.jarinjar"; + + private final String jarInJarName; + private final String bootstrapClassName; + @Singular + private final Set flags; + @Singular + private final List> constructorTypes; + @Singular + private final List constructorValues; + + public LoaderBootstrap loadPlugin() { + List relocations = new ArrayList<>(); + if (flags.contains(LoaderFlag.RELOCATE_ADVENTURE)) { + relocations.add(new Relocation("net/kyori/adventure", "com/rexcantor64/triton/lib/adventure")); + } + + @SuppressWarnings("resource") + JarInJarClassLoader loader = new JarInJarClassLoader(getClass().getClassLoader(), relocations, CORE_JAR_NAME, jarInJarName); + + Class[] constructorTypes = this.constructorTypes.toArray(new Class[this.constructorTypes.size() + 1]); + constructorTypes[constructorTypes.length - 1] = Set.class; + Object[] constructorValues = this.constructorValues.toArray(new Object[this.constructorValues.size() + 1]); + constructorValues[constructorValues.length - 1] = Collections.unmodifiableSet(this.flags); + return loader.instantiatePlugin(bootstrapClassName, constructorTypes, constructorValues); + } +} diff --git a/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/JarInJarClassLoader.java b/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/JarInJarClassLoader.java index d7fd4e67..f9b4aa0c 100644 --- a/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/JarInJarClassLoader.java +++ b/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/JarInJarClassLoader.java @@ -14,7 +14,6 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Arrays; -import java.util.LinkedList; import java.util.List; /** @@ -82,12 +81,11 @@ public LoaderBootstrap instantiatePlugin(String bootstrapClass, Class loa * Creates a new plugin instance. * * @param bootstrapClass the name of the bootstrap plugin class - * @param loaderPluginType the type of the loader plugin, the only parameter of the bootstrap - * plugin constructor - * @param loaderPlugin the loader plugin instance + * @param constructorTypes the types of the constructor of the bootstrap plugin class + * @param constructorArgs the values to pass to the constructor * @return the instantiated bootstrap plugin */ - public LoaderBootstrap instantiatePlugin(String bootstrapClass, Class[] loaderPluginType, Object[] loaderPlugin) throws LoadingException { + public LoaderBootstrap instantiatePlugin(String bootstrapClass, Class[] constructorTypes, Object[] constructorArgs) throws LoadingException { Class plugin; try { plugin = loadClass(bootstrapClass).asSubclass(LoaderBootstrap.class); @@ -97,13 +95,13 @@ public LoaderBootstrap instantiatePlugin(String bootstrapClass, Class[] loade Constructor constructor; try { - constructor = plugin.getConstructor(loaderPluginType); + constructor = plugin.getConstructor(constructorTypes); } catch (ReflectiveOperationException e) { throw new LoadingException("Unable to get bootstrap constructor", e); } try { - return constructor.newInstance(loaderPlugin); + return constructor.newInstance(constructorArgs); } catch (ReflectiveOperationException e) { throw new LoadingException("Unable to create bootstrap plugin instance", e); } diff --git a/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/LoaderFlag.java b/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/LoaderFlag.java new file mode 100644 index 00000000..45039cf0 --- /dev/null +++ b/core/loader/src/main/java/com/rexcantor64/triton/loader/utils/LoaderFlag.java @@ -0,0 +1,5 @@ +package com.rexcantor64.triton.loader.utils; + +public enum LoaderFlag { + RELOCATE_ADVENTURE, +} diff --git a/core/src/main/java/com/rexcantor64/triton/dependencies/Dependency.java b/core/src/main/java/com/rexcantor64/triton/dependencies/Dependency.java index 4f44cf9e..b7e315b5 100644 --- a/core/src/main/java/com/rexcantor64/triton/dependencies/Dependency.java +++ b/core/src/main/java/com/rexcantor64/triton/dependencies/Dependency.java @@ -1,10 +1,16 @@ package com.rexcantor64.triton.dependencies; +import com.rexcantor64.triton.loader.utils.LoaderFlag; +import lombok.Data; import lombok.Getter; import lombok.val; import net.byteflux.libby.Library; import net.byteflux.libby.relocation.Relocation; +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; + public enum Dependency { ADVENTURE( @@ -19,50 +25,50 @@ public enum Dependency { "adventure-text-serializer-gson", "4.15.0", "0t/P0pGWrqe0zNNySTUrWmEFbM7ijGXv9KmJ9zfuIDo=", - relocate("net{}kyori{}adventure", "adventure"), - //relocate("net{}kyori{}adventure{}text{}serializer{}gson", "adventure{}text{}serializer{}gson"), - //relocate("net{}kyori{}adventure{}text{}serializer{}json", "adventure{}text{}serializer{}json"), - relocate("net{}kyori{}option", "kyori{}option") + relocate("net{}kyori{}option", "kyori{}option"), + relocateIf("net{}kyori{}adventure", "adventure", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}gson", "adventure{}text{}serializer{}gson", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}json", "adventure{}text{}serializer{}json", LoaderFlag.RELOCATE_ADVENTURE) ), ADVENTURE_TEXT_SERIALIZER_LEGACY( "net{}kyori", "adventure-text-serializer-legacy", "4.15.0", "05buwHoYTm1E8/wJBJDZiCzMlinvDhmR51kIhceIDgs=", - relocate("net{}kyori{}adventure", "adventure") - //relocate("net{}kyori{}adventure{}text{}serializer{}legacy", "adventure{}text{}serializer{}legacy") + relocateIf("net{}kyori{}adventure", "adventure", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}legacy", "adventure{}text{}serializer{}legacy", LoaderFlag.RELOCATE_ADVENTURE) ), ADVENTURE_TEXT_SERIALIZER_PLAIN( "net{}kyori", "adventure-text-serializer-plain", "4.15.0", "T9uUMFA3ehElOSOfEOcy0tukCyoh8lKDlYooIypz+Ok=", - relocate("net{}kyori{}adventure", "adventure") - //relocate("net{}kyori{}adventure{}text{}serializer{}plain", "adventure{}text{}serializer{}plain") + relocateIf("net{}kyori{}adventure", "adventure", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}plain", "adventure{}text{}serializer{}plain", LoaderFlag.RELOCATE_ADVENTURE) ), ADVENTURE_TEXT_SERIALIZER_BUNGEECORD( "net{}kyori", "adventure-text-serializer-bungeecord", "4.3.2", "4bw3bG3HohAAFgFXNc5MzFNNKya/WrgqrHUcUDIFbDk=", - relocate("net{}kyori{}adventure", "adventure"), - //relocate("net{}kyori{}adventure{}text{}serializer{}bungeecord", "adventure{}text{}serializer{}bungeecord"), - //relocate("net{}kyori{}adventure{}text{}serializer{}gson", "adventure{}text{}serializer{}gson"), - //relocate("net{}kyori{}adventure{}text{}serializer{}json", "adventure{}text{}serializer{}json"), - relocate("net{}kyori{}option", "kyori{}option") - //relocate("net{}kyori{}adventure{}text{}serializer{}legacy", "adventure{}text{}serializer{}legacy") + relocate("net{}kyori{}option", "kyori{}option"), + relocateIf("net{}kyori{}adventure", "adventure", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}bungeecord", "adventure{}text{}serializer{}bungeecord", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}gson", "adventure{}text{}serializer{}gson", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}json", "adventure{}text{}serializer{}json", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}legacy", "adventure{}text{}serializer{}legacy", LoaderFlag.RELOCATE_ADVENTURE) ), ADVENTURE_MINI_MESSAGE( "net{}kyori", "adventure-text-minimessage", "4.15.0", "vsTSXxNV6TlBJFEobBkwnQa1qg3vXd6GBJnQDych2so=", - relocate("net{}kyori{}adventure", "adventure"), - //relocate("net{}kyori{}adventure{}text{}minimessage", "adventure{}text{}minimessage"), - //relocate("net{}kyori{}adventure{}text{}serializer{}gson", "adventure{}text{}serializer{}gson"), - //relocate("net{}kyori{}adventure{}text{}serializer{}json", "adventure{}text{}serializer{}json"), - relocate("net{}kyori{}option", "kyori{}option") - //relocate("net{}kyori{}adventure{}text{}serializer{}legacy", "adventure{}text{}serializer{}legacy") + relocate("net{}kyori{}option", "kyori{}option"), + relocateIf("net{}kyori{}adventure", "adventure", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}minimessage", "adventure{}text{}minimessage", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}gson", "adventure{}text{}serializer{}gson", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}json", "adventure{}text{}serializer{}json", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}legacy", "adventure{}text{}serializer{}legacy", LoaderFlag.RELOCATE_ADVENTURE) ), // Dependencies of Adventure @@ -78,9 +84,9 @@ public enum Dependency { "adventure-text-serializer-json", "4.15.0", "IjUGO0PYrqRiXPrCgKHlJ1NmDq0b4rk4Gz544ouMI6Y=", - relocate("net{}kyori{}adventure", "adventure"), - //relocate("net{}kyori{}adventure{}text{}serializer{}json", "adventure{}text{}serializer{}json"), - relocate("net{}kyori{}option", "kyori{}option") + relocate("net{}kyori{}option", "kyori{}option"), + relocateIf("net{}kyori{}adventure", "adventure", LoaderFlag.RELOCATE_ADVENTURE), + relocateIfNot("net{}kyori{}adventure{}text{}serializer{}json", "adventure{}text{}serializer{}json", LoaderFlag.RELOCATE_ADVENTURE) ), KYORI_EXAMINATION( "net{}kyori", @@ -97,22 +103,80 @@ public enum Dependency { ); @Getter - private final Library library; - - Dependency(String groupId, String artifactId, String version, String sha256Checksum, Relocation... relocations) { - val libraryBuilder = Library.builder() - .groupId(groupId) - .artifactId(artifactId) - .version(version) - .checksum(sha256Checksum); - for (Relocation relocation : relocations) { - libraryBuilder.relocate(relocation); - } - this.library = libraryBuilder.build(); + private final String groupId; + private final String artifactId; + private final String version; + private final String sha256Checksum; + private final OptionalRelocation[] relocations; + + Dependency(String groupId, String artifactId, String version, String sha256Checksum, OptionalRelocation... relocations) { + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + this.sha256Checksum = sha256Checksum; + this.relocations = relocations; + } + + public Library getLibrary(Set loaderFlags) { + val builder = Library.builder() + .groupId(this.groupId) + .artifactId(this.artifactId) + .version(this.version) + .checksum(this.sha256Checksum); + + Arrays.stream(relocations) + .map(relocation -> relocation.relocate(loaderFlags)) + .filter(Optional::isPresent) + .map(Optional::get) + .forEach(builder::relocate); + + return builder.build(); + } + + private static OptionalRelocation relocate(String relocateFrom, String relocateTo) { + return new SimpleRelocation(relocateInner(relocateFrom, relocateTo)); } - private static Relocation relocate(String relocateFrom, String relocateTo) { + private static OptionalRelocation relocateIf(String relocateFrom, String relocateTo, LoaderFlag flag) { + return new ConditionalRelocation(relocateFrom, relocateTo, flag, false); + } + + private static OptionalRelocation relocateIfNot(String relocateFrom, String relocateTo, LoaderFlag flag) { + return new ConditionalRelocation(relocateFrom, relocateTo, flag, true); + } + + private static Relocation relocateInner(String relocateFrom, String relocateTo) { return new Relocation(relocateFrom, "com{}rexcantor64{}triton{}lib{}" + relocateTo); } + private interface OptionalRelocation { + Optional relocate(Set loaderFlags); + } + + @Data + private static class ConditionalRelocation implements OptionalRelocation { + private final String relocateFrom; + private final String relocateTo; + private final LoaderFlag flag; + private final boolean negate; + + @Override + public Optional relocate(Set loaderFlags) { + if (loaderFlags.contains(flag) != negate) { + return Optional.of(Dependency.relocateInner(relocateFrom, relocateTo)); + } + return Optional.empty(); + } + } + + @Data + private static class SimpleRelocation implements OptionalRelocation { + private final Relocation relocation; + + @Override + public Optional relocate(Set loaderFlags) { + return Optional.of(relocation); + } + } + } diff --git a/core/src/main/java/com/rexcantor64/triton/dependencies/Repository.java b/core/src/main/java/com/rexcantor64/triton/dependencies/Repository.java new file mode 100644 index 00000000..f3cec78d --- /dev/null +++ b/core/src/main/java/com/rexcantor64/triton/dependencies/Repository.java @@ -0,0 +1,5 @@ +package com.rexcantor64.triton.dependencies; + +public class Repository { + public final static String DIOGOTC_MIRROR = "https://repo.diogotc.com/mirror/"; +} diff --git a/core/src/main/java/com/rexcantor64/triton/plugin/PluginLoader.java b/core/src/main/java/com/rexcantor64/triton/plugin/PluginLoader.java index d8d02a4e..92219a4b 100644 --- a/core/src/main/java/com/rexcantor64/triton/plugin/PluginLoader.java +++ b/core/src/main/java/com/rexcantor64/triton/plugin/PluginLoader.java @@ -1,8 +1,12 @@ package com.rexcantor64.triton.plugin; +import com.rexcantor64.triton.dependencies.Dependency; +import com.rexcantor64.triton.loader.utils.LoaderFlag; import com.rexcantor64.triton.logger.TritonLogger; +import net.byteflux.libby.LibraryManager; import java.io.InputStream; +import java.util.Set; public interface PluginLoader { @@ -12,4 +16,16 @@ public interface PluginLoader { InputStream getResourceAsStream(String fileName); + LibraryManager getLibraryManager(); + + Set getLoaderFlags(); + + default boolean hasLoaderFlag(LoaderFlag flag) { + return getLoaderFlags().contains(flag); + } + + default void loadDependency(Dependency dependency) { + getLibraryManager().loadLibrary(dependency.getLibrary(getLoaderFlags())); + }; + } diff --git a/triton-bungeecord/build.gradle b/triton-bungeecord/build.gradle index 5ed69333..13fcb51f 100644 --- a/triton-bungeecord/build.gradle +++ b/triton-bungeecord/build.gradle @@ -25,11 +25,11 @@ shadowJar { relocate 'org.bstats', 'com.rexcantor64.triton.metrics' - relocate 'net.kyori.adventure.text.minimessage', 'com.rexcantor64.triton.lib.adventure.minimessage' - relocate 'net.kyori.adventure.text.serializer.gson', 'com.rexcantor64.triton.lib.adventure.serializer.gson' - relocate 'net.kyori.adventure.text.serializer.legacy', 'com.rexcantor64.triton.lib.adventure.serializer.legacy' - relocate 'net.kyori.adventure.text.serializer.plain', 'com.rexcantor64.triton.lib.adventure.serializer.plain' - relocate 'net.kyori.adventure.text.serializer.bungeecord', 'com.rexcantor64.triton.lib.adventure.serializer.bungeecord' + relocate 'net.kyori.adventure.text.minimessage', 'com.rexcantor64.triton.lib.adventure.text.minimessage' + relocate 'net.kyori.adventure.text.serializer.gson', 'com.rexcantor64.triton.lib.adventure.text.serializer.gson' + relocate 'net.kyori.adventure.text.serializer.legacy', 'com.rexcantor64.triton.lib.adventure.text.serializer.legacy' + relocate 'net.kyori.adventure.text.serializer.plain', 'com.rexcantor64.triton.lib.adventure.text.serializer.plain' + relocate 'net.kyori.adventure.text.serializer.bungeecord', 'com.rexcantor64.triton.lib.adventure.text.serializer.bungeecord' relocate 'net.byteflux.libby', 'com.rexcantor64.triton.lib.libby' } \ No newline at end of file diff --git a/triton-bungeecord/loader/build.gradle b/triton-bungeecord/loader/build.gradle index 638f1e45..eb15043c 100644 --- a/triton-bungeecord/loader/build.gradle +++ b/triton-bungeecord/loader/build.gradle @@ -20,5 +20,5 @@ bungee { version = project.version description = pluginDescription author = pluginAuthor - main = 'com.rexcantor64.triton.bungeecord.plugin.BungeePlugin' + main = 'com.rexcantor64.triton.loader.BungeeLoader' } \ No newline at end of file diff --git a/triton-bungeecord/loader/src/main/java/com/rexcantor64/triton/loader/BungeeLoader.java b/triton-bungeecord/loader/src/main/java/com/rexcantor64/triton/loader/BungeeLoader.java index 767e40e1..5af25429 100644 --- a/triton-bungeecord/loader/src/main/java/com/rexcantor64/triton/loader/BungeeLoader.java +++ b/triton-bungeecord/loader/src/main/java/com/rexcantor64/triton/loader/BungeeLoader.java @@ -1,25 +1,25 @@ package com.rexcantor64.triton.loader; -import com.rexcantor64.triton.loader.utils.JarInJarClassLoader; +import com.rexcantor64.triton.loader.utils.CommonLoader; import com.rexcantor64.triton.loader.utils.LoaderBootstrap; -import me.lucko.jarrelocator.Relocation; +import com.rexcantor64.triton.loader.utils.LoaderFlag; import net.md_5.bungee.api.plugin.Plugin; -import java.util.ArrayList; -import java.util.List; - public class BungeeLoader extends Plugin { - private static final String CORE_JAR_NAME = "triton-core.jarinjar"; - private static final String SPIGOT_JAR_NAME = "triton-bungeecord.jarinjar"; + private static final String PLATFORM_JAR_NAME = "triton-bungeecord.jarinjar"; private static final String BOOTSTRAP_CLASS = "com.rexcantor64.triton.bungeecord.plugin.BungeePlugin"; private final LoaderBootstrap plugin; public BungeeLoader() { - List relocations = new ArrayList<>(); - relocations.add(new Relocation("net/kyori/adventure", "com/rexcantor64/triton/lib/adventure")); - JarInJarClassLoader loader = new JarInJarClassLoader(getClass().getClassLoader(), relocations, CORE_JAR_NAME, SPIGOT_JAR_NAME); - this.plugin = loader.instantiatePlugin(BOOTSTRAP_CLASS, Plugin.class, this); + this.plugin = CommonLoader.builder() + .jarInJarName(PLATFORM_JAR_NAME) + .bootstrapClassName(BOOTSTRAP_CLASS) + .constructorType(Plugin.class) + .constructorValue(this) + .flag(LoaderFlag.RELOCATE_ADVENTURE) + .build() + .loadPlugin(); } @Override @@ -31,4 +31,4 @@ public void onEnable() { public void onDisable() { this.plugin.onDisable(); } -} \ No newline at end of file +} diff --git a/triton-bungeecord/src/main/java/com/rexcantor64/triton/bungeecord/packetinterceptor/BungeeListener.java b/triton-bungeecord/src/main/java/com/rexcantor64/triton/bungeecord/packetinterceptor/BungeeListener.java index a60d7372..673f2a61 100644 --- a/triton-bungeecord/src/main/java/com/rexcantor64/triton/bungeecord/packetinterceptor/BungeeListener.java +++ b/triton-bungeecord/src/main/java/com/rexcantor64/triton/bungeecord/packetinterceptor/BungeeListener.java @@ -1,10 +1,10 @@ package com.rexcantor64.triton.bungeecord.packetinterceptor; import com.rexcantor64.triton.Triton; -import com.rexcantor64.triton.api.language.MessageParser; import com.rexcantor64.triton.bungeecord.player.BungeeLanguagePlayer; import com.rexcantor64.triton.bungeecord.utils.BaseComponentUtils; import com.rexcantor64.triton.config.MainConfig; +import com.rexcantor64.triton.language.parser.AdventureParser; import com.rexcantor64.triton.utils.ComponentUtils; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageEncoder; @@ -48,7 +48,7 @@ public BungeeListener(BungeeLanguagePlayer owner, int protocolVersion) { owner.setListener(this); } - private MessageParser parser() { + private AdventureParser parser() { return Triton.get().getMessageParser(); } diff --git a/triton-bungeecord/src/main/java/com/rexcantor64/triton/bungeecord/plugin/BungeePlugin.java b/triton-bungeecord/src/main/java/com/rexcantor64/triton/bungeecord/plugin/BungeePlugin.java index 9fac75c9..ec999e83 100644 --- a/triton-bungeecord/src/main/java/com/rexcantor64/triton/bungeecord/plugin/BungeePlugin.java +++ b/triton-bungeecord/src/main/java/com/rexcantor64/triton/bungeecord/plugin/BungeePlugin.java @@ -4,7 +4,9 @@ import com.rexcantor64.triton.bungeecord.BungeeTriton; import com.rexcantor64.triton.bungeecord.terminal.BungeeTerminalManager; import com.rexcantor64.triton.dependencies.Dependency; +import com.rexcantor64.triton.dependencies.Repository; import com.rexcantor64.triton.loader.utils.LoaderBootstrap; +import com.rexcantor64.triton.loader.utils.LoaderFlag; import com.rexcantor64.triton.logger.JavaLogger; import com.rexcantor64.triton.logger.TritonLogger; import com.rexcantor64.triton.plugin.Platform; @@ -13,9 +15,11 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import net.byteflux.libby.BungeeLibraryManager; +import net.byteflux.libby.LibraryManager; import net.md_5.bungee.api.plugin.Plugin; import java.io.InputStream; +import java.util.Set; import java.util.logging.Level; @RequiredArgsConstructor @@ -23,21 +27,29 @@ public class BungeePlugin implements PluginLoader, LoaderBootstrap { private TritonLogger logger; @Getter private final Plugin plugin; + @Getter + private final Set loaderFlags; + @Getter + private LibraryManager libraryManager; @Override public void onEnable() { this.logger = new JavaLogger(this.getPlugin().getLogger()); - BungeeLibraryManager libraryManager = new BungeeLibraryManager(this.getPlugin()); - libraryManager.addRepository("https://repo.diogotc.com/mirror/"); - libraryManager.loadLibrary(Dependency.ADVENTURE.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_GSON.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_LEGACY.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_PLAIN.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_BUNGEECORD.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_KEY.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_JSON.getLibrary()); - libraryManager.loadLibrary(Dependency.KYORI_EXAMINATION.getLibrary()); - libraryManager.loadLibrary(Dependency.KYORI_OPTION.getLibrary()); + this.libraryManager = new BungeeLibraryManager(this.getPlugin()); + libraryManager.addRepository(Repository.DIOGOTC_MIRROR); + + if (hasLoaderFlag(LoaderFlag.RELOCATE_ADVENTURE)) { + loadDependency(Dependency.ADVENTURE); + loadDependency(Dependency.ADVENTURE_KEY); + loadDependency(Dependency.KYORI_EXAMINATION); + } + loadDependency(Dependency.KYORI_OPTION); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_GSON); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_LEGACY); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_PLAIN); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_BUNGEECORD); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_JSON); + loadDependency(Dependency.ADVENTURE_MINI_MESSAGE); new BungeeTriton(this).onEnable(); } @@ -77,7 +89,7 @@ public TritonLogger getTritonLogger() { @Override public InputStream getResourceAsStream(String fileName) { - return this.getPlugin().getResourceAsStream(fileName); + return getClass().getClassLoader().getResourceAsStream(fileName); } } diff --git a/triton-spigot/loader/src/main/java/com/rexcantor64/triton/loader/SpigotLoader.java b/triton-spigot/loader/src/main/java/com/rexcantor64/triton/loader/SpigotLoader.java index 950cd23b..495a0a7c 100644 --- a/triton-spigot/loader/src/main/java/com/rexcantor64/triton/loader/SpigotLoader.java +++ b/triton-spigot/loader/src/main/java/com/rexcantor64/triton/loader/SpigotLoader.java @@ -1,32 +1,29 @@ package com.rexcantor64.triton.loader; -import com.rexcantor64.triton.loader.utils.JarInJarClassLoader; +import com.rexcantor64.triton.loader.utils.CommonLoader; import com.rexcantor64.triton.loader.utils.LoaderBootstrap; -import me.lucko.jarrelocator.Relocation; +import com.rexcantor64.triton.loader.utils.LoaderFlag; +import lombok.val; import org.bukkit.plugin.java.JavaPlugin; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; - public class SpigotLoader extends JavaPlugin { - private static final String CORE_JAR_NAME = "triton-core.jarinjar"; - private static final String SPIGOT_JAR_NAME = "triton-spigot.jarinjar"; + private static final String PLATFORM_JAR_NAME = "triton-spigot.jarinjar"; private static final String BOOTSTRAP_CLASS = "com.rexcantor64.triton.spigot.plugin.SpigotPlugin"; private final LoaderBootstrap plugin; public SpigotLoader() { - boolean relocateAdventure = shouldRelocateAdventure(); - List relocations = new ArrayList<>(); - if (relocateAdventure) { - getLogger().log(Level.INFO, "Adventure not found or is outdated: relocating it inside Triton"); - relocations.add(new Relocation("net/kyori/adventure", "com/rexcantor64/triton/lib/adventure")); - } else { - getLogger().log(Level.INFO, "Found up-to-date version of Adventure! Using server's Adventure library"); + val builder = CommonLoader.builder() + .jarInJarName(PLATFORM_JAR_NAME) + .bootstrapClassName(BOOTSTRAP_CLASS) + .constructorType(JavaPlugin.class) + .constructorValue(this); + + if (shouldRelocateAdventure()) { + builder.flag(LoaderFlag.RELOCATE_ADVENTURE); } - JarInJarClassLoader loader = new JarInJarClassLoader(getClass().getClassLoader(), relocations, CORE_JAR_NAME, SPIGOT_JAR_NAME); - this.plugin = loader.instantiatePlugin(BOOTSTRAP_CLASS, JavaPlugin.class, this); + + this.plugin = builder.build().loadPlugin(); } private boolean shouldRelocateAdventure() { @@ -34,7 +31,7 @@ private boolean shouldRelocateAdventure() { try { // Class only available on adventure 4.15.0+ - Class.forName("net/kyori/adventure/resource/ResourcePackCallback"); + Class.forName("net.kyori.adventure.resource.ResourcePackCallback"); // A modern version of adventure is already present return false; diff --git a/triton-spigot/src/main/java/com/rexcantor64/triton/spigot/plugin/SpigotPlugin.java b/triton-spigot/src/main/java/com/rexcantor64/triton/spigot/plugin/SpigotPlugin.java index 34995662..64e2f2f6 100644 --- a/triton-spigot/src/main/java/com/rexcantor64/triton/spigot/plugin/SpigotPlugin.java +++ b/triton-spigot/src/main/java/com/rexcantor64/triton/spigot/plugin/SpigotPlugin.java @@ -2,7 +2,9 @@ import com.rexcantor64.triton.Triton; import com.rexcantor64.triton.dependencies.Dependency; +import com.rexcantor64.triton.dependencies.Repository; import com.rexcantor64.triton.loader.utils.LoaderBootstrap; +import com.rexcantor64.triton.loader.utils.LoaderFlag; import com.rexcantor64.triton.logger.JavaLogger; import com.rexcantor64.triton.logger.TritonLogger; import com.rexcantor64.triton.plugin.Platform; @@ -12,31 +14,41 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import net.byteflux.libby.BukkitLibraryManager; +import net.byteflux.libby.LibraryManager; import org.bukkit.plugin.java.JavaPlugin; import java.io.InputStream; +import java.util.Set; @RequiredArgsConstructor public class SpigotPlugin implements PluginLoader, LoaderBootstrap { private TritonLogger logger; @Getter private final JavaPlugin plugin; + @Getter + private final Set loaderFlags; + @Getter + private LibraryManager libraryManager; @Override public void onEnable() { this.logger = new JavaLogger(this.plugin.getLogger()); - BukkitLibraryManager libraryManager = new BukkitLibraryManager(this.plugin); - libraryManager.addRepository("https://repo.diogotc.com/mirror/"); - libraryManager.loadLibrary(Dependency.ADVENTURE.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_GSON.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_LEGACY.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_PLAIN.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_BUNGEECORD.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_KEY.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_TEXT_SERIALIZER_JSON.getLibrary()); - libraryManager.loadLibrary(Dependency.ADVENTURE_MINI_MESSAGE.getLibrary()); - libraryManager.loadLibrary(Dependency.KYORI_EXAMINATION.getLibrary()); - libraryManager.loadLibrary(Dependency.KYORI_OPTION.getLibrary()); + + this.libraryManager = new BukkitLibraryManager(this.plugin); + libraryManager.addRepository(Repository.DIOGOTC_MIRROR); + + if (hasLoaderFlag(LoaderFlag.RELOCATE_ADVENTURE)) { + loadDependency(Dependency.ADVENTURE); + loadDependency(Dependency.ADVENTURE_KEY); + loadDependency(Dependency.KYORI_EXAMINATION); + } + loadDependency(Dependency.KYORI_OPTION); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_GSON); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_LEGACY); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_PLAIN); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_BUNGEECORD); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_JSON); + loadDependency(Dependency.ADVENTURE_MINI_MESSAGE); new SpigotTriton(this).onEnable(); } diff --git a/triton-velocity/build.gradle b/triton-velocity/build.gradle index 43d55448..e75372e4 100644 --- a/triton-velocity/build.gradle +++ b/triton-velocity/build.gradle @@ -19,6 +19,8 @@ dependencies { // FIXME in the future change this to dynamic download and loading implementation 'mysql:mysql-connector-java:8.0.30' + implementation 'net.byteflux:libby-velocity:1.3.0' + implementation 'org.bstats:bstats-velocity:3.0.0' } diff --git a/triton-velocity/loader/src/main/java/com/rexcantor64/triton/loader/VelocityLoader.java b/triton-velocity/loader/src/main/java/com/rexcantor64/triton/loader/VelocityLoader.java index def29568..336a4a1a 100644 --- a/triton-velocity/loader/src/main/java/com/rexcantor64/triton/loader/VelocityLoader.java +++ b/triton-velocity/loader/src/main/java/com/rexcantor64/triton/loader/VelocityLoader.java @@ -1,7 +1,7 @@ package com.rexcantor64.triton.loader; import com.google.inject.Inject; -import com.rexcantor64.triton.loader.utils.JarInJarClassLoader; +import com.rexcantor64.triton.loader.utils.CommonLoader; import com.rexcantor64.triton.loader.utils.LoaderBootstrap; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; @@ -11,25 +11,36 @@ import org.slf4j.Logger; import java.nio.file.Path; -import java.util.Collections; -@Plugin(id = "triton", name = "Triton", url = "https://triton.rexcantor64.com", description = - "A plugin that replaces any message on your server, to the receiver's language, in real time!", +@Plugin( + id = "triton", + name = "Triton", + url = "https://triton.rexcantor64.com", + description = "A plugin that replaces any message on your server, to the receiver's language, in real time!", version = "@version@", - authors = {"Rexcantor64"}) + authors = {"Rexcantor64"} +) public class VelocityLoader { - private static final String CORE_JAR_NAME = "triton-core.jarinjar"; - private static final String VELOCITY_JAR_NAME = "triton-velocity.jarinjar"; - private static final String BOOTSTRAP_CLASS = "com.rexcantor64.triton.spigot.plugin.SpigotPlugin"; + private static final String PLATFORM_JAR_NAME = "triton-velocity.jarinjar"; + private static final String BOOTSTRAP_CLASS = "com.rexcantor64.triton.velocity.plugin.VelocityPlugin"; private final LoaderBootstrap plugin; @Inject public VelocityLoader(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { - JarInJarClassLoader loader = new JarInJarClassLoader(getClass().getClassLoader(), Collections.emptyList(), CORE_JAR_NAME, VELOCITY_JAR_NAME); - this.plugin = loader.instantiatePlugin(BOOTSTRAP_CLASS, - new Class[]{ProxyServer.class, Logger.class, Path.class}, - new Object[]{server, logger, dataDirectory}); + this.plugin = CommonLoader.builder() + .jarInJarName(PLATFORM_JAR_NAME) + .bootstrapClassName(BOOTSTRAP_CLASS) + .constructorType(Object.class) + .constructorType(ProxyServer.class) + .constructorType(Logger.class) + .constructorType(Path.class) + .constructorValue(this) + .constructorValue(server) + .constructorValue(logger) + .constructorValue(dataDirectory) + .build() + .loadPlugin(); } @Subscribe diff --git a/triton-velocity/src/main/java/com/rexcantor64/triton/velocity/VelocityTriton.java b/triton-velocity/src/main/java/com/rexcantor64/triton/velocity/VelocityTriton.java index 44428dce..3eab9fe6 100644 --- a/triton-velocity/src/main/java/com/rexcantor64/triton/velocity/VelocityTriton.java +++ b/triton-velocity/src/main/java/com/rexcantor64/triton/velocity/VelocityTriton.java @@ -41,22 +41,26 @@ public VelocityPlugin getLoader() { return (VelocityPlugin) this.loader; } + public Object getPlugin() { + return getLoader().getPlugin(); + } + @Override public void onEnable() { instance = this; super.onEnable(); // bStats - Metrics metrics = getLoader().getMetricsFactory().make(getLoader(), 16222); + Metrics metrics = getLoader().getMetricsFactory().make(getPlugin(), 16222); metrics.addCustomChart(new SingleLineChart("active_placeholders", () -> this.getTranslationManager().getTranslationCount())); - val eventManager = getLoader().getServer().getEventManager(); - eventManager.register(getLoader(), new VelocityListener()); - eventManager.register(getLoader(), bridgeManager); + val eventManager = getVelocity().getEventManager(); + eventManager.register(getPlugin(), new VelocityListener()); + eventManager.register(getPlugin(), bridgeManager); this.bridgeChannelIdentifier = MinecraftChannelIdentifier.create("triton", "main"); - getLoader().getServer().getChannelRegistrar().register(this.bridgeChannelIdentifier); + getVelocity().getChannelRegistrar().register(this.bridgeChannelIdentifier); if (getStorage() instanceof LocalStorage) bridgeManager.sendConfigToEveryone(); @@ -80,7 +84,7 @@ public void reload() { protected void startConfigRefreshTask() { if (configRefreshTask != null) configRefreshTask.cancel(); if (getConfig().getConfigAutoRefresh() <= 0) return; - configRefreshTask = getLoader().getServer().getScheduler().buildTask(getLoader(), this::reload) + configRefreshTask = getVelocity().getScheduler().buildTask(getPlugin(), this::reload) .delay(getConfig().getConfigAutoRefresh(), TimeUnit.SECONDS).schedule(); } @@ -96,7 +100,7 @@ public String getVersion() { @Override public void runAsync(Runnable runnable) { - getLoader().getServer().getScheduler().buildTask(getLoader(), runnable).schedule(); + getVelocity().getScheduler().buildTask(getPlugin(), runnable).schedule(); } public ProxyServer getVelocity() { diff --git a/triton-velocity/src/main/java/com/rexcantor64/triton/velocity/plugin/VelocityPlugin.java b/triton-velocity/src/main/java/com/rexcantor64/triton/velocity/plugin/VelocityPlugin.java index 52a41a2f..6ef9d99e 100644 --- a/triton-velocity/src/main/java/com/rexcantor64/triton/velocity/plugin/VelocityPlugin.java +++ b/triton-velocity/src/main/java/com/rexcantor64/triton/velocity/plugin/VelocityPlugin.java @@ -1,18 +1,19 @@ package com.rexcantor64.triton.velocity.plugin; -import com.google.inject.Inject; +import com.rexcantor64.triton.dependencies.Dependency; +import com.rexcantor64.triton.dependencies.Repository; import com.rexcantor64.triton.loader.utils.LoaderBootstrap; +import com.rexcantor64.triton.loader.utils.LoaderFlag; import com.rexcantor64.triton.logger.SLF4JLogger; import com.rexcantor64.triton.logger.TritonLogger; import com.rexcantor64.triton.plugin.Platform; import com.rexcantor64.triton.plugin.PluginLoader; import com.rexcantor64.triton.velocity.VelocityTriton; -import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; -import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.proxy.ProxyServer; import lombok.Getter; +import net.byteflux.libby.LibraryManager; +import net.byteflux.libby.VelocityLibraryManager; import org.bstats.velocity.Metrics; import org.slf4j.Logger; @@ -20,18 +21,28 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.nio.file.Path; +import java.util.Set; @Getter public class VelocityPlugin implements PluginLoader, LoaderBootstrap { + @Getter + private final Object plugin; private final ProxyServer server; private final TritonLogger tritonLogger; private final Path dataDirectory; private final Metrics.Factory metricsFactory; + @Getter + private final Set loaderFlags; + @Getter + private final LibraryManager libraryManager; - public VelocityPlugin(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { + public VelocityPlugin(Object loader, ProxyServer server, Logger logger, @DataDirectory Path dataDirectory, Set loaderFlags) { + this.plugin = loader; this.server = server; this.tritonLogger = new SLF4JLogger(logger); this.dataDirectory = dataDirectory; + this.loaderFlags = loaderFlags; + this.libraryManager = new VelocityLibraryManager<>(logger, dataDirectory, server.getPluginManager(), loader); try { // Because the loader module does not depend on bStats, we have to do this instead @@ -46,6 +57,20 @@ public VelocityPlugin(ProxyServer server, Logger logger, @DataDirectory Path dat @Override public void onEnable() { + libraryManager.addRepository(Repository.DIOGOTC_MIRROR); + + if (hasLoaderFlag(LoaderFlag.RELOCATE_ADVENTURE)) { + loadDependency(Dependency.ADVENTURE); + loadDependency(Dependency.ADVENTURE_KEY); + loadDependency(Dependency.KYORI_EXAMINATION); + } + loadDependency(Dependency.KYORI_OPTION); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_GSON); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_LEGACY); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_PLAIN); + loadDependency(Dependency.ADVENTURE_TEXT_SERIALIZER_JSON); + loadDependency(Dependency.ADVENTURE_MINI_MESSAGE); + new VelocityTriton(this).onEnable(); }