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