mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-10 09:02:09 -07:00
Add simpler JavaPlugin command registration (#12142)
This commit is contained in:
@@ -2,6 +2,8 @@ package org.bukkit.plugin.java;
|
|||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -11,6 +13,8 @@ import java.io.OutputStream;
|
|||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -26,14 +30,16 @@ import org.bukkit.generator.ChunkGenerator;
|
|||||||
import org.bukkit.plugin.PluginBase;
|
import org.bukkit.plugin.PluginBase;
|
||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import org.bukkit.plugin.PluginLoader;
|
import org.bukkit.plugin.PluginLoader;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a Java plugin and its main class. It contains fundamental methods
|
* Represents a Java plugin and its main class. It contains fundamental methods
|
||||||
* and fields for a plugin to be loaded and work properly. This is an indirect
|
* and fields for a plugin to be loaded and work properly. This is an indirect
|
||||||
* implementation of {@link org.bukkit.plugin.Plugin}.
|
* implementation of {@link org.bukkit.plugin.Plugin}.
|
||||||
*/
|
*/
|
||||||
|
@NullMarked
|
||||||
public abstract class JavaPlugin extends PluginBase {
|
public abstract class JavaPlugin extends PluginBase {
|
||||||
private boolean isEnabled = false;
|
private boolean isEnabled = false;
|
||||||
private PluginLoader loader = null;
|
private PluginLoader loader = null;
|
||||||
@@ -61,7 +67,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
protected JavaPlugin(@NotNull final JavaPluginLoader loader, @NotNull final PluginDescriptionFile description, @NotNull final File dataFolder, @NotNull final File file) {
|
protected JavaPlugin(final JavaPluginLoader loader, final PluginDescriptionFile description, final File dataFolder, final File file) {
|
||||||
final ClassLoader classLoader = this.getClass().getClassLoader();
|
final ClassLoader classLoader = this.getClass().getClassLoader();
|
||||||
if (classLoader instanceof PluginClassLoader) {
|
if (classLoader instanceof PluginClassLoader) {
|
||||||
throw new IllegalStateException("Cannot use initialization constructor at runtime");
|
throw new IllegalStateException("Cannot use initialization constructor at runtime");
|
||||||
@@ -75,7 +81,6 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
*
|
*
|
||||||
* @return The folder.
|
* @return The folder.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public final File getDataFolder() {
|
public final File getDataFolder() {
|
||||||
return dataFolder;
|
return dataFolder;
|
||||||
@@ -88,7 +93,6 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* @deprecated Plugin loading now occurs at a point which makes it impossible to expose this
|
* @deprecated Plugin loading now occurs at a point which makes it impossible to expose this
|
||||||
* behavior. This instance will only throw unsupported operation exceptions.
|
* behavior. This instance will only throw unsupported operation exceptions.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
public final PluginLoader getPluginLoader() {
|
public final PluginLoader getPluginLoader() {
|
||||||
@@ -100,7 +104,6 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
*
|
*
|
||||||
* @return Server running this plugin
|
* @return Server running this plugin
|
||||||
*/
|
*/
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public final Server getServer() {
|
public final Server getServer() {
|
||||||
return server;
|
return server;
|
||||||
@@ -121,7 +124,6 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
*
|
*
|
||||||
* @return File containing this plugin
|
* @return File containing this plugin
|
||||||
*/
|
*/
|
||||||
@NotNull
|
|
||||||
protected File getFile() {
|
protected File getFile() {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@@ -132,19 +134,16 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* @return Contents of the plugin.yml file
|
* @return Contents of the plugin.yml file
|
||||||
* @deprecated No longer applicable to all types of plugins
|
* @deprecated No longer applicable to all types of plugins
|
||||||
*/
|
*/
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public final PluginDescriptionFile getDescription() {
|
public final PluginDescriptionFile getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public final io.papermc.paper.plugin.configuration.PluginMeta getPluginMeta() {
|
public final io.papermc.paper.plugin.configuration.PluginMeta getPluginMeta() {
|
||||||
return this.pluginMeta;
|
return this.pluginMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public FileConfiguration getConfig() {
|
public FileConfiguration getConfig() {
|
||||||
if (newConfig == null) {
|
if (newConfig == null) {
|
||||||
@@ -163,8 +162,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* @throws IllegalArgumentException if file is null
|
* @throws IllegalArgumentException if file is null
|
||||||
* @see ClassLoader#getResourceAsStream(String)
|
* @see ClassLoader#getResourceAsStream(String)
|
||||||
*/
|
*/
|
||||||
@Nullable
|
protected final @Nullable Reader getTextResource(String file) {
|
||||||
protected final Reader getTextResource(@NotNull String file) {
|
|
||||||
final InputStream in = getResource(file);
|
final InputStream in = getResource(file);
|
||||||
|
|
||||||
return in == null ? null : new InputStreamReader(in, Charsets.UTF_8);
|
return in == null ? null : new InputStreamReader(in, Charsets.UTF_8);
|
||||||
@@ -199,7 +197,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveResource(@NotNull String resourcePath, boolean replace) {
|
public void saveResource(String resourcePath, boolean replace) {
|
||||||
if (resourcePath == null || resourcePath.equals("")) {
|
if (resourcePath == null || resourcePath.equals("")) {
|
||||||
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
|
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
|
||||||
}
|
}
|
||||||
@@ -236,9 +234,8 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getResource(@NotNull String filename) {
|
public @Nullable InputStream getResource(String filename) {
|
||||||
if (filename == null) {
|
if (filename == null) {
|
||||||
throw new IllegalArgumentException("Filename cannot be null");
|
throw new IllegalArgumentException("Filename cannot be null");
|
||||||
}
|
}
|
||||||
@@ -263,7 +260,6 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
*
|
*
|
||||||
* @return ClassLoader holding this plugin
|
* @return ClassLoader holding this plugin
|
||||||
*/
|
*/
|
||||||
@NotNull
|
|
||||||
protected final ClassLoader getClassLoader() {
|
protected final ClassLoader getClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
@@ -296,11 +292,11 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
private static final PluginLoader INSTANCE = net.kyori.adventure.util.Services.service(PluginLoader.class)
|
private static final PluginLoader INSTANCE = net.kyori.adventure.util.Services.service(PluginLoader.class)
|
||||||
.orElseThrow();
|
.orElseThrow();
|
||||||
}
|
}
|
||||||
public final void init(@NotNull PluginLoader loader, @NotNull Server server, @NotNull PluginDescriptionFile description, @NotNull File dataFolder, @NotNull File file, @NotNull ClassLoader classLoader) {
|
public final void init(PluginLoader loader, Server server, PluginDescriptionFile description, File dataFolder, File file, ClassLoader classLoader) {
|
||||||
init(server, description, dataFolder, file, classLoader, description, com.destroystokyo.paper.utils.PaperPluginLogger.getLogger(description));
|
init(server, description, dataFolder, file, classLoader, description, com.destroystokyo.paper.utils.PaperPluginLogger.getLogger(description));
|
||||||
this.pluginMeta = description;
|
this.pluginMeta = description;
|
||||||
}
|
}
|
||||||
public final void init(@NotNull Server server, @NotNull PluginDescriptionFile description, @NotNull File dataFolder, @NotNull File file, @NotNull ClassLoader classLoader, @Nullable io.papermc.paper.plugin.configuration.PluginMeta configuration, @NotNull Logger logger) {
|
public final void init(Server server, PluginDescriptionFile description, File dataFolder, File file, ClassLoader classLoader, io.papermc.paper.plugin.configuration.@Nullable PluginMeta configuration, Logger logger) {
|
||||||
this.loader = DummyPluginLoaderImplHolder.INSTANCE;
|
this.loader = DummyPluginLoaderImplHolder.INSTANCE;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
@@ -316,7 +312,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,8 +320,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
public @Nullable List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String @NotNull [] args) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,14 +332,15 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* @param name name or alias of the command
|
* @param name name or alias of the command
|
||||||
* @return the plugin command if found, otherwise null
|
* @return the plugin command if found, otherwise null
|
||||||
* @throws UnsupportedOperationException if this plugin is a paper plugin and the method is called in {@link #onEnable()}
|
* @throws UnsupportedOperationException if this plugin is a paper plugin and the method is called in {@link #onEnable()}
|
||||||
|
* @see #registerCommand(String, String, Collection, BasicCommand)
|
||||||
*/
|
*/
|
||||||
@Nullable
|
public @Nullable PluginCommand getCommand(String name) {
|
||||||
public PluginCommand getCommand(@NotNull String name) {
|
|
||||||
if (this.isBeingEnabled && !(pluginMeta instanceof PluginDescriptionFile)) {
|
if (this.isBeingEnabled && !(pluginMeta instanceof PluginDescriptionFile)) {
|
||||||
throw new UnsupportedOperationException("""
|
throw new UnsupportedOperationException("""
|
||||||
You are trying to call JavaPlugin#getCommand on a Paper plugin during startup:
|
You are trying to call JavaPlugin#getCommand on a Paper plugin during startup:
|
||||||
you are probably trying to get a command you tried to define in paper-plugin.yml.
|
you are probably trying to get a command you tried to define in paper-plugin.yml.
|
||||||
Paper plugins do not support YAML-based command declarations!
|
Paper plugins do not support YAML-based command declarations!
|
||||||
|
You can use JavaPlugin#registerCommand to define commands in Paper plugins.
|
||||||
Please check the documentation for more information on how to define commands in Paper plugins: https://docs.papermc.io/paper/dev/getting-started/paper-plugins#commands
|
Please check the documentation for more information on how to define commands in Paper plugins: https://docs.papermc.io/paper/dev/getting-started/paper-plugins#commands
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@@ -362,6 +358,88 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a command for this plugin. Only valid to be called inside {@link #onEnable()}.
|
||||||
|
*
|
||||||
|
* <p>Commands have certain overriding behavior:
|
||||||
|
* <ul>
|
||||||
|
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
|
||||||
|
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
|
||||||
|
* <li>The main command/namespaced label will override already existing commands</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param label the label of the to-be-registered command
|
||||||
|
* @param basicCommand the basic command instance to register
|
||||||
|
* @see LifecycleEvents#COMMANDS
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public void registerCommand(final String label, final BasicCommand basicCommand) {
|
||||||
|
this.registerCommand(label, null, Collections.emptyList(), basicCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a command for this plugin. Only valid to be called inside {@link #onEnable()}.
|
||||||
|
*
|
||||||
|
* <p>Commands have certain overriding behavior:
|
||||||
|
* <ul>
|
||||||
|
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
|
||||||
|
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
|
||||||
|
* <li>The main command/namespaced label will override already existing commands</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param label the label of the to-be-registered command
|
||||||
|
* @param description the help description for the root literal node
|
||||||
|
* @param basicCommand the basic command instance to register
|
||||||
|
* @see LifecycleEvents#COMMANDS
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public void registerCommand(final String label, final @Nullable String description, final BasicCommand basicCommand) {
|
||||||
|
this.registerCommand(label, description, Collections.emptyList(), basicCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a command for this plugin. Only valid to be called inside {@link #onEnable()}.
|
||||||
|
*
|
||||||
|
* <p>Commands have certain overriding behavior:
|
||||||
|
* <ul>
|
||||||
|
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
|
||||||
|
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
|
||||||
|
* <li>The main command/namespaced label will override already existing commands</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param label the label of the to-be-registered command
|
||||||
|
* @param aliases a collection of aliases to register the basic command under.
|
||||||
|
* @param basicCommand the basic command instance to register
|
||||||
|
* @see LifecycleEvents#COMMANDS
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public void registerCommand(final String label, final Collection<String> aliases, final BasicCommand basicCommand) {
|
||||||
|
this.registerCommand(label, null, aliases, basicCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a command for this plugin. Only valid to be called inside {@link #onEnable()}.
|
||||||
|
*
|
||||||
|
* <p>Commands have certain overriding behavior:
|
||||||
|
* <ul>
|
||||||
|
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
|
||||||
|
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
|
||||||
|
* <li>The main command/namespaced label will override already existing commands</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param label the label of the to-be-registered command
|
||||||
|
* @param description the help description for the root literal node
|
||||||
|
* @param aliases a collection of aliases to register the basic command under.
|
||||||
|
* @param basicCommand the basic command instance to register
|
||||||
|
* @see LifecycleEvents#COMMANDS
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public void registerCommand(final String label, final @Nullable String description, final Collection<String> aliases, final BasicCommand basicCommand) {
|
||||||
|
this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, event -> {
|
||||||
|
event.registrar().register(label, description, aliases, basicCommand);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {}
|
public void onLoad() {}
|
||||||
|
|
||||||
@@ -371,15 +449,13 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
@Override
|
@Override
|
||||||
public void onEnable() {}
|
public void onEnable() {}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) {
|
public @Nullable ChunkGenerator getDefaultWorldGenerator(String worldName, @Nullable String id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeProvider getDefaultBiomeProvider(@NotNull String worldName, @Nullable String id) {
|
public @Nullable BiomeProvider getDefaultBiomeProvider(String worldName, @Nullable String id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,13 +469,11 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
this.naggable = canNag;
|
this.naggable = canNag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public Logger getLogger() {
|
public Logger getLogger() {
|
||||||
return logger;
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return description.getFullName();
|
return description.getFullName();
|
||||||
@@ -428,8 +502,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* @throws ClassCastException if plugin that provided the class does not
|
* @throws ClassCastException if plugin that provided the class does not
|
||||||
* extend the class
|
* extend the class
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public static <T extends JavaPlugin> T getPlugin(Class<T> clazz) {
|
||||||
public static <T extends JavaPlugin> T getPlugin(@NotNull Class<T> clazz) {
|
|
||||||
Preconditions.checkArgument(clazz != null, "Null class cannot have a plugin");
|
Preconditions.checkArgument(clazz != null, "Null class cannot have a plugin");
|
||||||
if (!JavaPlugin.class.isAssignableFrom(clazz)) {
|
if (!JavaPlugin.class.isAssignableFrom(clazz)) {
|
||||||
throw new IllegalArgumentException(clazz + " does not extend " + JavaPlugin.class);
|
throw new IllegalArgumentException(clazz + " does not extend " + JavaPlugin.class);
|
||||||
@@ -457,8 +530,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* @throws IllegalStateException if called from the static initializer for
|
* @throws IllegalStateException if called from the static initializer for
|
||||||
* given JavaPlugin
|
* given JavaPlugin
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public static JavaPlugin getProvidingPlugin(Class<?> clazz) {
|
||||||
public static JavaPlugin getProvidingPlugin(@NotNull Class<?> clazz) {
|
|
||||||
Preconditions.checkArgument(clazz != null, "Null class cannot have a plugin");
|
Preconditions.checkArgument(clazz != null, "Null class cannot have a plugin");
|
||||||
final ClassLoader cl = clazz.getClassLoader();
|
final ClassLoader cl = clazz.getClassLoader();
|
||||||
if (!(cl instanceof io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader configuredPluginClassLoader)) {
|
if (!(cl instanceof io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader configuredPluginClassLoader)) {
|
||||||
@@ -472,7 +544,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager<org.bukkit.plugin.Plugin> getLifecycleManager() {
|
public final io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.plugin.Plugin> getLifecycleManager() {
|
||||||
return this.lifecycleEventManager;
|
return this.lifecycleEventManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user