Advertisement
Jnk1296

Command System

Feb 10th, 2015
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.97 KB | None | 0 0
  1. public class CommandInterpreter {
  2.  
  3.     private Client client;
  4.  
  5.     private DirectoryManager dirMan;
  6.     private DirectoryChanger dirChange;
  7.  
  8.     private Thread iThread;
  9.  
  10.     public CommandInterpreter(final Client client) {
  11.         this.client = client;
  12.         this.startInterpreter();
  13.     }
  14.  
  15.     private void startInterpreter() {
  16.         this.iThread = new Thread(){
  17.             @Override
  18.             public void run() {
  19.                 CommandManager CM = new CommandManager();
  20.                 CM.registerStore(new CmdStore());
  21.  
  22.                 System.out.println("Remote File Access Terminal, Version 1.0a. Copyright © 2015 JuNK Software. All rights reserved.");
  23.  
  24.                 while(true) {
  25.                     Scanner scan = new Scanner(System.in);
  26.                     System.out.print(""/*Current Directory Prompt (EX: ~/bin># _ )*/); // Execution Halts here until we receive a command.
  27.                     String input = scan.nextLine();
  28.  
  29.                     String[] args = input.split("\\s+");
  30.  
  31.                     ParseResult pResult = this.CM.parseCommand(args);
  32.  
  33.                     // If the Parser returned a Command
  34.                     if (pResult.getResult() == ResultType.SUCCESS) {
  35.                         /*
  36.                          * A new command instance must be created when a command is called,
  37.                          * so as to prevent static commands from being served to players.
  38.                          * This prevents any form of data swappage between two different
  39.                          * players executing the same command at the same time.
  40.                          */
  41.  
  42.                         // New Command Instance.
  43.                         Command cmd = null;
  44.  
  45.                         // The dirty dynamic hack :D
  46.                         try {
  47.                             // Fetch Class Type
  48.                             Class<?> clazz = Class.forName(
  49.                                     pResult.getCommand().getClass().getName());
  50.  
  51.                             // Create the Constructor for the Command class. This works
  52.                             // only because all commands extend Command, which requires
  53.                             // these three arguments to be constructed.
  54.                             Constructor<?> ctor = clazz.getConstructor(String[].class, CommandType.class);
  55.  
  56.                             // Create the specified Command Instance
  57.                             cmd = (Command) ctor.newInstance(
  58.                                     pResult.getCommand().getCallArgs(),
  59.                                     pResult.getCommand().getType());
  60.                         } catch (Exception e) {
  61.                             e.printStackTrace();
  62.                         }
  63.  
  64.                         // If Player is calling this command, check Permissions and execute
  65.                         if (cmd != null) {
  66.                             cmd.onExecute(args); // *** Execution halts here until Command has finished executing ***
  67.                         } else {
  68.                             System.out.println("An error occurred while generating a dynamic instance of the requested command.");
  69.                         }
  70.  
  71.                         // If the Parser returned a Command, but the Argument count was bad
  72.                     } else if (pResult.getResult() == ResultType.BAD_NUM_ARGS) {
  73.                         System.out.println("An invalid number of arguments was specified.");
  74.  
  75.                         // If the Parser did not return a Command
  76.                     } else if (pResult.getResult() == ResultType.FAIL) {
  77.                         System.out.println("Command specified does not exist.");
  78.                     }
  79.                 }
  80.             }
  81.         };
  82.  
  83.         this.iThread.start();
  84.     }
  85. }
  86.  
  87. public class Command {
  88.     private String name, syntax, help;
  89.     private String[] callArgs;
  90.     private CommandType type;
  91.  
  92.     public Command(String[] callArgs, CommandType type) {
  93.         this.callArgs = callArgs;
  94.         this.type = type;
  95.     }
  96.  
  97.     public void onExecute(String[] args) {
  98.         throw new UnsupportedOperationException(
  99.             "Base class does not implement.");
  100.     }
  101.  
  102.     public final CommandType getType() {
  103.         return this.type;
  104.     }
  105.  
  106.     /**
  107.      * Returns the Name of this Command.
  108.      *
  109.      * @return String
  110.      */
  111.     public final String getName() {
  112.         return this.name;
  113.     }
  114.  
  115.     /**
  116.      * Sets the Display Name for this Command.</br>
  117.      * <p/>
  118.      * </br>The name can be any string.
  119.      *
  120.      * @param cmdName
  121.      */
  122.     public final void setName(String cmdName) {
  123.         this.name = cmdName;
  124.     }
  125.  
  126.     /**
  127.      * Returns the Syntax of this Command, minus the root.
  128.      *
  129.      * @return String
  130.      */
  131.     public final String getSyntax() {
  132.         return this.syntax;
  133.     }
  134.  
  135.     /**
  136.      * Sets the syntax for this Command.</br>
  137.      * <p/>
  138.      * </br>When set, the string passed should contain the literal (sic) syntax
  139.      * to be used when calling your command, <strong>minus the root command
  140.      * </strong>. The syntax string is generally used for displaying help
  141.      * information and should be relatively easy to understand.</br>
  142.      * <p/>
  143.      * </br>Ex: <em>ban {@literal <}player{@literal >} [message]</em>
  144.      *
  145.      * @param cmdSyntax
  146.      */
  147.     public final void setSyntax(String cmdSyntax) {
  148.         this.syntax = cmdSyntax;
  149.     }
  150.  
  151.     /**
  152.      * Returns the Help Description text for this Command.
  153.      *
  154.      * @return String
  155.      */
  156.     public final String getHelp() {
  157.         return this.help;
  158.     }
  159.  
  160.     /**
  161.      * Sets the Help Description text for this command.</br>
  162.      * <p/>
  163.      * </br>This text is displayed in the Help Command and is used to describe
  164.      * what this Command does, as well as any other information the end user may
  165.      * need to know.
  166.      *
  167.      * @param helpDesc
  168.      */
  169.     public final void setHelp(String helpDesc) {
  170.         this.help = helpDesc;
  171.     }
  172.  
  173.     /**
  174.      * Returns a String[] containing all the arguments required to be typed by
  175.      * the end user for this Command to be identified by the Command Manager.
  176.      *
  177.      * @return String[]
  178.      */
  179.     public final String[] getCallArgs() {
  180.         return this.callArgs;
  181.     }
  182. }
  183.  
  184. public class CmdListCommand extends Command {
  185.  
  186.     public ListCommand(String[] callArgs, CommandType type) {
  187.         super(callArgs, type);
  188.         setName("List Directory");
  189.         setHelp("Displays a list of files and folders for the current directory. \n'/W' switch will display contents in multiple columns, '/L' switch \nwill list files in a single column.");
  190.         setSyntax("dir [/W || /L]");
  191.     }
  192.  
  193.     @Override
  194.     public void onExecute(String[] args) {
  195.  
  196.     }
  197.  
  198. }
  199.  
  200. public class CmdChangeDirCommand extends Command {
  201.  
  202.     public ListCommand(String[] callArgs, CommandType type) {
  203.         super(callArgs, type);
  204.         setHelp("Change Directory");
  205.         setHelp("Changes your current operating directory. Arguments accepted are either a case sensitive file name (for Unix support) or the UP operator \"..\".");
  206.         setSyntax("cd <dir_name || ..>");
  207.     }
  208.  
  209.     @Override
  210.     public void onExecute(String[] args) {
  211.  
  212.     }
  213.  
  214. }
  215.  
  216. public enum CommandType {
  217.     STATIC,
  218.     VARIABLE,
  219.     DYNAMIC;
  220. }
  221.  
  222. public class CommandManager {
  223.     private ArrayList<Command> commands = new ArrayList<Command>();
  224.     private boolean debugMode = false;
  225.  
  226.     public final void registerStore(CommandStore cmdStore) {
  227.         this.commands = cmdStore.getCommands();
  228.     }
  229.  
  230.     public final boolean registerCommand(Command cmd) {
  231.         if (this.commands.add(cmd)) {
  232.             return true;
  233.         } else {
  234.             System.out.println("Failed to register command. Perhaps it is already registered?");
  235.             return false;
  236.         }
  237.     }
  238.  
  239.     public final Command getCommand(String identifier) {
  240.         for (Command cmd : this.commands) {
  241.             if (cmd.getName().equalsIgnoreCase(identifier)) return cmd;
  242.         }
  243.  
  244.         return null;
  245.     }
  246.  
  247.     public final ArrayList<Command> getAllCommands() {
  248.         return this.commands;
  249.     }
  250.  
  251.     public final ParseResult parseCommand(String[] args) {
  252.         for (Command cmd : this.commands) {
  253.             Parser parser;
  254.  
  255.             if (cmd.getType() == CommandType.STATIC) {
  256.                 parser = new StaticParser(this, cmd, args);
  257.             } else if (cmd.getType() == CommandType.VARIABLE) {
  258.                 parser = new VariableParser(this, cmd, args);
  259.             } else if (cmd.getType() == CommandType.DYNAMIC) {
  260.                 parser = new DynamicParser(this, cmd, args);
  261.             } else {
  262.                 parser = new StaticParser(this, cmd, args);
  263.             }
  264.  
  265.             ComparisonResult result = parser.parseCommand();
  266.  
  267.             if (result.equals(ComparisonResult.GOOD)) {
  268.                 return new ParseResult(ResultType.SUCCESS, cmd);
  269.             } else if (result.equals(ComparisonResult.ARG_ERR)) {
  270.                 return new ParseResult(ResultType.BAD_NUM_ARGS, cmd);
  271.             }
  272.         }
  273.  
  274.         return new ParseResult(ResultType.FAIL, null);
  275.     }
  276.  
  277.     public void setDebugMode(boolean flag) {
  278.         this.debugMode = flag;
  279.     }
  280.  
  281.     public boolean debugMode() {
  282.         return this.debugMode;
  283.     }
  284. }
  285.  
  286. public class CommandStore extends Store {
  287.  
  288.     private ArrayList<Command> commands;
  289.  
  290.     public CommandStore() {
  291.         this.commands = new ArrayList<Command>();
  292.         initializeStore();
  293.     }
  294.  
  295.     public void initializeStore() {
  296.         throw new UnsupportedOperationException("Base class does not implement.");
  297.     }
  298.  
  299.     public final void add(Command cmd) {
  300.         this.commands.add(cmd);
  301.     }
  302.  
  303.     public final ArrayList<Command> getCommands() {
  304.         return this.commands;
  305.     }
  306.  
  307. }
  308.  
  309. public class CmdStore extends CommandStore {
  310.  
  311.     public CmdStore() {
  312.         super();
  313.     }
  314.  
  315.     @Override
  316.     public void initializeStore() {
  317.         // CD Command
  318.         this.add(
  319.             new CmdChangeDirCommand(new String[]{"cd", "VAR_ARG"},
  320.                 CommandType.DYNAMIC));
  321.         // DIR Command
  322.         this.add(
  323.             new CmdListCommand(new String[]{"dir", "VAR_ARG_OPT"},
  324.                 CommandType.VARIABLE));
  325.     }
  326. }
  327.  
  328. public enum ComparisonResult {
  329.     GOOD,
  330.     ARG_ERR,
  331.     BAD;
  332. }
  333.  
  334. public class ParseResult {
  335.  
  336.     private final Command cmd;
  337.     private final ResultType type;
  338.  
  339.     public ParseResult(final ResultType type, final Command cmd) {
  340.         this.type = type;
  341.         this.cmd = cmd;
  342.     }
  343.  
  344.     public final ResultType getResult() {
  345.         return this.type;
  346.     }
  347.  
  348.     public final Command getCommand() {
  349.         return this.cmd;
  350.     }
  351. }
  352.  
  353. public enum ResultType {
  354.     SUCCESS,
  355.     BAD_NUM_ARGS,
  356.     FAIL;
  357. }
  358.  
  359. public class Parser {
  360.  
  361.     public CommandManager cmdManager;
  362.     public Command cmd;
  363.     public String[] input;
  364.  
  365.     public Parser(CommandManager mngr, Command cmd, String[] input) {
  366.         this.cmdManager =  mngr;
  367.         this.cmd = cmd;
  368.         this.input = input;
  369.     }
  370.  
  371.     public ComparisonResult parseCommand(){
  372.         throw new UnsupportedOperationException(
  373.             "The parse instructions for this parser have not been specified!");
  374.     }
  375. }
  376.  
  377. // PARSER CLASSES
  378. public class DynamicParser extends Parser {
  379.  
  380.     public DynamicParser(CommandManager mngr, Command cmd, String[] args) {
  381.         super(mngr, cmd, args);
  382.     }
  383.  
  384.     @Override
  385.     public ComparisonResult parseCommand() {
  386.         String[] COMMAND_ARGS = new String[this.cmd.getCallArgs().length];
  387.         String[] INPUT_ARGS = new String[this.cmd.getCallArgs().length];
  388.  
  389.         for (int i = 0; i < this.cmd.getCallArgs().length; i++) {
  390.             COMMAND_ARGS[i] = this.cmd.getCallArgs()[i];
  391.         }
  392.  
  393.         for (int i = 0; i < this.cmd.getCallArgs().length; i++) {
  394.             if (i >= this.input.length) {
  395.                 INPUT_ARGS[i] = "null";
  396.             } else {
  397.                 INPUT_ARGS[i] = this.input[i];
  398.             }
  399.         }
  400.  
  401.         // Check for Matching Arguments
  402.         for (int i = 0; i < COMMAND_ARGS.length; i++) {
  403.             // Debug Output
  404.             if (this.cmdManager.debugMode()) {
  405.                 System.out.println("Command Expected: " + COMMAND_ARGS[i]);
  406.                 System.out.println("Received: " + INPUT_ARGS[i]);
  407.             }
  408.  
  409.             if (COMMAND_ARGS[i].equals("VAR_ARG_OPT")) continue;
  410.  
  411.             if (COMMAND_ARGS[i].equals("VAR_ARG") &&
  412.                     INPUT_ARGS[i].equals("null")) {
  413.                 return ComparisonResult.ARG_ERR;
  414.             } else if (COMMAND_ARGS[i].equals("VAR_ARG")) {
  415.                 continue;
  416.             }
  417.  
  418.             if (!INPUT_ARGS[i].equalsIgnoreCase(COMMAND_ARGS[i])) {
  419.                 return ComparisonResult.BAD;
  420.             }
  421.         }
  422.  
  423.         return ComparisonResult.GOOD;
  424.     }
  425. }
  426.  
  427. public class StaticParser extends Parser {
  428.  
  429.     public StaticParser(CommandManager mngr, Command cmd, String[] args) {
  430.         super(mngr, cmd, args);
  431.     }
  432.  
  433.     @Override
  434.     public ComparisonResult parseCommand() {
  435.         int callSize = this.cmd.getCallArgs().length;
  436.         int inputSize = this.input.length;
  437.  
  438.         String[] COMMAND_ARGS;
  439.         String[] INPUT_ARGS;
  440.  
  441.         if (callSize > inputSize) {
  442.             COMMAND_ARGS = new String[callSize];
  443.             INPUT_ARGS = new String[callSize];
  444.         } else {
  445.             COMMAND_ARGS = new String[inputSize];
  446.             INPUT_ARGS = new String[inputSize];
  447.         }
  448.  
  449.         for (int i = 0; i < this.cmd.getCallArgs().length; i++) {
  450.             COMMAND_ARGS[i] = this.cmd.getCallArgs()[i];
  451.         }
  452.         for (int i = 0; i < this.input.length; i++) {
  453.             INPUT_ARGS[i] = this.input[i];
  454.         }
  455.  
  456.         if (callSize > inputSize) {
  457.             for (int i = inputSize; i < INPUT_ARGS.length; i++) {
  458.                 INPUT_ARGS[i] = "null";
  459.             }
  460.         } else {
  461.             for (int i = callSize; i < COMMAND_ARGS.length; i++) {
  462.                 COMMAND_ARGS[i] = "null";
  463.             }
  464.         }
  465.  
  466.         // Check for Matching Arguments
  467.         for (int i = 0; i < COMMAND_ARGS.length; i++) {
  468.             // Debug Output
  469.             if (this.cmdManager.debugMode()) {
  470.                 System.out.println("Command Expected: " + COMMAND_ARGS[i]);
  471.                 System.out.println("Received: " + INPUT_ARGS[i]);
  472.             }
  473.  
  474.             if (COMMAND_ARGS[i].equals("null")) {
  475.                 return ComparisonResult.ARG_ERR;
  476.             }
  477.  
  478.             if (!INPUT_ARGS[i].equalsIgnoreCase(COMMAND_ARGS[i])) {
  479.                 return ComparisonResult.BAD;
  480.             }
  481.         }
  482.  
  483.         return ComparisonResult.GOOD;
  484.     }
  485.  
  486. }
  487.  
  488. public class VariableParser extends Parser {
  489.  
  490.     public VariableParser(CommandManager mngr, Command cmd, String[] args) {
  491.         super(mngr, cmd, args);
  492.     }
  493.  
  494.     @Override
  495.     public ComparisonResult parseCommand() {
  496.         int callSize = this.cmd.getCallArgs().length;
  497.         int inputSize = this.input.length;
  498.  
  499.         String[] COMMAND_ARGS;
  500.         String[] INPUT_ARGS;
  501.  
  502.         if (callSize > inputSize) {
  503.             COMMAND_ARGS = new String[callSize];
  504.             INPUT_ARGS = new String[callSize];
  505.         } else {
  506.             COMMAND_ARGS = new String[inputSize];
  507.             INPUT_ARGS = new String[inputSize];
  508.         }
  509.  
  510.         for (int i = 0; i < this.cmd.getCallArgs().length; i++) {
  511.             COMMAND_ARGS[i] = this.cmd.getCallArgs()[i];
  512.         }
  513.         for (int i = 0; i < this.input.length; i++) {
  514.             INPUT_ARGS[i] = this.input[i];
  515.         }
  516.  
  517.         if (callSize > inputSize) {
  518.             for (int i = inputSize; i < INPUT_ARGS.length; i++) {
  519.                 INPUT_ARGS[i] = "null";
  520.             }
  521.         } else {
  522.             for (int i = callSize; i < COMMAND_ARGS.length; i++) {
  523.                 COMMAND_ARGS[i] = "null";
  524.             }
  525.         }
  526.  
  527.         for (int i = 0; i < COMMAND_ARGS.length; i++) {
  528.             // Debug Output
  529.             if (this.cmdManager.debugMode()) {
  530.                 System.out.println("Command Expected: " + COMMAND_ARGS[i]);
  531.                 System.out.println("Received: " + INPUT_ARGS[i]);
  532.             }
  533.  
  534.             if (COMMAND_ARGS[i].equals("VAR_ARG_OPT")) continue;
  535.  
  536.             if (COMMAND_ARGS[i].equals("VAR_ARG") &&
  537.                     INPUT_ARGS[i].equals("null")) {
  538.                 return ComparisonResult.ARG_ERR;
  539.             } else if (COMMAND_ARGS[i].equals("VAR_ARG")) {
  540.                 continue;
  541.             }
  542.  
  543.             if (COMMAND_ARGS[i].equals("null")) {
  544.                 return ComparisonResult.ARG_ERR;
  545.             }
  546.  
  547.             if (!INPUT_ARGS[i].equalsIgnoreCase(COMMAND_ARGS[i])) {
  548.                 return ComparisonResult.BAD;
  549.             }
  550.         }
  551.  
  552.         return ComparisonResult.GOOD;
  553.     }
  554. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement