Skip to content

Commit

Permalink
feat: conditionally relocate adventure across all platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
diogotcorreia committed Jun 25, 2024
1 parent 725a6e5 commit b82f1bb
Show file tree
Hide file tree
Showing 19 changed files with 325 additions and 129 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand All @@ -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
}
Expand Down
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ test {
}

dependencies {
compileOnly project(':core:triton-core-loader')
compileOnly project(":api")

// Adventure / MiniMessage
Expand Down
Original file line number Diff line number Diff line change
@@ -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<LoaderFlag> flags;
@Singular
private final List<Class<?>> constructorTypes;
@Singular
private final List<Object> constructorValues;

public LoaderBootstrap loadPlugin() {
List<Relocation> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -82,12 +81,11 @@ public <T> LoaderBootstrap instantiatePlugin(String bootstrapClass, Class<T> 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<? extends LoaderBootstrap> plugin;
try {
plugin = loadClass(bootstrapClass).asSubclass(LoaderBootstrap.class);
Expand All @@ -97,13 +95,13 @@ public LoaderBootstrap instantiatePlugin(String bootstrapClass, Class<?>[] loade

Constructor<? extends LoaderBootstrap> 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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.rexcantor64.triton.loader.utils;

public enum LoaderFlag {
RELOCATE_ADVENTURE,
}
136 changes: 100 additions & 36 deletions core/src/main/java/com/rexcantor64/triton/dependencies/Dependency.java
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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
Expand All @@ -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",
Expand All @@ -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<LoaderFlag> 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<Relocation> relocate(Set<LoaderFlag> 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<Relocation> relocate(Set<LoaderFlag> 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<Relocation> relocate(Set<LoaderFlag> loaderFlags) {
return Optional.of(relocation);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.rexcantor64.triton.dependencies;

public class Repository {
public final static String DIOGOTC_MIRROR = "https://repo.diogotc.com/mirror/";
}
16 changes: 16 additions & 0 deletions core/src/main/java/com/rexcantor64/triton/plugin/PluginLoader.java
Original file line number Diff line number Diff line change
@@ -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 {

Expand All @@ -12,4 +16,16 @@ public interface PluginLoader {

InputStream getResourceAsStream(String fileName);

LibraryManager getLibraryManager();

Set<LoaderFlag> getLoaderFlags();

default boolean hasLoaderFlag(LoaderFlag flag) {
return getLoaderFlags().contains(flag);
}

default void loadDependency(Dependency dependency) {
getLibraryManager().loadLibrary(dependency.getLibrary(getLoaderFlags()));
};

}
10 changes: 5 additions & 5 deletions triton-bungeecord/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}
2 changes: 1 addition & 1 deletion triton-bungeecord/loader/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}
Loading

0 comments on commit b82f1bb

Please sign in to comment.