diff --git a/.github/ISSUE_TEMPLATE/help.md b/.github/ISSUE_TEMPLATE/help.md index 686935cfe..d46a29e87 100644 --- a/.github/ISSUE_TEMPLATE/help.md +++ b/.github/ISSUE_TEMPLATE/help.md @@ -5,42 +5,82 @@ labels: 'type: question' --- - +2. Fill out the template. + Run the commands in the console. Don't just put "latest" as a version, or + we will ignore it. This will help us understand what problem you've + encountered and help us find a solution. + +3. When linking logs or config files, do not attach them to the post! + Copy and paste any logs into https://gist.github.com/, then paste a + link to them in the relevant parts of the template. Do not use Hastebin + or Pastebin, as this can cause issues when trying to solve issues in the + future. + **DO NOT drag logs into this text box!** + +4. If you are encountering a performance issue, please include a link to a + Timings and/or profiler report. + +--> ### Information -Full output of `/ess version`: +**Full output of `/ess version`:** + +``` - +``` -**Server log:** +**Server startup log:** + + + +**EssentialsX config:** + -**EssentialsX config** ### Help request -**Problem** - +**Problem:** + -**What I have tried** - +**What I have tried:** + -**Screenshots** - +**Console stack trace:** + +``` + +``` + +**Screenshots:** + diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index b6b22c2c2..3583fd794 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -7,7 +7,11 @@ labels: 'bug: unconfirmed' +--> ### Information -**Full output of `/ess version`**: - -``` - +**Full output of `/ess version`:** + ``` -**Server log**: +``` + +**Server startup log:** + + + +**EssentialsX config:** + -**EssentialsX config**: ### Details -**Description** - +**Description:** + -**Steps to reproduce** - +**Steps to reproduce:** + -**Expected behavior** - +**Expected behavior:** + -**Screenshots** - +**Console stack trace:** + +``` + +``` + +**Screenshots:** + diff --git a/.github/ISSUE_TEMPLATE/request-a-feature.md b/.github/ISSUE_TEMPLATE/request-a-feature.md index a848dfa7b..fcda835c3 100644 --- a/.github/ISSUE_TEMPLATE/request-a-feature.md +++ b/.github/ISSUE_TEMPLATE/request-a-feature.md @@ -7,8 +7,11 @@ labels: 'type: enhancement' +--> ### Feature request -**Feature description** - +**Feature description:** + -**How the feature is useful** - +**How the feature is useful:** + diff --git a/.github/PULL_REQUEST_TEMPLATE/bug-fix.md b/.github/PULL_REQUEST_TEMPLATE/bug-fix.md new file mode 100644 index 000000000..c833e1210 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/bug-fix.md @@ -0,0 +1,82 @@ +--- +name: Bug fix +about: Use this if your PR fixes a bug in EssentialsX. +labels: 'type: bugfix' +--- + + + +### Information + + + +This PR fixes #nnnn. + +### Details + +**Proposed fix:** + + + +**Environments tested:** + + +- [ ] Paper 1.16.3 (any OS, any Java 8+ version) +- [ ] CraftBukkit/Spigot/Paper 1.12.2 (any OS, any Java 8+ version) +- [ ] CraftBukkit 1.8.8 (any OS, any Java 8+ version) + + +**Demonstration:** + diff --git a/.github/PULL_REQUEST_TEMPLATE/config.yml b/.github/PULL_REQUEST_TEMPLATE/config.yml new file mode 100644 index 000000000..68f0c161b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: MOSS Discord Server + url: https://discord.gg/casfFyh + about: Need help with using EssentialsX? Join the MOSS Discord server for help. + - name: EssentialsX Development Discord Server + url: https://discord.gg/CUN7qVb + about: Got questions or want to discuss changes before opening your PR? Join the EssentialsX Development Discord server. (Need help? Join MOSS instead.) diff --git a/.github/PULL_REQUEST_TEMPLATE/new-feature.md b/.github/PULL_REQUEST_TEMPLATE/new-feature.md new file mode 100644 index 000000000..c019e8037 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/new-feature.md @@ -0,0 +1,82 @@ +--- +name: Feature addition +about: Use this if your PR adds a new feature to EssentialsX. +labels: 'type: enhancement' +--- + + + +### Information + + + +This PR closes #nnnn. + +### Details + +**Proposed feature** + + +**Environments tested:** + + +- [ ] Paper 1.16.3 (any OS, any Java 8+ version) +- [ ] CraftBukkit/Spigot/Paper 1.12.2 (any OS, any Java 8+ version) +- [ ] CraftBukkit 1.8.8 (any OS, any Java 8+ version) + +**Demonstration:** + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..0c26baf29 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,31 @@ +Contributing to EssentialsX +=========================== + +Want to help improve EssentialsX? There are several ways you can support and contribute to the project. + +If you'd like to make a financial contribution to the project, you can join our [Patreon](https://www.patreon.com/essentialsx/), +or to make a one-off donation you can visit our [Ko-fi page](https://ko-fi.com/essentialsx). If you can't make a +donation, don't worry! There are lots of other ways to contribute: + +* Do you run a server? Take a look at our ["help wanted"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22help+wanted%22) + and ["bug: unconfirmed"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22bug%3A+unconfirmed%22) + issues, where you can find issues that need extra testing and investigation. +* Do you speak multiple languages? If so, we always welcome contributions to our [Crowdin project](https://crowdin.com/project/essentialsx-official). +* Do you enjoy helping others? If so, why not contribute to the [EssentialsX documentation](https://github.com/EssentialsX/wiki)? + You can also join the [MOSS Discord community](https://discord.gg/casfFyh) and provide direct community support to + other EssentialsX users. +* If you're a developer, you could look through our ["open to PR"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22status%3A+open+to+PR%22) + issues. We're always happy to receive bug fixes and feature additions as pull requests. + +Submitting a PR +--------------- + +EssentialsX has extensive templates for PRs that detail how to submit your PR. To find out more, see the PR templates for: +* [Bug fixes](https://github.com/EssentialsX/Essentials/blob/2.x/.github/PULL_REQUEST_TEMPLATE/bug-fix.md) +* [New features](https://github.com/EssentialsX/Essentials/blob/2.x/.github/PULL_REQUEST_TEMPLATE/new-feature.md) + +Want to discuss a feature before opening a PR? Join the [EssentialsX Development Discord server](https://discord.gg/CUN7qVb). Note that this server is **not for end-users** - if you need support with EssentialsX, you should join [MOSS](https://discord.gg/casfFyh) instead. + +By contributing to EssentialsX, you agree to license your code under the [GNU General Public License version 3](https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE). + + diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index 933a4b6b7..bb694c6f0 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -17,7 +17,6 @@ */ package com.earth2me.essentials; -import com.earth2me.essentials.commands.Commandhat; import com.earth2me.essentials.commands.EssentialsCommand; import com.earth2me.essentials.commands.IEssentialsCommand; import com.earth2me.essentials.commands.NoChargeException; @@ -28,6 +27,7 @@ import com.earth2me.essentials.items.CustomItemResolver; import com.earth2me.essentials.items.FlatItemDb; import com.earth2me.essentials.items.LegacyItemDb; import com.earth2me.essentials.metrics.MetricsWrapper; +import com.earth2me.essentials.perm.PermissionsDefaults; import com.earth2me.essentials.perm.PermissionsHandler; import com.earth2me.essentials.register.payment.Methods; import com.earth2me.essentials.signs.SignBlockListener; @@ -47,7 +47,9 @@ import net.ess3.api.ISettings; import net.ess3.nms.refl.providers.ReflServerStateProvider; import net.ess3.nms.refl.providers.ReflSpawnEggProvider; import net.ess3.nms.refl.providers.ReflSpawnerBlockProvider; +import net.ess3.nms.refl.providers.ReflKnownCommandsProvider; import net.ess3.provider.ContainerProvider; +import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.PotionMetaProvider; import net.ess3.provider.ProviderListener; import net.ess3.provider.ServerStateProvider; @@ -61,6 +63,7 @@ import net.ess3.provider.providers.FlatSpawnEggProvider; import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacySpawnEggProvider; import net.ess3.provider.providers.PaperContainerProvider; +import net.ess3.provider.providers.PaperKnownCommandsProvider; import net.ess3.provider.providers.PaperRecipeBookListener; import net.ess3.provider.providers.PaperServerStateProvider; import org.bukkit.Bukkit; @@ -82,8 +85,6 @@ import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldUnloadEvent; -import org.bukkit.permissions.Permission; -import org.bukkit.permissions.PermissionDefault; import org.bukkit.plugin.InvalidDescriptionException; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; @@ -134,6 +135,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { private transient PotionMetaProvider potionMetaProvider; private transient ServerStateProvider serverStateProvider; private transient ContainerProvider containerProvider; + private transient KnownCommandsProvider knownCommandsProvider; private transient ProviderListener recipeBookEventProvider; private transient Kits kits; private transient RandomTeleport randomTeleport; @@ -154,18 +156,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { super(new JavaPluginLoader(server), new PluginDescriptionFile("Essentials", "", "com.earth2me.essentials.Essentials"), null, null); } - private static void addDefaultBackPermissionsToWorld(final World w) { - final String permName = "essentials.back.into." + w.getName(); - - Permission p = Bukkit.getPluginManager().getPermission(permName); - if (p == null) { - p = new Permission(permName, - "Allows access to /back when the destination location is within world " + w.getName(), - PermissionDefault.TRUE); - Bukkit.getPluginManager().addPermission(p); - } - } - @Override public ISettings getSettings() { return settings; @@ -210,8 +200,16 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { Console.setInstance(this); - if (!VersionUtil.isServerSupported()) { - getLogger().severe(tl("serverUnsupported")); + switch (VersionUtil.getServerSupportStatus()) { + case UNSTABLE: + getLogger().severe(tl("serverUnsupportedMods")); + break; + case OUTDATED: + getLogger().severe(tl("serverUnsupported")); + break; + case LIMITED: + getLogger().info(tl("serverUnsupportedLimitedApi")); + break; } final PluginManager pm = getServer().getPluginManager(); @@ -324,6 +322,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { } } + //Known Commands Provider + if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01)) { + knownCommandsProvider = new PaperKnownCommandsProvider(); + } else { + knownCommandsProvider = new ReflKnownCommandsProvider(); + } + execTimer.mark("Init(Providers)"); reload(); @@ -343,17 +348,15 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { permissionsHandler = new PermissionsHandler(this, settings.useBukkitPermissions()); alternativeCommandsHandler = new AlternativeCommandsHandler(this); - // Register hat permissions - Commandhat.registerPermissionsIfNecessary(getServer().getPluginManager()); - timer = new EssentialsTimer(this); scheduleSyncRepeatingTask(timer, 1000, 50); Economy.setEss(this); execTimer.mark("RegHandler"); - for (final World w : Bukkit.getWorlds()) - addDefaultBackPermissionsToWorld(w); + // Register /hat and /back default permissions + PermissionsDefaults.registerAllBackDefaults(); + PermissionsDefaults.registerAllHatDefaults(); metrics = new MetricsWrapper(this, 858, true); @@ -1013,6 +1016,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { return containerProvider; } + @Override + public KnownCommandsProvider getKnownCommandsProvider() { + return knownCommandsProvider; + } + private AbstractItemDb getItemDbFromConfig() { final String setting = settings.getItemDbType(); @@ -1040,7 +1048,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { @EventHandler(priority = EventPriority.LOW) public void onWorldLoad(final WorldLoadEvent event) { - addDefaultBackPermissionsToWorld(event.getWorld()); + PermissionsDefaults.registerBackDefaultFor(event.getWorld()); ess.getJails().onReload(); ess.getWarps().reloadConfig(); diff --git a/Essentials/src/com/earth2me/essentials/IEssentials.java b/Essentials/src/com/earth2me/essentials/IEssentials.java index 98294dfee..dda4eba61 100644 --- a/Essentials/src/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/com/earth2me/essentials/IEssentials.java @@ -5,6 +5,7 @@ import com.earth2me.essentials.api.IJails; import com.earth2me.essentials.api.IWarps; import com.earth2me.essentials.perm.PermissionsHandler; import net.ess3.provider.ContainerProvider; +import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.ServerStateProvider; import net.ess3.provider.SpawnerBlockProvider; import net.ess3.provider.SpawnerItemProvider; @@ -115,4 +116,6 @@ public interface IEssentials extends Plugin { ServerStateProvider getServerStateProvider(); ContainerProvider getContainerProvider(); + + KnownCommandsProvider getKnownCommandsProvider(); } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandessentials.java b/Essentials/src/com/earth2me/essentials/commands/Commandessentials.java index 0b2684eb4..89e8b1430 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandessentials.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandessentials.java @@ -314,11 +314,20 @@ public class Commandessentials extends EssentialsCommand { boolean isMismatched = false; boolean isVaultInstalled = false; boolean isUnsupported = false; - final boolean isServerSupported = VersionUtil.isServerSupported(); + final VersionUtil.SupportStatus supportStatus = VersionUtil.getServerSupportStatus(); final PluginManager pm = server.getPluginManager(); final String essVer = pm.getPlugin("Essentials").getDescription().getVersion(); - sender.sendMessage(tl(isServerSupported ? "versionOutputFine" : "versionOutputWarn", "Server", server.getBukkitVersion() + " " + server.getVersion())); + final String serverMessageKey; + if (supportStatus.isSupported()) { + serverMessageKey = "versionOutputFine"; + } else if (supportStatus == VersionUtil.SupportStatus.UNSTABLE) { + serverMessageKey = "versionOutputUnsupported"; + } else { + serverMessageKey = "versionOutputWarn"; + } + + sender.sendMessage(tl(serverMessageKey, "Server", server.getBukkitVersion() + " " + server.getVersion())); sender.sendMessage(tl("versionOutputFine", "EssentialsX", essVer)); for (final Plugin plugin : pm.getPlugins()) { @@ -366,8 +375,16 @@ public class Commandessentials extends EssentialsCommand { sender.sendMessage(tl("versionOutputUnsupportedPlugins")); } - if (!VersionUtil.isServerSupported()) { - sender.sendMessage(tl("serverUnsupported")); + switch (supportStatus) { + case UNSTABLE: + sender.sendMessage(tl("serverUnsupportedMods")); + break; + case OUTDATED: + sender.sendMessage(tl("serverUnsupported")); + break; + case LIMITED: + sender.sendMessage(tl("serverUnsupportedLimitedApi")); + break; } } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandhat.java b/Essentials/src/com/earth2me/essentials/commands/Commandhat.java index ff5cf7b99..caae135d5 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandhat.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandhat.java @@ -3,16 +3,12 @@ package com.earth2me.essentials.commands; import com.earth2me.essentials.User; import com.earth2me.essentials.craftbukkit.InventoryWorkaround; import com.earth2me.essentials.utils.VersionUtil; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; -import org.bukkit.permissions.Permission; -import org.bukkit.permissions.PermissionDefault; -import org.bukkit.plugin.PluginManager; import java.util.Collections; import java.util.List; @@ -20,35 +16,14 @@ import java.util.List; import static com.earth2me.essentials.I18n.tl; public class Commandhat extends EssentialsCommand { - /** - * The prefix for hat prevention commands - */ - private static final String PERM_PREFIX = "essentials.hat.prevent-type."; + + // The prefix for hat prevention commands + public static final String PERM_PREFIX = "essentials.hat.prevent-type."; public Commandhat() { super("hat"); } - /** - * Register permissions used by this command. - * - * @param toRegister The plugin manager to register permissions in. - */ - public static void registerPermissionsIfNecessary(final PluginManager toRegister) { - final Permission hatPerm = toRegister.getPermission(PERM_PREFIX + "*"); - if (hatPerm != null) { - return; - } - - final ImmutableMap.Builder children = ImmutableMap.builder(); - for (final Material mat : Material.values()) { - final String matPerm = PERM_PREFIX + mat.name().toLowerCase(); - children.put(matPerm, true); - toRegister.addPermission(new Permission(matPerm, "Prevent using " + mat + " as a type of hat.", PermissionDefault.FALSE)); - } - toRegister.addPermission(new Permission(PERM_PREFIX + "*", "Prevent all types of hats", PermissionDefault.FALSE, children.build())); - } - @Override protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception { if (args.length == 0 || (!args[0].contains("rem") && !args[0].contains("off") && !args[0].equalsIgnoreCase("0"))) { diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtree.java b/Essentials/src/com/earth2me/essentials/commands/Commandtree.java index b65ec19a9..16fb6865f 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandtree.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtree.java @@ -32,10 +32,6 @@ public class Commandtree extends EssentialsCommand { } if (args[0].equalsIgnoreCase("jungle")) { tree = TreeType.SMALL_JUNGLE; - } else if (args[0].equalsIgnoreCase("acacia")) { - tree = TreeType.ACACIA; - } else if (args[0].equalsIgnoreCase("birch")) { - tree = TreeType.BIRCH; } if (tree == null) { throw new NotEnoughArgumentsException(); diff --git a/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java b/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java index 1834d72af..5db8b4b68 100644 --- a/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java +++ b/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java @@ -8,13 +8,14 @@ import com.earth2me.essentials.User; import com.earth2me.essentials.utils.FormatUtil; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import net.ess3.api.IEssentials; import org.bukkit.Server; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginIdentifiableCommand; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.util.StringUtil; import java.util.ArrayList; @@ -316,17 +317,15 @@ public abstract class EssentialsCommand implements IEssentialsCommand { /** * Lists all commands. - *

- * TODO: Use the real commandmap to do this automatically. */ - protected final List getCommands(final Server server) { - final List commands = Lists.newArrayList(); - for (final Plugin p : server.getPluginManager().getPlugins()) { - final PluginDescriptionFile desc = p.getDescription(); - final Map> cmds = desc.getCommands(); - if (cmds != null) { - commands.addAll(cmds.keySet()); + protected final List getCommands(Server server) { + final Map commandMap = Maps.newHashMap(this.ess.getKnownCommandsProvider().getKnownCommands()); + final List commands = Lists.newArrayListWithCapacity(commandMap.size()); + for (final Command command : commandMap.values()) { + if (!(command instanceof PluginIdentifiableCommand)) { + continue; } + commands.add(command.getName()); } return commands; } @@ -356,13 +355,17 @@ public abstract class EssentialsCommand implements IEssentialsCommand { } final int numArgs = args.length - index - 1; - ess.getLogger().info(numArgs + " " + index + " " + Arrays.toString(args)); + if (ess.getSettings().isDebug()) { + ess.getLogger().info(numArgs + " " + index + " " + Arrays.toString(args)); + } String[] effectiveArgs = new String[numArgs]; System.arraycopy(args, index, effectiveArgs, 0, numArgs); if (effectiveArgs.length == 0) { effectiveArgs = new String[] {""}; } - ess.getLogger().info(command + " -- " + Arrays.toString(effectiveArgs)); + if (ess.getSettings().isDebug()) { + ess.getLogger().info(command + " -- " + Arrays.toString(effectiveArgs)); + } return command.tabComplete(sender.getSender(), label, effectiveArgs); } diff --git a/Essentials/src/com/earth2me/essentials/perm/PermissionsDefaults.java b/Essentials/src/com/earth2me/essentials/perm/PermissionsDefaults.java new file mode 100644 index 000000000..ee854e59b --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/perm/PermissionsDefaults.java @@ -0,0 +1,51 @@ +package com.earth2me.essentials.perm; + +import com.earth2me.essentials.commands.Commandhat; +import com.google.common.collect.ImmutableMap; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.plugin.PluginManager; + +public final class PermissionsDefaults { + + private PermissionsDefaults() { + } + + public static void registerAllBackDefaults() { + for (final World world : Bukkit.getWorlds()) { + registerBackDefaultFor(world); + } + } + + public static void registerBackDefaultFor(final World w) { + final String permName = "essentials.back.into." + w.getName(); + + Permission p = Bukkit.getPluginManager().getPermission(permName); + if (p == null) { + p = new Permission(permName, + "Allows access to /back when the destination location is within world " + w.getName(), + PermissionDefault.TRUE); + Bukkit.getPluginManager().addPermission(p); + } + } + + public static void registerAllHatDefaults() { + final PluginManager pluginManager = Bukkit.getPluginManager(); + + final Permission hatPerm = pluginManager.getPermission(Commandhat.PERM_PREFIX + "*"); + if (hatPerm != null) { + return; + } + + final ImmutableMap.Builder children = ImmutableMap.builder(); + for (final Material mat : Material.values()) { + final String matPerm = Commandhat.PERM_PREFIX + mat.name().toLowerCase(); + children.put(matPerm, true); + pluginManager.addPermission(new Permission(matPerm, "Prevent using " + mat + " as a type of hat.", PermissionDefault.FALSE)); + } + pluginManager.addPermission(new Permission(Commandhat.PERM_PREFIX + "*", "Prevent all types of hats", PermissionDefault.FALSE, children.build())); + } +} diff --git a/Essentials/src/com/earth2me/essentials/textreader/HelpInput.java b/Essentials/src/com/earth2me/essentials/textreader/HelpInput.java index 859a5f30a..dd3442c80 100644 --- a/Essentials/src/com/earth2me/essentials/textreader/HelpInput.java +++ b/Essentials/src/com/earth2me/essentials/textreader/HelpInput.java @@ -1,11 +1,14 @@ package com.earth2me.essentials.textreader; import com.earth2me.essentials.User; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import net.ess3.api.IEssentials; +import org.bukkit.command.Command; +import org.bukkit.command.PluginIdentifiableCommand; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -17,15 +20,12 @@ import java.util.logging.Logger; import static com.earth2me.essentials.I18n.tl; public class HelpInput implements IText { - private static final String DESCRIPTION = "description"; - private static final String PERMISSION = "permission"; - private static final String PERMISSIONS = "permissions"; private static final Logger logger = Logger.getLogger("Essentials"); private final transient List lines = new ArrayList<>(); private final transient List chapters = new ArrayList<>(); private final transient Map bookmarks = new HashMap<>(); - public HelpInput(final User user, final String match, final IEssentials ess) throws IOException { + public HelpInput(final User user, final String match, final IEssentials ess) { boolean reported = false; final List newLines = new ArrayList<>(); String pluginName = ""; @@ -34,7 +34,16 @@ public class HelpInput implements IText { lines.add(tl("helpMatching", match)); } - for (final Plugin p : ess.getServer().getPluginManager().getPlugins()) { + final Multimap pluginCommands = HashMultimap.create(); + for (final Command command : ess.getKnownCommandsProvider().getKnownCommands().values()) { + if (!(command instanceof PluginIdentifiableCommand)) { + continue; + } + final PluginIdentifiableCommand pluginIdentifiableCommand = (PluginIdentifiableCommand) command; + pluginCommands.put(pluginIdentifiableCommand.getPlugin(), command); + } + + for (Plugin p : ess.getServer().getPluginManager().getPlugins()) { try { final List pluginLines = new ArrayList<>(); final PluginDescriptionFile desc = p.getDescription(); @@ -48,46 +57,51 @@ public class HelpInput implements IText { } final boolean isOnWhitelist = user.isAuthorized("essentials.help." + pluginNameLow); - for (final Map.Entry> k : cmds.entrySet()) { + for (final Command command : pluginCommands.get(p)) { try { - if (!match.equalsIgnoreCase("") && !pluginNameLow.contains(match) && !k.getKey().toLowerCase(Locale.ENGLISH).contains(match) && !(k.getValue().get(DESCRIPTION) instanceof String && ((String) k.getValue().get(DESCRIPTION)).toLowerCase(Locale.ENGLISH).contains(match))) { + final String commandName = command.getName(); + final String commandDescription = command.getDescription(); + + if (!match.equalsIgnoreCase("") + && (!pluginNameLow.contains(match)) + && (!commandName.toLowerCase(Locale.ENGLISH).contains(match)) + && (!commandDescription.toLowerCase(Locale.ENGLISH).contains(match))) { continue; } if (pluginNameLow.contains("essentials")) { - final String node = "essentials." + k.getKey(); - if (!ess.getSettings().isCommandDisabled(k.getKey()) && user.isAuthorized(node)) { - pluginLines.add(tl("helpLine", k.getKey(), k.getValue().get(DESCRIPTION))); + final String node = "essentials." + commandName; + if (!ess.getSettings().isCommandDisabled(commandName) && user.isAuthorized(node)) { + pluginLines.add(tl("helpLine", commandName, commandDescription)); } } else { if (ess.getSettings().showNonEssCommandsInHelp()) { - final Map value = k.getValue(); - Object permissions = null; - if (value.containsKey(PERMISSION)) { - permissions = value.get(PERMISSION); - } else if (value.containsKey(PERMISSIONS)) { - permissions = value.get(PERMISSIONS); + final String permissionRaw = command.getPermission(); + final String[] permissions; + if (permissionRaw == null) { + permissions = new String[0]; + } else { + permissions = permissionRaw.split(";"); } - if (isOnWhitelist || user.isAuthorized("essentials.help." + pluginNameLow + "." + k.getKey())) { - pluginLines.add(tl("helpLine", k.getKey(), value.get(DESCRIPTION))); - } else if (permissions instanceof List && !((List) permissions).isEmpty()) { + + if (isOnWhitelist || user.isAuthorized("essentials.help." + pluginNameLow + "." + commandName)) { + pluginLines.add(tl("helpLine", commandName, commandDescription)); + } else if (permissions.length != 0) { boolean enabled = false; - for (final Object o : (List) permissions) { - if (o instanceof String && user.isAuthorized(o.toString())) { + + for (final String permission : permissions) { + if (user.isAuthorized(permission)) { enabled = true; break; } } + if (enabled) { - pluginLines.add(tl("helpLine", k.getKey(), value.get(DESCRIPTION))); - } - } else if (permissions instanceof String && !"".equals(permissions)) { - if (user.isAuthorized(permissions.toString())) { - pluginLines.add(tl("helpLine", k.getKey(), value.get(DESCRIPTION))); + pluginLines.add(tl("helpLine", commandName, commandDescription)); } } else { if (!ess.getSettings().hidePermissionlessHelp()) { - pluginLines.add(tl("helpLine", k.getKey(), value.get(DESCRIPTION))); + pluginLines.add(tl("helpLine", commandName, commandDescription)); } } } diff --git a/Essentials/src/com/earth2me/essentials/utils/VersionUtil.java b/Essentials/src/com/earth2me/essentials/utils/VersionUtil.java index 5bb44d4d3..9ffdb295c 100644 --- a/Essentials/src/com/earth2me/essentials/utils/VersionUtil.java +++ b/Essentials/src/com/earth2me/essentials/utils/VersionUtil.java @@ -3,6 +3,7 @@ package com.earth2me.essentials.utils; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; +import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; import java.util.Set; @@ -44,8 +45,22 @@ public final class VersionUtil { return serverVersion; } + public static SupportStatus getServerSupportStatus() { + try { + Class.forName("net.minecraftforge.common.MinecraftForge"); + return SupportStatus.UNSTABLE; + } catch (final ClassNotFoundException ignored) { + } + + if (!supportedVersions.contains(getServerBukkitVersion())) { + return SupportStatus.OUTDATED; + } + + return PaperLib.isPaper() ? SupportStatus.FULL : SupportStatus.LIMITED; + } + public static boolean isServerSupported() { - return supportedVersions.contains(getServerBukkitVersion()); + return getServerSupportStatus().isSupported(); } public static final class BukkitVersion implements Comparable { @@ -188,4 +203,22 @@ public final class VersionUtil { } } } + + public enum SupportStatus { + FULL(true), + LIMITED(true), + UNSTABLE(false), + OUTDATED(false) + ; + + private final boolean supported; + + SupportStatus(final boolean supported) { + this.supported = supported; + } + + public boolean isSupported() { + return supported; + } + } } diff --git a/Essentials/src/messages.properties b/Essentials/src/messages.properties index 802bf77b0..5a3828d8a 100644 --- a/Essentials/src/messages.properties +++ b/Essentials/src/messages.properties @@ -706,6 +706,8 @@ serverFull=Server is full\! serverReloading=There's a good chance you're reloading your server right now. If that's the case, why do you hate yourself? Expect no support from the EssentialsX team when using /reload. serverTotal=\u00a76Server Total\:\u00a7c {0} serverUnsupported=You are running an unsupported server version! +serverUnsupportedLimitedApi=You are running a server with limited API functionality. EssentialsX will still work, but certain features may be disabled. +serverUnsupportedMods=You are running a server that does not properly support Bukkit plugins. Bukkit plugins should not be used with Forge mods! Consider using ForgeEssentials, or SpongeForge + Nucleus. setBal=\u00a7aYour balance was set to {0}. setBalOthers=\u00a7aYou set {0}\u00a7a''s balance to {1}. setSpawner=\u00a76Changed spawner type to\u00a7c {0}\u00a76. diff --git a/Essentials/test/com/earth2me/essentials/FakeServer.java b/Essentials/test/com/earth2me/essentials/FakeServer.java new file mode 100644 index 000000000..59150ffcc --- /dev/null +++ b/Essentials/test/com/earth2me/essentials/FakeServer.java @@ -0,0 +1,1401 @@ +package com.earth2me.essentials; + +import com.earth2me.essentials.craftbukkit.FakeWorld; +import org.bukkit.BanList; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Keyed; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Server; +import org.bukkit.Statistic; +import org.bukkit.StructureType; +import org.bukkit.Tag; +import org.bukkit.UnsafeValues; +import org.bukkit.Warning.WarningState; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.WorldCreator; +import org.bukkit.advancement.Advancement; +import org.bukkit.block.data.BlockData; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarFlag; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.boss.KeyedBossBar; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.conversations.Conversation; +import org.bukkit.conversations.ConversationAbandonedEvent; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.help.HelpMap; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Merchant; +import org.bukkit.inventory.Recipe; +import org.bukkit.loot.LootTable; +import org.bukkit.map.MapView; +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginLoader; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.RegisteredListener; +import org.bukkit.plugin.ServicesManager; +import org.bukkit.plugin.UnknownDependencyException; +import org.bukkit.plugin.messaging.Messenger; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.scheduler.BukkitWorker; +import org.bukkit.scoreboard.ScoreboardManager; +import org.bukkit.util.CachedServerIcon; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.function.Consumer; +import java.util.logging.Logger; + +public class FakeServer implements Server { + private final List worlds = new ArrayList<>(); + private final PluginManager pluginManager = new FakePluginManager(); + private List players = new ArrayList<>(); + + FakeServer() { + if (Bukkit.getServer() == null) { + Bukkit.setServer(this); + } + } + + @Override + public String getName() { + return "Essentials Fake Server"; + } + + @Override + public String getVersion() { + return "1.0"; + } + + @Override + public Collection getOnlinePlayers() { + return players; + } + + public void setOnlinePlayers(final List players) { + this.players = players; + } + + @Override + public int getMaxPlayers() { + return 100; + } + + @Override + public int getPort() { + return 25565; + } + + @Override + public String getIp() { + return "127.0.0.1"; + } + + @Override + public int broadcastMessage(final String string) { + int i = 0; + for (final Player player : players) { + player.sendMessage(string); + i++; + } + return i; + } + + @Override + public String getUpdateFolder() { + return "update"; + } + + @Override + public File getUpdateFolderFile() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isHardcore() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Player getPlayer(final String string) { + for (final Player player : players) { + if (player.getName().equalsIgnoreCase(string)) { + return player; + } + } + return null; + } + + @Override + public List matchPlayer(final String string) { + final List matches = new ArrayList<>(); + for (final Player player : players) { + if (player.getName().substring(0, Math.min(player.getName().length(), string.length())).equalsIgnoreCase(string)) { + matches.add(player); + } + } + return matches; + } + + @Override + public PluginManager getPluginManager() { + return pluginManager; + } + + @Override + public BukkitScheduler getScheduler() { + return new BukkitScheduler() { + @Override + public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable r, final long l) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int scheduleSyncDelayedTask(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable r) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int scheduleSyncDelayedTask(final Plugin plugin, final BukkitRunnable bukkitRunnable) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int scheduleSyncRepeatingTask(final Plugin plugin, final Runnable r, final long l, final long l1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int scheduleSyncRepeatingTask(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l, final long l1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int scheduleAsyncRepeatingTask(final Plugin plugin, final Runnable r, final long l, final long l1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Future callSyncMethod(final Plugin plugin, final Callable clbl) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void cancelTask(final int i) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void cancelTasks(final Plugin plugin) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isCurrentlyRunning(final int i) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isQueued(final int i) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getActiveWorkers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getPendingTasks() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BukkitTask runTask(final Plugin plugin, final Runnable r) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void runTask(final Plugin plugin, final Consumer task) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BukkitTask runTask(final Plugin plugin, final BukkitRunnable bukkitRunnable) throws IllegalArgumentException { + return null; + } + + @Override + public BukkitTask runTaskAsynchronously(final Plugin plugin, final Runnable r) throws IllegalArgumentException { + r.run(); + return null; + } + + @Override + public void runTaskAsynchronously(final Plugin plugin, final Consumer task) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BukkitTask runTaskAsynchronously(final Plugin plugin, final BukkitRunnable bukkitRunnable) throws IllegalArgumentException { + return null; + } + + @Override + public BukkitTask runTaskLater(final Plugin plugin, final Runnable r, final long l) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void runTaskLater(final Plugin plugin, final Consumer task, final long delay) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BukkitTask runTaskLater(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l) throws IllegalArgumentException { + return null; + } + + @Override + public BukkitTask runTaskLaterAsynchronously(final Plugin plugin, final Runnable r, final long l) throws IllegalArgumentException { + r.run(); + return null; + } + + @Override + public void runTaskLaterAsynchronously(final Plugin plugin, final Consumer task, final long delay) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BukkitTask runTaskLaterAsynchronously(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l) throws IllegalArgumentException { + return null; + } + + @Override + public BukkitTask runTaskTimer(final Plugin plugin, final Runnable r, final long l, final long l1) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void runTaskTimer(final Plugin plugin, final Consumer task, final long delay, final long period) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BukkitTask runTaskTimer(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l, final long l1) throws IllegalArgumentException { + return null; + } + + @Override + public BukkitTask runTaskTimerAsynchronously(final Plugin plugin, final Runnable r, final long l, final long l1) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void runTaskTimerAsynchronously(final Plugin plugin, final Consumer task, final long delay, final long period) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BukkitTask runTaskTimerAsynchronously(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l, final long l1) throws IllegalArgumentException { + return null; + } + + @Override + public int scheduleAsyncDelayedTask(final Plugin plugin, final Runnable r, final long l) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int scheduleAsyncDelayedTask(final Plugin plugin, final Runnable r) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + } + + @Override + public ServicesManager getServicesManager() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getWorlds() { + return worlds; + } + + public World createWorld(final String string, final Environment e) { + final World w = new FakeWorld(string, e); + worlds.add(w); + return w; + } + + public World createWorld(final String string, final Environment e, final long l) { + final World w = new FakeWorld(string, e); + worlds.add(w); + return w; + } + + @Override + public World getWorld(final String string) { + for (final World world : worlds) { + if (world.getName().equalsIgnoreCase(string)) { + return world; + } + } + return null; + } + + @Override + public void reload() { + } + + @Override + public Logger getLogger() { + return Logger.getLogger("Minecraft"); + } + + @Override + public PluginCommand getPluginCommand(final String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void savePlayers() { + } + + @Override + public boolean dispatchCommand(final CommandSender cs, final String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean addRecipe(final Recipe recipe) { + throw new UnsupportedOperationException("Not supported yet."); + } + + void addPlayer(final Player base1) { + players.add(base1); + pluginManager.callEvent(new PlayerJoinEvent(base1, null)); + } + + OfflinePlayer createPlayer(final String name) { + final OfflinePlayer player = new OfflinePlayer(name, this); + player.setLocation(new Location(worlds.get(0), 0, 0, 0, 0, 0)); + return player; + } + + @Override + public World createWorld(final WorldCreator creator) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean unloadWorld(final String string, final boolean bln) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean unloadWorld(final World world, final boolean bln) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Map getCommandAliases() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getSpawnRadius() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setSpawnRadius(final int i) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getOnlineMode() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public World getWorld(final long l) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public World getWorld(final UUID uuid) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public MapView getMap(final int id) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getViewDistance() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getAllowNether() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean hasWhitelist() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public MapView createMap(final World world) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ItemStack createExplorerMap(final World world, final Location location, final StructureType structureType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ItemStack createExplorerMap(final World world, final Location location, final StructureType structureType, final int radius, final boolean findUnexplored) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getAllowFlight() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setWhitelist(final boolean bln) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getWhitelistedPlayers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void reloadWhitelist() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Player getPlayerExact(final String string) { + for (final Player player : players) { + if (player.getName().equals(string)) { + return player; + } + } + return null; + } + + @Override + public void shutdown() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int broadcast(final String string, final String string1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public org.bukkit.OfflinePlayer getOfflinePlayer(final String string) { + return createOPlayer(string); + } + + private org.bukkit.OfflinePlayer createOPlayer(final String string) { + return new org.bukkit.OfflinePlayer() { + @Override + public boolean isOnline() { + return false; + } + + @Override + public String getName() { + return string; + } + + @Override + public boolean isBanned() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isWhitelisted() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setWhitelisted(final boolean bln) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Player getPlayer() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isOp() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Map serialize() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public long getFirstPlayed() { + throw new UnsupportedOperationException("Not supported yet."); + } @Override + public void setOp(final boolean bln) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public long getLastPlayed() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean hasPlayedBefore() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Location getBedSpawnLocation() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public UUID getUniqueId() { + switch (string) { + case "testPlayer1": + return UUID.fromString("3c9ebe1a-9098-43fd-bc0c-a369b76817ba"); + case "testPlayer2": + return UUID.fromString("2c9ebe1a-9098-43fd-bc0c-a369b76817ba"); + case "npc1": + return null; + } + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void incrementStatistic(final Statistic statistic) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void decrementStatistic(final Statistic statistic) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getStatistic(final Statistic statistic) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void incrementStatistic(final Statistic statistic, final int amount) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void decrementStatistic(final Statistic statistic, final int amount) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setStatistic(final Statistic statistic, final int newValue) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void incrementStatistic(final Statistic statistic, final Material material) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void decrementStatistic(final Statistic statistic, final Material material) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getStatistic(final Statistic statistic, final Material material) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void incrementStatistic(final Statistic statistic, final Material material, final int amount) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void decrementStatistic(final Statistic statistic, final Material material, final int amount) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setStatistic(final Statistic statistic, final Material material, final int newValue) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void incrementStatistic(final Statistic statistic, final EntityType entityType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void decrementStatistic(final Statistic statistic, final EntityType entityType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getStatistic(final Statistic statistic, final EntityType entityType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void incrementStatistic(final Statistic statistic, final EntityType entityType, final int amount) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void decrementStatistic(final Statistic statistic, final EntityType entityType, final int amount) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setStatistic(final Statistic statistic, final EntityType entityType, final int newValue) { + throw new UnsupportedOperationException("Not supported yet."); + } + + + + }; + } + + @Override + public Set getIPBans() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void banIP(final String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void unbanIP(final String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getBannedPlayers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public GameMode getDefaultGameMode() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setDefaultGameMode(final GameMode gamemode) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ConsoleCommandSender getConsoleSender() { + return new ConsoleCommandSender() { + @Override + public void sendMessage(final String message) { + System.out.println("Console message: " + message); + } + + @Override + public void sendMessage(final String[] messages) { + for (final String message : messages) { + System.out.println("Console message: " + message); + } + } + + @Override + public void sendMessage(final UUID uuid, final String message) { + sendMessage(message); + } + + @Override + public void sendMessage(final UUID uuid, final String[] messages) { + sendMessage(messages); + } + + @Override + public Server getServer() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getName() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Spigot spigot() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isPermissionSet(final String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isPermissionSet(final Permission perm) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean hasPermission(final String name) { + return true; + } + + @Override + public boolean hasPermission(final Permission perm) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PermissionAttachment addAttachment(final Plugin plugin, final String name, final boolean value) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PermissionAttachment addAttachment(final Plugin plugin) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PermissionAttachment addAttachment(final Plugin plugin, final String name, final boolean value, final int ticks) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public PermissionAttachment addAttachment(final Plugin plugin, final int ticks) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removeAttachment(final PermissionAttachment attachment) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void recalculatePermissions() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getEffectivePermissions() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isOp() { + return true; + } + + @Override + public boolean isConversing() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void acceptConversationInput(final String input) { + throw new UnsupportedOperationException("Not supported yet."); + } @Override + public void setOp(final boolean value) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean beginConversation(final Conversation conversation) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void abandonConversation(final Conversation conversation) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void abandonConversation(final Conversation conversation, final ConversationAbandonedEvent details) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void sendRawMessage(final String message) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void sendRawMessage(final UUID uuid, final String s) { + + } + + }; + } + + @Override + public Set getOperators() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getBukkitVersion() { + return "Essentials Fake-Server"; + } + + @Override + public File getWorldContainer() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public OfflinePlayer[] getOfflinePlayers() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getAllowEnd() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Messenger getMessenger() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void sendPluginMessage(final Plugin plugin, final String string, final byte[] bytes) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getListeningPluginChannels() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getTicksPerAnimalSpawns() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getTicksPerMonsterSpawns() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getTicksPerWaterSpawns() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getTicksPerWaterAmbientSpawns() { + return 0; + } + + @Override + public int getTicksPerAmbientSpawns() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getRecipesFor(final ItemStack is) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Recipe getRecipe(final NamespacedKey namespacedKey) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Iterator recipeIterator() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void clearRecipes() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void resetRecipes() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean removeRecipe(final NamespacedKey key) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public HelpMap getHelpMap() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Inventory createInventory(final InventoryHolder ih, final InventoryType it) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Inventory createInventory(final InventoryHolder ih, final int i) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Inventory createInventory(final InventoryHolder ih, final int i, final String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Merchant createMerchant(final String s) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getWorldType() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean getGenerateStructures() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public long getConnectionThrottle() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getMonsterSpawnLimit() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getAnimalSpawnLimit() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getWaterAnimalSpawnLimit() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getWaterAmbientSpawnLimit() { + return 0; + } + + @Override + public boolean isPrimaryThread() { + return true; // Can be set to true or false, just needs to return for AFK status test to pass. + } + + @Override + public String getMotd() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public WarningState getWarningState() { + return WarningState.DEFAULT; + } + + @Override + public int getAmbientSpawnLimit() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public String getShutdownMessage() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ItemFactory getItemFactory() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ScoreboardManager getScoreboardManager() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CachedServerIcon getServerIcon() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CachedServerIcon loadServerIcon(final File file) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public CachedServerIcon loadServerIcon(final BufferedImage bufferedImage) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getIdleTimeout() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void setIdleTimeout(final int i) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public ChunkGenerator.ChunkData createChunkData(final World world) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BossBar createBossBar(final String s, final BarColor barColor, final BarStyle barStyle, final BarFlag... barFlags) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public KeyedBossBar createBossBar(final NamespacedKey key, final String title, final BarColor color, final BarStyle style, final BarFlag... flags) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Iterator getBossBars() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public KeyedBossBar getBossBar(final NamespacedKey key) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean removeBossBar(final NamespacedKey key) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + @SuppressWarnings("deprecation") + public UnsafeValues getUnsafe() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Spigot spigot() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BanList getBanList(final BanList.Type arg0) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Player getPlayer(final UUID arg0) { + for (final Player player : players) { + if (player.getUniqueId().equals(arg0)) { + return player; + } + } + return null; + } + + @Override + public org.bukkit.OfflinePlayer getOfflinePlayer(final UUID arg0) { + if (arg0.toString().equalsIgnoreCase("3c9ebe1a-9098-43fd-bc0c-a369b76817ba")) { + return createOPlayer("testPlayer1"); + } + if (arg0.toString().equalsIgnoreCase("f4a37409-5c40-3b2c-9cd6-57d3c5abdc76")) { + return createOPlayer("npc1"); + } + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Inventory createInventory(final InventoryHolder arg0, final InventoryType arg1, final String arg2) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void reloadData() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Entity getEntity(final UUID uuid) { + return getPlayer(uuid); + } + + @Override + public Advancement getAdvancement(final NamespacedKey key) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Iterator advancementIterator() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BlockData createBlockData(final Material material) { + return null; + } + + @Override + public BlockData createBlockData(final Material material, final Consumer consumer) { + return null; + } + + @Override + public BlockData createBlockData(final String data) throws IllegalArgumentException { + return null; + } + + @Override + public BlockData createBlockData(final Material material, final String data) throws IllegalArgumentException { + return null; + } + + @Override + public Tag getTag(final String s, final NamespacedKey namespacedKey, final Class aClass) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public Iterable> getTags(final String registry, final Class clazz) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public LootTable getLootTable(final NamespacedKey arg0) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List selectEntities(final CommandSender sender, final String selector) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + static class FakePluginManager implements PluginManager { + final ArrayList listeners = new ArrayList<>(); + + @Override + public void registerInterface(final Class loader) throws IllegalArgumentException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Plugin getPlugin(final String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Plugin[] getPlugins() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isPluginEnabled(final String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean isPluginEnabled(final Plugin plugin) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Plugin loadPlugin(final File file) throws UnknownDependencyException { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Plugin[] loadPlugins(final File directory) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void disablePlugins() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void clearPlugins() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void callEvent(final Event event) throws IllegalStateException { + Logger.getLogger("Minecraft").info("Called event " + event.getEventName()); + if (event instanceof PlayerJoinEvent) { + for (final RegisteredListener listener : listeners) { + if (listener.getListener() instanceof EssentialsPlayerListener) { + final PlayerJoinEvent jEvent = (PlayerJoinEvent) event; + final EssentialsPlayerListener epl = (EssentialsPlayerListener) listener.getListener(); + epl.onPlayerJoin(jEvent); + final Essentials ess = (Essentials) listener.getPlugin(); + ess.getLogger().info("Sending join event to Essentials"); + ess.getUser(jEvent.getPlayer()); + } + } + } + } + + @Override + public void registerEvents(final Listener listener, final Plugin plugin) { + listeners.add(new RegisteredListener(listener, null, null, plugin, false)); + } + + @Override + public void registerEvent(final Class event, final Listener listener, final EventPriority priority, final EventExecutor executor, final Plugin plugin) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void registerEvent(final Class event, final Listener listener, final EventPriority priority, final EventExecutor executor, final Plugin plugin, final boolean ignoreCancelled) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void enablePlugin(final Plugin plugin) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void disablePlugin(final Plugin plugin) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Permission getPermission(final String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addPermission(final Permission perm) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removePermission(final Permission perm) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void removePermission(final String name) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getDefaultPermissions(final boolean op) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void recalculatePermissionDefaults(final Permission perm) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void subscribeToPermission(final String permission, final Permissible permissible) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void unsubscribeFromPermission(final String permission, final Permissible permissible) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getPermissionSubscriptions(final String permission) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void subscribeToDefaultPerms(final boolean op, final Permissible permissible) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void unsubscribeFromDefaultPerms(final boolean op, final Permissible permissible) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getDefaultPermSubscriptions(final boolean op) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Set getPermissions() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean useTimings() { + throw new UnsupportedOperationException("Not supported yet."); + } + } + +} diff --git a/README.md b/README.md index 0bc1f572e..66f60c2c9 100644 --- a/README.md +++ b/README.md @@ -59,11 +59,11 @@ To depend on EssentialsX 2.18.1, you should use the artifact `net.ess3:Essential Contributing ------------ -Want to help improve EssentialsX? There are numerous ways you can contribute to the project. +Want to help improve EssentialsX? There are several ways you can support and contribute to the project. If you'd like to make a financial contribution to the project, you can join our [Patreon](https://www.patreon.com/essentialsx/), or to make a one-off donation you can visit our [Ko-fi page](https://ko-fi.com/essentialsx). If you can't make a -donation, don't worry! There's lots of other ways to contribute: +donation, don't worry! There are lots of other ways to contribute: * Do you run a server? Take a look at our ["help wanted"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22help+wanted%22) and ["bug: unconfirmed"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22bug%3A+unconfirmed%22) @@ -74,3 +74,5 @@ donation, don't worry! There's lots of other ways to contribute: other EssentialsX users. * If you're a developer, you could look through our ["open to PR"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22status%3A+open+to+PR%22) issues. We're always happy to receive bug fixes and feature additions as pull requests. + +See [CONTRIBUTING.md](https://github.com/EssentialsX/Essentials/blob/2.x/CONTRIBUTING.md) to find out more. diff --git a/pom.xml b/pom.xml index 9e5253569..ee6418d76 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ junit junit - 4.12 + 4.13.1 test diff --git a/providers/BaseProviders/src/net/ess3/provider/KnownCommandsProvider.java b/providers/BaseProviders/src/net/ess3/provider/KnownCommandsProvider.java new file mode 100644 index 000000000..952db7136 --- /dev/null +++ b/providers/BaseProviders/src/net/ess3/provider/KnownCommandsProvider.java @@ -0,0 +1,9 @@ +package net.ess3.provider; + +import org.bukkit.command.Command; + +import java.util.Map; + +public interface KnownCommandsProvider extends Provider { + Map getKnownCommands(); +} diff --git a/providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflKnownCommandsProvider.java b/providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflKnownCommandsProvider.java new file mode 100644 index 000000000..19c558d56 --- /dev/null +++ b/providers/NMSReflectionProvider/src/net/ess3/nms/refl/providers/ReflKnownCommandsProvider.java @@ -0,0 +1,48 @@ +package net.ess3.nms.refl.providers; + +import net.ess3.nms.refl.ReflUtil; +import net.ess3.provider.KnownCommandsProvider; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.Command; +import org.bukkit.command.SimpleCommandMap; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +public class ReflKnownCommandsProvider implements KnownCommandsProvider { + private final Map knownCommands; + + public ReflKnownCommandsProvider() { + Map knownCommands = new HashMap<>(); + try { + @SuppressWarnings("unchecked") + final Class craftServerClass = (Class) ReflUtil.getOBCClass("CraftServer"); + if (craftServerClass != null) { + final Field commandMapField = ReflUtil.getFieldCached(craftServerClass, "commandMap"); + if (commandMapField != null) { + final SimpleCommandMap simpleCommandMap = (SimpleCommandMap) commandMapField.get(Bukkit.getServer()); + final Field knownCommandsField = ReflUtil.getFieldCached(SimpleCommandMap.class, "knownCommands"); + if (knownCommandsField != null) { + knownCommands = (Map) knownCommandsField.get(simpleCommandMap); + } + } + } + } catch (final Exception exception) { + exception.printStackTrace(); + } finally { + this.knownCommands = knownCommands; + } + } + + @Override + public Map getKnownCommands() { + return this.knownCommands; + } + + @Override + public String getDescription() { + return "NMS Reflection Known Commands Provider"; + } +} diff --git a/providers/PaperProvider/src/net/ess3/provider/providers/PaperKnownCommandsProvider.java b/providers/PaperProvider/src/net/ess3/provider/providers/PaperKnownCommandsProvider.java new file mode 100644 index 000000000..b1666962b --- /dev/null +++ b/providers/PaperProvider/src/net/ess3/provider/providers/PaperKnownCommandsProvider.java @@ -0,0 +1,19 @@ +package net.ess3.provider.providers; + +import net.ess3.provider.KnownCommandsProvider; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; + +import java.util.Map; + +public class PaperKnownCommandsProvider implements KnownCommandsProvider { + @Override + public Map getKnownCommands() { + return Bukkit.getCommandMap().getKnownCommands(); + } + + @Override + public String getDescription() { + return "Paper Known Commands Provider"; + } +}