Skip to content

Commit

Permalink
workaround yet another paper-plugin breakage!
Browse files Browse the repository at this point in the history
  • Loading branch information
Jannyboy11 committed Jun 8, 2023
1 parent 6a18989 commit e489d98
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class ScalaPluginDescription {
private final LinkedHashSet<String> hardDependencies = new LinkedHashSet<>();
private final LinkedHashSet<String> softDependencies = new LinkedHashSet<>(); { addSoftDepend("ScalaLoader"); }
private final LinkedHashSet<String> inverseDependencies = new LinkedHashSet<>();
//TODO paperplugin-style dependencies?
private final LinkedHashSet<String> provides = new LinkedHashSet<>();
private final LinkedHashSet<String> mavenDependencies = new LinkedHashSet<>();
private PermissionDefault permissionDefault = null;
Expand Down Expand Up @@ -493,9 +494,9 @@ public void readFromPluginYamlData(Map<String, Object> pluginYaml) {
addContributor(contrib.toString());
website((String) pluginYaml.get("website"));
prefix((String) pluginYaml.get("prefix"));
String load = (String) pluginYaml.get("load");
if (load != null && this.loadOrder == null)
loadOrder(PluginLoadOrder.valueOf(load));
String pluginLoadOrder = (String) pluginYaml.get("load");
if (pluginLoadOrder != null && this.loadOrder == null)
loadOrder(PluginLoadOrder.valueOf(pluginLoadOrder));
String defaultPermissionDefault = (String) pluginYaml.get("default-permission");
if (defaultPermissionDefault != null && this.permissionDefault == null)
permissionDefault(PermissionDefault.getByName(defaultPermissionDefault));
Expand All @@ -514,13 +515,22 @@ public void readFromPluginYamlData(Map<String, Object> pluginYaml) {
for (String inverseDep : inverseDepend)
if (inverseDep != null)
addLoadBefore(inverseDep);
List<Map<String, Object>> paperDependencies = (List<Map<String, Object>>) pluginYaml.get("dependencies");
if (paperDependencies != null)
for (Map<String, Object> paperDependency : paperDependencies)
if (Boolean.parseBoolean(paperDependency.get("required").toString()))
addHardDepend(paperDependency.get("name").toString());
else
addSoftDepend(paperDependency.get("name").toString());

Object paperDependencies = pluginYaml.get("dependencies");
if (paperDependencies instanceof List) {
List<Map<String, Object>> paperDeps = (List) paperDependencies;
if (paperDependencies != null)
for (Map<String, Object> paperDependency : paperDeps)
if (Boolean.parseBoolean(paperDependency.get("required").toString()))
addHardDepend(paperDependency.get("name").toString());
else
addSoftDepend(paperDependency.get("name").toString());
} else if (paperDependencies instanceof Map) {
//TODO might want to track paper plugin dependencies separately in ScalaPluginDescription or ScalaPluginMeta
Map<String, Object> map = (Map) paperDependencies;
addPaperDependency(this, (Map<String, Map<String, Object>>) map.get("bootstrap"));
addPaperDependency(this, (Map<String, Map<String, Object>>) map.get("server"));
}
List<Map<String, Object>> paperLoadBefores = (List<Map<String, Object>>) pluginYaml.get("load-before");
if (paperLoadBefores != null)
for (Map<String, Object> paperLoadBefore : paperLoadBefores)
Expand All @@ -529,6 +539,7 @@ public void readFromPluginYamlData(Map<String, Object> pluginYaml) {
if (paperLoadAfters != null)
for (Map<String, Object> paperLoadAfter : paperLoadAfters)
addSoftDepend(paperLoadAfter.get("name").toString());

List<String> provides = (List<String>) pluginYaml.get("provides");
if (provides != null)
provides(provides.toArray(new String[0]));
Expand Down Expand Up @@ -561,6 +572,29 @@ public void readFromPluginYamlData(Map<String, Object> pluginYaml) {
}
}

private static void addPaperDependency(ScalaPluginDescription receiver, Map<String, Map<String, Object>> dependencies) {
for (Map.Entry<String, Map<String, Object>> entry : dependencies.entrySet()) {
String pluginName = entry.getKey();
Map<String, Object> dependencyConfig = entry.getValue();
String load = dependencyConfig.getOrDefault("load", "OMIT").toString();
boolean required = (Boolean) dependencyConfig.getOrDefault("required", true);
boolean joinClassPath = (Boolean) dependencyConfig.getOrDefault("join-classpath", true);
if (!required) {
if (joinClassPath) {
receiver.addSoftDepend(pluginName);
} else {
receiver.addLoadBefore(pluginName);
}
} else {
switch (load) {
case "BEFORE": receiver.addHardDepend(pluginName); break;
case "AFTER": receiver.addLoadBefore(pluginName); break;
case "OMIT": receiver.addSoftDepend(pluginName); break;
}
}
}
}

private static Permission makePermission(String name, Map<String, Object> properties) {
Permission perm = new Permission(name);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import com.google.common.graph.GraphBuilder;
import com.google.common.graph.MutableGraph;
import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
import io.papermc.paper.plugin.bootstrap.PluginProviderContext;
import org.bukkit.Server;
import org.bukkit.command.CommandMap;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerLoadEvent;
import org.bukkit.event.server.ServerLoadEvent.LoadType;
import org.bukkit.plugin.PluginLoadOrder;
import org.bukkit.plugin.UnknownDependencyException;
import org.bukkit.plugin.java.JavaPlugin;
import org.objectweb.asm.ClassReader;
import org.yaml.snakeyaml.Yaml;
Expand All @@ -29,6 +29,7 @@
import xyz.janboerman.scalaloader.dependency.PluginYamlLibraryLoader;
import xyz.janboerman.scalaloader.event.EventBus;
import xyz.janboerman.scalaloader.event.plugin.ScalaPluginEnableEvent;
import xyz.janboerman.scalaloader.paper.plugin.ScalaPluginBootstrapContext;
import xyz.janboerman.scalaloader.plugin.PluginScalaVersion;
import xyz.janboerman.scalaloader.plugin.ScalaCompatMap;
import xyz.janboerman.scalaloader.plugin.ScalaPluginDescription;
Expand Down Expand Up @@ -62,6 +63,7 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
Expand Down Expand Up @@ -295,14 +297,14 @@ private void loadScalaPlugins(File[] files) {
ScalaPluginDescription description = descriptions.get(file);
//TODO check dependencies. if not available, might want to try to load the ScalaPlugin again once Paper's own JavaPlugin loading process has finished.

ScalaPluginProviderContext context = new ScalaPluginProviderContext(file, description);
ScalaPluginProviderContext context = makeScalaPluginProviderContext(file, description); //used to be just new ScalaPluginProviderContext(file, description)
var optionalBootstrap = getBootstrap(description, descriptionPlugins.get(file).descriptionClassLoader());
if (optionalBootstrap.isEmpty()) continue;
PluginBootstrap bootstrapper = optionalBootstrap.get();
ScalaPluginLoader loader = new ScalaPluginLoader();
ScalaPluginClasspathBuilder pluginClasspathBuilder = new ScalaPluginClasspathBuilder(context);

bootstrapper.bootstrap(context);
bootstrap(bootstrapper, context); //used to be just boostrapper.bootstrap(context), but PluginBootstrap#bootstrap(PluginProviderContext) got changed to PluginBootstrap#bootstrap(BootstrapContext).
loader.classloader(pluginClasspathBuilder);

var optionalPlugin = buildPlugin(pluginName, file, context, scanResult, loader, bootstrapper, pluginClasspathBuilder);
Expand All @@ -317,6 +319,44 @@ private void loadScalaPlugins(File[] files) {

}

private static ScalaPluginProviderContext makeScalaPluginProviderContext(File file, ScalaPluginDescription description) {
try {
Class.forName("io.papermc.paper.plugin.bootstrap.BootstrapContext");
return new ScalaPluginBootstrapContext(file, description);
} catch (ClassNotFoundException e) {
return new ScalaPluginProviderContext(file, description);
}
}

private static void bootstrap(PluginBootstrap bootstrapper, ScalaPluginProviderContext context) {
Method bootstrap = null;
RuntimeException ex = new RuntimeException("could not bootstrap plugin using bootstrapper: " + bootstrapper + " and context " + context);

try {
Class<?> bootstrapContextClazz = Class.forName("io.papermc.paper.plugin.bootstrap.BootstrapContext");
bootstrap = PluginBootstrap.class.getMethod("bootstrap", bootstrapContextClazz);
} catch (ReflectiveOperationException e1) {
ex.addSuppressed(e1);

try {
bootstrap = PluginBootstrap.class.getMethod("bootstrap", PluginProviderContext.class);
} catch (ReflectiveOperationException e2) {
ex.addSuppressed(e2);
}
}

if (bootstrap != null) {
try {
bootstrap.invoke(bootstrapper, context);
return;
} catch (IllegalAccessException | InvocationTargetException e) {
ex.addSuppressed(e);
}
}

throw ex;
}

private void enableScalaPlugins(PluginLoadOrder loadOrder) {
for (ScalaPlugin plugin : getScalaPlugins()) {
if (!plugin.isEnabled() && plugin.getPluginMeta().getLoadOrder() == loadOrder) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package xyz.janboerman.scalaloader.paper.plugin;

import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
import io.papermc.paper.plugin.bootstrap.PluginProviderContext;
import org.jetbrains.annotations.NotNull;
Expand All @@ -14,7 +15,7 @@
*/
public class ScalaPluginBootstrap implements PluginBootstrap {

@Override
/*@Override*/
public void bootstrap(@NotNull PluginProviderContext context) {
//context provides access to:
// - configuration (ScalaPluginMeta)
Expand All @@ -27,6 +28,11 @@ public void bootstrap(@NotNull PluginProviderContext context) {
scalaPluginMeta.description.setScalaVersion(compatMap.getLatestVersion(scalaPluginMeta.getScalaVersion()).getVersionString());
}

@Override
public void bootstrap(@NotNull BootstrapContext context) {
bootstrap((PluginProviderContext) context);
}

@Override
public @NotNull ScalaPlugin createPlugin(@NotNull PluginProviderContext context) {
ScalaPluginProviderContext scalaContext = (ScalaPluginProviderContext) context;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package xyz.janboerman.scalaloader.paper.plugin;

import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import xyz.janboerman.scalaloader.plugin.ScalaPluginDescription;

import java.io.File;

public class ScalaPluginBootstrapContext extends ScalaPluginProviderContext implements BootstrapContext {
public ScalaPluginBootstrapContext(File pluginJarFile, ScalaPluginDescription description) {
super(pluginJarFile, description);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package xyz.janboerman.scalaloader.paper.plugin;

import io.papermc.paper.plugin.provider.configuration.PaperPluginMeta;
import io.papermc.paper.plugin.provider.configuration.type.DependencyConfiguration;
import io.papermc.paper.plugin.provider.configuration.type.DependencyConfiguration.LoadOrder;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.PluginLoadOrder;
Expand All @@ -19,6 +21,7 @@

public class ScalaPluginMeta extends PaperPluginMeta /*implements PluginMeta*/ {

//TODO separate paper plugin dependency configuration?
final ScalaPluginDescription description;

public ScalaPluginMeta(ScalaPluginDescription description) {
Expand Down Expand Up @@ -77,6 +80,36 @@ public ScalaPluginMeta(ScalaPluginDescription description) {
return Compat.listCopy(description.getProvides());
}

//TODO track new paper-style dependency configuration separately?
@Override
public Map<String, DependencyConfiguration> getServerDependencies() {
Map<String, DependencyConfiguration> res = new HashMap<>();

for (String pluginName : getPluginDependencies()) {
res.put(pluginName, new DependencyConfiguration(LoadOrder.BEFORE, true, true));
}
for (String pluginName : getPluginSoftDependencies()) {
res.put(pluginName, new DependencyConfiguration(LoadOrder.OMIT, false, true));
}
for (String pluginName : getLoadBeforePlugins()) {
res.put(pluginName, new DependencyConfiguration(LoadOrder.AFTER, true, true));
}

return res;
}

//TODO track new paper-style dependency configuration separately?
@Override
public Map<String, DependencyConfiguration> getBoostrapDependencies() {
Map<String, DependencyConfiguration> res = new HashMap<>();

for (String pluginName : getPluginDependencies()) {
res.put(pluginName, new DependencyConfiguration(LoadOrder.BEFORE, true, true));
}

return res;
}

@Override
public @NotNull List<String> getAuthors() {
return description.getAuthors();
Expand Down

0 comments on commit e489d98

Please sign in to comment.