Partial Overhaul of Commands

Made progress on overhauling and prettifying our commands. There are
still more changes to be done for this to be functional. I need to do an
intermediate commit because I want to merge in recent changes by Steven.
This commit is contained in:
SenseiKiwi 2013-06-25 13:55:13 -04:00
parent 06a8abbf74
commit bc2745a596
14 changed files with 425 additions and 226 deletions

View file

@ -200,19 +200,9 @@ public class DimData implements Serializable
this.dimY=new HashMap<Integer, HashMap<Integer, LinkData>>(); this.dimY=new HashMap<Integer, HashMap<Integer, LinkData>>();
} }
this.dimX.remove(locationXCoord); this.dimX.remove(locationXCoord);
this.dimY.put(locationYCoord, dimX); this.dimY.put(locationYCoord, dimX);
this.linksInThisDim.put(locationZCoord, dimY); this.linksInThisDim.put(locationZCoord, dimY);
} }
public LinkData findLinkAtCoords(int locationXCoord, int locationYCoord, int locationZCoord) public LinkData findLinkAtCoords(int locationXCoord, int locationYCoord, int locationZCoord)
@ -239,40 +229,29 @@ public class DimData implements Serializable
{ {
return null; return null;
} }
return null; return null;
} }
public ArrayList<LinkData> printAllLinkData() public ArrayList<LinkData> printAllLinkData()
{ {
ArrayList links = new ArrayList(); //TODO: We might want to modify this function, but I'm afraid of breaking something right now.
//To begin with, the name is wrong. This doesn't print anything! >_o ~SenseiKiwi
ArrayList<LinkData> links = new ArrayList<LinkData>();
if (this.linksInThisDim == null) if (this.linksInThisDim == null)
{ {
return links; return links;
} }
for (HashMap<Integer, HashMap<Integer, LinkData>> first : this.linksInThisDim.values()) for (HashMap<Integer, HashMap<Integer, LinkData>> first : this.linksInThisDim.values())
{ {
for (HashMap<Integer, LinkData> second : first.values()) for (HashMap<Integer, LinkData> second : first.values())
{ {
for (LinkData linkData : second.values()) for (LinkData linkData : second.values())
{ {
links.add(linkData); links.add(linkData);
} }
} }
} }
return links; return links;
} }
} }

View file

@ -16,9 +16,6 @@ public class LinkData implements Serializable
public boolean isLocPocket; public boolean isLocPocket;
public int linkOrientation; public int linkOrientation;
public int destDimID; public int destDimID;
public int locDimID; public int locDimID;
@ -43,7 +40,6 @@ public class LinkData implements Serializable
public LinkData(int locationDimID, int destinationDimID, int locationXCoord, int locationYCoord, int locationZCoord, int destinationXCoord, int destinationYCoord, int destinationZCoord, boolean isPocket,int orientation) public LinkData(int locationDimID, int destinationDimID, int locationXCoord, int locationYCoord, int locationZCoord, int destinationXCoord, int destinationYCoord, int destinationZCoord, boolean isPocket,int orientation)
{ {
this.exists = true; this.exists = true;
this.locXCoord=locationXCoord; this.locXCoord=locationXCoord;
this.locYCoord=locationYCoord; this.locYCoord=locationYCoord;
@ -57,20 +53,16 @@ public class LinkData implements Serializable
this.locDimID=locationDimID; this.locDimID=locationDimID;
this.isLocPocket=isPocket; this.isLocPocket=isPocket;
this.linkOrientation=orientation; this.linkOrientation=orientation;
} }
public String printLinkData() public String printLinkData()
{ {
//TODO: Rewrite this to make it prettier. @_@ I'm afraid of changing it to ToString() on the off
//chance it'll cause explosions and sadness. Damn serialization! ~SenseiKiwi
String linkInfo; String linkInfo;
linkInfo = String.valueOf(this.locDimID) + "locDimID "+String.valueOf(this.locXCoord)+":locXCoord "+String.valueOf(this.locYCoord)+":locYCoord "+String.valueOf(this.locZCoord)+":locZCoord "; linkInfo = String.valueOf(this.locDimID) + "locDimID "+String.valueOf(this.locXCoord)+":locXCoord "+String.valueOf(this.locYCoord)+":locYCoord "+String.valueOf(this.locZCoord)+":locZCoord ";
linkInfo.concat("\n"+ String.valueOf(this.destDimID)+"DestDimID "+String.valueOf(this.destXCoord)+":destXCoord "+String.valueOf(this.destYCoord)+":destYCoord "+String.valueOf(this.destZCoord)+":destZCoord "); linkInfo.concat("\n"+ String.valueOf(this.destDimID)+"DestDimID "+String.valueOf(this.destXCoord)+":destXCoord "+String.valueOf(this.destYCoord)+":destYCoord "+String.valueOf(this.destZCoord)+":destZCoord ");
return linkInfo; return linkInfo;
} }
} }

View file

@ -1,9 +1,9 @@
package StevenDimDoors.mod_pocketDim.commands; package StevenDimDoors.mod_pocketDim.commands;
import java.io.File;
import java.util.Collection; import java.util.Collection;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import StevenDimDoors.mod_pocketDim.DungeonGenerator; import StevenDimDoors.mod_pocketDim.DungeonGenerator;
import StevenDimDoors.mod_pocketDim.LinkData; import StevenDimDoors.mod_pocketDim.LinkData;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper; import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
@ -15,7 +15,7 @@ public class CommandCreateDungeonRift extends DDCommandBase
private CommandCreateDungeonRift() private CommandCreateDungeonRift()
{ {
super("dd-rift"); super("dd-rift", "<dungeon name | 'list' | 'random'>");
} }
public static CommandCreateDungeonRift instance() public static CommandCreateDungeonRift instance()
@ -27,71 +27,101 @@ public class CommandCreateDungeonRift extends DDCommandBase
} }
@Override @Override
public void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
DungeonHelper dungeonHelper = DungeonHelper.instance(); DungeonHelper dungeonHelper = DungeonHelper.instance();
if(command==null||sender.worldObj.isRemote) if (sender.worldObj.isRemote)
{ {
return; return DDCommandResult.SUCCESS;
}
if (command.length == 0)
{
return DDCommandResult.TOO_FEW_ARGUMENTS;
}
if (command.length > 1)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
} }
LinkData link = new LinkData(sender.worldObj.provider.dimensionId, 0, if (command[0].equals("list"))
(int) sender.posX,
(int) sender.posY + 1,
(int) sender.posZ,
(int) sender.posX,
(int) sender.posY + 1,
(int) sender.posZ,true,3);
if(command.length!=0&&command[0].equals("random"))
{
sender.sendChatToPlayer("Created dungeon rift");
dimHelper.instance.createLink(link);
link = dimHelper.instance.createPocket(link,true, true);
}
else if (command.length != 0 && command[0].equals("list"))
{ {
Collection<String> dungeonNames = dungeonHelper.getDungeonNames(); Collection<String> dungeonNames = dungeonHelper.getDungeonNames();
for (String name : dungeonNames) for (String name : dungeonNames)
{ {
getCommandSenderAsPlayer(sender).sendChatToPlayer(name); sender.sendChatToPlayer(name);
}
}
else if(command.length!=0)
{
for(DungeonGenerator dungeonGen : dungeonHelper.registeredDungeons)
{
String dungeonName =dungeonGen.schematicPath.toLowerCase();
if(dungeonName.contains(command[0].toLowerCase()))
{
link = dimHelper.instance.createPocket(link,true, true);
dimHelper.dimList.get(link.destDimID).dungeonGenerator=dungeonGen;
sender.sendChatToPlayer("Genned dungeon " +dungeonName);
return;
}
}
for(DungeonGenerator dungeonGen : dungeonHelper.customDungeons)
{
String dungeonName =dungeonGen.schematicPath.toLowerCase();
if(dungeonName.contains(command[0].toLowerCase()))
{
link = dimHelper.instance.createPocket(link,true, true);
dimHelper.dimList.get(link.destDimID).dungeonGenerator=dungeonGen;
sender.sendChatToPlayer("Genned dungeon " +dungeonName);
return;
}
}
if(command!=null&&!command[0].equals("random"))
{
sender.sendChatToPlayer("could not find dungeon, 'list' for list of dungeons");
} }
sender.sendChatToPlayer("");
} }
else else
{ {
sender.sendChatToPlayer("invalid arguments- 'random' for random dungeon, or 'list' for dungeon names"); DungeonGenerator result;
int x = (int) sender.posX;
int y = (int) sender.posY;
int z = (int) sender.posZ;
LinkData link = new LinkData(sender.worldObj.provider.dimensionId, 0, x, y + 1, z, x, y + 1, z, true, 3);
if (command[0].equals("random"))
{
dimHelper.instance.createLink(link);
link = dimHelper.instance.createPocket(link, true, true);
sender.sendChatToPlayer("Created a rift to a random dungeon (Dimension ID = " + link.destDimID + ").");
}
else
{
result = findDungeonByPartialName(command[0], dungeonHelper.registeredDungeons);
if (result == null)
{
result = findDungeonByPartialName(command[0], dungeonHelper.customDungeons);
}
//Check if we found any matches
if (result != null)
{
//Create a rift to our selected dungeon and notify the player
link = dimHelper.instance.createPocket(link, true, true);
dimHelper.dimList.get(link.destDimID).dungeonGenerator = result;
sender.sendChatToPlayer("Created a rift to \"" + getSchematicName(result) + "\" dungeon (Dimension ID = " + link.destDimID + ").");
}
else
{
//No matches!
return new DDCommandResult("Error: The specified dungeon was not found. Use 'list' to see a list of the available dungeons.");
} }
} }
} }
return DDCommandResult.SUCCESS;
}
private DungeonGenerator findDungeonByPartialName(String query, Collection<DungeonGenerator> dungeons)
{
//Search for the shortest dungeon name that contains the lowercase query string.
String dungeonName;
String normalQuery = query.toLowerCase();
DungeonGenerator bestMatch = null;
int matchLength = Integer.MAX_VALUE;
for (DungeonGenerator dungeon : dungeons)
{
//We need to extract the file's name. Comparing against schematicPath could
//yield false matches if the query string is contained within the path.
dungeonName = getSchematicName(dungeon).toLowerCase();
if (dungeonName.length() < matchLength && dungeonName.contains(normalQuery))
{
matchLength = dungeonName.length();
bestMatch = dungeon;
}
}
return bestMatch;
}
private static String getSchematicName(DungeonGenerator dungeon)
{
//TODO: Move this to DungeonHelper and use it for all schematic name parsing.
//In the future, we really should include the schematic's name as part of DungeonGenerator
//to avoid redoing this work constantly.
File schematic = new File(dungeon.schematicPath);
String fileName = schematic.getName();
return fileName.substring(0, fileName.length() - DungeonHelper.SCHEMATIC_FILE_EXTENSION.length());
}
}

View file

@ -26,7 +26,7 @@ public class CommandDeleteAllLinks extends DDCommandBase
} }
@Override @Override
protected void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
int linksRemoved=0; int linksRemoved=0;
int targetDim; int targetDim;

View file

@ -26,7 +26,7 @@ public class CommandDeleteDimensionData extends DDCommandBase
} }
@Override @Override
protected void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
int linksRemoved=0; int linksRemoved=0;
int targetDim; int targetDim;

View file

@ -27,7 +27,7 @@ public class CommandDeleteRifts extends DDCommandBase
} }
@Override @Override
protected void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
int linksRemoved=0; int linksRemoved=0;
int targetDim; int targetDim;

View file

@ -12,7 +12,9 @@ public class CommandEndDungeonCreation extends DDCommandBase
private CommandEndDungeonCreation() private CommandEndDungeonCreation()
{ {
super("dd-export"); super("dd-export", new String[] {
"<dungeon type> <dungeon name> <'open' | 'closed'> [weight] ['override']",
"<schematic name> override" } );
} }
public static CommandEndDungeonCreation instance() public static CommandEndDungeonCreation instance()
@ -24,57 +26,160 @@ public class CommandEndDungeonCreation extends DDCommandBase
} }
@Override @Override
protected void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
DungeonHelper dungeonHelper = DungeonHelper.instance(); /*
DDProperties properties = DDProperties.instance(); * There are two versions of this command. One version takes 3 to 5 arguments consisting
* of the information needed for a proper schematic name and an optional override argument.
* The override argument only allows the user to export any dimension, even if it wasn't
* meant for custom dungeon creation. It does not allow the user to export a dungeon with
* invalid tags.
*
* If the user wishes to name his schematic in a different format, then he will have to use
* the 2-argument version of this command, which accepts a schematic name and a mandatory
* override argument.
*/
DungeonHelper dungeonHelper = DungeonHelper.instance();
if (!dungeonHelper.isCustomDungeon(sender.worldObj.provider.dimensionId))
{
if (command.length < 2) if (command.length < 2)
{ {
sender.sendChatToPlayer("Must have started dungeon creation, use argument OVERRIDE to export anyway"); return DDCommandResult.TOO_FEW_ARGUMENTS;
return; }
if (command.length > 5)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
} }
else if (!command[1].contains("OVERRIDE")) //Check if we received the 2-argument version
if (command.length == 2)
{ {
sender.sendChatToPlayer("Must have started dungeon creation, use argument OVERRIDE to export anyway"); if (command[1].equalsIgnoreCase("override"))
return; {
//Check that the schematic name is a legal name
if (DungeonHelper.SchematicNamePattern.matcher(command[0]).matches())
{
//Export the schematic
return exportDungeon(sender, command[0]);
}
else
{
//The schematic name contains illegal characters. Inform the user.
return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores.");
}
}
else
{
//The command is malformed in some way. Assume that the user meant to use
//the 3-argument version and report an error.
return DDCommandResult.TOO_FEW_ARGUMENTS;
}
} }
//The user must have used the 3-argument version of this command
//Check if the current dimension is a pocket for building custom dungeons or if the override argument was used.
if (!dungeonHelper.isCustomDungeon(sender.worldObj.provider.dimensionId) ||
!command[command.length - 1].equalsIgnoreCase("override"))
{
//This dimension may not be exported without overriding!
return new DDCommandResult("Error: The current dimension was not made for dungeon creation. Use the 'override' argument to export anyway.");
} }
int x = (int) sender.posX; //TODO: Why do we check remoteness here but not before? And why not for the other export case?
int y = (int) sender.posY; //Something feels wrong... ~SenseiKiwi
int z = (int) sender.posZ;
if (command.length == 0) if (!sender.worldObj.isRemote)
{ {
sender.sendChatToPlayer("Must name file"); //TODO: This validation should be in DungeonHelper or in another class. We should move it
//once the during the save file format rewrite. ~SenseiKiwi
if (!dungeonHelper.validateDungeonType(command[0]))
{
return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types.");
} }
else if(!sender.worldObj.isRemote) if (!DungeonHelper.DungeonNamePattern.matcher(command[1]).matches())
{ {
//Check that the dungeon name is valid to prevent directory traversal and other forms of abuse return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes.");
if (DungeonHelper.NamePattern.matcher(command[0]).matches()) }
if (!command[2].equalsIgnoreCase("open") && !command[2].equalsIgnoreCase("closed"))
{ {
String exportPath = properties.CustomSchematicDirectory + "/" + command[0] + ".schematic"; return new DDCommandResult("Error: Please specify whether the dungeon is 'open' or 'closed'.");
if (dungeonHelper.exportDungeon(sender.worldObj, x, y, z, exportPath)) }
//If there are no more argument, export the dungeon.
if (command.length == 3)
{ {
sender.sendChatToPlayer("Saved dungeon schematic in " + exportPath); return exportDungeon(sender, join(command, "_", 0, 3));
}
//Validate the 4th argument, which might be the weight or might be "override".
try
{
int weight = Integer.parseInt(command[3]);
if (weight >= 0 && weight <= DungeonHelper.MAX_DUNGEON_WEIGHT)
{
return exportDungeon(sender, join(command, "_", 0, 4));
}
}
catch (Exception e)
{
//The 4th argument could be "override", but only if it's the last argument.
//In that case, we assume the default dungeon weight.
if (command.length == 4 && command[3].equalsIgnoreCase("override"))
{
return exportDungeon(sender, join(command, "_", 0, 3));
}
}
//If we've reached this point, then we must have an invalid weight.
return new DDCommandResult("Invalid dungeon weight. Please specify a weight between 0 and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive.");
}
return DDCommandResult.SUCCESS;
}
private static DDCommandResult exportDungeon(EntityPlayer player, String name)
{
DDProperties properties = DDProperties.instance();
DungeonHelper dungeonHelper = DungeonHelper.instance();
int x = (int) player.posX;
int y = (int) player.posY;
int z = (int) player.posZ;
String exportPath = properties.CustomSchematicDirectory + File.separator + name + ".schematic";
if (dungeonHelper.exportDungeon(player.worldObj, x, y, z, exportPath))
{
player.sendChatToPlayer("Saved dungeon schematic in " + exportPath);
dungeonHelper.registerCustomDungeon(new File(exportPath)); dungeonHelper.registerCustomDungeon(new File(exportPath));
return DDCommandResult.SUCCESS;
} }
else else
{ {
sender.sendChatToPlayer("Failed to save dungeon schematic!"); return new DDCommandResult("Error: Failed to save dungeon schematic!");
} }
} }
else
private static String join(String[] source, String delimiter, int start, int end)
{ {
sender.sendChatToPlayer("Invalid schematic name. Please use only letters, numbers, and underscores."); //TODO: This function should be moved to a helper, but we have several single-function helpers as is.
} //I find that to be worse than keeping this private. ~SenseiKiwi
}
int index;
int length = 0;
StringBuilder buffer;
for (index = start; index < end; index++)
{
length += source[index].length();
}
length += (end - start - 1) * delimiter.length();
buffer = new StringBuilder(length);
buffer.append(source[start]);
for (index = start + 1; index < end; index++)
{
buffer.append(delimiter);
buffer.append(source[index]);
}
return buffer.toString();
} }
} }

View file

@ -1,7 +1,6 @@
package StevenDimDoors.mod_pocketDim.commands; package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import StevenDimDoors.mod_pocketDim.DimData; import StevenDimDoors.mod_pocketDim.DimData;
@ -14,7 +13,7 @@ public class CommandPrintDimensionData extends DDCommandBase
private CommandPrintDimensionData() private CommandPrintDimensionData()
{ {
super("dd-dimensiondata"); super("dd-dimensiondata", "[dimension number]");
} }
public static CommandPrintDimensionData instance() public static CommandPrintDimensionData instance()
@ -26,10 +25,10 @@ public class CommandPrintDimensionData extends DDCommandBase
} }
@Override @Override
protected void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
int targetDim; int targetDim;
boolean shouldGo= true; DimData dimData;
if (command.length == 0) if (command.length == 0)
{ {
@ -37,34 +36,34 @@ public class CommandPrintDimensionData extends DDCommandBase
} }
else if (command.length == 1) else if (command.length == 1)
{ {
targetDim = parseInt(sender, command[0]); try
if(!dimHelper.dimList.containsKey(targetDim))
{ {
sender.sendChatToPlayer("Error- dim "+targetDim+" not registered"); targetDim = Integer.parseInt(command[0]);
shouldGo=false; }
catch (Exception ex)
{
return DDCommandResult.INVALID_DIMENSION_ID;
} }
} }
else else
{ {
targetDim=0; return DDCommandResult.TOO_MANY_ARGUMENTS;
shouldGo=false;
sender.sendChatToPlayer("Error-Invalid argument, print_dim_data <targetDimID> or blank for current dim");
} }
if(shouldGo) dimData = dimHelper.dimList.get(targetDim);
if (dimData == null)
{ {
if(dimHelper.dimList.containsKey(targetDim)) return DDCommandResult.UNREGISTERED_DIMENSION;
{ }
DimData dimData = dimHelper.dimList.get(targetDim);
Collection<LinkData> links = new ArrayList<LinkData>();
links.addAll( dimData.printAllLinkData());
ArrayList<LinkData> links = dimData.printAllLinkData();
sender.sendChatToPlayer("Dimension ID = " + dimData.dimID);
sender.sendChatToPlayer("Dimension Depth = " + dimData.depth);
for (LinkData link : links) for (LinkData link : links)
{ {
sender.sendChatToPlayer(link.printLinkData()); sender.sendChatToPlayer(link.printLinkData());
} }
sender.sendChatToPlayer("DimID= "+dimData.dimID+"Dim depth = "+dimData.depth); return DDCommandResult.SUCCESS;
}
}
} }
} }

View file

@ -26,7 +26,7 @@ public class CommandPruneDimensions extends DDCommandBase
} }
@Override @Override
protected void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
int numRemoved=0; int numRemoved=0;
ArrayList<Integer> dimsWithLinks = new ArrayList<Integer>(); ArrayList<Integer> dimsWithLinks = new ArrayList<Integer>();

View file

@ -26,7 +26,7 @@ public class CommandRegenPocket extends DDCommandBase
} }
@Override @Override
protected void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
DungeonHelper dungeonHelper = DungeonHelper.instance(); DungeonHelper dungeonHelper = DungeonHelper.instance();
DDProperties properties = DDProperties.instance(); DDProperties properties = DDProperties.instance();

View file

@ -10,7 +10,7 @@ public class CommandStartDungeonCreation extends DDCommandBase
private CommandStartDungeonCreation() private CommandStartDungeonCreation()
{ {
super("dd-create"); super("dd-create", "");
} }
public static CommandStartDungeonCreation instance() public static CommandStartDungeonCreation instance()
@ -22,10 +22,18 @@ public class CommandStartDungeonCreation extends DDCommandBase
} }
@Override @Override
protected void processCommand(EntityPlayer sender, String[] command) protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{ {
//TODO: Some commands have isRemote checks, some do not. Why? Can commands even run locally anyway?
//What does it mean when you run a command locally? ~SenseiKiwi
if (!sender.worldObj.isRemote) if (!sender.worldObj.isRemote)
{ {
if (command.length > 0)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
//Place a door leading to a pocket dimension where the player is standing. //Place a door leading to a pocket dimension where the player is standing.
//The pocket dimension will be serve as a room for the player to build a dungeon. //The pocket dimension will be serve as a room for the player to build a dungeon.
int x = (int) sender.posX; int x = (int) sender.posX;
@ -34,7 +42,8 @@ public class CommandStartDungeonCreation extends DDCommandBase
LinkData link = DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z); LinkData link = DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z);
//Notify the player //Notify the player
sender.sendChatToPlayer("Created a door to a pocket dimension (ID = " + link.destDimID + "). Please build your dungeon there."); sender.sendChatToPlayer("Created a door to a pocket dimension (Dimension ID = " + link.destDimID + "). Please build your dungeon there.");
} }
return DDCommandResult.SUCCESS;
} }
} }

View file

@ -12,16 +12,25 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent;
public abstract class DDCommandBase extends CommandBase public abstract class DDCommandBase extends CommandBase
{ {
private String name; private String name;
private String[] formats;
public DDCommandBase(String name) public DDCommandBase(String name, String format)
{ {
this.name = name; this.name = name;
this.formats = new String[] { format };
}
public DDCommandBase(String name, String[] formats)
{
this.name = name;
this.formats = formats;
} }
/* /*
* When overridden in a derived class, processes the command sent by the server. * When overridden in a derived class, processes the command sent by the server
* and returns a status code and message for the result of the operation.
*/ */
protected abstract void processCommand(EntityPlayer sender, String[] command); protected abstract DDCommandResult processCommand(EntityPlayer sender, String[] command);
public final String getCommandName() public final String getCommandName()
{ {
@ -43,6 +52,21 @@ public abstract class DDCommandBase extends CommandBase
public final void processCommand(ICommandSender sender, String[] command) public final void processCommand(ICommandSender sender, String[] command)
{ {
//Forward the command //Forward the command
processCommand(getCommandSenderAsPlayer(sender), command); EntityPlayer player = getCommandSenderAsPlayer(sender);
DDCommandResult result = processCommand(player, command);
//If the command failed, send the player a status message.
if (result.failed())
{
if (result.shouldPrintUsage())
{
//Send the argument formats for this command
for (String format : formats)
{
player.sendChatToPlayer("Usage: " + name + " " + format);
}
}
player.sendChatToPlayer(result.getMessage());
}
} }
} }

View file

@ -0,0 +1,54 @@
package StevenDimDoors.mod_pocketDim.commands;
public class DDCommandResult {
public static final DDCommandResult SUCCESS = new DDCommandResult(0, "", false);
public static final DDCommandResult TOO_FEW_ARGUMENTS = new DDCommandResult(1, "Error: Too few arguments passed to the command", true);
public static final DDCommandResult TOO_MANY_ARGUMENTS = new DDCommandResult(2, "Error: Too many arguments passed to the command", true);
public static final DDCommandResult INVALID_DIMENSION_ID = new DDCommandResult(3, "Error: Invalid dimension ID", true);
public static final DDCommandResult UNREGISTERED_DIMENSION = new DDCommandResult(4, "Error: Dimension is not registered", false);
public static final int CUSTOM_ERROR_CODE = -1;
private int code;
private String message;
private boolean printUsage;
private DDCommandResult(int code, String message, boolean printUsage)
{
this.code = code;
this.message = message;
this.printUsage = printUsage;
}
public DDCommandResult(String message)
{
this(CUSTOM_ERROR_CODE, message, false);
}
public DDCommandResult(String message, boolean printUsage)
{
this(CUSTOM_ERROR_CODE, message, printUsage);
}
public boolean failed()
{
return (code != 0);
}
public int getCode()
{
return code;
}
public String getMessage()
{
return message;
}
public boolean shouldPrintUsage()
{
return printUsage;
}
}

View file

@ -31,11 +31,12 @@ public class DungeonHelper
{ {
private static DungeonHelper instance = null; private static DungeonHelper instance = null;
private static DDProperties properties = null; private static DDProperties properties = null;
public static final Pattern NamePattern = Pattern.compile("[A-Za-z0-9_\\-]+"); public static final Pattern SchematicNamePattern = Pattern.compile("[A-Za-z0-9_\\-]+");
public static final Pattern DungeonNamePattern = Pattern.compile("[A-Za-z0-9\\-]+");
private static final String SCHEMATIC_FILE_EXTENSION = ".schematic"; public static final String SCHEMATIC_FILE_EXTENSION = ".schematic";
private static final int DEFAULT_DUNGEON_WEIGHT = 100; private static final int DEFAULT_DUNGEON_WEIGHT = 100;
private static final int MAX_DUNGEON_WEIGHT = 10000; //Used to prevent overflows and math breaking down public static final int MAX_DUNGEON_WEIGHT = 10000; //Used to prevent overflows and math breaking down
private static final String HUB_DUNGEON_TYPE = "Hub"; private static final String HUB_DUNGEON_TYPE = "Hub";
private static final String TRAP_DUNGEON_TYPE = "Trap"; private static final String TRAP_DUNGEON_TYPE = "Trap";
@ -166,6 +167,12 @@ public class DungeonHelper
return customDungeonStatus.containsKey(dimensionID); return customDungeonStatus.containsKey(dimensionID);
} }
public boolean validateDungeonType(String type)
{
//Check if the dungeon type is valid
return dungeonTypeChecker.contains(type.toLowerCase());
}
public boolean validateSchematicName(String name) public boolean validateSchematicName(String name)
{ {
String[] dungeonData; String[] dungeonData;
@ -184,7 +191,7 @@ public class DungeonHelper
return false; return false;
//Check if the name is valid //Check if the name is valid
if (!NamePattern.matcher(dungeonData[1]).matches()) if (!SchematicNamePattern.matcher(dungeonData[1]).matches())
return false; return false;
//Check if the open/closed flag is present //Check if the open/closed flag is present