New command: /wb help [command] - get help on command usage. This provides further help for any specified command. Accordingly, help info has been added to every command. This info is also provided if there was an error with the command parameters passed to any given command.

Some further changes as well, including some minor code design improvement. As part of that, the root plugin's GetWorldBorder(String worldName) method has been deprecated and replaced with proper first-letter capitalization: getWorldBorder(String worldName).

All commands have now been tested in-game and through console, and a couple of remaining command bugs have been fixed.
This commit is contained in:
Brettflan 2014-03-10 22:27:42 -05:00
parent cd9ee900ae
commit 1faccf0a25
30 changed files with 375 additions and 123 deletions

View File

@ -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<String, WBCmd> subCommands = new LinkedHashMap<String, WBCmd>();
public Map<String, WBCmd> subCommands = new LinkedHashMap<String, WBCmd>();
// ref. list of the commands which can have a world name in front of the command itself (ex. /wb _world_ radius 100)
private Set<String> subCommandsWithWorldNames = new LinkedHashSet<String>();
// 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<String> instead of input primitive String[]
private List<String> concatenateQuotedWorldName(String[] split)
{
@ -191,4 +200,13 @@ public class WBCommand implements CommandExecutor
return args;
}
public Set<String> getCommandNames()
{
// using TreeSet to sort alphabetically
Set<String> 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;
}
}

View File

@ -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);
}
}

View File

@ -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) + ".");
}

View File

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

View File

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

View File

@ -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 + "<required> " + clrOpt + "[optional]" );
sender.sendMessage( C_HEAD + WorldBorder.plugin.getDescription().getFullName() + " - key: " +
commandEmphasized("command") + C_REQ + "<required> " + 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
{

View File

@ -16,6 +16,14 @@ public class CmdDebug extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<on|off> - 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);
}
}
}

View File

@ -16,6 +16,15 @@ public class CmdDelay extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<amount> - time between border checks.");
helpText = "Default value: 5. The <amount> 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);
}
}

View File

@ -16,6 +16,16 @@ public class CmdDenypearl extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<on|off> - 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);
}
}
}

View File

@ -16,6 +16,14 @@ public class CmdDynmap extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<on|off> - 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() + "\".");
}
}

View File

@ -16,6 +16,15 @@ public class CmdDynmapmsg extends WBCmd
minParams = 1;
addCmdExample(nameEmphasized() + "<text> - 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);
}
}

View File

@ -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 + ".");
}
}

View File

@ -16,6 +16,25 @@ public class CmdFillautosave extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<seconds> - 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);
}
}

View File

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

View File

@ -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<String> params, String worldName)
{
if (params.isEmpty())
{
sendCmdHelp(sender);
return;
}
Set<String> 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.");
}
}

View File

@ -16,6 +16,17 @@ public class CmdKnockback extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<distance> - 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);
}
}

View File

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

View File

@ -16,6 +16,15 @@ public class CmdPortal extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<on|off> - 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);
}
}
}

View File

@ -18,6 +18,8 @@ public class CmdRadius extends WBCmd
maxParams = 2;
addCmdExample(nameEmphasizedW() + "<radiusX> [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

View File

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

View File

@ -16,6 +16,23 @@ public class CmdRemount extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<amount> - 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);
}
}

View File

@ -21,10 +21,13 @@ public class CmdSet extends WBCmd
minParams = 1;
maxParams = 4;
addCmdExample(nameEmphasized() + "<radiusX> [radiusZ] - set border, centered on you.", true, false, true);
addCmdExample(nameEmphasizedW() + "<radiusX> [radiusZ] <x> <z> - use x/z coords.");
addCmdExample(nameEmphasizedW() + "<radiusX> [radiusZ] ^spawn - use spawn point.");
addCmdExample(nameEmphasized() + "<radiusX> [radiusZ] - set border, centered on you.", true, false, true);
addCmdExample(nameEmphasized() + "<radiusX> [radiusZ] ^player <name> - 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 <x> and <z> 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;
}

View File

@ -19,6 +19,9 @@ public class CmdSetcorners extends WBCmd
minParams = maxParams = 4;
addCmdExample(nameEmphasizedW() + "<x1> <z1> <x2> <z2> - 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

View File

@ -16,6 +16,16 @@ public class CmdSetmsg extends WBCmd
minParams = 1;
addCmdExample(nameEmphasized() + "<text> - 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);
}
}

View File

@ -17,6 +17,16 @@ public class CmdShape extends WBCmd
addCmdExample(nameEmphasized() + "<round|square> - set the default border shape.");
addCmdExample(nameEmphasized() + "<elliptic|rectangular> - 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);
}
}

View File

@ -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 + ".");
}
}

View File

@ -16,6 +16,14 @@ public class CmdWhoosh extends WBCmd
minParams = maxParams = 1;
addCmdExample(nameEmphasized() + "<on|off> - 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);
}
}
}

View File

@ -17,6 +17,9 @@ public class CmdWrap extends WBCmd
maxParams = 2;
addCmdExample(nameEmphasized() + "{world} <on|off> - 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

View File

@ -17,8 +17,11 @@ public class CmdWshape extends WBCmd
maxParams = 2;
addCmdExample(nameEmphasized() + "{world} <elliptic|rectangular|default> - 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} <round|square|default> - 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

View File

@ -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<String> 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<String> cmdExamplesConsole = new ArrayList<String>(48); // 48 command capacity, 6 full pages
public final static List<String> cmdExamplesPlayer = new ArrayList<String>(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) / "<world>" (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);
}