diff --git a/src/main/java/com/wimbli/WorldBorder/WBCommand.java b/src/main/java/com/wimbli/WorldBorder/WBCommand.java index edc33bd..83f1bd7 100644 --- a/src/main/java/com/wimbli/WorldBorder/WBCommand.java +++ b/src/main/java/com/wimbli/WorldBorder/WBCommand.java @@ -8,6 +8,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeSet; import org.bukkit.command.*; import org.bukkit.entity.Player; @@ -18,38 +19,43 @@ import com.wimbli.WorldBorder.cmd.*; public class WBCommand implements CommandExecutor { // map of all sub-commands with the command name (string) for quick reference - private Map subCommands = new LinkedHashMap(); + public Map subCommands = new LinkedHashMap(); // ref. list of the commands which can have a world name in front of the command itself (ex. /wb _world_ radius 100) private Set subCommandsWithWorldNames = new LinkedHashSet(); // constructor - public WBCommand (WorldBorder plugin) + public WBCommand () { - addCmd(new CmdSet()); - addCmd(new CmdSetcorners()); - addCmd(new CmdRadius()); - addCmd(new CmdShape()); - addCmd(new CmdClear()); - addCmd(new CmdList()); - addCmd(new CmdFill()); - addCmd(new CmdTrim()); - addCmd(new CmdBypass()); - addCmd(new CmdBypasslist()); - addCmd(new CmdKnockback()); - addCmd(new CmdWrap()); - addCmd(new CmdWhoosh()); - addCmd(new CmdGetmsg()); - addCmd(new CmdSetmsg()); - addCmd(new CmdDelay()); - addCmd(new CmdWshape()); - addCmd(new CmdDynmap()); - addCmd(new CmdDynmapmsg()); - addCmd(new CmdRemount()); - addCmd(new CmdFillautosave()); - addCmd(new CmdPortal()); - addCmd(new CmdDenypearl()); - addCmd(new CmdReload()); - addCmd(new CmdDebug()); + addCmd(new CmdHelp()); // 1 example + addCmd(new CmdSet()); // 4 examples for player, 3 for console + addCmd(new CmdSetcorners()); // 1 + addCmd(new CmdRadius()); // 1 + addCmd(new CmdList()); // 1 + //----- 8 per page of examples + addCmd(new CmdShape()); // 2 + addCmd(new CmdClear()); // 2 + addCmd(new CmdFill()); // 1 + addCmd(new CmdTrim()); // 1 + addCmd(new CmdBypass()); // 1 + addCmd(new CmdBypasslist()); // 1 + //----- + addCmd(new CmdKnockback()); // 1 + addCmd(new CmdWrap()); // 1 + addCmd(new CmdWhoosh()); // 1 + addCmd(new CmdGetmsg()); // 1 + addCmd(new CmdSetmsg()); // 1 + addCmd(new CmdWshape()); // 3 + //----- + addCmd(new CmdDelay()); // 1 + addCmd(new CmdDynmap()); // 1 + addCmd(new CmdDynmapmsg()); // 1 + addCmd(new CmdRemount()); // 1 + addCmd(new CmdFillautosave()); // 1 + addCmd(new CmdPortal()); // 1 + addCmd(new CmdDenypearl()); // 1 + addCmd(new CmdReload()); // 1 + //----- + addCmd(new CmdDebug()); // 1 // this is the default command, which shows command example pages; should be last just in case addCmd(new CmdCommands()); @@ -98,7 +104,7 @@ public class WBCommand implements CommandExecutor } catch(NumberFormatException ignored) { - sender.sendMessage(WBCmd.clrErr + "Command not recognized. Showing command list."); + sender.sendMessage(WBCmd.C_ERR + "Command not recognized. Showing command list."); } cmdName = "commands"; params.add(0, Integer.toString(page)); @@ -113,7 +119,7 @@ public class WBCommand implements CommandExecutor // if command requires world name when run by console, make sure that's in place if (player == null && subCommand.hasWorldNameInput && subCommand.consoleRequiresWorldName && worldName == null) { - sender.sendMessage(WBCmd.clrErr + "This command requires a world to be specified if run by the console."); + sender.sendMessage(WBCmd.C_ERR + "This command requires a world to be specified if run by the console."); subCommand.sendCmdHelp(sender); return true; } @@ -121,7 +127,10 @@ public class WBCommand implements CommandExecutor // make sure valid number of parameters has been provided if (params.size() < subCommand.minParams || params.size() > subCommand.maxParams) { - sender.sendMessage(WBCmd.clrErr + "You have not provided a valid number of arguments."); + if (subCommand.maxParams == 0) + sender.sendMessage(WBCmd.C_ERR + "This command does not accept any parameters."); + else + sender.sendMessage(WBCmd.C_ERR + "You have not provided a valid number of parameters."); subCommand.sendCmdHelp(sender); return true; } @@ -135,7 +144,7 @@ public class WBCommand implements CommandExecutor private boolean wasWorldQuotation = false; - // if world name is surrounded by quotation marks, combine it down and tag wasWorldQuotation if it's the first parameter + // if world name is surrounded by quotation marks, combine it down and flag wasWorldQuotation if it's first param. // also return List instead of input primitive String[] private List concatenateQuotedWorldName(String[] split) { @@ -191,4 +200,13 @@ public class WBCommand implements CommandExecutor return args; } + public Set getCommandNames() + { + // using TreeSet to sort alphabetically + Set commands = new TreeSet(subCommands.keySet()); + // removing default "commands" command as it's not normally shown or run like other commands + commands.remove("commands"); + return commands; + } + } \ No newline at end of file diff --git a/src/main/java/com/wimbli/WorldBorder/WorldBorder.java b/src/main/java/com/wimbli/WorldBorder/WorldBorder.java index 8ad6244..0173587 100644 --- a/src/main/java/com/wimbli/WorldBorder/WorldBorder.java +++ b/src/main/java/com/wimbli/WorldBorder/WorldBorder.java @@ -6,21 +6,22 @@ import org.bukkit.plugin.java.JavaPlugin; public class WorldBorder extends JavaPlugin { - public static WorldBorder plugin; - - public WorldBorder() - { - plugin = this; - } + public static volatile WorldBorder plugin = null; + public static volatile WBCommand wbCommand = null; @Override public void onEnable() { + if (plugin == null) + plugin = this; + if (wbCommand == null) + wbCommand = new WBCommand(); + // Load (or create new) config file Config.load(this, false); // our one real command, though it does also have aliases "wb" and "worldborder" - getCommand("wborder").setExecutor(new WBCommand(this)); + getCommand("wborder").setExecutor(wbCommand); // keep an eye on teleports, to redirect them to a spot inside the border if necessary getServer().getPluginManager().registerEvents(new WBListener(), this); @@ -43,8 +44,17 @@ public class WorldBorder extends JavaPlugin } // for other plugins to hook into - public BorderData GetWorldBorder(String worldName) + public BorderData getWorldBorder(String worldName) { return Config.Border(worldName); } + + /** + * @deprecated Replaced by {@link #getWorldBorder(String worldName)}; + * this method name starts with an uppercase letter, which it shouldn't + */ + public BorderData GetWorldBorder(String worldName) + { + return getWorldBorder(worldName); + } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdBypass.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdBypass.java index 8a007ad..1b3a4bb 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdBypass.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdBypass.java @@ -17,7 +17,19 @@ public class CmdBypass extends WBCmd minParams = 0; maxParams = 2; - addCmdExample(nameEmphasized() + "{player} [on/off] - let player go beyond border."); + addCmdExample(nameEmphasized() + "{player} [on|off] - let player go beyond border."); + helpText = "If [player] isn't specified, command sender is used. If [on|off] isn't specified, the value will " + + "be toggled. Once bypass is enabled, the player will not be stopped by any borders until bypass is " + + "disabled for them again. Use the " + commandEmphasized("bypasslist") + C_DESC + "command to list all " + + "players with bypass enabled."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + boolean bypass = Config.isPlayerBypassing(((Player)sender).getName()); + if (sender instanceof Player) + sender.sendMessage(C_HEAD + "Border bypass is currently " + enabledColored(bypass) + C_HEAD + " for you."); } @Override @@ -41,7 +53,8 @@ public class CmdBypass extends WBCmd if (target != null && target.isOnline()) target.sendMessage("Border bypass is now " + enabledColored(bypassing) + "."); - Config.log("Border bypass for player \"" + sPlayer + "\" is " + (bypassing ? "enabled" : "disabled") + (player != null ? " at the command of player \"" + player.getName() + "\"" : "") + "."); + Config.log("Border bypass for player \"" + sPlayer + "\" is " + (bypassing ? "enabled" : "disabled") + + (player != null ? " at the command of player \"" + player.getName() + "\"" : "") + "."); if (player != null && player != target) sender.sendMessage("Border bypass for player \"" + sPlayer + "\" is " + enabledColored(bypassing) + "."); } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdBypasslist.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdBypasslist.java index 05d942d..dbea75a 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdBypasslist.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdBypasslist.java @@ -16,6 +16,8 @@ public class CmdBypasslist extends WBCmd minParams = maxParams = 0; addCmdExample(nameEmphasized() + "- list players with border bypass enabled."); + helpText = "The bypass list will persist between server restarts, and applies to all worlds. Use the " + + commandEmphasized("bypass") + C_DESC + "command to add or remove players."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdClear.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdClear.java index 5b7fb2a..b56303d 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdClear.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdClear.java @@ -20,6 +20,8 @@ public class CmdClear extends WBCmd addCmdExample(nameEmphasizedW() + "- remove border for this world."); addCmdExample(nameEmphasized() + "^all - remove border for all worlds."); + helpText = "If run by an in-game player and [world] or \"all\" isn't specified, the world you are currently " + + "in is used."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdCommands.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdCommands.java index 42431cf..9871761 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdCommands.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdCommands.java @@ -42,8 +42,8 @@ public class CmdCommands extends WBCmd page = (player == null) ? 0 : 1; // send command example header - sender.sendMessage( clrHead + WorldBorder.plugin.getDescription().getFullName() + " - key: " + - commandEmphasized("command") + clrReq + " " + clrOpt + "[optional]" ); + sender.sendMessage( C_HEAD + WorldBorder.plugin.getDescription().getFullName() + " - key: " + + commandEmphasized("command") + C_REQ + " " + C_OPT + "[optional]" ); if (page > 0) { @@ -56,11 +56,11 @@ public class CmdCommands extends WBCmd } // send page footer, if relevant; manual spacing to get right side lined up near edge is crude, but sufficient - String footer = clrHead + " (Page " + page + "/" + pageCount + ") " + ((player == null) ? cmdC : cmdP); + String footer = C_HEAD + " (Page " + page + "/" + pageCount + ") " + cmd(sender); if (page < pageCount) - sender.sendMessage(footer + Integer.toString(page + 1) + clrDesc + " - view next page of commands."); + sender.sendMessage(footer + Integer.toString(page + 1) + C_DESC + " - view next page of commands."); else if (page > 1) - sender.sendMessage(footer + clrDesc + "- view first page of commands."); + sender.sendMessage(footer + C_DESC + "- view first page of commands."); } else { diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDebug.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDebug.java index 8579258..337a6e1 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDebug.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDebug.java @@ -16,6 +16,14 @@ public class CmdDebug extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - turn console debug output on or off."); + helpText = "Default value: off. Debug mode will show some extra debugging data in the server console/log when " + + "players are knocked back from the border or are teleported."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + sender.sendMessage(C_HEAD + "Debug mode is " + enabledColored(Config.Debug()) + C_HEAD + "."); } @Override @@ -26,7 +34,7 @@ public class CmdDebug extends WBCmd if (player != null) { Config.log((Config.Debug() ? "Enabled" : "Disabled") + " debug output at the command of player \"" + player.getName() + "\"."); - sender.sendMessage("Debug mode " + enabledColored(Config.Debug()) + "."); + cmdStatus(sender); } } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDelay.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDelay.java index 23765f2..021aa8c 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDelay.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDelay.java @@ -16,6 +16,15 @@ public class CmdDelay extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - time between border checks."); + helpText = "Default value: 5. The is in server ticks, of which there are roughly 20 every second, each " + + "tick taking ~50ms. The default value therefore has border checks run about 4 times per second."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + int delay = Config.TimerTicks(); + sender.sendMessage(C_HEAD + "Timer delay is set to " + delay + " tick(s). That is roughly " + (delay * 50) + "ms."); } @Override @@ -37,6 +46,6 @@ public class CmdDelay extends WBCmd Config.setTimerTicks(delay); if (player != null) - sender.sendMessage("Timer delay set to " + delay + " tick(s). That is roughly " + (delay * 50) + "ms."); + cmdStatus(sender); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDenypearl.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDenypearl.java index e6c50ea..fd09174 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDenypearl.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDenypearl.java @@ -16,6 +16,16 @@ public class CmdDenypearl extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - stop ender pearls past the border."); + helpText = "Default value: on. When enabled, this setting will directly cancel attempts to use an ender pearl to " + + "get past the border rather than just knocking the player back. This should prevent usage of ender " + + "pearls to glitch into areas otherwise inaccessible at the border edge."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + sender.sendMessage(C_HEAD + "Direct cancellation of ender pearls thrown past the border is " + + enabledColored(Config.getDenyEnderpearl()) + C_HEAD + "."); } @Override @@ -26,7 +36,7 @@ public class CmdDenypearl extends WBCmd if (player != null) { Config.log((Config.getDenyEnderpearl() ? "Enabled" : "Disabled") + " direct cancellation of ender pearls thrown past the border at the command of player \"" + player.getName() + "\"."); - sender.sendMessage("Direct cancellation of ender pearls thrown past the border " + enabledColored(Config.getDenyEnderpearl()) + "."); + cmdStatus(sender); } } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDynmap.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDynmap.java index 8e8d3dc..979f2e3 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDynmap.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDynmap.java @@ -16,6 +16,14 @@ public class CmdDynmap extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - turn DynMap border display on or off."); + helpText = "Default value: on. If you are running the DynMap plugin and this setting is enabled, all borders will " + + "be visually shown in DynMap."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + sender.sendMessage(C_HEAD + "DynMap border display is " + enabledColored(Config.DynmapBorderEnabled()) + C_HEAD + "."); } @Override @@ -25,7 +33,7 @@ public class CmdDynmap extends WBCmd if (player != null) { - sender.sendMessage("DynMap border display " + (Config.DynmapBorderEnabled() ? "enabled" : "disabled") + "."); + cmdStatus(sender); Config.log((Config.DynmapBorderEnabled() ? "Enabled" : "Disabled") + " DynMap border display at the command of player \"" + player.getName() + "\"."); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDynmapmsg.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDynmapmsg.java index 691f8f8..2c969c8 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdDynmapmsg.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdDynmapmsg.java @@ -16,6 +16,15 @@ public class CmdDynmapmsg extends WBCmd minParams = 1; addCmdExample(nameEmphasized() + " - DynMap border labels will show this."); + helpText = "Default value: \"The border of the world.\". If you are running the DynMap plugin and the " + + commandEmphasized("dynmap") + C_DESC + "command setting is enabled, the borders shown in DynMap will " + + "be labelled with this text."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + sender.sendMessage(C_HEAD + "DynMap border label is set to: " + C_ERR + Config.DynmapMessage()); } @Override @@ -34,6 +43,6 @@ public class CmdDynmapmsg extends WBCmd Config.setDynmapMessage(message.toString()); if (player != null) - sender.sendMessage("DynMap border label is now set to: " + clrErr + Config.DynmapMessage()); + cmdStatus(sender); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdFill.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdFill.java index aa82d7f..d4a6ba8 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdFill.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdFill.java @@ -20,6 +20,10 @@ public class CmdFill extends WBCmd maxParams = 3; addCmdExample(nameEmphasizedW() + "[freq] [pad] [force] - fill world to border."); + helpText = "This command will generate missing world chunks inside your border. [freq] is the frequency " + + "of chunks per second that will be checked (default 20). [pad] is the number of blocks padding added " + + "beyond the border itself (default 208, to cover player visual range). [force] can be specified as true " + + "to force all chunks to be loaded even if they seem to be fully generated (default false)."; } @Override @@ -35,7 +39,7 @@ public class CmdFill extends WBCmd { if (!makeSureFillIsRunning(sender)) return; - sender.sendMessage(clrHead + "Cancelling the world map generation task."); + sender.sendMessage(C_HEAD + "Cancelling the world map generation task."); fillDefaults(); Config.StopFillTask(); return; @@ -45,7 +49,7 @@ public class CmdFill extends WBCmd if (!makeSureFillIsRunning(sender)) return; Config.fillTask.pause(); - sender.sendMessage(clrHead + "The world map generation task is now " + (Config.fillTask.isPaused() ? "" : "un") + "paused."); + sender.sendMessage(C_HEAD + "The world map generation task is now " + (Config.fillTask.isPaused() ? "" : "un") + "paused."); return; } @@ -65,13 +69,13 @@ public class CmdFill extends WBCmd } // colorized "/wb fill " - String cmd = ((player == null) ? cmdC : cmdP) + nameEmphasized() + clrCmd; + String cmd = cmd(sender) + nameEmphasized() + C_CMD; // make sure Fill isn't already running if (Config.fillTask != null && Config.fillTask.valid()) { - sender.sendMessage(clrErr + "The world map generation task is already running."); - sender.sendMessage(clrDesc + "You can cancel at any time with " + cmd + "cancel" + clrDesc + ", or pause/unpause with " + cmd + "pause" + clrDesc + "."); + sender.sendMessage(C_ERR + "The world map generation task is already running."); + sender.sendMessage(C_DESC + "You can cancel at any time with " + cmd + "cancel" + C_DESC + ", or pause/unpause with " + cmd + "pause" + C_DESC + "."); return; } @@ -130,7 +134,7 @@ public class CmdFill extends WBCmd sender.sendMessage("WorldBorder map generation task for world \"" + fillWorld + "\" started."); } else - sender.sendMessage(clrErr + "The world map generation task failed to start."); + sender.sendMessage(C_ERR + "The world map generation task failed to start."); fillDefaults(); } @@ -142,10 +146,10 @@ public class CmdFill extends WBCmd return; } - sender.sendMessage(clrHead + "World generation task is ready for world \"" + fillWorld + "\", attempting to process up to " + fillFrequency + " chunks per second (default 20). The map will be padded out " + fillPadding + " blocks beyond the border (default " + defaultPadding + "). Parts of the world which are already fully generated will be " + (fillForceLoad ? "loaded anyway." : "skipped.")); - sender.sendMessage(clrHead + "This process can take a very long time depending on the world's border size. Also, depending on the chunk processing rate, players will likely experience severe lag for the duration."); - sender.sendMessage(clrDesc + "You should now use " + cmd + "confirm" + clrDesc + " to start the process."); - sender.sendMessage(clrDesc + "You can cancel at any time with " + cmd + "cancel" + clrDesc + ", or pause/unpause with " + cmd + "pause" + clrDesc + "."); + sender.sendMessage(C_HEAD + "World generation task is ready for world \"" + fillWorld + "\", attempting to process up to " + fillFrequency + " chunks per second (default 20). The map will be padded out " + fillPadding + " blocks beyond the border (default " + defaultPadding + "). Parts of the world which are already fully generated will be " + (fillForceLoad ? "loaded anyway." : "skipped.")); + sender.sendMessage(C_HEAD + "This process can take a very long time depending on the world's border size. Also, depending on the chunk processing rate, players will likely experience severe lag for the duration."); + sender.sendMessage(C_DESC + "You should now use " + cmd + "confirm" + C_DESC + " to start the process."); + sender.sendMessage(C_DESC + "You can cancel at any time with " + cmd + "cancel" + C_DESC + ", or pause/unpause with " + cmd + "pause" + C_DESC + "."); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdFillautosave.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdFillautosave.java index 6b0ce99..158a174 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdFillautosave.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdFillautosave.java @@ -16,6 +16,25 @@ public class CmdFillautosave extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - world save interval for Fill."); + helpText = "Default value: 30 seconds."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + int seconds = Config.FillAutosaveFrequency(); + if (seconds == 0) + { + sender.sendMessage(C_HEAD + "World autosave frequency during Fill process is set to 0, disabling it."); + sender.sendMessage(C_HEAD + "Note that much progress can be lost this way if there is a bug or crash in " + + "the world generation process from Bukkit or any world generation plugin you use."); + } + else + { + sender.sendMessage(C_HEAD + "World autosave frequency during Fill process is set to " + seconds + " seconds (rounded to a multiple of 5)."); + sender.sendMessage(C_HEAD + "New chunks generated by the Fill process will be forcibly saved to disk " + + "this often to prevent loss of progress due to bugs or crashes in the world generation process."); + } } @Override @@ -37,17 +56,6 @@ public class CmdFillautosave extends WBCmd Config.setFillAutosaveFrequency(seconds); if (player != null) - { - if (seconds == 0) - { - sender.sendMessage("World autosave frequency during Fill process set to 0, disabling it."); - sender.sendMessage("Note that much progress can be lost this way if there is a bug or crash in the world generation process from Bukkit or any world generation plugin you use."); - } - else - { - sender.sendMessage("World autosave frequency during Fill process set to " + seconds + " seconds (rounded to a multiple of 5)."); - sender.sendMessage("New chunks generated by the Fill process will be forcibly saved to disk this often to prevent loss of progress due to bugs or crashes in the world generation process."); - } - } + cmdStatus(sender); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdGetmsg.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdGetmsg.java index c8e9f81..d147716 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdGetmsg.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdGetmsg.java @@ -16,6 +16,7 @@ public class CmdGetmsg extends WBCmd minParams = maxParams = 0; addCmdExample(nameEmphasized() + "- display border message."); + helpText = "This command simply displays the message shown to players knocked back from the border."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdHelp.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdHelp.java new file mode 100644 index 0000000..771dabc --- /dev/null +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdHelp.java @@ -0,0 +1,53 @@ +package com.wimbli.WorldBorder.cmd; + +import java.util.List; +import java.util.Set; + +import org.bukkit.command.*; +import org.bukkit.entity.Player; + +import com.wimbli.WorldBorder.*; + + +public class CmdHelp extends WBCmd +{ + public CmdHelp() + { + name = permission = "help"; + minParams = 0; + maxParams = 10; + + addCmdExample(nameEmphasized() + "[command] - get help on command usage."); +// helpText = "If [command] is specified, info for that particular command will be provided."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + String commands = WorldBorder.wbCommand.getCommandNames().toString().replace(", ", C_DESC + ", " + C_CMD); + sender.sendMessage(C_HEAD + "Commands: " + C_CMD + commands.substring(1, commands.length() - 1)); + sender.sendMessage("Example, for info on \"set\" command: " + cmd(sender) + nameEmphasized() + C_CMD + "set"); + sender.sendMessage(C_HEAD + "For a full command example list, simply run the root " + cmd(sender) + C_HEAD + "command by itself with nothing specified."); + } + + @Override + public void execute(CommandSender sender, Player player, List params, String worldName) + { + if (params.isEmpty()) + { + sendCmdHelp(sender); + return; + } + + Set commands = WorldBorder.wbCommand.getCommandNames(); + for (String param : params) + { + if (commands.contains(param.toLowerCase())) + { + WorldBorder.wbCommand.subCommands.get(param.toLowerCase()).sendCmdHelp(sender); + return; + } + } + sendErrorAndHelp(sender, "No command recognized."); + } +} diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdKnockback.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdKnockback.java index e9e448f..4876a4d 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdKnockback.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdKnockback.java @@ -16,6 +16,17 @@ public class CmdKnockback extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - how far to move the player back."); + helpText = "Default value: 3.0 (blocks). Players who cross the border will be knocked back to this distance inside."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + double kb = Config.KnockBack(); + if (kb < 1) + sender.sendMessage(C_HEAD + "Knockback is set to 0, disabling border enforcement."); + else + sender.sendMessage(C_HEAD + "Knockback is set to " + kb + " blocks inside the border."); } @Override @@ -37,6 +48,6 @@ public class CmdKnockback extends WBCmd Config.setKnockBack(numBlocks); if (player != null) - sender.sendMessage("Knockback set to " + numBlocks + " blocks inside the border."); + cmdStatus(sender); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdList.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdList.java index a0d09a8..043d7f7 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdList.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdList.java @@ -17,6 +17,8 @@ public class CmdList extends WBCmd minParams = maxParams = 0; addCmdExample(nameEmphasized() + "- show border information for all worlds."); + helpText = "This command will list full information for every border you have set including position, " + + "radius, and shape. The default border shape will also be indicated."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdPortal.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdPortal.java index 1f5f409..14f5ced 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdPortal.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdPortal.java @@ -16,6 +16,15 @@ public class CmdPortal extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - turn portal redirection on or off."); + helpText = "Default value: on. This feature monitors new portal creation and changes the target new portal " + + "location if it is outside of the border. Try disabling this if you have problems with other plugins " + + "related to portals."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + sender.sendMessage(C_HEAD + "Portal redirection is " + enabledColored(Config.portalRedirection()) + C_HEAD + "."); } @Override @@ -26,7 +35,7 @@ public class CmdPortal extends WBCmd if (player != null) { Config.log((Config.portalRedirection() ? "Enabled" : "Disabled") + " portal redirection at the command of player \"" + player.getName() + "\"."); - sender.sendMessage("Portal redirection " + enabledColored(Config.portalRedirection()) + "."); + cmdStatus(sender); } } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdRadius.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdRadius.java index 73aca0c..bf76124 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdRadius.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdRadius.java @@ -18,6 +18,8 @@ public class CmdRadius extends WBCmd maxParams = 2; addCmdExample(nameEmphasizedW() + " [radiusZ] - change radius."); + helpText = "Using this command you can adjust the radius of an existing border. If [radiusZ] is not " + + "specified, the radiusX value will be used for both."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdReload.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdReload.java index 396710b..e5f2a0d 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdReload.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdReload.java @@ -16,6 +16,8 @@ public class CmdReload extends WBCmd minParams = maxParams = 0; addCmdExample(nameEmphasized() + "- re-load data from config.yml."); + helpText = "If you make manual changes to config.yml while the server is running, you can use this command " + + "to make WorldBorder load the changes without needing to restart the server."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdRemount.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdRemount.java index a49dbe5..cd70f02 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdRemount.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdRemount.java @@ -16,6 +16,23 @@ public class CmdRemount extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - player remount delay after knockback."); + helpText = "Default value: 0 (disabled). If set higher than 0, WorldBorder will attempt to re-mount players who " + + "are knocked back from the border while riding something after this many server ticks. This setting can " + + "cause really nasty glitches if enabled and set too low due to CraftBukkit teleportation problems."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + int delay = Config.RemountTicks(); + if (delay == 0) + sender.sendMessage(C_HEAD + "Remount delay set to 0. Players will be left dismounted when knocked back from the border while on a vehicle."); + else + { + sender.sendMessage(C_HEAD + "Remount delay set to " + delay + " tick(s). That is roughly " + (delay * 50) + "ms / " + (((double)delay * 50.0) / 1000.0) + " seconds. Setting to 0 would disable remounting."); + if (delay < 10) + sender.sendMessage(C_ERR + "WARNING:" + C_DESC + " setting this to less than 10 (and greater than 0) is not recommended. This can lead to nasty client glitches."); + } } @Override @@ -37,15 +54,6 @@ public class CmdRemount extends WBCmd Config.setRemountTicks(delay); if (player != null) - { - if (delay == 0) - sender.sendMessage("Remount delay set to 0. Players will be left dismounted when knocked back from the border while on a vehicle."); - else - { - sender.sendMessage("Remount delay set to " + delay + " tick(s). That is roughly " + (delay * 50) + "ms / " + (((double)delay * 50.0) / 1000.0) + " seconds. Setting to 0 would disable remounting."); - if (delay < 10) - sender.sendMessage(clrErr + "WARNING:" + clrDesc + " setting this to less than 10 (and greater than 0) is not recommended. This can lead to nasty client glitches."); - } - } + cmdStatus(sender); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdSet.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdSet.java index 774a887..7acde84 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdSet.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdSet.java @@ -21,10 +21,13 @@ public class CmdSet extends WBCmd minParams = 1; maxParams = 4; - addCmdExample(nameEmphasized() + " [radiusZ] - set border, centered on you.", true, false, true); addCmdExample(nameEmphasizedW() + " [radiusZ] - use x/z coords."); addCmdExample(nameEmphasizedW() + " [radiusZ] ^spawn - use spawn point."); + addCmdExample(nameEmphasized() + " [radiusZ] - set border, centered on you.", true, false, true); addCmdExample(nameEmphasized() + " [radiusZ] ^player - center on player."); + helpText = "Set a border for a world, with several options for defining the center location. [world] is " + + "optional for players and defaults to the world the player is in. If [radiusZ] is not specified, the " + + "radiusX value will be used for both. The and coordinates can be decimal values (ex. 1.234)."; } @Override @@ -33,7 +36,7 @@ public class CmdSet extends WBCmd // passsing a single parameter (radiusX) is only acceptable from player if ((params.size() == 1) && player == null) { - sendErrorAndHelp(sender, "You have not provided a sufficient number of arguments."); + sendErrorAndHelp(sender, "You have not provided a sufficient number of parameters."); return; } @@ -90,7 +93,7 @@ public class CmdSet extends WBCmd z = loc.getZ(); radiusCount -= 1; } - else if (params.get(params.size() - 2).equalsIgnoreCase("player")) + else if (params.size() > 2 && params.get(params.size() - 2).equalsIgnoreCase("player")) { // player name specified for x/z coordinates Player playerT = Bukkit.getPlayer(params.get(params.size() - 1)); if (playerT == null || ! playerT.isOnline()) @@ -123,10 +126,16 @@ public class CmdSet extends WBCmd radiusZ = radiusX; else radiusZ = Integer.parseInt(params.get(1)); + + if (radiusX < Config.KnockBack() || radiusZ < Config.KnockBack()) + { + sendErrorAndHelp(sender, "Radius value(s) must be more than the knockback distance."); + return; + } } catch(NumberFormatException ex) { - sendErrorAndHelp(sender, "The radius value(s) must be integers and the x and z values must be numerical."); + sendErrorAndHelp(sender, "Radius value(s) must be integers and x and z values must be numerical."); return; } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdSetcorners.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdSetcorners.java index 6194bfa..c937237 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdSetcorners.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdSetcorners.java @@ -19,6 +19,9 @@ public class CmdSetcorners extends WBCmd minParams = maxParams = 4; addCmdExample(nameEmphasizedW() + " - corner coords."); + helpText = "This is an alternate way to set a border, by specifying the X and Z coordinates of two opposite " + + "corners of the border area ((x1, z1) to (x2, z2)). [world] is optional for players and defaults to the " + + "world the player is in."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdSetmsg.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdSetmsg.java index 3a18cb3..29d6232 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdSetmsg.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdSetmsg.java @@ -16,6 +16,16 @@ public class CmdSetmsg extends WBCmd minParams = 1; addCmdExample(nameEmphasized() + " - set border message."); + helpText = "Default value: \"&cYou have reached the edge of this world.\". This command lets you set the message shown to players who are knocked back from the border."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + sender.sendMessage(C_HEAD + "Border message is set to:"); + sender.sendMessage(Config.MessageRaw()); + sender.sendMessage(C_HEAD + "Formatted border message:"); + sender.sendMessage(Config.Message()); } @Override @@ -33,9 +43,6 @@ public class CmdSetmsg extends WBCmd Config.setMessage(message.toString()); - sender.sendMessage("Border message is now set to:"); - sender.sendMessage(Config.MessageRaw()); - sender.sendMessage("Formatted border message:"); - sender.sendMessage(Config.Message()); + cmdStatus(sender); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdShape.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdShape.java index 78830fd..1f5c4a8 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdShape.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdShape.java @@ -17,6 +17,16 @@ public class CmdShape extends WBCmd addCmdExample(nameEmphasized() + " - set the default border shape."); addCmdExample(nameEmphasized() + " - same as above."); + helpText = "Default value: round/elliptic. The default border shape will be used on all worlds which don't " + + "have an individual shape set using the " + commandEmphasized("wshape") + C_DESC + "command. Elliptic " + + "and round work the same, as rectangular and square do. The difference is down to whether the X and Z " + + "radius are the same."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + sender.sendMessage(C_HEAD + "The default border shape for all worlds is currently set to \"" + Config.ShapeName() + "\"."); } @Override @@ -29,11 +39,11 @@ public class CmdShape extends WBCmd Config.setShape(true); else { - sendErrorAndHelp(sender, "You must specify one of the 4 valid shape names as indicated below."); + sendErrorAndHelp(sender, "You must specify one of the 4 valid shape names below."); return; } if (player != null) - sender.sendMessage("Default border shape for all worlds is now set to \"" + Config.ShapeName() + "\"."); + cmdStatus(sender); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdTrim.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdTrim.java index 78361da..2941119 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdTrim.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdTrim.java @@ -20,6 +20,9 @@ public class CmdTrim extends WBCmd maxParams = 2; addCmdExample(nameEmphasizedW() + "[freq] [pad] - trim world outside of border."); + helpText = "This command will remove chunks which are outside the world's border. [freq] is the frequency " + + "of chunks per second that will be checked (default 5000). [pad] is the number of blocks padding kept " + + "beyond the border itself (default 208, to cover player visual range)."; } @Override @@ -35,7 +38,7 @@ public class CmdTrim extends WBCmd { if (!makeSureTrimIsRunning(sender)) return; - sender.sendMessage(clrHead + "Cancelling the world map trimming task."); + sender.sendMessage(C_HEAD + "Cancelling the world map trimming task."); trimDefaults(); Config.StopTrimTask(); return; @@ -45,7 +48,7 @@ public class CmdTrim extends WBCmd if (!makeSureTrimIsRunning(sender)) return; Config.trimTask.pause(); - sender.sendMessage(clrHead + "The world map trimming task is now " + (Config.trimTask.isPaused() ? "" : "un") + "paused."); + sender.sendMessage(C_HEAD + "The world map trimming task is now " + (Config.trimTask.isPaused() ? "" : "un") + "paused."); return; } @@ -65,13 +68,13 @@ public class CmdTrim extends WBCmd } // colorized "/wb trim " - String cmd = ((player == null) ? cmdC : cmdP) + nameEmphasized() + clrCmd; + String cmd = cmd(sender) + nameEmphasized() + C_CMD; // make sure Trim isn't already running if (Config.trimTask != null && Config.trimTask.valid()) { - sender.sendMessage(clrErr + "The world map trimming task is already running."); - sender.sendMessage(clrDesc + "You can cancel at any time with " + cmd + "cancel" + clrDesc + ", or pause/unpause with " + cmd + "pause" + clrDesc + "."); + sender.sendMessage(C_ERR + "The world map trimming task is already running."); + sender.sendMessage(C_DESC + "You can cancel at any time with " + cmd + "cancel" + C_DESC + ", or pause/unpause with " + cmd + "pause" + C_DESC + "."); return; } @@ -125,7 +128,7 @@ public class CmdTrim extends WBCmd sender.sendMessage("WorldBorder map trimming task for world \"" + trimWorld + "\" started."); } else - sender.sendMessage(clrErr + "The world map trimming task failed to start."); + sender.sendMessage(C_ERR + "The world map trimming task failed to start."); trimDefaults(); } @@ -137,10 +140,10 @@ public class CmdTrim extends WBCmd return; } - sender.sendMessage(clrHead + "World trimming task is ready for world \"" + trimWorld + "\", attempting to process up to " + trimFrequency + " chunks per second (default 20). The map will be trimmed past " + trimPadding + " blocks beyond the border (default " + defaultPadding + ")."); - sender.sendMessage(clrHead + "This process can take a very long time depending on the world's overall size. Also, depending on the chunk processing rate, players may experience lag for the duration."); - sender.sendMessage(clrDesc + "You should now use " + cmd + "confirm" + clrDesc + " to start the process."); - sender.sendMessage(clrDesc + "You can cancel at any time with " + cmd + "cancel" + clrDesc + ", or pause/unpause with " + cmd + "pause" + clrDesc + "."); + sender.sendMessage(C_HEAD + "World trimming task is ready for world \"" + trimWorld + "\", attempting to process up to " + trimFrequency + " chunks per second (default 20). The map will be trimmed past " + trimPadding + " blocks beyond the border (default " + defaultPadding + ")."); + sender.sendMessage(C_HEAD + "This process can take a very long time depending on the world's overall size. Also, depending on the chunk processing rate, players may experience lag for the duration."); + sender.sendMessage(C_DESC + "You should now use " + cmd + "confirm" + C_DESC + " to start the process."); + sender.sendMessage(C_DESC + "You can cancel at any time with " + cmd + "cancel" + C_DESC + ", or pause/unpause with " + cmd + "pause" + C_DESC + "."); } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdWhoosh.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdWhoosh.java index 1a60a34..6f1e90e 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdWhoosh.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdWhoosh.java @@ -16,6 +16,14 @@ public class CmdWhoosh extends WBCmd minParams = maxParams = 1; addCmdExample(nameEmphasized() + " - turn knockback effect on or off."); + helpText = "Default value: off. This will show a particle effect and play a sound where a player is knocked " + + "back from the border."; + } + + @Override + public void cmdStatus(CommandSender sender) + { + sender.sendMessage(C_HEAD + "\"Whoosh\" knockback effect is " + enabledColored(Config.whooshEffect()) + C_HEAD + "."); } @Override @@ -26,7 +34,7 @@ public class CmdWhoosh extends WBCmd if (player != null) { Config.log((Config.whooshEffect() ? "Enabled" : "Disabled") + " \"whoosh\" knockback effect at the command of player \"" + player.getName() + "\"."); - sender.sendMessage("\"Whoosh\" knockback effect " + enabledColored(Config.whooshEffect()) + "."); + cmdStatus(sender); } } } diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdWrap.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdWrap.java index 5aed90e..0a92ca2 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdWrap.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdWrap.java @@ -17,6 +17,9 @@ public class CmdWrap extends WBCmd maxParams = 2; addCmdExample(nameEmphasized() + "{world} - can make border crossings wrap."); + helpText = "When border wrapping is enabled for a world, players will be sent around to the opposite edge " + + "of the border when they cross it instead of being knocked back. [world] is optional for players and " + + "defaults to the world the player is in."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/CmdWshape.java b/src/main/java/com/wimbli/WorldBorder/cmd/CmdWshape.java index 7fd5c73..1596865 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/CmdWshape.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/CmdWshape.java @@ -17,8 +17,11 @@ public class CmdWshape extends WBCmd maxParams = 2; addCmdExample(nameEmphasized() + "{world} - shape"); - addCmdExample(clrDesc + " override for a single world.", true, true, false); + addCmdExample(C_DESC + " override for a single world.", true, true, false); addCmdExample(nameEmphasized() + "{world} - same as above."); + helpText = "This will override the default border shape for a single world. The value \"default\" implies " + + "a world is just using the default border shape. See the " + commandEmphasized("shape") + C_DESC + + "command for more info and to set the default border shape."; } @Override diff --git a/src/main/java/com/wimbli/WorldBorder/cmd/WBCmd.java b/src/main/java/com/wimbli/WorldBorder/cmd/WBCmd.java index 284eea1..40ed158 100644 --- a/src/main/java/com/wimbli/WorldBorder/cmd/WBCmd.java +++ b/src/main/java/com/wimbli/WorldBorder/cmd/WBCmd.java @@ -26,27 +26,35 @@ public abstract class WBCmd public int minParams = 0; public int maxParams = 9999; + // help/explanation text to be shown after command example(s) for this command + public String helpText = null; + /* * The guts of the command run in here; needs to be overriden in the subclassed commands */ public abstract void execute(CommandSender sender, Player player, List params, String worldName); + /* + * This is an optional override, used to provide some extra command status info, like the currently set value + */ + public void cmdStatus(CommandSender sender) {} + /* * Helper variables and methods */ // color values for strings - public final static String clrCmd = ChatColor.AQUA.toString(); // main commands - public final static String clrDesc = ChatColor.WHITE.toString(); // command descriptions - public final static String clrErr = ChatColor.RED.toString(); // errors / notices - public final static String clrHead = ChatColor.YELLOW.toString(); // command listing header - public final static String clrOpt = ChatColor.DARK_GREEN.toString(); // optional values - public final static String clrReq = ChatColor.GREEN.toString(); // required values + public final static String C_CMD = ChatColor.AQUA.toString(); // main commands + public final static String C_DESC = ChatColor.WHITE.toString(); // command descriptions + public final static String C_ERR = ChatColor.RED.toString(); // errors / notices + public final static String C_HEAD = ChatColor.YELLOW.toString(); // command listing header + public final static String C_OPT = ChatColor.DARK_GREEN.toString(); // optional values + public final static String C_REQ = ChatColor.GREEN.toString(); // required values // colorized root command, for console and for player - public final static String cmdC = clrCmd + "wb "; - public final static String cmdP = clrCmd + "/wb "; + public final static String CMD_C = C_CMD + "wb "; + public final static String CMD_P = C_CMD + "/wb "; // list of command examples for this command to be displayed as usage reference, separate between players and console // ... these generally should be set indirectly using addCmdExample() within the constructor for each command class @@ -57,7 +65,7 @@ public abstract class WBCmd public final static List cmdExamplesConsole = new ArrayList(48); // 48 command capacity, 6 full pages public final static List cmdExamplesPlayer = new ArrayList(48); // still, could need to increase later - + // add command examples for use the default "/wb" command list and for internal usage reference, formatted and colorized public void addCmdExample(String example) { @@ -66,33 +74,39 @@ public abstract class WBCmd public void addCmdExample(String example, boolean forPlayer, boolean forConsole, boolean prefix) { // go ahead and colorize required "<>" and optional "[]" parameters, extra command words, and description - example = example.replace("<", clrReq+"<").replace("[", clrOpt+"[").replace("^", clrCmd).replace("- ", clrDesc+"- "); + example = example.replace("<", C_REQ+"<").replace("[", C_OPT+"[").replace("^", C_CMD).replace("- ", C_DESC+"- "); // all "{}" are replaced by "[]" (optional) for player, "<>" (required) for console if (forPlayer) { - String exampleP = (prefix ? cmdP : "") + example.replace("{", clrOpt + "[").replace("}", "]"); + String exampleP = (prefix ? CMD_P : "") + example.replace("{", C_OPT + "[").replace("}", "]"); cmdExamplePlayer.add(exampleP); cmdExamplesPlayer.add(exampleP); } if (forConsole) { - String exampleC = (prefix ? cmdC : "") + example.replace("{", clrReq + "<").replace("}", ">"); + String exampleC = (prefix ? CMD_C : "") + example.replace("{", C_REQ + "<").replace("}", ">"); cmdExampleConsole.add(exampleC); cmdExamplesConsole.add(exampleC); } } + // return root command formatted for player or console, based on sender + public String cmd(CommandSender sender) + { + return (sender instanceof Player) ? CMD_P : CMD_C; + } + // formatted and colorized text, intended for marking command name public String commandEmphasized(String text) { - return clrCmd + ChatColor.UNDERLINE + text + ChatColor.RESET + " "; + return C_CMD + ChatColor.UNDERLINE + text + ChatColor.RESET + " "; } // returns green "enabled" or red "disabled" text public String enabledColored(boolean enabled) { - return enabled ? clrReq+"enabled" : clrErr+"disabled"; + return enabled ? C_REQ+"enabled" : C_ERR+"disabled"; } // formatted and colorized command name, optionally prefixed with "[world]" (for player) / "" (for console) @@ -105,19 +119,22 @@ public abstract class WBCmd return "{world} " + nameEmphasized(); } - // send command example message(s) + // send command example message(s) and other helpful info public void sendCmdHelp(CommandSender sender) { for (String example : ((sender instanceof Player) ? cmdExamplePlayer : cmdExampleConsole)) { sender.sendMessage(example); } + cmdStatus(sender); + if (helpText != null && !helpText.isEmpty()) + sender.sendMessage(C_DESC + helpText); } // send error message followed by command example message(s) public void sendErrorAndHelp(CommandSender sender, String error) { - sender.sendMessage(clrErr + error); + sender.sendMessage(C_ERR + error); sendCmdHelp(sender); }