From 5e7229ce35adb0a0ace0d58056c74cbb2e708899 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 29 May 2022 19:26:34 +0200 Subject: [PATCH] Replaces all old functionality with a config command --- README.md | 35 +- pom.xml | 62 +++ src/config.yml | 0 .../stargatecommand/StargateCommand.java | 42 ++ .../command/CommandConfig.java | 241 ++++++++++ .../command/CommandStarGateCommand.java | 33 ++ .../command/ConfigTabCompleter.java | 156 +++++++ .../command/StargateCommandTabCompleter.java | 50 +++ .../TheDgtl/StargateCommand/SGCListener.java | 131 ------ .../TheDgtl/StargateCommand/SGCPlayer.java | 25 -- .../StargateCommand/StargateCommand.java | 410 ------------------ src/plugin.yml | 43 +- 12 files changed, 602 insertions(+), 626 deletions(-) create mode 100644 pom.xml delete mode 100644 src/config.yml create mode 100644 src/main/java/net/knarcraft/stargatecommand/StargateCommand.java create mode 100644 src/main/java/net/knarcraft/stargatecommand/command/CommandConfig.java create mode 100644 src/main/java/net/knarcraft/stargatecommand/command/CommandStarGateCommand.java create mode 100644 src/main/java/net/knarcraft/stargatecommand/command/ConfigTabCompleter.java create mode 100644 src/main/java/net/knarcraft/stargatecommand/command/StargateCommandTabCompleter.java delete mode 100644 src/net/TheDgtl/StargateCommand/SGCListener.java delete mode 100644 src/net/TheDgtl/StargateCommand/SGCPlayer.java delete mode 100644 src/net/TheDgtl/StargateCommand/StargateCommand.java diff --git a/README.md b/README.md index cbd62fd..bdc304e 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,24 @@ -> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-> THIS ADDON IS A **WORK IN PROGRESS**.
DO __**NOT**__ USE IT ON PRODUCTION INSTANCES

-> No stable releases are available at this time.
-> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- - > Please visit [our discord](https://discord.gg/mTaHuK6BVa) for all updates and support! # Description -StargateCommand is an addon for Stargate that allows users to interact with Stargate with commands. +Stargate-Command is an addon for Stargate which adds additional useful commands to the vanilla Stargate experience. #### Features: -[Still being determined](https://github.com/stargate-rewritten/SG-Command/issues) -- sg dial - - Specifies your destination for networked gates. -- sg visualiser - - Maps a network in a text-based tree format or possibly a gui -- sg config - - Modify various config values in-game -- sg api - - Perform a function from the stargate API in-game. +* The ability to edit the config file through commands, and automated reloading of changed values ## Dependencies -[The most recent version of Stargate](https://www.spigotmc.org/resources/stargate.87978/) +[The most recent version of Stargate (> 1.0.0.4)](https://www.spigotmc.org/resources/stargate.87978/) # Permissions ### Nodes ``` -sg.command.node [NOT IMPLEMENTED - sg.command.node.subnode +stargate.command.config - Gives access to the `/sgc config` command ``` -### Defaults -``` -sg.command.node -- OP -``` - -## Instructions -Not yet available. - -## Configuration -Not yet available. # Changes +[Version 0.1.0] +- Full takeover removing old functionality, and, for now, replacing it with config editing [Version 0.0.4] - Fix for Bukkit's direction fix [Version 0.0.3] diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..66bc8f6 --- /dev/null +++ b/pom.xml @@ -0,0 +1,62 @@ + + 4.0.0 + + net.knarcraft + StargateCommand + 0.1.0 + + + + GNU Lesser General Public License + https://www.gnu.org/licenses/lgpl-3.0.en.html + + + + + UTF-8 + 17 + 17 + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + + + + org.spigotmc + spigot-api + 1.18.2-R0.1-SNAPSHOT + + + org.jetbrains + annotations + RELEASE + compile + + + net.TheDgtl + Stargate + 1.0.0.4-ALPHA + + + + + src/main/java + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 17 + 17 + + + + + \ No newline at end of file diff --git a/src/config.yml b/src/config.yml deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/net/knarcraft/stargatecommand/StargateCommand.java b/src/main/java/net/knarcraft/stargatecommand/StargateCommand.java new file mode 100644 index 0000000..b7c4c99 --- /dev/null +++ b/src/main/java/net/knarcraft/stargatecommand/StargateCommand.java @@ -0,0 +1,42 @@ +package net.knarcraft.stargatecommand; + +import net.TheDgtl.Stargate.api.StargateAPI; +import net.knarcraft.stargatecommand.command.CommandStarGateCommand; +import net.knarcraft.stargatecommand.command.StargateCommandTabCompleter; +import org.bukkit.command.PluginCommand; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicesManager; +import org.bukkit.plugin.java.JavaPlugin; + +/** + * The main class for the Stargate-Command add-on + */ +@SuppressWarnings("unused") +public class StargateCommand extends JavaPlugin { + + @Override + public void onEnable() { + //Get the Stargate API + ServicesManager servicesManager = this.getServer().getServicesManager(); + RegisteredServiceProvider stargateProvider = servicesManager.getRegistration(StargateAPI.class); + if (stargateProvider != null) { + StargateAPI stargateAPI = stargateProvider.getProvider(); + + //Register commands + PluginCommand stargateCommand = this.getCommand("stargatecommand"); + if (stargateCommand != null) { + stargateCommand.setExecutor(new CommandStarGateCommand(stargateAPI)); + stargateCommand.setTabCompleter(new StargateCommandTabCompleter()); + } + } else { + throw new IllegalStateException("Unable to hook into Stargate. Make sure the Stargate plugin is installed " + + "and enabled."); + } + } + + @Override + public void onDisable() { + //Currently, nothing needs to be disabled + } + +} diff --git a/src/main/java/net/knarcraft/stargatecommand/command/CommandConfig.java b/src/main/java/net/knarcraft/stargatecommand/command/CommandConfig.java new file mode 100644 index 0000000..a6472c5 --- /dev/null +++ b/src/main/java/net/knarcraft/stargatecommand/command/CommandConfig.java @@ -0,0 +1,241 @@ +package net.knarcraft.stargatecommand.command; + +import net.TheDgtl.Stargate.config.ConfigurationAPI; +import net.TheDgtl.Stargate.config.ConfigurationOption; +import net.TheDgtl.Stargate.config.OptionDataType; +import net.md_5.bungee.api.ChatColor; +import org.apache.commons.lang.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +/** + * This command represents the config command for changing config values + */ +public class CommandConfig implements CommandExecutor { + + private final ConfigurationAPI configurationAPI; + + /** + * Instantiates a new instance of the config command + * + * @param configurationAPI

A reference to the Stargate API

+ */ + public CommandConfig(ConfigurationAPI configurationAPI) { + super(); + + this.configurationAPI = configurationAPI; + } + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] args) { + if (commandSender instanceof Player player) { + if (!player.hasPermission("stargate.command.config")) { + player.sendMessage("Permission Denied"); + return true; + } + } + + if (args.length > 0) { + ConfigurationOption selectedOption; + try { + selectedOption = ConfigurationOption.valueOf(args[0].toUpperCase()); + } catch (IllegalArgumentException exception) { + commandSender.sendMessage("Invalid configuration option specified"); + return true; + } + if (args.length > 1) { + updateConfigValue(selectedOption, commandSender, args[1]); + } else { + //Display info and the current value of the given config value + printConfigOptionValue(commandSender, selectedOption); + } + return true; + } else { + //Display all config options + displayConfigValues(commandSender); + } + return true; + } + + /** + * Updates a config value + * + * @param selectedOption

The option which should be updated

+ * @param commandSender

The command sender that changed the value

+ * @param value

The new value of the config option

+ */ + private void updateConfigValue(ConfigurationOption selectedOption, CommandSender commandSender, String value) { + //Validate any sign colors + if (selectedOption.getDataType() == OptionDataType.COLOR) { + try { + ChatColor.of(value.toUpperCase()); + } catch (IllegalArgumentException | NullPointerException ignored) { + commandSender.sendMessage(ChatColor.RED + "Invalid color given"); + return; + } + } + OptionDataType optionDataType = selectedOption.getDataType(); + + //Validate the input based on the data type + switch (optionDataType) { + case INTEGER -> { + if (getInteger(commandSender, selectedOption, value) == null) { + return; + } + } + case DOUBLE -> { + if (getDouble(commandSender, selectedOption, value) == null) { + return; + } + } + } + + /* Test any option data type with a defined set of values. + * Color is excluded as it has a near-infinite number of valid values. */ + if (optionDataType != OptionDataType.COLOR && optionDataType.getValues() != null && + optionDataType.getValues().length > 0) { + if (!checkIfValueMatchesDatatype(optionDataType, value, commandSender)) { + return; + } + } + + configurationAPI.setConfigurationOptionValue(selectedOption, value); + saveAndReload(commandSender); + } + + /** + * Checks if the given value is valid for the given option data type and warns if it isn't + * + * @param dataType

The expected type for the value

+ * @param value

The value to check

+ * @param commandSender

The command sender to warn about invalid values

+ * @return

True if the given value is valid for the option data type

+ */ + private boolean checkIfValueMatchesDatatype(OptionDataType dataType, String value, CommandSender commandSender) { + if (!matchesOptionDataType(dataType, value)) { + commandSender.sendMessage(String.format("Invalid %s given", + dataType.name().toLowerCase().replace('_', ' '))); + return false; + } else { + return true; + } + } + + /** + * Checks if the given value is valid for the given option data type + * + * @param dataType

The expected type for the value

+ * @param value

The value to check

+ * @return

True if the given value is valid for the option data type

+ */ + private boolean matchesOptionDataType(OptionDataType dataType, String value) { + return Arrays.asList(dataType.getValues()).contains(value); + } + + /** + * Saves the configuration file and reloads + * + * @param commandSender

The command sender that executed the config command

+ */ + private void saveAndReload(CommandSender commandSender) { + configurationAPI.saveConfiguration(); + configurationAPI.reload(); + commandSender.sendMessage("Config updated"); + } + + /** + * Gets an integer from a string + * + * @param commandSender

The command sender that sent the config command

+ * @param selectedOption

The option the command sender is trying to change

+ * @param value

The value given

+ * @return

An integer, or null if it was invalid

+ */ + private Integer getInteger(CommandSender commandSender, ConfigurationOption selectedOption, String value) { + try { + int intValue = Integer.parseInt(value); + + if ((selectedOption == ConfigurationOption.USE_COST || selectedOption == ConfigurationOption.CREATION_COST) && intValue < 0) { + commandSender.sendMessage(ChatColor.RED + "This config option cannot be negative."); + return null; + } + + return intValue; + } catch (NumberFormatException exception) { + commandSender.sendMessage(ChatColor.RED + "Invalid number given"); + return null; + } + } + + /** + * Gets a double from a string + * + * @param commandSender

The command sender that sent the config command

+ * @param selectedOption

The option the command sender is trying to change

+ * @param value

The value given

+ * @return

A double, or null if it was invalid

+ */ + private Double getDouble(CommandSender commandSender, ConfigurationOption selectedOption, String value) { + try { + double doubleValue = Double.parseDouble(value); + + if (selectedOption == ConfigurationOption.GATE_EXIT_SPEED_MULTIPLIER && doubleValue < 0) { + commandSender.sendMessage(ChatColor.RED + "This config option cannot be negative."); + return null; + } + + return doubleValue; + } catch (NumberFormatException exception) { + commandSender.sendMessage(ChatColor.RED + "Invalid number given"); + return null; + } + } + + /** + * Prints information about a config option and its current value + * + * @param sender

The command sender that sent the command

+ * @param option

The config option to print information about

+ */ + private void printConfigOptionValue(CommandSender sender, ConfigurationOption option) { + Object value = configurationAPI.getConfigurationOptionValue(option); + sender.sendMessage(getOptionDescription(option)); + sender.sendMessage(ChatColor.GREEN + "Current value: " + ChatColor.GOLD + value); + } + + /** + * Displays the name and a small description of every config value + * + * @param sender

The command sender to display the config list to

+ */ + private void displayConfigValues(CommandSender sender) { + sender.sendMessage(ChatColor.GREEN + "Stargate" + ChatColor.GOLD + "Config values:"); + + for (ConfigurationOption option : ConfigurationOption.values()) { + sender.sendMessage(getOptionDescription(option)); + } + } + + /** + * Gets the description of a single config option + * + * @param option

The option to describe

+ * @return

A string describing the config option

+ */ + private String getOptionDescription(ConfigurationOption option) { + Object defaultValue = option.getDefaultValue(); + String stringValue = String.valueOf(defaultValue); + if (option.getDataType() == OptionDataType.STRING_LIST) { + stringValue = "[" + StringUtils.join((String[]) defaultValue, ",") + "]"; + } + return ChatColor.GOLD + option.name() + ChatColor.WHITE + " - " + ChatColor.GREEN + option.getDescription() + + ChatColor.DARK_GRAY + " (Default: " + ChatColor.GRAY + stringValue + ChatColor.DARK_GRAY + ")"; + } + +} diff --git a/src/main/java/net/knarcraft/stargatecommand/command/CommandStarGateCommand.java b/src/main/java/net/knarcraft/stargatecommand/command/CommandStarGateCommand.java new file mode 100644 index 0000000..1265c47 --- /dev/null +++ b/src/main/java/net/knarcraft/stargatecommand/command/CommandStarGateCommand.java @@ -0,0 +1,33 @@ +package net.knarcraft.stargatecommand.command; + +import net.TheDgtl.Stargate.api.StargateAPI; +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * This command represents any command which starts with stargate-command (sgc) + */ +public class CommandStarGateCommand implements CommandExecutor { + + private StargateAPI stargateAPI; + + public CommandStarGateCommand(StargateAPI stargateAPI) { + this.stargateAPI = stargateAPI; + } + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] args) { + if (args.length > 0) { + if (args[0].equalsIgnoreCase("config")) { + String[] subArgs = (String[]) ArrayUtils.remove(args, 0); + return new CommandConfig(stargateAPI.getConfigurationAPI()).onCommand(commandSender, command, s, subArgs); + } + } + return false; + } + +} diff --git a/src/main/java/net/knarcraft/stargatecommand/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargatecommand/command/ConfigTabCompleter.java new file mode 100644 index 0000000..aadf9b2 --- /dev/null +++ b/src/main/java/net/knarcraft/stargatecommand/command/ConfigTabCompleter.java @@ -0,0 +1,156 @@ +package net.knarcraft.stargatecommand.command; + +import net.TheDgtl.Stargate.config.ConfigurationOption; +import net.TheDgtl.Stargate.config.OptionDataType; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * This is the completer for stargates config sub-command (/sg config) + */ +public class ConfigTabCompleter implements TabCompleter { + + private List booleans; + private List integers; + private List chatColors; + private List doubles; + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] args) { + if (booleans == null || integers == null || chatColors == null) { + initializeAutoCompleteLists(); + } + if (args.length > 1) { + ConfigurationOption selectedOption; + try { + selectedOption = ConfigurationOption.valueOf(args[0].toUpperCase()); + } catch (IllegalArgumentException exception) { + return new ArrayList<>(); + } + return getPossibleOptionValues(selectedOption, args[1]); + } else { + List configOptionNames = new ArrayList<>(); + for (ConfigurationOption option : ConfigurationOption.values()) { + configOptionNames.add(option.name()); + } + return filterMatching(configOptionNames, args[0]); + } + } + + /** + * Find completable strings which match the text typed by the command's sender + * + * @param values

The values to filter

+ * @param typedText

The text the player has started typing

+ * @return

The given string values which start with the player's typed text

+ */ + private List filterMatching(List values, String typedText) { + List configValues = new ArrayList<>(); + for (String value : values) { + if (value.toLowerCase().startsWith(typedText.toLowerCase())) { + configValues.add(value); + } + } + return configValues; + } + + /** + * Get possible values for the selected option + * + * @param selectedOption

The selected option

+ * @param typedText

The beginning of the typed text, for filtering matching results

+ * @return

Some or all of the valid values for the option

+ */ + private List getPossibleOptionValues(ConfigurationOption selectedOption, String typedText) { + switch (selectedOption) { + case LANGUAGE: + //Return available languages + return filterMatching(List.of(OptionDataType.LANGUAGE.getValues()), typedText); + case DEFAULT_NETWORK: + //Just return the default value as most values should be possible + if (typedText.trim().isEmpty()) { + return putStringInList((String) selectedOption.getDefaultValue()); + } else { + return new ArrayList<>(); + } + } + + if (selectedOption.getDataType() == OptionDataType.COLOR) { + return filterMatching(chatColors, typedText); + } + + //If the config value is a boolean, show the two boolean values + if (selectedOption.getDataType() == OptionDataType.BOOLEAN) { + return filterMatching(booleans, typedText); + } + + //If the config value is an integer, display some valid numbers + if (selectedOption.getDataType() == OptionDataType.INTEGER) { + if (typedText.trim().isEmpty()) { + return integers; + } else { + return new ArrayList<>(); + } + } + + //If the config value is a double, display some valid numbers + if (selectedOption.getDataType() == OptionDataType.DOUBLE) { + if (typedText.trim().isEmpty()) { + return doubles; + } else { + return new ArrayList<>(); + } + } + return null; + } + + /** + * Puts a single string value into a string list + * + * @param value

The string to make into a list

+ * @return

A list containing the string value

+ */ + private List putStringInList(String value) { + List list = new ArrayList<>(); + list.add(value); + return list; + } + + /** + * Initializes all lists of auto-completable values + */ + private void initializeAutoCompleteLists() { + booleans = new ArrayList<>(); + booleans.add("true"); + booleans.add("false"); + + integers = new ArrayList<>(); + integers.add("0"); + integers.add("5"); + + getColors(); + + doubles = new ArrayList<>(); + doubles.add("5"); + doubles.add("1"); + doubles.add("0.5"); + doubles.add("0.1"); + } + + + /** + * Initializes the list of chat colors + */ + private void getColors() { + chatColors = List.of(OptionDataType.COLOR.getValues()); + } + +} diff --git a/src/main/java/net/knarcraft/stargatecommand/command/StargateCommandTabCompleter.java b/src/main/java/net/knarcraft/stargatecommand/command/StargateCommandTabCompleter.java new file mode 100644 index 0000000..538ebae --- /dev/null +++ b/src/main/java/net/knarcraft/stargatecommand/command/StargateCommandTabCompleter.java @@ -0,0 +1,50 @@ +package net.knarcraft.stargatecommand.command; + +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class StargateCommandTabCompleter implements TabCompleter { + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, + @NotNull String s, @NotNull String[] args) { + if (args.length == 1) { + List commands = getAvailableCommands(commandSender); + List matchingCommands = new ArrayList<>(); + for (String availableCommand : commands) { + if (availableCommand.startsWith(args[0])) { + matchingCommands.add(availableCommand); + } + } + return matchingCommands; + } else if (args.length > 1 && args[0].equalsIgnoreCase("config")) { + String[] subArgs = (String[]) ArrayUtils.remove(args, 0); + return new ConfigTabCompleter().onTabComplete(commandSender, command, s, subArgs); + } else { + return new ArrayList<>(); + } + } + + /** + * Gets the available commands + * + * @param commandSender

The command sender to get available commands for

+ * @return

The commands available to the command sender

+ */ + private List getAvailableCommands(CommandSender commandSender) { + List commands = new ArrayList<>(); + if (!(commandSender instanceof Player player) || player.hasPermission("stargate.command.config")) { + commands.add("config"); + } + return commands; + } + +} diff --git a/src/net/TheDgtl/StargateCommand/SGCListener.java b/src/net/TheDgtl/StargateCommand/SGCListener.java deleted file mode 100644 index 7259275..0000000 --- a/src/net/TheDgtl/StargateCommand/SGCListener.java +++ /dev/null @@ -1,131 +0,0 @@ -package net.TheDgtl.StargateCommand; - -import net.TheDgtl.Stargate.Gate; -import net.TheDgtl.Stargate.Portal; -import net.TheDgtl.Stargate.Stargate; -import net.TheDgtl.Stargate.event.StargateActivateEvent; -import net.TheDgtl.StargateCommand.StargateCommand.Action; - -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.Event.Result; -import org.bukkit.event.player.PlayerInteractEvent; - -public class SGCListener implements Listener { - StargateCommand sgc; - public SGCListener(StargateCommand plugin) { - sgc = plugin; - } - - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - // We want right-click block only - Player player = event.getPlayer(); - Block block = null; - if (event.isCancelled() && event.getAction() == org.bukkit.event.block.Action.RIGHT_CLICK_AIR) { - try { - block = player.getTargetBlock(null, 5); - } catch (IllegalStateException ex) { - // We can safely ignore this exception, it only happens in void or max height - return; - } - } else { - block = event.getClickedBlock(); - } - - if (block == null || block.getType() == Material.AIR) return; - - SGCPlayer sPlayer = sgc.players.get(player); - if (sPlayer == null) return; - if (sPlayer.action == Action.IMPORT) { - event.setCancelled(true); - event.setUseInteractedBlock(Result.DENY); - event.setUseItemInHand(Result.DENY); - // First block - if (sPlayer.blocks.size() == 0) { - sPlayer.blocks.add(block); - StargateCommand.sendMessage(player, "Please select a second block by right-clicking it", false); - return; - } else { - Block fb = sPlayer.blocks.poll(); - int modX = fb.getX() - block.getX(); - int modZ = fb.getZ() - block.getZ(); - int modY = fb.getY() - block.getY(); - if (modY != 0 || modX > 1 || modX < -1 || modZ > 1 || modZ < -1 || (modX != 0 && modZ != 0)) { - StargateCommand.sendMessage(player, "The blocks you selected were not next to eachother. Exiting", true); - sgc.players.remove(player); - return; - } - Gate gate = Gate.getGateByName(sPlayer.args[1] + ".gate"); - boolean force = false; - if (sPlayer.args.length > 2 && sPlayer.args[2].equalsIgnoreCase("force")) force = true; - sgc.importGate(player, gate, fb, modX, modZ, force); - sgc.players.remove(player); - } - } else if (sPlayer.action == Action.EXPORT) { - event.setCancelled(true); - event.setUseInteractedBlock(Result.DENY); - event.setUseItemInHand(Result.DENY); - if (sPlayer.blocks.size() == 0) { - sPlayer.blocks.add(block); - StargateCommand.sendMessage(player, "Please select the button location", false); - } else if (sPlayer.blocks.size() == 1) { - sPlayer.blocks.add(block); - StargateCommand.sendMessage(player, "Please select the exit location", false); - } else if (sPlayer.blocks.size() == 2) { - sPlayer.blocks.add(block); - StargateCommand.sendMessage(player, "Please select the top-left block of the bedrock frame", false); - } else if (sPlayer.blocks.size() == 3) { - // First we find the dimensions of the frame - if (block.getType() != Material.BEDROCK) { - StargateCommand.sendMessage(player, "You did not select bedrock, exiting export mode", true); - sgc.players.remove(player); - return; - } - sgc.exportGate(player, block); - sgc.players.remove(player); - } - } else if (sPlayer.action == Action.OWNER) { - event.setCancelled(true); - event.setUseInteractedBlock(Result.DENY); - event.setUseItemInHand(Result.DENY); - Portal portal = Portal.getByBlock(block); - if (portal == null) { - StargateCommand.sendMessage(player, "You did not select a gate, exiting", true); - sgc.players.remove(player); - return; - } - portal.setOwner(sPlayer.args[1]); - Portal.saveAllGates(portal.getWorld()); - sgc.players.remove(player); - StargateCommand.sendMessage(player, "Owner of " + portal.getName() + " on network " + portal.getNetwork() + " set to " + sPlayer.args[1], false); - } - } - - @EventHandler - public void onStargateActivate(StargateActivateEvent event) { - Portal portal = event.getPortal(); - Player player = event.getPlayer(); - SGCPlayer sPlayer = sgc.players.get(player); - if (sPlayer == null) return; - if (sPlayer.action != Action.DIAL) return; - sgc.players.remove(player); - Portal destPortal = Portal.getByName(sPlayer.args[0], portal.getNetwork()); - if (destPortal == null) { - StargateCommand.sendMessage(player, "The specified destination does not exist for this gate. Exiting", true); - } else { - if (!Stargate.canAccessNetwork(player, portal.getNetwork())) { - StargateCommand.sendMessage(player, "You do not have access to that network.", true); - return; - } - event.setCancelled(true); - portal.activate(player); - portal.setDestination(destPortal); - Stargate.openPortal(player, portal); - portal.drawSign(); - } - } -} diff --git a/src/net/TheDgtl/StargateCommand/SGCPlayer.java b/src/net/TheDgtl/StargateCommand/SGCPlayer.java deleted file mode 100644 index c253c80..0000000 --- a/src/net/TheDgtl/StargateCommand/SGCPlayer.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.TheDgtl.StargateCommand; - -import java.util.LinkedList; - -import net.TheDgtl.StargateCommand.StargateCommand.Action; - -import org.bukkit.block.Block; -import org.bukkit.entity.Player; - -public class SGCPlayer { - public Player player; - public LinkedList blocks = new LinkedList(); - public Action action; - public String[] args; - - public SGCPlayer(Player player, Action action) { - this.player = player; - this.action = action; - } - - public SGCPlayer(Player player, Action action, String[] args) { - this(player, action); - this.args = args; - } -} diff --git a/src/net/TheDgtl/StargateCommand/StargateCommand.java b/src/net/TheDgtl/StargateCommand/StargateCommand.java deleted file mode 100644 index 3b4b403..0000000 --- a/src/net/TheDgtl/StargateCommand/StargateCommand.java +++ /dev/null @@ -1,410 +0,0 @@ -package net.TheDgtl.StargateCommand; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.logging.Logger; - -import net.TheDgtl.Stargate.Blox; -import net.TheDgtl.Stargate.Gate; -import net.TheDgtl.Stargate.Portal; -import net.TheDgtl.Stargate.Stargate; - -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Server; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.java.JavaPlugin; - -public class StargateCommand extends JavaPlugin { - private Logger log; - private Server server; - private PluginManager pm; - - private Stargate sg = null; - - public HashMap players = new HashMap(); - - public void onEnable() { - this.server = getServer(); - this.pm = server.getPluginManager(); - this.log = server.getLogger(); - - sg = (Stargate)pm.getPlugin("Stargate"); - - if (sg == null) { - log.severe("[SGC] Error, Stargate not found. Disabling"); - pm.disablePlugin(this); - return; - } - - pm.registerEvents(new SGCListener(this), this); - } - - public void onDisable() { - - } - - public void importGate(Player player, Gate gate, Block baseBlock, int modX, int modZ, boolean force) { - if (gate == null) { - StargateCommand.sendMessage(player, "The gate specified does not exist", true); - return; - } - - Blox topLeft = new Blox(baseBlock.getLocation().add(0, gate.getLayout().length, 0)); - - if (!drawGate(topLeft, gate, modX, modZ, force)) { - StargateCommand.sendMessage(player, "Gate interfered with existing terrain. Import cancelled. User force to ignore", true); - return; - } - sendMessage(player, "Your gate has been imported successfully", false); - } - - public boolean drawGate(Blox topleft, Gate gate, int modX, int modZ, boolean force) { - Character[][] layout = gate.getLayout(); - HashMap types = gate.getTypes(); - HashMap metadata = gate.getMetaData(); - int closedType = gate.getPortalBlockClosed(); - - // Queue used incase we need to undo - ArrayList blockQueue = new ArrayList(); - - for (int y = 0; y < layout.length; y++) { - for (int x = 0; x < layout[y].length; x++) { - int id = types.get(layout[y][x]); - Integer mData = metadata.get(layout[y][x]); - - if (id == Gate.ANYTHING) { - continue; - } - - if (id == Gate.ENTRANCE || id == Gate.EXIT) { - id = closedType; - } - - Blox block = topleft.modRelative(x, y, 0, modX, 1, modZ); - if (block.getType() != Material.AIR.getId() && !force) { - return false; - } - - BlockChange bc = new BlockChange(); - bc.block = block; - bc.newType = id; - bc.newData = mData; - blockQueue.add(bc); - } - } - - for(BlockChange bc : blockQueue) { - bc.block.setType(bc.newType); - if (bc.newData != null) - bc.block.setData(bc.newData); - } - return true; - } - - private boolean checkOffset(Location a, Location b, int modX, int modZ, int width, int height) { - int offX = Math.abs(a.getBlockX() - b.getBlockX()); - int offY = Math.abs(a.getBlockY() - b.getBlockY()); - int offZ = Math.abs(a.getBlockZ() - b.getBlockZ()); - if (modX == 0 && (offX != 0 || offZ > width)) return false; - if (modZ == 0 && (offZ != 0 || offX > width)) return false; - if (offY > height) return false; - return true; - } - - public void exportGate(Player player, Block topleft) { - SGCPlayer sPlayer = players.get(player); - // Determine facing - int tmp = 0; - int modX = 0; - int modZ = 0; - if (topleft.getRelative(BlockFace.EAST).getType() == Material.BEDROCK) { - modX = 1; - tmp++; - } - if (topleft.getRelative(BlockFace.WEST).getType() == Material.BEDROCK) { - modX = -1; - tmp++; - } - if (topleft.getRelative(BlockFace.NORTH).getType() == Material.BEDROCK) { - modZ = -1; - tmp++; - } - if (topleft.getRelative(BlockFace.SOUTH).getType() == Material.BEDROCK) { - modZ = 1; - tmp++; - } - if (tmp != 1 || topleft.getRelative(BlockFace.DOWN).getType() != Material.BEDROCK) { - StargateCommand.sendMessage(player, "There was an error determining your frame. Exiting export mode", true); - players.remove(player); - return; - } - - // Check offset of control blocks - Block signBlock = sPlayer.blocks.poll(); - Block buttonBlock = sPlayer.blocks.poll(); - - // Check offset of exit block - Block exitBlock = sPlayer.blocks.poll(); - - // Determine frame width/height - int frameWidth = 1; - int frameHeight = 1; - while (topleft.getRelative(modX * frameWidth, 0, modZ * frameWidth).getType() == Material.BEDROCK) { - frameWidth++; - } - while (topleft.getRelative(0, -frameHeight, 0).getType() == Material.BEDROCK) { - frameHeight++; - } - frameWidth = frameWidth - 2; - frameHeight = frameHeight - 2; - Block startBlock = topleft.getRelative(modX, -1, modZ); - - if (!checkOffset(signBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { - sendMessage(player, "Your sign block is outside of your stargate. Exiting", true); - return; - } - if (!checkOffset(buttonBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { - sendMessage(player, "Your button block is outside of your stargate. Exiting", true); - return; - } - if (!checkOffset(exitBlock.getLocation(), startBlock.getLocation(), modX, modZ, frameWidth, frameHeight)) { - sendMessage(player, "Your exit block is outside of your stargate. Exiting", true); - return; - } - - Gate gate = storeGate(player, startBlock, signBlock, buttonBlock, exitBlock, modX, modZ, frameWidth, frameHeight); - if (gate != null) { - Gate.registerGate(gate); - sendMessage(player, "Your gate layout has been exported and loaded", false); - } - } - - public Gate storeGate(Player player, Block startBlock, Block signBlock, Block buttonBlock, Block exitBlock, int modX, int modZ, int width, int height) { - SGCPlayer sPlayer = players.get(player); - // Store the gate layout - HashMap typeLookup = new HashMap(); - - Character[][] layout = new Character[height][width]; - HashMap types = new HashMap(); - HashMap metadata = new HashMap(); - - // Validate gate before saving - boolean exitFound = false; - int controlsFound = 0; - - // Init types map - Character nextChar = 'A'; - types.put('.', Gate.ENTRANCE); - types.put('*', Gate.EXIT); - types.put(' ', Gate.ANYTHING); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - Block fBlock = startBlock.getRelative(modX * x, -y, modZ * x); - int type = fBlock.getTypeId(); - int data = fBlock.getData(); - int lookup = type + (data << 16); - // Anything - if (type == Material.AIR.getId()) { - layout[y][x] = ' '; - continue; - } - // Entrance - if (type == Material.BEDROCK.getId()) { - if (fBlock.equals(exitBlock)) { - exitFound = true; - layout[y][x] = '*'; - continue; - } - layout[y][x] = '.'; - continue; - } - if (fBlock.equals(signBlock) || fBlock.equals(buttonBlock)) { - controlsFound++; - layout[y][x] = '-'; - Integer cType = types.get('-'); - if (cType != null && cType != type) { - sendMessage(player, "Both your control blocks must be on the same block type. Exiting", true); - return null; - } - types.put('-', type); - continue; - } - // Store block/metadata for gate - if (!typeLookup.containsKey(lookup)) { - typeLookup.put(lookup, nextChar); - types.put(nextChar, type); - if (data != 0) - metadata.put(nextChar, data); - nextChar++; - } - layout[y][x] = typeLookup.get(lookup); - } - } - - if (!exitFound) { - sendMessage(player, "Your exit was not in an entrance block. Exiting", true); - return null; - } - if (controlsFound != 2) { - sendMessage(player, "One of your control blocks was missing. Exiting", true); - return null; - } - - Gate gate = new Gate(sPlayer.args[1] + ".gate", layout, types, metadata); - gate.setPortalBlockOpen(Material.PORTAL.getId()); - gate.setPortalBlockClosed(Material.AIR.getId()); - gate.save(Stargate.getGateFolder()); - return gate; - } - - public void dialGate(Player player, String dest, String source, String network) { - Portal sourcePortal = Portal.getByName(source, network); - Portal destPortal = Portal.getByName(dest, network); - if (sourcePortal == null || destPortal == null) { - sendMessage(player, "The specified Stargate connection does not exist", true); - return; - } - if (sourcePortal.getWorld() != player.getWorld() && destPortal.getWorld() != player.getWorld()) { - sendMessage(player, "Neither of the specified gates are on your world", true); - return; - } - if (!Stargate.canAccessNetwork(player, network)) { - sendMessage(player, "You do not have access to that gate network", true); - return; - } - sourcePortal.activate(player); - sourcePortal.setDestination(destPortal); - Stargate.openPortal(player, sourcePortal); - sourcePortal.drawSign(); - sendMessage(player, "The gate has been connected and opened", false); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (!(sender instanceof Player)) { - sendMessage(sender, "This command can only be used ingame", true); - return true; - } - Player player = (Player)sender; - // SGC import/export - if (command.getName().equalsIgnoreCase("sgc")) { - if (args.length == 0) return false; - // Import - if (args[0].equalsIgnoreCase("import")) { - if (!Stargate.hasPerm(player, "stargate.command.import")) { - StargateCommand.sendMessage(player, "Permission Denied", true); - return true; - } - if (args.length < 2) { - sendMessage(player, "Usage: /sgc import [force]", false); - sendMessage(player, "Use force to ignore terrain intersection", false); - sendMessage(player, "Example: /sgc import super force", false); - return true; - } - if (Gate.getGateByName(args[1] + ".gate") == null) { - StargateCommand.sendMessage(player, "The gate you specified does not exist", true); - return true; - } - - StargateCommand.sendMessage(player, "Please select two blocks to define gate location/direction", false); - StargateCommand.sendMessage(player, "Do this by right-clicking two blocks next to each other", false); - players.put(player, new SGCPlayer(player, Action.IMPORT, args)); - // Export - } else if (args[0].equalsIgnoreCase("export")) { - if (!Stargate.hasPerm(player, "stargate.command.export")) { - StargateCommand.sendMessage(player, "Permission Denied", true); - return true; - } - if (args.length < 2) { - StargateCommand.sendMessage(player, "Usage: /sgc export [force]", false); - StargateCommand.sendMessage(player, "Use force to overwrite existing .gate files", false); - sendMessage(player, "Example: /sgc export super force", false); - return true; - } - boolean force = false; - if (args.length > 2 && args[2].equalsIgnoreCase("force")) force = true; - if (Gate.getGateByName(args[1] + ".gate") != null && !force) { - sendMessage(player, "A gate by that name exists. Use force to overwrite", true); - return true; - } - StargateCommand.sendMessage(player, "Please select where you would like the sign placed", false); - StargateCommand.sendMessage(player, "Do this by right-clicking the block", false); - players.put(player, new SGCPlayer(player, Action.EXPORT, args)); - // Cancel - } else if (args[0].equalsIgnoreCase("cancel")) { - players.remove(player); - StargateCommand.sendMessage(player, "Command cancelled", false); - } else if (args[0].equalsIgnoreCase("owner")) { - if (!Stargate.hasPerm(player, "stargate.command.owner")) { - StargateCommand.sendMessage(player, "Permission Denied", true); - return true; - } - if (args.length != 2) { - StargateCommand.sendMessage(player, "Usage: /sgc owner ", false); - return true; - } - StargateCommand.sendMessage(player, "Please right-click a target gate to assign ownership", false); - players.put(player, new SGCPlayer(player, Action.OWNER, args)); - } - return true; - } else if (command.getName().equalsIgnoreCase("dial")) { - if (args.length < 1 || args.length > 3) return false; - String dest = null; - String source = null; - String network = null; - if (args.length == 1) { - if (!Stargate.hasPerm(player, "stargate.command.dial.interactive")) { - sendMessage(player, "Permission Denied", true); - return true; - } - dest = args[0]; - players.put(player, new SGCPlayer(player, Action.DIAL, args)); - sendMessage(player, "The next Stargate you activate will connect to " + dest + " if available", false); - } else if (args.length > 1) { - if (!Stargate.hasPerm(player, "stargate.command.dial.direct")) { - sendMessage(player, "Permission Denied", true); - return true; - } - source = args[0]; - dest = args[1]; - if (args.length > 2) { - network = args[2]; - } else { - network = Stargate.getDefaultNetwork(); - } - dialGate(player, dest, source, network); - } - return true; - } - return false; - } - - public static void sendMessage(CommandSender sender, String message, boolean error) { - if (error) { - message = ChatColor.RED + "[SGC] " + ChatColor.WHITE + message; - } else { - message = ChatColor.BLUE + "[SGC] " + ChatColor.WHITE + message; - } - sender.sendMessage(message); - } - - private class BlockChange { - public Blox block; - public Integer newType; - public Integer newData; - } - - public enum Action { - IMPORT, - EXPORT, - DIAL, - OWNER - } -} diff --git a/src/plugin.yml b/src/plugin.yml index 4fc5492..7759527 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,37 +1,18 @@ name: StargateCommand -main: net.TheDgtl.StargateCommand.StargateCommand -version: 0.0.4 +main: net.knarcraft.stargatecommand.StargateCommand +version: 0.1.0 description: Command addon for the Stargate plugin for Bukkit -author: Drakia +author: EpicKnarvik97 depend: [Stargate] -website: https://discord.gg/mTaHuK6BVa commands: - sgc: - description: StargateCommand import/export/owner commands. + stargatecommand: + aliases: + - sgc + description: The root command for all added commands usage: | - / [force] - Type: "/ import" for help with import - Type: "/ export" for help with export - Type: "/ cancel" to cancel any pending SGC action - / owner - dial: - description: Dial a stargate - usage: | - / - / [network] + / + / config permissions: - stargate.command.owner: - description: Allow the user of /sgc owner - default: op - stargate.command.import: - description: Allow the use of /sgc import - default: op - stargate.command.export: - description: Allow the use of /sgc export - default: op - stargate.command.dial: - description: Allow the use of /dial - default: true - children: - stargate.command.dial.interactive: true - stargate.command.dial.direct: false \ No newline at end of file + stargate.command.config: + description: Allow the user of /sgc config + default: false \ No newline at end of file