Add initial multi plugin management
This commit is contained in:
parent
df55162d73
commit
94e4693b5e
54 changed files with 1988 additions and 937 deletions
|
|
@ -21,16 +21,15 @@ public class VelocityCommandServerUtils
|
|||
extends CommandServerUtils<VelocityPlugin, PluginContainer, VelocityCommandSender> {
|
||||
|
||||
public VelocityCommandServerUtils(VelocityPlugin plugin) {
|
||||
super(plugin);
|
||||
super(plugin, PluginContainer[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FormatBuilder createPluginInfo(
|
||||
FormatBuilder builder,
|
||||
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
|
||||
String pluginName
|
||||
PluginContainer container
|
||||
) {
|
||||
PluginContainer container = plugin.getPluginManager().getPlugin(pluginName);
|
||||
PluginDescription desc = container.getDescription();
|
||||
|
||||
return builder
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
package net.frankheijden.serverutils.velocity.entities;
|
||||
|
||||
import com.velocitypowered.api.plugin.PluginContainer;
|
||||
import net.frankheijden.serverutils.common.entities.LoadResult;
|
||||
import net.frankheijden.serverutils.common.entities.Result;
|
||||
|
||||
public class VelocityLoadResult extends LoadResult<PluginContainer> {
|
||||
|
||||
public VelocityLoadResult(PluginContainer obj, Result result) {
|
||||
super(obj, result);
|
||||
}
|
||||
|
||||
public VelocityLoadResult(PluginContainer obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
public VelocityLoadResult(Result result) {
|
||||
super(result);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,12 +15,7 @@ import net.frankheijden.serverutils.velocity.listeners.VelocityPlayerListener;
|
|||
import net.frankheijden.serverutils.velocity.managers.VelocityPluginManager;
|
||||
import net.frankheijden.serverutils.velocity.managers.VelocityTaskManager;
|
||||
|
||||
public class VelocityPlugin extends ServerUtilsPlugin<
|
||||
PluginContainer,
|
||||
ScheduledTask,
|
||||
VelocityCommandSender,
|
||||
CommandSource
|
||||
> {
|
||||
public class VelocityPlugin extends ServerUtilsPlugin<PluginContainer, ScheduledTask, VelocityCommandSender, CommandSource, VelocityPluginDescription> {
|
||||
|
||||
private final ServerUtils plugin;
|
||||
private final VelocityPluginManager pluginManager;
|
||||
|
|
@ -46,13 +41,15 @@ public class VelocityPlugin extends ServerUtilsPlugin<
|
|||
|
||||
@Override
|
||||
protected VelocityCommandManager<VelocityCommandSender> newCommandManager() {
|
||||
return new VelocityCommandManager<>(
|
||||
VelocityCommandManager<VelocityCommandSender> commandManager = new VelocityCommandManager<>(
|
||||
plugin.getPluginContainer(),
|
||||
plugin.getProxy(),
|
||||
AsynchronousCommandExecutionCoordinator.<VelocityCommandSender>newBuilder().build(),
|
||||
chatProvider::get,
|
||||
VelocityCommandSender::getSource
|
||||
);
|
||||
handleBrigadier(commandManager.brigadierManager());
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
package net.frankheijden.serverutils.velocity.entities;
|
||||
|
||||
import com.velocitypowered.api.plugin.PluginDescription;
|
||||
import com.velocitypowered.api.plugin.meta.PluginDependency;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import net.frankheijden.serverutils.common.entities.ServerUtilsPluginDescription;
|
||||
import net.frankheijden.serverutils.common.entities.exceptions.InvalidPluginDescriptionException;
|
||||
|
||||
public class VelocityPluginDescription implements ServerUtilsPluginDescription {
|
||||
|
||||
private final PluginDescription description;
|
||||
private final File file;
|
||||
private final String author;
|
||||
private final Set<String> dependencies;
|
||||
|
||||
/**
|
||||
* Constructs a new BungeePluginDescription.
|
||||
*/
|
||||
public VelocityPluginDescription(PluginDescription description) {
|
||||
this.description = description;
|
||||
|
||||
Optional<Path> sourceOptional = description.getSource();
|
||||
if (!sourceOptional.isPresent()) throw new InvalidPluginDescriptionException("Source path is null");
|
||||
|
||||
this.file = sourceOptional.get().toFile();
|
||||
this.author = String.join(", ", description.getAuthors());
|
||||
this.dependencies = description.getDependencies().stream()
|
||||
.map(PluginDependency::getId)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.description.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.description.getName().orElse("<UNKNOWN>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return this.description.getVersion().orElse("<UNKNOWN>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return this.author;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFile() {
|
||||
return this.file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDependencies() {
|
||||
return this.dependencies;
|
||||
}
|
||||
|
||||
public PluginDescription getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,11 +26,13 @@ import java.util.List;
|
|||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import net.frankheijden.serverutils.common.entities.CloseableResult;
|
||||
import net.frankheijden.serverutils.common.entities.Result;
|
||||
import net.frankheijden.serverutils.common.entities.exceptions.InvalidPluginDescriptionException;
|
||||
import net.frankheijden.serverutils.common.entities.results.CloseablePluginResults;
|
||||
import net.frankheijden.serverutils.common.entities.results.PluginResults;
|
||||
import net.frankheijden.serverutils.common.entities.results.Result;
|
||||
import net.frankheijden.serverutils.common.events.PluginEvent;
|
||||
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
|
||||
import net.frankheijden.serverutils.velocity.entities.VelocityLoadResult;
|
||||
import net.frankheijden.serverutils.velocity.entities.VelocityPluginDescription;
|
||||
import net.frankheijden.serverutils.velocity.events.VelocityPluginDisableEvent;
|
||||
import net.frankheijden.serverutils.velocity.events.VelocityPluginEnableEvent;
|
||||
import net.frankheijden.serverutils.velocity.events.VelocityPluginLoadEvent;
|
||||
|
|
@ -44,7 +46,7 @@ import net.frankheijden.serverutils.velocity.reflection.RVelocityPluginManager;
|
|||
import net.frankheijden.serverutils.velocity.reflection.RVelocityScheduler;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class VelocityPluginManager implements AbstractPluginManager<PluginContainer> {
|
||||
public class VelocityPluginManager extends AbstractPluginManager<PluginContainer, VelocityPluginDescription> {
|
||||
|
||||
private static VelocityPluginManager instance;
|
||||
private final ProxyServer proxy;
|
||||
|
|
@ -66,195 +68,223 @@ public class VelocityPluginManager implements AbstractPluginManager<PluginContai
|
|||
}
|
||||
|
||||
@Override
|
||||
public VelocityLoadResult loadPlugin(String pluginFile) {
|
||||
return loadPlugin(new File(getPluginsFolder(), pluginFile));
|
||||
}
|
||||
public PluginResults<PluginContainer> loadPluginDescriptions(List<VelocityPluginDescription> descriptions) {
|
||||
PluginResults<PluginContainer> loadResults = new PluginResults<>();
|
||||
|
||||
@Override
|
||||
public VelocityLoadResult loadPlugin(File file) {
|
||||
if (!file.exists() || file.isDirectory()) return new VelocityLoadResult(Result.NOT_EXISTS);
|
||||
for (VelocityPluginDescription description : descriptions) {
|
||||
Path source = description.getFile().toPath();
|
||||
Path baseDirectory = source.getParent();
|
||||
|
||||
Object javaPluginLoader = RJavaPluginLoader.newInstance(proxy, file.toPath().getParent());
|
||||
PluginDescription candidate = RJavaPluginLoader.loadPluginDescription(javaPluginLoader, file.toPath());
|
||||
if (proxy.getPluginManager().isLoaded(candidate.getId())) return new VelocityLoadResult(Result.ALREADY_LOADED);
|
||||
Object javaPluginLoader = RJavaPluginLoader.newInstance(proxy, baseDirectory);
|
||||
PluginDescription candidate = RJavaPluginLoader.loadPluginDescription(javaPluginLoader, source);
|
||||
|
||||
for (PluginDependency dependency : candidate.getDependencies()) {
|
||||
if (!dependency.isOptional() && !proxy.getPluginManager().isLoaded(dependency.getId())) {
|
||||
logger.error(
|
||||
"Can't load plugin {} due to missing dependency {}",
|
||||
candidate.getId(),
|
||||
dependency.getId()
|
||||
);
|
||||
return new VelocityLoadResult(Result.UNKNOWN_DEPENDENCY.arg(dependency.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
PluginDescription realPlugin = RJavaPluginLoader.loadPlugin(javaPluginLoader, candidate);
|
||||
PluginContainer container = RVelocityPluginContainer.newInstance(realPlugin);
|
||||
proxy.getEventManager().fire(new VelocityPluginLoadEvent(container, PluginEvent.Stage.PRE));
|
||||
proxy.getEventManager().fire(new VelocityPluginLoadEvent(container, PluginEvent.Stage.POST));
|
||||
|
||||
return new VelocityLoadResult(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result enablePlugin(PluginContainer container) {
|
||||
proxy.getEventManager().fire(new VelocityPluginEnableEvent(container, PluginEvent.Stage.PRE));
|
||||
if (proxy.getPluginManager().isLoaded(container.getDescription().getId())) return Result.ALREADY_ENABLED;
|
||||
|
||||
Object javaPluginLoader = RJavaPluginLoader.newInstance(
|
||||
proxy,
|
||||
container.getDescription().getSource().map(Path::getParent).orElse(null)
|
||||
);
|
||||
PluginDescription realPlugin = container.getDescription();
|
||||
Module module = RJavaPluginLoader.createModule(javaPluginLoader, container);
|
||||
|
||||
AbstractModule commonModule = new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ProxyServer.class).toInstance(proxy);
|
||||
bind(PluginManager.class).toInstance(proxy.getPluginManager());
|
||||
bind(EventManager.class).toInstance(proxy.getEventManager());
|
||||
bind(CommandManager.class).toInstance(proxy.getCommandManager());
|
||||
for (PluginContainer container : proxy.getPluginManager().getPlugins()) {
|
||||
bind(PluginContainer.class)
|
||||
.annotatedWith(Names.named(container.getDescription().getId()))
|
||||
.toInstance(container);
|
||||
dependencyCheck:
|
||||
for (PluginDependency dependency : candidate.getDependencies()) {
|
||||
String pluginId = dependency.getId();
|
||||
for (VelocityPluginDescription desc : descriptions) {
|
||||
if (desc.getId().equals(pluginId)) continue dependencyCheck;
|
||||
}
|
||||
bind(PluginContainer.class)
|
||||
.annotatedWith(Names.named(realPlugin.getId()))
|
||||
.toInstance(container);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
RJavaPluginLoader.createPlugin(javaPluginLoader, container, module, commonModule);
|
||||
} catch (Exception ex) {
|
||||
logger.error(
|
||||
String.format("Can't create plugin %s", container.getDescription().getId()),
|
||||
ex
|
||||
);
|
||||
return Result.ERROR;
|
||||
if (!dependency.isOptional() && !proxy.getPluginManager().isLoaded(dependency.getId())) {
|
||||
logger.error(
|
||||
"Can't load plugin {} due to missing dependency {}",
|
||||
candidate.getId(),
|
||||
dependency.getId()
|
||||
);
|
||||
return loadResults.addResult(
|
||||
description.getId(),
|
||||
Result.UNKNOWN_DEPENDENCY.arg(dependency.getId())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PluginDescription realPlugin = RJavaPluginLoader.loadPlugin(javaPluginLoader, candidate);
|
||||
PluginContainer container = RVelocityPluginContainer.newInstance(realPlugin);
|
||||
proxy.getEventManager().fire(new VelocityPluginLoadEvent(container, PluginEvent.Stage.PRE));
|
||||
proxy.getEventManager().fire(new VelocityPluginLoadEvent(container, PluginEvent.Stage.POST));
|
||||
|
||||
loadResults.addResult(description.getId(), container);
|
||||
}
|
||||
|
||||
logger.info(
|
||||
"Loaded plugin {} {} by {}",
|
||||
realPlugin.getId(),
|
||||
realPlugin.getVersion().orElse("<UNKNOWN>"),
|
||||
Joiner.on(", ").join(realPlugin.getAuthors())
|
||||
);
|
||||
return loadResults;
|
||||
}
|
||||
|
||||
RVelocityPluginManager.registerPlugin(proxy.getPluginManager(), container);
|
||||
container.getInstance().ifPresent(pluginInstance -> {
|
||||
RVelocityEventManager.registerInternally(proxy.getEventManager(), container, pluginInstance);
|
||||
RVelocityEventManager.fireForPlugin(
|
||||
proxy.getEventManager(),
|
||||
new ProxyInitializeEvent(),
|
||||
pluginInstance
|
||||
).join();
|
||||
@Override
|
||||
public PluginResults<PluginContainer> enableOrderedPlugins(List<PluginContainer> containers) {
|
||||
PluginResults<PluginContainer> enableResults = new PluginResults<>();
|
||||
|
||||
ConsoleCommandSource console = proxy.getConsoleCommandSource();
|
||||
PermissionsSetupEvent event = new PermissionsSetupEvent(
|
||||
console,
|
||||
s -> PermissionFunction.ALWAYS_TRUE
|
||||
List<Object> pluginInstances = new ArrayList<>(containers.size());
|
||||
for (PluginContainer container : containers) {
|
||||
String pluginId = container.getDescription().getId();
|
||||
proxy.getEventManager().fire(new VelocityPluginEnableEvent(container, PluginEvent.Stage.PRE));
|
||||
if (isPluginEnabled(pluginId)) {
|
||||
return enableResults.addResult(pluginId, Result.ALREADY_ENABLED);
|
||||
}
|
||||
|
||||
Object javaPluginLoader = RJavaPluginLoader.newInstance(
|
||||
proxy,
|
||||
container.getDescription().getSource().map(Path::getParent).orElse(null)
|
||||
);
|
||||
PermissionFunction permissionFunction = RVelocityEventManager.fireForPlugin(
|
||||
proxy.getEventManager(),
|
||||
event,
|
||||
pluginInstance
|
||||
).join().createFunction(console);
|
||||
PluginDescription realPlugin = container.getDescription();
|
||||
Module module = RJavaPluginLoader.createModule(javaPluginLoader, container);
|
||||
|
||||
if (permissionFunction == null) {
|
||||
AbstractModule commonModule = new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ProxyServer.class).toInstance(proxy);
|
||||
bind(PluginManager.class).toInstance(proxy.getPluginManager());
|
||||
bind(EventManager.class).toInstance(proxy.getEventManager());
|
||||
bind(CommandManager.class).toInstance(proxy.getCommandManager());
|
||||
for (PluginContainer container : proxy.getPluginManager().getPlugins()) {
|
||||
bind(PluginContainer.class)
|
||||
.annotatedWith(Names.named(container.getDescription().getId()))
|
||||
.toInstance(container);
|
||||
}
|
||||
for (PluginContainer container : containers) {
|
||||
bind(PluginContainer.class)
|
||||
.annotatedWith(Names.named(container.getDescription().getId()))
|
||||
.toInstance(container);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
RJavaPluginLoader.createPlugin(javaPluginLoader, container, module, commonModule);
|
||||
} catch (Exception ex) {
|
||||
logger.error(
|
||||
"A plugin permission provider {} provided an invalid permission function for the console."
|
||||
+ " This is a bug in the plugin, not in Velocity."
|
||||
+ " Falling back to the default permission function.",
|
||||
event.getProvider().getClass().getName()
|
||||
String.format("Can't create plugin %s", container.getDescription().getId()),
|
||||
ex
|
||||
);
|
||||
permissionFunction = PermissionFunction.ALWAYS_TRUE;
|
||||
return enableResults.addResult(pluginId, Result.ERROR);
|
||||
}
|
||||
|
||||
RVelocityConsole.setPermissionFunction(console, permissionFunction);
|
||||
});
|
||||
logger.info(
|
||||
"Loaded plugin {} {} by {}",
|
||||
realPlugin.getId(),
|
||||
realPlugin.getVersion().orElse("<UNKNOWN>"),
|
||||
Joiner.on(", ").join(realPlugin.getAuthors())
|
||||
);
|
||||
|
||||
proxy.getEventManager().fire(new VelocityPluginEnableEvent(container, PluginEvent.Stage.POST));
|
||||
return Result.SUCCESS;
|
||||
RVelocityPluginManager.registerPlugin(proxy.getPluginManager(), container);
|
||||
Optional<?> instanceOptional = container.getInstance();
|
||||
if (instanceOptional.isPresent()) {
|
||||
Object pluginInstance = instanceOptional.get();
|
||||
RVelocityEventManager.registerInternally(proxy.getEventManager(), container, pluginInstance);
|
||||
pluginInstances.add(pluginInstance);
|
||||
}
|
||||
}
|
||||
|
||||
RVelocityEventManager.fireForPlugins(
|
||||
proxy.getEventManager(),
|
||||
new ProxyInitializeEvent(),
|
||||
pluginInstances
|
||||
).join();
|
||||
|
||||
ConsoleCommandSource console = proxy.getConsoleCommandSource();
|
||||
PermissionsSetupEvent event = new PermissionsSetupEvent(
|
||||
console,
|
||||
s -> PermissionFunction.ALWAYS_TRUE
|
||||
);
|
||||
PermissionFunction permissionFunction = RVelocityEventManager.fireForPlugins(
|
||||
proxy.getEventManager(),
|
||||
event,
|
||||
pluginInstances
|
||||
).join().createFunction(console);
|
||||
|
||||
if (permissionFunction == null) {
|
||||
logger.error(
|
||||
"A plugin permission provider {} provided an invalid permission function for the console."
|
||||
+ " This is a bug in the plugin, not in Velocity."
|
||||
+ " Falling back to the default permission function.",
|
||||
event.getProvider().getClass().getName()
|
||||
);
|
||||
permissionFunction = PermissionFunction.ALWAYS_TRUE;
|
||||
}
|
||||
|
||||
RVelocityConsole.setPermissionFunction(console, permissionFunction);
|
||||
|
||||
for (PluginContainer container : containers) {
|
||||
proxy.getEventManager().fire(new VelocityPluginEnableEvent(container, PluginEvent.Stage.POST));
|
||||
enableResults.addResult(container.getDescription().getId(), container);
|
||||
}
|
||||
|
||||
return enableResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result disablePlugin(PluginContainer container) {
|
||||
proxy.getEventManager().fire(new VelocityPluginDisableEvent(container, PluginEvent.Stage.PRE));
|
||||
Object pluginInstance = container.getInstance().orElse(null);
|
||||
if (pluginInstance == null) return Result.NOT_EXISTS;
|
||||
public boolean isPluginEnabled(String pluginId) {
|
||||
return proxy.getPluginManager().isLoaded(pluginId);
|
||||
}
|
||||
|
||||
RVelocityEventManager.fireForPlugin(
|
||||
@Override
|
||||
public PluginResults<PluginContainer> disableOrderedPlugins(List<PluginContainer> containers) {
|
||||
PluginResults<PluginContainer> disableResults = new PluginResults<>();
|
||||
|
||||
List<Object> pluginInstances = new ArrayList<>(containers.size());
|
||||
for (PluginContainer container : containers) {
|
||||
proxy.getEventManager().fire(new VelocityPluginDisableEvent(container, PluginEvent.Stage.PRE));
|
||||
String pluginId = getPluginId(container);
|
||||
Object pluginInstance = container.getInstance().orElse(null);
|
||||
if (pluginInstance == null) {
|
||||
return disableResults.addResult(pluginId, Result.ALREADY_DISABLED);
|
||||
}
|
||||
|
||||
pluginInstances.add(pluginInstance);
|
||||
}
|
||||
|
||||
RVelocityEventManager.fireForPlugins(
|
||||
proxy.getEventManager(),
|
||||
pluginInstance,
|
||||
new ProxyShutdownEvent()
|
||||
new ProxyShutdownEvent(),
|
||||
pluginInstances
|
||||
);
|
||||
|
||||
proxy.getEventManager().fire(new VelocityPluginDisableEvent(container, PluginEvent.Stage.POST));
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result reloadPlugin(String pluginName) {
|
||||
Optional<PluginContainer> pluginOptional = proxy.getPluginManager().getPlugin(pluginName);
|
||||
if (!pluginOptional.isPresent()) return Result.NOT_EXISTS;
|
||||
return reloadPlugin(pluginOptional.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result reloadPlugin(PluginContainer plugin) {
|
||||
CloseableResult result = unloadPlugin(plugin);
|
||||
if (result.getResult() != Result.SUCCESS) return result.getResult();
|
||||
result.tryClose();
|
||||
|
||||
File file = getPluginFile(plugin.getDescription().getId());
|
||||
if (file == null) return Result.FILE_DELETED;
|
||||
|
||||
VelocityLoadResult loadResult = loadPlugin(file);
|
||||
if (!loadResult.isSuccess()) return loadResult.getResult();
|
||||
|
||||
return enablePlugin(loadResult.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloseableResult unloadPlugin(String pluginName) {
|
||||
Optional<PluginContainer> pluginOptional = proxy.getPluginManager().getPlugin(pluginName);
|
||||
if (!pluginOptional.isPresent()) return new CloseableResult(Result.NOT_EXISTS);
|
||||
return unloadPlugin(pluginOptional.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloseableResult unloadPlugin(PluginContainer container) {
|
||||
proxy.getEventManager().fire(new VelocityPluginUnloadEvent(container, PluginEvent.Stage.PRE));
|
||||
Optional<?> pluginInstanceOptional = container.getInstance();
|
||||
if (!pluginInstanceOptional.isPresent()) return new CloseableResult(Result.INVALID_PLUGIN);
|
||||
Object pluginInstance = pluginInstanceOptional.get();
|
||||
|
||||
proxy.getEventManager().unregisterListeners(pluginInstance);
|
||||
for (ScheduledTask task : RVelocityScheduler.getTasksByPlugin(proxy.getScheduler()).removeAll(pluginInstance)) {
|
||||
task.cancel();
|
||||
for (PluginContainer container : containers) {
|
||||
proxy.getEventManager().fire(new VelocityPluginDisableEvent(container, PluginEvent.Stage.POST));
|
||||
disableResults.addResult(getPluginId(container), container);
|
||||
}
|
||||
|
||||
String pluginId = container.getDescription().getId();
|
||||
for (String alias : pluginCommandManager.getPluginCommands().removeAll(pluginId)) {
|
||||
proxy.getCommandManager().unregister(alias);
|
||||
return disableResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CloseablePluginResults<PluginContainer> unloadOrderedPlugins(List<PluginContainer> containers) {
|
||||
CloseablePluginResults<PluginContainer> unloadResults = new CloseablePluginResults<>();
|
||||
|
||||
for (PluginContainer container : containers) {
|
||||
proxy.getEventManager().fire(new VelocityPluginUnloadEvent(container, PluginEvent.Stage.PRE));
|
||||
String pluginId = getPluginId(container);
|
||||
Optional<?> pluginInstanceOptional = container.getInstance();
|
||||
if (!pluginInstanceOptional.isPresent()) {
|
||||
return unloadResults.addResult(pluginId, Result.INVALID_PLUGIN);
|
||||
}
|
||||
|
||||
Object pluginInstance = pluginInstanceOptional.get();
|
||||
|
||||
proxy.getEventManager().unregisterListeners(pluginInstance);
|
||||
for (ScheduledTask task : RVelocityScheduler.getTasksByPlugin(proxy.getScheduler())
|
||||
.removeAll(pluginInstance)) {
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
for (String alias : pluginCommandManager.getPluginCommands().removeAll(pluginId)) {
|
||||
proxy.getCommandManager().unregister(alias);
|
||||
}
|
||||
|
||||
RVelocityPluginManager.getPlugins(proxy.getPluginManager()).remove(pluginId);
|
||||
RVelocityPluginManager.getPluginInstances(proxy.getPluginManager()).remove(pluginInstance);
|
||||
|
||||
List<Closeable> closeables = new ArrayList<>();
|
||||
|
||||
ClassLoader loader = pluginInstance.getClass().getClassLoader();
|
||||
if (loader instanceof Closeable) {
|
||||
closeables.add((Closeable) loader);
|
||||
}
|
||||
|
||||
proxy.getEventManager().fire(new VelocityPluginUnloadEvent(container, PluginEvent.Stage.POST));
|
||||
unloadResults.addResult(pluginId, container, closeables);
|
||||
}
|
||||
|
||||
RVelocityPluginManager.getPlugins(proxy.getPluginManager()).remove(pluginId);
|
||||
RVelocityPluginManager.getPluginInstances(proxy.getPluginManager()).remove(pluginInstance);
|
||||
|
||||
List<Closeable> closeables = new ArrayList<>();
|
||||
|
||||
ClassLoader loader = pluginInstance.getClass().getClassLoader();
|
||||
if (loader instanceof Closeable) {
|
||||
closeables.add((Closeable) loader);
|
||||
}
|
||||
|
||||
proxy.getEventManager().fire(new VelocityPluginUnloadEvent(container, PluginEvent.Stage.POST));
|
||||
return new CloseableResult(closeables);
|
||||
return unloadResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -263,7 +293,7 @@ public class VelocityPluginManager implements AbstractPluginManager<PluginContai
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getPluginName(PluginContainer plugin) {
|
||||
public String getPluginId(PluginContainer plugin) {
|
||||
return plugin.getDescription().getId();
|
||||
}
|
||||
|
||||
|
|
@ -275,22 +305,43 @@ public class VelocityPluginManager implements AbstractPluginManager<PluginContai
|
|||
}
|
||||
|
||||
@Override
|
||||
public File getPluginFile(String pluginName) {
|
||||
public Optional<File> getPluginFile(String pluginName) {
|
||||
Object javaPluginLoader = RJavaPluginLoader.newInstance(instance.proxy, getPluginsFolder().toPath());
|
||||
|
||||
for (File file : getPluginJars()) {
|
||||
PluginDescription desc = RJavaPluginLoader.loadPluginDescription(javaPluginLoader, file.toPath());
|
||||
|
||||
if (desc.getId().equals(pluginName)) {
|
||||
return file;
|
||||
return Optional.of(file);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginContainer getPlugin(String pluginName) {
|
||||
return proxy.getPluginManager().getPlugin(pluginName).orElse(null);
|
||||
public Optional<PluginContainer> getPlugin(String pluginName) {
|
||||
return proxy.getPluginManager().getPlugin(pluginName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VelocityPluginDescription getLoadedPluginDescription(PluginContainer plugin) {
|
||||
return new VelocityPluginDescription(plugin.getDescription());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<VelocityPluginDescription> getPluginDescription(
|
||||
File file
|
||||
) throws InvalidPluginDescriptionException {
|
||||
Path source = file.toPath();
|
||||
Path baseDirectory = source.getParent();
|
||||
|
||||
try {
|
||||
Object javaPluginLoader = RJavaPluginLoader.newInstance(proxy, baseDirectory);
|
||||
PluginDescription candidate = RJavaPluginLoader.loadPluginDescription(javaPluginLoader, source);
|
||||
return Optional.of(new VelocityPluginDescription(candidate));
|
||||
} catch (Exception ex) {
|
||||
throw new InvalidPluginDescriptionException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import dev.frankheijden.minecraftreflection.MinecraftReflection;
|
|||
import java.lang.reflect.Array;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RVelocityEventManager {
|
||||
|
|
@ -27,9 +28,14 @@ public class RVelocityEventManager {
|
|||
* Retrieves the registrations from a plugin for a specific event.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Object> getRegistrationsByPlugin(EventManager manager, Object plugin, Class<?> eventClass) {
|
||||
public static List<Object> getRegistrationsByPlugins(
|
||||
EventManager manager,
|
||||
List<Object> plugins,
|
||||
Class<?> eventClass
|
||||
) {
|
||||
return (List<Object>) getHandlersByType(manager).get(eventClass).stream()
|
||||
.filter(r -> RHandlerRegistration.getPlugin(r).getInstance().orElse(null) == plugin)
|
||||
.filter(r -> plugins.contains(RHandlerRegistration.getPlugin(r).getInstance().orElse(null)))
|
||||
.sorted(reflection.get(manager, "handlerComparator"))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
@ -48,26 +54,27 @@ public class RVelocityEventManager {
|
|||
/**
|
||||
* Fires an event specifically for one plugin.
|
||||
*/
|
||||
public static <E> CompletableFuture<E> fireForPlugin(
|
||||
public static <E> CompletableFuture<E> fireForPlugins(
|
||||
EventManager manager,
|
||||
E event,
|
||||
Object plugin
|
||||
List<Object> pluginInstances
|
||||
) {
|
||||
List<Object> registrations = getRegistrationsByPlugin(manager, plugin, event.getClass());
|
||||
List<Object> registrations = getRegistrationsByPlugins(manager, pluginInstances, event.getClass());
|
||||
CompletableFuture<E> future = new CompletableFuture<>();
|
||||
|
||||
Object registrationsEmptyArray = Array.newInstance(RHandlerRegistration.reflection.getClazz(), 0);
|
||||
Class<?> registrationsArrayClass = registrationsEmptyArray.getClass();
|
||||
|
||||
reflection.invoke(
|
||||
ExecutorService executor = reflection.invoke(manager, "getAsyncExecutor");
|
||||
executor.execute(() -> reflection.invoke(
|
||||
manager,
|
||||
"fire",
|
||||
ClassObject.of(CompletableFuture.class, future),
|
||||
ClassObject.of(Object.class, event),
|
||||
ClassObject.of(int.class, 0),
|
||||
ClassObject.of(boolean.class, false),
|
||||
ClassObject.of(boolean.class, true),
|
||||
ClassObject.of(registrationsArrayClass, registrations.toArray((Object[]) registrationsEmptyArray))
|
||||
);
|
||||
));
|
||||
|
||||
return future;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue