Example #1
0
  public List<Variable> getVariables(String command) {
    String[] cmds = command.split(" ");
    List<String> args = new ArrayList(Arrays.asList(cmds));

    StringBuilder lastVar = new StringBuilder();

    ArrayList<Variable> vars = new ArrayList<Variable>();
    Variable v = null;
    for (int j = 0; j < cleft.size(); j++) {
      try {
        if (cleft.get(j).getCType() == ConstructType.VARIABLE) {
          if (((Variable) cleft.get(j)).getName().equals("$")) {
            for (int k = j; k < args.size(); k++) {
              lastVar.append(args.get(k).trim()).append(" ");
            }
            v =
                new Variable(
                    ((Variable) cleft.get(j)).getName(), lastVar.toString().trim(), Target.UNKNOWN);
          } else {
            v = new Variable(((Variable) cleft.get(j)).getName(), args.get(j), Target.UNKNOWN);
          }
        }
      } catch (IndexOutOfBoundsException e) {
        v =
            new Variable(
                ((Variable) cleft.get(j)).getName(),
                ((Variable) cleft.get(j)).getDefault(),
                Target.UNKNOWN);
      }
      if (v != null) {
        vars.add(v);
      }
    }
    return vars;
  }
Example #2
0
 private boolean compileLeft() {
   cleft = new ArrayList<Construct>();
   if (label != null && label.startsWith("!")) {
     if (label.length() > 1) {
       label = label.substring(1);
     }
     nolog = true;
   }
   for (int i = 0; i < left.size(); i++) {
     Token t = left.get(i);
     if (t.value.startsWith("/")) {
       cleft.add(new Command(t.val(), t.target));
     } else if (t.type == Token.TType.VARIABLE) {
       cleft.add(new Variable(t.val(), null, t.target));
     } else if (t.type.equals(TType.FINAL_VAR)) {
       Variable v = new Variable(t.val(), null, t.target);
       v.setFinal(true);
       cleft.add(v);
     } else if (t.type.equals(TType.LSQUARE_BRACKET)) {
       if (i + 2 < left.size() && left.get(i + 2).type.equals(TType.OPT_VAR_ASSIGN)) {
         Variable v = new Variable(left.get(i + 1).val(), left.get(i + 3).val(), t.target);
         v.setOptional(true);
         if (left.get(i + 1).type.equals(TType.FINAL_VAR)) {
           v.setFinal(true);
         }
         cleft.add(v);
         i += 4;
       } else {
         t = left.get(i + 1);
         Variable v = new Variable(t.val(), null, t.target);
         v.setOptional(true);
         if (t.val().equals("$")) {
           v.setFinal(true);
         }
         cleft.add(v);
         i += 2;
       }
     } else {
       cleft.add(new CString(t.val(), t.getTarget()));
     }
   }
   return true;
 }
Example #3
0
  public void run(final List<Variable> vars, Environment myEnv, final MethodScriptComplete done) {
    // Some things, such as the label are determined at compile time
    this.CurrentEnv = myEnv;
    this.CurrentEnv.getEnv(GlobalEnv.class).SetLabel(this.label);
    MCCommandSender p = myEnv.getEnv(CommandHelperEnvironment.class).GetCommandSender();
    if (!hasBeenCompiled || compilerError) {
      Target target = Target.UNKNOWN;
      if (left.size() >= 1) {
        try {
          target = new Target(left.get(0).line_num, left.get(0).file, left.get(0).column);
        } catch (NullPointerException e) {
          // Oh well, we tried to get more information
        }
      }
      throw new ConfigRuntimeException(
          "Unable to run command, script not yet compiled, or a compiler error occured for that command."
              + " To see the compile error, run /reloadaliases",
          null,
          target);
    }
    if (p instanceof MCPlayer) {
      if (CurrentEnv.getEnv(GlobalEnv.class).GetLabel() != null) {
        PermissionsResolver perms = CurrentEnv.getEnv(GlobalEnv.class).GetPermissionsResolver();
        String[] groups = CurrentEnv.getEnv(GlobalEnv.class).GetLabel().split("/");
        for (String group : groups) {
          if (group.startsWith("-")
              && perms.inGroup(((MCPlayer) p).getName(), group.substring(1))) {
            // negative permission
            throw new ConfigRuntimeException(
                "You do not have permission to use that command",
                ExceptionType.InsufficientPermissionException,
                Target.UNKNOWN);
          } else if (perms.inGroup(((MCPlayer) p).getName(), group)) {
            // They do have permission.
            break;
          }
        }
      }
    }

    try {
      for (ParseTree rootNode : cright) {
        for (Construct tempNode : rootNode.getAllData()) {
          if (tempNode instanceof Variable) {
            if (left_vars == null) {
              throw new ConfigRuntimeException(
                  "$variables may not be used in this context. Only @variables may be.",
                  null,
                  tempNode.getTarget());
            }
            ((Variable) tempNode)
                .setVal(
                    new CString(
                        Static.resolveDollarVar(
                                left_vars.get(((Variable) tempNode).getName()), vars)
                            .toString(),
                        tempNode.getTarget()));
          }
        }

        MethodScriptCompiler.registerAutoIncludes(CurrentEnv, this);
        MethodScriptCompiler.execute(rootNode, CurrentEnv, done, this);
      }
    } catch (ConfigRuntimeException ex) {
      // We don't know how to handle this really, so let's pass it up the chain.
      throw ex;
    } catch (CancelCommandException e) {
      // p.sendMessage(e.getMessage());
      // The message in the exception is actually empty
    } catch (LoopBreakException e) {
      if (p != null) {
        p.sendMessage("The break() function must be used inside a for() or foreach() loop");
      }
      System.out.println("The break() function must be used inside a for() or foreach() loop");
    } catch (LoopContinueException e) {
      if (p != null) {
        p.sendMessage("The continue() function must be used inside a for() or foreach() loop");
      }
      System.out.println("The continue() function must be used inside a for() or foreach() loop");
    } catch (FunctionReturnException e) {
      if (myEnv.getEnv(CommandHelperEnvironment.class).GetEvent() != null) {
        // Oh, we're running in an event handler. Those know how to catch it too.
        throw e;
      }
      if (p != null) {
        p.sendMessage("The return() function must be used inside a procedure.");
      }
      System.out.println("The return() function must be used inside a procedure.");
    } catch (Throwable t) {
      System.out.println("An unexpected exception occured during the execution of a script.");
      t.printStackTrace();
      if (p != null) {
        p.sendMessage(
            "An unexpected exception occured during the execution of your script. Please check the console for more information.");
      }
    }
    if (done != null) {
      done.done(null);
    }
  }
Example #4
0
  public void checkAmbiguous(List<Script> scripts) throws ConfigCompileException {
    // for (int i = 0; i < scripts.size(); i++) {
    List<Construct> thisCommand = this.cleft;
    for (int j = 0; j < scripts.size(); j++) {
      List<Construct> thatCommand = scripts.get(j).cleft;
      if (thatCommand == null) {
        // it hasn't been compiled yet.
        return;
      }
      if (this.cleft == scripts.get(j).cleft) {
        // Of course this command is going to match it's own signature
        continue;
      }
      boolean soFarAMatch = true;
      for (int k = 0; k < thisCommand.size(); k++) {
        try {
          Construct c1 = thisCommand.get(k);
          Construct c2 = thatCommand.get(k);
          if (c1.getCType() != c2.getCType()
              || ((c1 instanceof Variable) && !((Variable) c1).isOptional())) {
            soFarAMatch = false;
          } else {
            // It's a literal, check to see if it's the same literal
            if (c1.nval() == null || !c1.val().equals(c2.val())) {
              soFarAMatch = false;
            }
          }
        } catch (IndexOutOfBoundsException e) {
          /**
           * The two commands: /cmd $var1 [$var2] /cmd $var1 would cause this exception to be
           * thrown, but the signatures are the same, so the fact that they've matched this far
           * means they are ambiguous. However, /cmd $var1 $var2 /cmd $var1 is not ambiguous
           */
          // thatCommand is the short one
          if (!(thisCommand.get(k) instanceof Variable)
              || (thisCommand.get(k) instanceof Variable
                  && !((Variable) thisCommand.get(k)).isOptional())) {
            soFarAMatch = false;
          }
        }
      }
      if (thatCommand.size() > thisCommand.size()) {
        int k = thisCommand.size();
        // thisCommand is the short one
        if (!(thatCommand.get(k) instanceof Variable)
            || (thatCommand.get(k) instanceof Variable
                && !((Variable) thatCommand.get(k)).isOptional())) {
          soFarAMatch = false;
        }
      }

      if (soFarAMatch) {
        String commandThis = "";
        for (Construct c : thisCommand) {
          commandThis += c.val() + " ";
        }
        String commandThat = "";
        for (Construct c : thatCommand) {
          commandThat += c.val() + " ";
        }
        scripts.get(j).compilerError = true;
        this.compilerError = true;
        throw new ConfigCompileException(
            "The command "
                + commandThis.trim()
                + " is ambiguous because it "
                + "matches the signature of "
                + commandThat.trim(),
            thisCommand.get(0).getTarget());
      }
    }

    //        //Also, check for undefined variables on the right, and unused variables on the left
    //        ArrayList<String> left_copy = new ArrayList<String>();
    //        for (Map.Entry<String, Variable> v : left_vars.entrySet()) {
    //            left_copy.add(v.getValue().getName());
    //        }
    //        Arrays.asList(new String[]{}).toArray(new String[]{});
    //        for (ParseTree gtn : cright) {
    //            GenericTree<Construct> tree = new GenericTree<Construct>();
    //            tree.setRoot(gtn);
    //            List<ParseTree> builtTree = tree.build(GenericTreeTraversalOrderEnum.PRE_ORDER);
    //            for (ParseTree c : builtTree) {
    //                if (c.getData() instanceof Variable) {
    //                    for (Map.Entry<String, Variable> v : left_vars.entrySet()) {
    //                        if (v.getValue().getName().equals(((Variable) c.getData()).getName()))
    // {
    //                            //Found it, remove this from the left_copy, and break
    //                            left_copy.remove(v.getValue().getName());
    //                            break;
    //                            //TODO: Layton!
    //                        }
    //                    }
    //                }
    //            }
    //        }
    // }
  }
Example #5
0
  private boolean verifyLeft() throws ConfigCompileException {
    boolean inside_opt_var = false;
    boolean after_no_def_opt_var = false;
    String lastVar = null;
    // Go through our token list and readjust non-spaced symbols. Any time we combine a symbol,
    // the token becomes a string
    List<Token> tempLeft = new ArrayList<Token>();
    for (int i = 0; i < left.size(); i++) {
      Token t = left.get(i);
      if (i == 0 && t.type == TType.NEWLINE) {
        continue;
      }
      if (t.type.isSymbol() && left.size() - 1 > i && left.get(i + 1).type != TType.WHITESPACE) {
        StringBuilder b = new StringBuilder();
        b.append(t.value);
        i++;
        Token m = left.get(i);
        while (m.type.isSymbol() && m.type != TType.WHITESPACE) {
          b.append(m.value);
          i++;
          m = left.get(i);
        }

        if (m.type != TType.WHITESPACE && m.type != TType.LABEL) {
          b.append(m.value);
        }
        t = new Token(TType.STRING, b.toString(), t.target);
        if (m.type == TType.LABEL) {
          tempLeft.add(t);
          tempLeft.add(m);
          continue;
        }
      }
      // Go ahead and toString the other symbols too
      if (t.type.isSymbol()) {
        t = new Token(TType.STRING, t.value, t.target);
      }
      if (t.type != TType.WHITESPACE) {
        tempLeft.add(t);
      }
    }
    // Look through and concatenate all tokens before the label, if such exists.
    boolean hasLabel = false;
    for (int i = 0; i < tempLeft.size(); i++) {
      if (tempLeft.get(i).type == TType.LABEL) {
        hasLabel = true;
        break;
      }
    }
    if (hasLabel) {
      StringBuilder b = new StringBuilder();
      int count = 0;
      while (tempLeft.get(count).type != TType.LABEL) {
        b.append(tempLeft.get(count).val());
        count++;
      }
      tempLeft.set(0, new Token(TType.STRING, b.toString(), Target.UNKNOWN));
      for (int i = 0; i < count - 1; i++) {
        tempLeft.remove(1);
      }
    }
    left = tempLeft;
    for (int j = 0; j < left.size(); j++) {
      Token t = left.get(j);
      // Token prev_token = j - 2 >= 0?c.tokens.get(j - 2):new Token(TType.UNKNOWN, "", t.line_num);
      Token last_token = j - 1 >= 0 ? left.get(j - 1) : new Token(TType.UNKNOWN, "", t.getTarget());
      Token next_token =
          j + 1 < left.size() ? left.get(j + 1) : new Token(TType.UNKNOWN, "", t.getTarget());
      Token after_token =
          j + 2 < left.size() ? left.get(j + 2) : new Token(TType.UNKNOWN, "", t.getTarget());

      if (j == 0) {
        if (next_token.type == TType.LABEL) {
          this.label = t.val();
          j--;
          left.remove(0);
          left.remove(0);
          continue;
        }
      }

      if (t.type == TType.LABEL) {
        continue;
      }

      if (t.type.equals(TType.FINAL_VAR) && left.size() - j >= 5) {
        throw new ConfigCompileException(
            "FINAL_VAR must be the last argument in the alias", t.target);
      }
      if (t.type.equals(TType.VARIABLE) || t.type.equals(TType.FINAL_VAR)) {
        Variable v = new Variable(t.val(), null, t.target);
        lastVar = t.val();
        v.setOptional(last_token.type.equals(TType.LSQUARE_BRACKET));
        left_vars.put(t.val(), v);
        if (v.isOptional()) {
          after_no_def_opt_var = true;
        } else {
          v.setDefault("");
        }
      }
      // We're looking for a command up front
      if (j == 0 && !t.value.startsWith("/")) {
        if (!(next_token.type == TType.LABEL && after_token.type == TType.COMMAND)) {
          throw new ConfigCompileException(
              "Expected command (/command) at start of alias."
                  + " Instead, found "
                  + t.type
                  + " ("
                  + t.val()
                  + ")",
              t.target);
        }
      }
      if (last_token.type.equals(TType.LSQUARE_BRACKET)) {
        inside_opt_var = true;
        if (!(t.type.equals(TType.FINAL_VAR) || t.type.equals(TType.VARIABLE))) {
          throw new ConfigCompileException(
              "Unexpected "
                  + t.type.toString()
                  + " ("
                  + t.val()
                  + "), was expecting"
                  + " a $variable",
              t.target);
        }
      }
      if (after_no_def_opt_var && !inside_opt_var) {
        if (t.type.equals(TType.VARIABLE) || t.type.equals(TType.FINAL_VAR)) {
          throw new ConfigCompileException(
              "You cannot have anything other than optional arguments after your"
                  + " first optional argument.",
              t.target);
        }
      }
      if (!t.type.equals(TType.LSQUARE_BRACKET)
          && !t.type.equals(TType.OPT_VAR_ASSIGN)
          && !t.type.equals(TType.RSQUARE_BRACKET)
          && !t.type.equals(TType.VARIABLE)
          && !t.type.equals(TType.LIT)
          && !t.type.equals(TType.COMMAND)
          && !t.type.equals(TType.FINAL_VAR)) {
        if (j - 1 > 0
            && !(
            /*t.type.equals(TType.STRING) &&*/ left.get(j - 1).type.equals(TType.OPT_VAR_ASSIGN))) {
          throw new ConfigCompileException("Unexpected " + t.type + " (" + t.val() + ")", t.target);
        }
      }
      if (last_token.type.equals(TType.COMMAND)) {
        if (!(t.type.equals(TType.VARIABLE)
            || t.type.equals(TType.LSQUARE_BRACKET)
            || t.type.equals(TType.FINAL_VAR)
            || t.type.equals(TType.LIT))) {
          throw new ConfigCompileException(
              "Unexpected " + t.type + " (" + t.val() + ") after command", t.target);
        }
      }
      if (inside_opt_var && t.type.equals(TType.OPT_VAR_ASSIGN)) {
        if (!((next_token.type.equals(TType.STRING) || next_token.type.equals(TType.LIT))
                && after_token.type.equals(TType.RSQUARE_BRACKET)
            || (next_token.type.equals(TType.RSQUARE_BRACKET)))) {
          throw new ConfigCompileException("Unexpected token in optional variable", t.target);
        } else if (next_token.type.equals(TType.STRING) || next_token.type.equals(TType.LIT)) {
          left_vars.get(lastVar).setDefault(next_token.val());
        }
      }
      if (t.type.equals(TType.RSQUARE_BRACKET)) {
        if (!inside_opt_var) {
          throw new ConfigCompileException("Unexpected " + t.type.toString(), t.target);
        }
        inside_opt_var = false;
        //                if (last_token.type.equals(TType.VARIABLE)
        //                        || last_token.type.equals(TType.FINAL_VAR)) {
        //                    after_no_def_opt_var = true;
        //                }
      }
    }

    return true;
  }
Example #6
0
  public boolean match(String command) {
    if (cleft == null) {
      // The compilation error happened during the signature declaration, so
      // we can't match it, nor can we even tell if it's what they intended for us to run.
      return false;
    }
    boolean case_sensitive = Prefs.CaseSensitive();
    String[] cmds = command.split(" ");
    List<String> args = new ArrayList(Arrays.asList(cmds));
    boolean isAMatch = true;
    StringBuilder lastVar = new StringBuilder();
    int lastJ = 0;
    try {
      for (int j = 0; j < cleft.size(); j++) {
        if (!isAMatch) {
          break;
        }
        lastJ = j;
        Construct c = cleft.get(j);
        String arg = args.get(j);
        if (c.getCType() != ConstructType.VARIABLE) {
          if (case_sensitive && !c.val().equals(arg)
              || !case_sensitive && !c.val().equalsIgnoreCase(arg)) {
            isAMatch = false;
            continue;
          }
        } else {
          // It's a variable. If it's optional, the rest of them are optional too, so as long as the
          // size of
          // args isn't greater than the size of cleft, it's a match
          if (((Variable) c).isOptional()) {
            if (args.size() <= cleft.size()) {
              return true;
            } else {
              Construct fin = cleft.get(cleft.size() - 1);
              if (fin instanceof Variable) {
                if (((Variable) fin).isFinal()) {
                  return true;
                }
              }
              return false;
            }
          }
        }
        if (j == cleft.size() - 1) {
          if (cleft.get(j).getCType() == ConstructType.VARIABLE) {
            Variable lv = (Variable) cleft.get(j);
            if (lv.isFinal()) {
              for (int a = j; a < args.size(); a++) {
                if (lastVar.length() == 0) {
                  lastVar.append(args.get(a));
                } else {
                  lastVar.append(" ").append(args.get(a));
                }
              }
            }
          }
        }
      }
    } catch (IndexOutOfBoundsException e) {
      if (cleft.get(lastJ).getCType() != ConstructType.VARIABLE
          || cleft.get(lastJ).getCType() == ConstructType.VARIABLE
              && !((Variable) cleft.get(lastJ)).isOptional()) {
        isAMatch = false;
      }
    }
    boolean lastIsFinal = false;
    if (cleft.get(cleft.size() - 1) instanceof Variable) {
      Variable v = (Variable) cleft.get(cleft.size() - 1);
      if (v.isFinal()) {
        lastIsFinal = true;
      }
    }
    if ((cleft.get(lastJ) instanceof Variable && ((Variable) cleft.get(lastJ)).isOptional())) {
      return true;
    }

    if (cleft.size() != cmds.length && !lastIsFinal) {
      isAMatch = false;
    }
    //        ArrayList<Variable> vars = new ArrayList<Variable>();
    //        Variable v = null;
    //        for (int j = 0; j < cleft.size(); j++) {
    //            try {
    //                if (cleft.get(j).getCType() == ConstructType.VARIABLE) {
    //                    if (((Variable) cleft.get(j)).getName().equals("$")) {
    //                        v = new Variable(((Variable) cleft.get(j)).getName(),
    //                                lastVar.toString(), Target.UNKNOWN);
    //                    } else {
    //                        v = new Variable(((Variable) cleft.get(j)).getName(),
    //                                args.get(j), Target.UNKNOWN);
    //                    }
    //                }
    //            } catch (IndexOutOfBoundsException e) {
    //                v = new Variable(((Variable) cleft.get(j)).getName(),
    //                        ((Variable) cleft.get(j)).getDefault(), Target.UNKNOWN);
    //            }
    //            if (v != null) {
    //                vars.add(v);
    //            }
    //        }
    return isAMatch;
  }