Exemplo n.º 1
0
  public boolean execute(ScriptEntry scriptEntry) {
    Matcher m;
    StringBuffer sb;
    if (scriptEntry.getCommandName().indexOf('%') != -1) {
      m = definition_pattern.matcher(scriptEntry.getCommandName());
      sb = new StringBuffer();
      while (m.find()) {
        String definition = scriptEntry.getResidingQueue().getDefinition(m.group(1));
        if (definition == null) definition = "null";
        m.appendReplacement(sb, definition);
      }
      m.appendTail(sb);
      scriptEntry.setCommandName(sb.toString());
    }

    // Get the command instance ready for the execution of the scriptEntry
    AbstractCommand command = plugin.getCommandRegistry().get(scriptEntry.getCommandName());

    if (command == null) {
      dB.echoDebug(
          scriptEntry, DebugElement.Header, "Executing command: " + scriptEntry.getCommandName());
      dB.echoError(
          scriptEntry.getCommandName() + " is an invalid dCommand! Are you sure it loaded?");
      dB.echoDebug(scriptEntry, DebugElement.Footer);
      return false;
    }

    // Debugger information
    if (scriptEntry.getPlayer() != null)
      dB.echoDebug(
          scriptEntry,
          DebugElement.Header,
          "Executing dCommand: "
              + scriptEntry.getCommandName()
              + "/"
              + scriptEntry.getPlayer().getName());
    else
      dB.echoDebug(
          scriptEntry,
          DebugElement.Header,
          "Executing dCommand: "
              + scriptEntry.getCommandName()
              + (scriptEntry.getNPC() != null ? "/" + scriptEntry.getNPC().getName() : ""));

    // Don't execute() if problems arise in parseArgs()
    boolean keepGoing = true;

    try {

      // Throw exception if arguments are required for this command, but not supplied.
      if (command.getOptions().REQUIRED_ARGS > scriptEntry.getArguments().size())
        throw new InvalidArgumentsException("");

      if (scriptEntry.has_tags)
        scriptEntry.setArguments(
            TagManager.fillArguments(
                scriptEntry.getArguments(), scriptEntry, true)); // Replace tags

      /*  If using NPC:# or PLAYER:Name arguments, these need to be changed out immediately because...
       *  1) Denizen/Player flags need the desired NPC/PLAYER before parseArgs's getFilledArguments() so that
       *     the Player/Denizen flags will read from the correct Object. If using PLAYER or NPCID arguments,
       *     the desired Objects are obviously not the same objects that were sent with the ScriptEntry.
       *  2) These arguments should be valid for EVERY ScriptCommand, so why not just take care of it
       *     here, instead of requiring each command to take care of the argument.
       */

      List<String> newArgs = new ArrayList<String>();

      // Don't fill in tags if there were brackets detected..
      // This means we're probably in a nested if.
      int nested_depth = 0;
      // Watch for IF command to avoid filling player and npc arguments
      // prematurely
      boolean if_ignore = false;

      for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) {
        if (arg.getValue().equals("{")) nested_depth++;
        if (arg.getValue().equals("}")) nested_depth--;

        // If nested, continue.
        if (nested_depth > 0) {
          newArgs.add(arg.raw_value);
          continue;
        }

        if (arg.raw_value.indexOf('%') != -1) {
          m = definition_pattern.matcher(arg.raw_value);
          sb = new StringBuffer();
          while (m.find()) {
            String definition = scriptEntry.getResidingQueue().getDefinition(m.group(1));
            if (definition == null) definition = "null";
            m.appendReplacement(sb, definition);
          }
          m.appendTail(sb);
          arg = aH.Argument.valueOf(sb.toString());
        }

        // If using IF, check if we've reached the command + args
        // so that we don't fill player: or npc: prematurely
        if (command.getName().equalsIgnoreCase("if")
            && DenizenAPI.getCurrentInstance().getCommandRegistry().get(arg.getValue()) != null)
          if_ignore = true;

        // Fill player/off-line player
        if (arg.matchesPrefix("player") && !if_ignore) {
          dB.echoDebug(scriptEntry, "...replacing the linked player with " + arg.getValue());
          String value =
              TagManager.tag(
                  scriptEntry.getPlayer(),
                  scriptEntry.getNPC(),
                  arg.getValue(),
                  false,
                  scriptEntry);
          dPlayer player = dPlayer.valueOf(value);
          if (player == null || !player.isValid()) {
            dB.echoError(value + " is an invalid player!");
            return false;
          }
          scriptEntry.setPlayer(player);
        }

        // Fill NPCID/NPC argument
        else if (arg.matchesPrefix("npc, npcid") && !if_ignore) {
          dB.echoDebug(scriptEntry, "...replacing the linked NPC with " + arg.getValue());
          String value =
              TagManager.tag(
                  scriptEntry.getPlayer(),
                  scriptEntry.getNPC(),
                  arg.getValue(),
                  false,
                  scriptEntry);
          dNPC npc = dNPC.valueOf(value);
          if (npc == null || !npc.isValid()) {
            dB.echoError(value + " is an invalid NPC!");
            return false;
          }
          scriptEntry.setNPC(npc);
        }

        // Save the scriptentry if needed later for fetching scriptentry context
        else if (arg.matchesPrefix("save") && !if_ignore) {
          dB.echoDebug(scriptEntry, "...remembering this script entry!");
          scriptEntry.getResidingQueue().holdScriptEntry(arg.getValue(), scriptEntry);
        } else newArgs.add(arg.raw_value);
      }

      // Add the arguments back to the scriptEntry.
      scriptEntry.setArguments(newArgs);

      // Now process non-instant tags.
      if (scriptEntry.has_tags)
        scriptEntry.setArguments(
            TagManager.fillArguments(scriptEntry.getArguments(), scriptEntry, false));

      // Parse the rest of the arguments for execution.
      command.parseArgs(scriptEntry);

    } catch (InvalidArgumentsException e) {

      keepGoing = false;
      // Give usage hint if InvalidArgumentsException was called.
      dB.echoError("Woah! Invalid arguments were specified!");
      if (e.getMessage() != null && e.getMessage().length() > 0)
        dB.log(
            ChatColor.YELLOW
                + "+> MESSAGE follows: "
                + ChatColor.WHITE
                + "'"
                + e.getMessage()
                + "'");
      dB.log("Usage: " + command.getUsageHint());
      dB.echoDebug(scriptEntry, DebugElement.Footer);
      scriptEntry.setFinished(true);

    } catch (Exception e) {

      keepGoing = false;
      dB.echoError("Woah! An exception has been called with this command!");
      dB.echoError(e);
      dB.echoDebug(scriptEntry, DebugElement.Footer);
      scriptEntry.setFinished(true);

    } finally {

      if (keepGoing)
        try {
          // Run the execute method in the command
          command.execute(scriptEntry);
        } catch (Exception e) {
          dB.echoError("Woah!! An exception has been called with this command!");
          dB.echoError(e);
          scriptEntry.setFinished(true);
        }
    }

    return true;
  }
  @Override
  public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {

    // Extract objects from ScriptEntry
    List<dLocation> locations = (List<dLocation>) scriptEntry.getObject("location");
    List<dPlayer> targets = (List<dPlayer>) scriptEntry.getObject("targets");
    Effect effect = (Effect) scriptEntry.getObject("effect");
    Particle particleEffect = (Particle) scriptEntry.getObject("particleeffect");
    Element iconcrack = scriptEntry.getElement("iconcrack");
    Element iconcrack_data = scriptEntry.getElement("iconcrack_data");
    Element iconcrack_type = scriptEntry.getElement("iconcrack_type");
    Element radius = scriptEntry.getElement("radius");
    Element data = scriptEntry.getElement("data");
    Element qty = scriptEntry.getElement("qty");
    dLocation offset = scriptEntry.getdObject("offset");

    // Report to dB
    dB.report(
        scriptEntry,
        getName(),
        (effect != null
                ? aH.debugObj("effect", effect.getName())
                : particleEffect != null
                    ? aH.debugObj("special effect", particleEffect.getName())
                    : iconcrack_type.debug()
                        + iconcrack.debug()
                        + (iconcrack_data != null ? iconcrack_data.debug() : ""))
            + aH.debugObj("locations", locations.toString())
            + (targets != null ? aH.debugObj("targets", targets.toString()) : "")
            + radius.debug()
            + data.debug()
            + qty.debug()
            + offset.debug());

    for (dLocation location : locations) {
      // Slightly increase the location's Y so effects don't seem to come out of the ground
      location.add(0, 1, 0);

      // Play the Bukkit effect the number of times specified
      if (effect != null) {
        for (int n = 0; n < qty.asInt(); n++) {
          if (targets != null) {
            for (dPlayer player : targets) {
              if (player.isValid() && player.isOnline()) {
                effect.playFor(player.getPlayerEntity(), location, data.asInt());
              }
            }
          } else {
            effect.play(location, data.asInt(), radius.asInt());
          }
        }
      }

      // Play a ParticleEffect
      else if (particleEffect != null) {
        float osX = (float) offset.getX();
        float osY = (float) offset.getY();
        float osZ = (float) offset.getZ();
        List<Player> players = new ArrayList<Player>();
        if (targets == null) {
          float rad = radius.asFloat();
          for (Player player : location.getWorld().getPlayers()) {
            if (player.getLocation().distanceSquared(location) < rad * rad) {
              players.add(player);
            }
          }
        } else {
          for (dPlayer player : targets) {
            if (player.isValid() && player.isOnline()) {
              players.add(player.getPlayerEntity());
            }
          }
        }
        for (Player player : players) {
          particleEffect.playFor(player, location, qty.asInt(), offset.toVector(), data.asFloat());
        }
      }

      // Play an iconcrack (item break) effect
      else {
        float osX = (float) offset.getX();
        float osY = (float) offset.getY();
        float osZ = (float) offset.getZ();
        List<Player> players = new ArrayList<Player>();
        if (targets == null) {
          float rad = radius.asFloat();
          for (Player player : location.getWorld().getPlayers()) {
            if (player.getLocation().distanceSquared(location) < rad * rad) {
              players.add(player);
            }
          }
        } else {
          for (dPlayer player : targets) {
            if (player.isValid() && player.isOnline()) {
              players.add(player.getPlayerEntity());
            }
          }
        }
        // TODO: better this all
        if (iconcrack_type.asString().equalsIgnoreCase("iconcrack")) {
          ItemStack itemStack =
              new ItemStack(iconcrack.asInt(), iconcrack_data != null ? iconcrack_data.asInt() : 0);
          Particle particle =
              NMSHandler.getInstance().getParticleHelper().getParticle("ITEM_CRACK");
          for (Player player : players) {
            particle.playFor(
                player, location, qty.asInt(), offset.toVector(), data.asFloat(), itemStack);
          }
        } else if (iconcrack_type.asString().equalsIgnoreCase("blockcrack")) {
          MaterialData materialData =
              new MaterialData(
                  iconcrack.asInt(), (byte) (iconcrack_data != null ? iconcrack_data.asInt() : 0));
          Particle particle =
              NMSHandler.getInstance().getParticleHelper().getParticle("BLOCK_CRACK");
          for (Player player : players) {
            particle.playFor(
                player, location, qty.asInt(), offset.toVector(), data.asFloat(), materialData);
          }
        } else { // blockdust
          MaterialData materialData =
              new MaterialData(
                  iconcrack.asInt(), (byte) (iconcrack_data != null ? iconcrack_data.asInt() : 0));
          Particle particle =
              NMSHandler.getInstance().getParticleHelper().getParticle("BLOCK_DUST");
          for (Player player : players) {
            particle.playFor(
                player, location, qty.asInt(), offset.toVector(), data.asFloat(), materialData);
          }
        }
      }
    }
  }