mirror of
https://github.com/Dreeam-qwq/Gale.git
synced 2025-12-19 14:59:29 +00:00
473 lines
19 KiB
Diff
473 lines
19 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Martijn Muijsers <martijnmuijsers@live.nl>
|
|
Date: Sat, 26 Nov 2022 10:47:56 +0100
|
|
Subject: [PATCH] Gale commands
|
|
|
|
License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
|
Gale - https://galemc.org
|
|
|
|
This patch is based on the following patch:
|
|
"Paper command"
|
|
By: Zach Brown <zach.brown@destroystokyo.com>
|
|
As part of: Paper (https://github.com/PaperMC/Paper)
|
|
Licensed under: MIT (https://opensource.org/licenses/MIT)
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
index a250a1a4e68eb5971cc09b6b2cf2d0576cb7ba64..5ae5eba9b42b3a5adbad4896e692be0b7338ebaa 100644
|
|
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
@@ -45,6 +45,7 @@ import net.minecraft.world.level.GameRules;
|
|
import net.minecraft.world.level.GameType;
|
|
import net.minecraft.world.level.block.entity.SkullBlockEntity;
|
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
|
+import org.galemc.gale.command.GaleCommands;
|
|
import org.slf4j.Logger;
|
|
|
|
// CraftBukkit start
|
|
@@ -216,6 +217,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash);
|
|
thread.start(); // Paper - start console thread after MinecraftServer.console & PaperConfig are initialized
|
|
io.papermc.paper.command.PaperCommands.registerCommands(this);
|
|
+ GaleCommands.registerCommands(this); // Gale - Gale commands - register commands
|
|
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics();
|
|
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
|
|
io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider
|
|
diff --git a/src/main/java/org/galemc/gale/command/GaleCommand.java b/src/main/java/org/galemc/gale/command/GaleCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..87d3aed35341dfa9358af064dd54d7de95078269
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/galemc/gale/command/GaleCommand.java
|
|
@@ -0,0 +1,179 @@
|
|
+// Gale - Gale commands - /gale command
|
|
+
|
|
+package org.galemc.gale.command;
|
|
+
|
|
+import io.papermc.paper.command.CommandUtil;
|
|
+import it.unimi.dsi.fastutil.Pair;
|
|
+import net.minecraft.Util;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.Location;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.bukkit.permissions.Permission;
|
|
+import org.bukkit.permissions.PermissionDefault;
|
|
+import org.bukkit.plugin.PluginManager;
|
|
+import org.galemc.gale.command.subcommands.InfoCommand;
|
|
+import org.galemc.gale.command.subcommands.ReloadCommand;
|
|
+import org.galemc.gale.command.subcommands.VersionCommand;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
+
|
|
+import java.util.ArrayList;
|
|
+import java.util.Arrays;
|
|
+import java.util.Collection;
|
|
+import java.util.Collections;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Locale;
|
|
+import java.util.Map;
|
|
+import java.util.Objects;
|
|
+import java.util.Set;
|
|
+import java.util.stream.Collectors;
|
|
+
|
|
+import static net.kyori.adventure.text.Component.newline;
|
|
+import static net.kyori.adventure.text.Component.text;
|
|
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
|
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
|
|
+
|
|
+public final class GaleCommand extends Command {
|
|
+ public static final String COMMAND_LABEL = "gale";
|
|
+ public static final String BASE_PERM = GaleCommands.COMMAND_BASE_PERM + "." + COMMAND_LABEL;
|
|
+ private static final Permission basePermission = new Permission(BASE_PERM, PermissionDefault.TRUE);
|
|
+ // subcommand label -> subcommand
|
|
+ private static final GaleSubcommand RELOAD_SUBCOMMAND = new ReloadCommand();
|
|
+ private static final GaleSubcommand VERSION_SUBCOMMAND = new VersionCommand();
|
|
+ private static final GaleSubcommand INFO_SUBCOMMAND = new InfoCommand();
|
|
+ private static final Map<String, GaleSubcommand> SUBCOMMANDS = Util.make(() -> {
|
|
+ final Map<Set<String>, GaleSubcommand> commands = new HashMap<>();
|
|
+
|
|
+ commands.put(Set.of(ReloadCommand.LITERAL_ARGUMENT), RELOAD_SUBCOMMAND);
|
|
+ commands.put(Set.of(VersionCommand.LITERAL_ARGUMENT), VERSION_SUBCOMMAND);
|
|
+ commands.put(Set.of(InfoCommand.LITERAL_ARGUMENT), INFO_SUBCOMMAND);
|
|
+
|
|
+ return commands.entrySet().stream()
|
|
+ .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
|
|
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
|
+ });
|
|
+ // alias -> subcommand label
|
|
+ private static final Map<String, String> ALIASES = Util.make(() -> {
|
|
+ final Map<String, Set<String>> aliases = new HashMap<>();
|
|
+
|
|
+ aliases.put(VersionCommand.LITERAL_ARGUMENT, Set.of("ver"));
|
|
+ aliases.put(InfoCommand.LITERAL_ARGUMENT, Set.of("about"));
|
|
+
|
|
+ return aliases.entrySet().stream()
|
|
+ .flatMap(entry -> entry.getValue().stream().map(s -> Map.entry(s, entry.getKey())))
|
|
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
|
+ });
|
|
+
|
|
+ private String createUsageMessage(Collection<String> arguments) {
|
|
+ return "/" + COMMAND_LABEL + " [" + String.join(" | ", arguments) + "]";
|
|
+ }
|
|
+
|
|
+ public GaleCommand() {
|
|
+ super(COMMAND_LABEL);
|
|
+ this.description = "Gale related commands";
|
|
+ this.usageMessage = this.createUsageMessage(SUBCOMMANDS.keySet());
|
|
+ final List<Permission> permissions = SUBCOMMANDS.values().stream().map(GaleSubcommand::getPermission).filter(Objects::nonNull).toList();
|
|
+ this.setPermission(BASE_PERM);
|
|
+ final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
|
+ pluginManager.addPermission(basePermission);
|
|
+ for (final Permission permission : permissions) {
|
|
+ pluginManager.addPermission(permission);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<String> tabComplete(
|
|
+ final CommandSender sender,
|
|
+ final String alias,
|
|
+ final String[] args,
|
|
+ final @Nullable Location location
|
|
+ ) throws IllegalArgumentException {
|
|
+ if (args.length <= 1) {
|
|
+ List<String> subCommandArguments = new ArrayList<>(SUBCOMMANDS.size());
|
|
+ for (Map.Entry<String, GaleSubcommand> subCommandEntry : SUBCOMMANDS.entrySet()) {
|
|
+ if (subCommandEntry.getValue().testPermission(sender)) {
|
|
+ subCommandArguments.add(subCommandEntry.getKey());
|
|
+ }
|
|
+ }
|
|
+ return CommandUtil.getListMatchingLast(sender, args, subCommandArguments);
|
|
+ }
|
|
+
|
|
+ final @Nullable Pair<String, GaleSubcommand> subCommand = resolveCommand(args[0]);
|
|
+ if (subCommand != null && subCommand.second().testPermission(sender)) {
|
|
+ return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length));
|
|
+ }
|
|
+
|
|
+ return Collections.emptyList();
|
|
+ }
|
|
+
|
|
+ private boolean testHasOnePermission(CommandSender sender) {
|
|
+ for (Map.Entry<String, GaleSubcommand> subCommandEntry : SUBCOMMANDS.entrySet()) {
|
|
+ if (subCommandEntry.getValue().testPermission(sender)) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(
|
|
+ final CommandSender sender,
|
|
+ final String commandLabel,
|
|
+ final String[] args
|
|
+ ) {
|
|
+
|
|
+ // Check if the sender has the base permission and at least one specific permission
|
|
+ if (!sender.hasPermission(basePermission) || !this.testHasOnePermission(sender)) {
|
|
+ sender.sendMessage(Bukkit.permissionMessage());
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ // Determine the usage message with the subcommands they can perform
|
|
+ List<String> subCommandArguments = new ArrayList<>(SUBCOMMANDS.size());
|
|
+ for (Map.Entry<String, GaleSubcommand> subCommandEntry : SUBCOMMANDS.entrySet()) {
|
|
+ if (subCommandEntry.getValue().testPermission(sender)) {
|
|
+ subCommandArguments.add(subCommandEntry.getKey());
|
|
+ }
|
|
+ }
|
|
+ String specificUsageMessage = this.createUsageMessage(subCommandArguments);
|
|
+
|
|
+ // If they did not give a subcommand
|
|
+ if (args.length == 0) {
|
|
+ INFO_SUBCOMMAND.execute(sender, InfoCommand.LITERAL_ARGUMENT, new String[0]);
|
|
+ sender.sendMessage(newline().append(text("Command usage: " + specificUsageMessage, GRAY)));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // If they do not have permission for the subcommand they gave, or the argument is not a valid subcommand
|
|
+ final @Nullable Pair<String, GaleSubcommand> subCommand = resolveCommand(args[0]);
|
|
+ if (subCommand == null || !subCommand.second().testPermission(sender)) {
|
|
+ sender.sendMessage(text("Usage: " + specificUsageMessage, RED));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Execute the subcommand
|
|
+ final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length);
|
|
+ return subCommand.second().execute(sender, subCommand.first(), choppedArgs);
|
|
+
|
|
+ }
|
|
+
|
|
+ private static @Nullable Pair<String, GaleSubcommand> resolveCommand(String label) {
|
|
+ label = label.toLowerCase(Locale.ENGLISH);
|
|
+ @Nullable GaleSubcommand subCommand = SUBCOMMANDS.get(label);
|
|
+ if (subCommand == null) {
|
|
+ final @Nullable String command = ALIASES.get(label);
|
|
+ if (command != null) {
|
|
+ label = command;
|
|
+ subCommand = SUBCOMMANDS.get(command);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (subCommand != null) {
|
|
+ return Pair.of(label, subCommand);
|
|
+ }
|
|
+
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/org/galemc/gale/command/GaleCommands.java b/src/main/java/org/galemc/gale/command/GaleCommands.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..b729f2c778e6158f1cb3aecc7f0ed0a746ff6339
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/galemc/gale/command/GaleCommands.java
|
|
@@ -0,0 +1,31 @@
|
|
+// Gale - Gale commands
|
|
+
|
|
+package org.galemc.gale.command;
|
|
+
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.craftbukkit.util.permissions.CraftDefaultPermissions;
|
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
|
+
|
|
+import java.util.HashMap;
|
|
+import java.util.Map;
|
|
+
|
|
+@DefaultQualifier(NonNull.class)
|
|
+public final class GaleCommands {
|
|
+
|
|
+ public static final String COMMAND_BASE_PERM = CraftDefaultPermissions.GALE_ROOT + ".command";
|
|
+
|
|
+ private GaleCommands() {}
|
|
+
|
|
+ private static final Map<String, Command> COMMANDS = new HashMap<>();
|
|
+ static {
|
|
+ COMMANDS.put(GaleCommand.COMMAND_LABEL, new GaleCommand());
|
|
+ }
|
|
+
|
|
+ public static void registerCommands(final MinecraftServer server) {
|
|
+ COMMANDS.forEach((s, command) -> {
|
|
+ server.server.getCommandMap().register(s, "Gale", command);
|
|
+ });
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/org/galemc/gale/command/GaleSubcommand.java b/src/main/java/org/galemc/gale/command/GaleSubcommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..7bcf875f91f5018daa06ef3280c4cdd7e8df4fd5
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/galemc/gale/command/GaleSubcommand.java
|
|
@@ -0,0 +1,27 @@
|
|
+// Gale - Gale commands
|
|
+
|
|
+package org.galemc.gale.command;
|
|
+
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.bukkit.permissions.Permission;
|
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
+
|
|
+import java.util.Collections;
|
|
+import java.util.List;
|
|
+
|
|
+@DefaultQualifier(NonNull.class)
|
|
+public interface GaleSubcommand {
|
|
+
|
|
+ boolean execute(CommandSender sender, String subCommand, String[] args);
|
|
+
|
|
+ default List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
|
+ return Collections.emptyList();
|
|
+ }
|
|
+
|
|
+ boolean testPermission(CommandSender sender);
|
|
+
|
|
+ @Nullable Permission getPermission();
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/org/galemc/gale/command/PermissionedGaleSubcommand.java b/src/main/java/org/galemc/gale/command/PermissionedGaleSubcommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..35ffa5f1bb682ac962ab9466e682a461efa65e7b
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/galemc/gale/command/PermissionedGaleSubcommand.java
|
|
@@ -0,0 +1,32 @@
|
|
+// Gale - Gale commands
|
|
+
|
|
+package org.galemc.gale.command;
|
|
+
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.bukkit.permissions.Permission;
|
|
+import org.bukkit.permissions.PermissionDefault;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
+
|
|
+public abstract class PermissionedGaleSubcommand implements GaleSubcommand {
|
|
+
|
|
+ public final Permission permission;
|
|
+
|
|
+ protected PermissionedGaleSubcommand(Permission permission) {
|
|
+ this.permission = permission;
|
|
+ }
|
|
+
|
|
+ protected PermissionedGaleSubcommand(String permission, PermissionDefault permissionDefault) {
|
|
+ this(new Permission(permission, permissionDefault));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean testPermission(CommandSender sender) {
|
|
+ return sender.hasPermission(this.permission);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @Nullable Permission getPermission() {
|
|
+ return this.permission;
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/org/galemc/gale/command/subcommands/InfoCommand.java b/src/main/java/org/galemc/gale/command/subcommands/InfoCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..a781afaf6821a4b7bd770b33eaf65527bfbed04e
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/galemc/gale/command/subcommands/InfoCommand.java
|
|
@@ -0,0 +1,42 @@
|
|
+// Gale - Gale commands - /gale info command
|
|
+
|
|
+package org.galemc.gale.command.subcommands;
|
|
+
|
|
+import net.kyori.adventure.text.event.ClickEvent;
|
|
+import net.kyori.adventure.text.format.TextDecoration;
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.bukkit.permissions.Permission;
|
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
|
+import org.galemc.gale.command.GaleSubcommand;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
+
|
|
+import static net.kyori.adventure.text.Component.text;
|
|
+
|
|
+@DefaultQualifier(NonNull.class)
|
|
+public final class InfoCommand implements GaleSubcommand {
|
|
+
|
|
+ public final static String LITERAL_ARGUMENT = "info";
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
|
+ sender.sendMessage(
|
|
+ text("Gale is a performant Minecraft server system. Find us on: ")
|
|
+ .append(text("https://github.com/GaleMC/Gale")
|
|
+ .decorate(TextDecoration.UNDERLINED)
|
|
+ .clickEvent(ClickEvent.openUrl("https://github.com/GaleMC/Gale")))
|
|
+ );
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean testPermission(CommandSender sender) {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public @Nullable Permission getPermission() {
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/org/galemc/gale/command/subcommands/ReloadCommand.java b/src/main/java/org/galemc/gale/command/subcommands/ReloadCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..c6ca5d3cf7e709f59f68ccd28db378e9e6303fdd
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/galemc/gale/command/subcommands/ReloadCommand.java
|
|
@@ -0,0 +1,46 @@
|
|
+// Gale - Gale commands - /gale reload command
|
|
+
|
|
+package org.galemc.gale.command.subcommands;
|
|
+
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.bukkit.craftbukkit.CraftServer;
|
|
+import org.bukkit.permissions.PermissionDefault;
|
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
|
+import org.galemc.gale.command.GaleCommand;
|
|
+import org.galemc.gale.command.PermissionedGaleSubcommand;
|
|
+
|
|
+import static net.kyori.adventure.text.Component.text;
|
|
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
|
|
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
|
+
|
|
+@DefaultQualifier(NonNull.class)
|
|
+public final class ReloadCommand extends PermissionedGaleSubcommand {
|
|
+
|
|
+ public final static String LITERAL_ARGUMENT = "reload";
|
|
+ public static final String PERM = GaleCommand.BASE_PERM + "." + LITERAL_ARGUMENT;
|
|
+
|
|
+ public ReloadCommand() {
|
|
+ super(PERM, PermissionDefault.OP);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
|
+ this.doReload(sender);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ private void doReload(final CommandSender sender) {
|
|
+ Command.broadcastCommandMessage(sender, text("Please note that this command is not supported and may cause issues.", RED));
|
|
+ Command.broadcastCommandMessage(sender, text("If you encounter any issues please use the /stop command to restart your server.", RED));
|
|
+
|
|
+ MinecraftServer server = ((CraftServer) sender.getServer()).getServer();
|
|
+ server.galeConfigurations.reloadConfigs(server);
|
|
+ server.server.reloadCount++;
|
|
+
|
|
+ Command.broadcastCommandMessage(sender, text("Gale config reload complete.", GREEN));
|
|
+ }
|
|
+
|
|
+}
|
|
diff --git a/src/main/java/org/galemc/gale/command/subcommands/VersionCommand.java b/src/main/java/org/galemc/gale/command/subcommands/VersionCommand.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..675cd4295dabfade1b9cc5473010b5b20dc32039
|
|
--- /dev/null
|
|
+++ b/src/main/java/org/galemc/gale/command/subcommands/VersionCommand.java
|
|
@@ -0,0 +1,39 @@
|
|
+// Gale - Gale commands - /gale version command
|
|
+
|
|
+package org.galemc.gale.command.subcommands;
|
|
+
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import org.bukkit.command.Command;
|
|
+import org.bukkit.command.CommandSender;
|
|
+import org.bukkit.permissions.PermissionDefault;
|
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
|
+import org.checkerframework.checker.nullness.qual.Nullable;
|
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
|
+import org.galemc.gale.command.GaleCommand;
|
|
+import org.galemc.gale.command.PermissionedGaleSubcommand;
|
|
+
|
|
+@DefaultQualifier(NonNull.class)
|
|
+public final class VersionCommand extends PermissionedGaleSubcommand {
|
|
+
|
|
+ public final static String LITERAL_ARGUMENT = "version";
|
|
+ public static final String PERM = GaleCommand.BASE_PERM + "." + LITERAL_ARGUMENT;
|
|
+
|
|
+ public VersionCommand() {
|
|
+ super(PERM, PermissionDefault.TRUE);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
|
+ final @Nullable Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version");
|
|
+ if (ver != null) {
|
|
+ ver.execute(sender, GaleCommand.COMMAND_LABEL, new String[0]);
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean testPermission(CommandSender sender) {
|
|
+ return super.testPermission(sender) && sender.hasPermission("bukkit.command.version");
|
|
+ }
|
|
+
|
|
+}
|