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
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