Package net.aufdemrand.denizen.scripts.commands.core

Source Code of net.aufdemrand.denizen.scripts.commands.core.RunCommand

package net.aufdemrand.denizen.scripts.commands.core;

import java.util.List;

import net.aufdemrand.denizen.BukkitScriptEntryData;
import net.aufdemrand.denizencore.exceptions.CommandExecutionException;
import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.objects.Duration;
import net.aufdemrand.denizen.objects.Element;
import net.aufdemrand.denizen.objects.aH;
import net.aufdemrand.denizen.objects.dList;
import net.aufdemrand.denizen.objects.dNPC;
import net.aufdemrand.denizen.objects.dPlayer;
import net.aufdemrand.denizen.objects.dScript;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.scripts.commands.AbstractCommand;
import net.aufdemrand.denizencore.scripts.commands.Holdable;
import net.aufdemrand.denizen.scripts.queues.ScriptQueue;
import net.aufdemrand.denizen.scripts.queues.core.InstantQueue;
import net.aufdemrand.denizen.scripts.queues.core.TimedQueue;
import net.aufdemrand.denizen.utilities.debugging.dB;

/**
* Runs a task script in a new ScriptQueue.
* This replaces the now-deprecated runtask command with queue argument.
*
* @author Jeremy Schroeder
*
*/

public class RunCommand extends AbstractCommand implements Holdable {

    // <--[example]
    // @Title Using Local Scripts tutorial
    // @Description
    // Use local scripts as a way to avoid making unnecessary script containers
    // or to group together utility task scripts.
    //
    // @Code
    // # +--------------------
    // # | Using Local Scripts tutorial
    // # |
    // # | Since Script Containers are stored inside Denizen on a global level,
    // # | the problem of duplicate container names can become a problem.
    // # |
    // # | Using local scripts can be a good way to avoid situations by cutting
    // # | down on the amount of total script containers needed by allowing task utility
    // # | scripts to be included in other containers, or grouped together in a single
    // # | container.
    //
    // Local Script Tutorial:
    //   type: task
    //
    //   # As you probably already know, to run a 'base script' inside a task script
    //   # the 'run' or 'inject' commands can be used. This requires the name of the
    //   # script container as an argument in the commands. For example, type
    //   # /ex run 's@Local Script Tutorial' .. to run the script
    //   # below.
    //
    //   script:
    //   - narrate "This is the 'base script' of this task script container."
    //   - narrate "The current time is <util.date.time>!"
    //
    //
    //   # Local Script support by Denizen allows you to stash more scripts. Just specify
    //   # a new node. To run this script from other containers, specify the script as well as
    //   # the local script name node with a 'p' or 'path:' prefix. For example, to run the
    //   # script below, type /ex run 's@Local Script Tutorial' 'p:subscript_1'
    //
    //   subscript_1:
    //   - narrate "This is a 'local script' in the task script container 'LocalScript Tutorial'."
    //
    //   # But wait, there's more! If wanting to run a local script that is within the
    //   # same container, the run command can be even simpler by specifying 'local'
    //   # in place of the script name. Take a look at the next two local scripts. Type
    //   # /ex run 's@Local Script Tutorial' 'p:subscript_2' .. to run the script below
    //   # which will in turn run 'subscript_3' locally. Notice if you specify locally,
    //   # the script used is
    //
    //   subscript_2:
    //   - narrate "This is the second 'local script' in this task script container."
    //   - narrate "This script will now run 'subscript_3'."
    //   - run locally 'subscript_3'
    //
    //   subscript_3:
    //   - narrate "Done. This has been a message from subscript_3!"
    //
    //
    //   # There you have it! Three separate scripts inside a single task script container!
    //   # Both the 'run' command and 'inject' command support local scripts.
    //
    // -->

    @Override
    public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {

        for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) {

            if (arg.matchesPrefix("i", "id"))
                scriptEntry.addObject("id", arg.asElement());

            else if (arg.matchesPrefix("a", "as")
                    && arg.matchesArgumentType(dPlayer.class)) {
                scriptEntry.setPlayer(arg.asType(dPlayer.class));
                dB.echoError(scriptEntry.getResidingQueue(), "Run as:<player> is outdated, use player:<player>");
            }

            else if (arg.matchesPrefix("a", "as")
                    && arg.matchesArgumentType(dNPC.class)) {
                scriptEntry.setNPC(arg.asType(dNPC.class));
                dB.echoError(scriptEntry.getResidingQueue(), "Run as:<npc> is outdated, use npc:<npc>");
            }

            // Catch invalid entry for 'as' argument
            else if (arg.matchesPrefix("a", "as"))
                dB.echoError(scriptEntry.getResidingQueue(), "Specified target was not attached. Value must contain a valid PLAYER or NPC object.");

            else if (arg.matchesPrefix("d", "def", "define", "c", "context"))
                scriptEntry.addObject("definitions", arg.asType(dList.class));

            else if (arg.matches("instant", "instantly"))
                scriptEntry.addObject("instant", new Element(true));

            else if (arg.matchesPrefix("delay")
                    && arg.matchesArgumentType(Duration.class))
                scriptEntry.addObject("delay", arg.asType(Duration.class));

            else if (arg.matches("local", "locally"))
                scriptEntry.addObject("local", new Element(true));

            else if (!scriptEntry.hasObject("script")
                    && arg.matchesArgumentType(dScript.class)
                    && !arg.matchesPrefix("p", "path"))
                scriptEntry.addObject("script", arg.asType(dScript.class));

            else if (!scriptEntry.hasObject("path"))
                scriptEntry.addObject("path", arg.asElement());

            else arg.reportUnhandled();

        }

        if (!scriptEntry.hasObject("script") && !scriptEntry.hasObject("local"))
            throw new InvalidArgumentsException("Must define a SCRIPT to be run.");

        if (!scriptEntry.hasObject("path") && scriptEntry.hasObject("local"))
            throw new InvalidArgumentsException("Must specify a PATH.");

    }

    @Override
    public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
        dB.report(scriptEntry, getName(),
                (scriptEntry.hasObject("script") ? scriptEntry.getdObject("script").debug() : scriptEntry.getScript().debug())
                        + (scriptEntry.hasObject("instant") ? scriptEntry.getdObject("instant").debug() : "")
                        + (scriptEntry.hasObject("path") ? scriptEntry.getElement("path").debug() : "")
                        + (scriptEntry.hasObject("local") ? scriptEntry.getElement("local").debug() : "")
                        + (scriptEntry.hasObject("delay") ? scriptEntry.getdObject("delay").debug() : "")
                        + (scriptEntry.hasObject("id") ? scriptEntry.getdObject("id").debug() : "")
                        + (scriptEntry.hasObject("definitions") ? scriptEntry.getdObject("definitions").debug(): ""));

        // Get the script
        dScript script = scriptEntry.getdObject("script");

        // Get the entries
        List<ScriptEntry> entries;
        // If it's local
        if (scriptEntry.hasObject("local")) {
            entries = scriptEntry.getScript().getContainer().getEntries(scriptEntry.entryData.clone(),
                    scriptEntry.getElement("path").asString());
            script = scriptEntry.getScript();
        }

            // If it has a path
        else if (scriptEntry.hasObject("path") && scriptEntry.getObject("path") != null)
            entries = script.getContainer().getEntries(scriptEntry.entryData.clone(),
                    scriptEntry.getElement("path").asString());

            // Else, assume standard path
        else entries = script.getContainer().getBaseEntries(scriptEntry.entryData.clone());

        // Get the 'id' if specified
        String id = (scriptEntry.hasObject("id") ?
                (scriptEntry.getElement("id")).asString() : ScriptQueue.getNextId(script.getContainer().getName()));

        // Build the queue
        ScriptQueue queue;
        if (scriptEntry.hasObject("instant")) {
            queue = InstantQueue.getQueue(id).addEntries(entries);
        }
        else {
            queue = TimedQueue.getQueue(id).addEntries(entries);

            // Check speed of the script if a TimedQueue -- if identified, use the speed from the script.
            if (script != null && script.getContainer().contains("SPEED"))
                ((TimedQueue) queue).setSpeed(Duration.valueOf(script.getContainer().getString("SPEED", "0")).getTicks());

        }

        // Set any delay
        if (scriptEntry.hasObject("delay"))
            queue.delayUntil(System.currentTimeMillis() + ((Duration) scriptEntry.getObject("delay")).getMillis());

        // Set any definitions
        if (scriptEntry.hasObject("definitions")) {
            int x = 1;
            dList definitions = (dList) scriptEntry.getObject("definitions");
            String[] definition_names = null;
            try { definition_names = script.getContainer().getString("definitions").split("\\|"); }
            catch (Exception e) { }
            for (String definition : definitions) {
                String name = definition_names != null && definition_names.length >= x ?
                        definition_names[x - 1].trim() : String.valueOf(x);
                queue.addDefinition(name, definition);
                dB.echoDebug(scriptEntry, "Adding definition %" + name + "% as " + definition);
                x++;
            }
        }


        // Setup a callback if the queue is being waited on
        if (scriptEntry.shouldWaitFor()) {
            // Record the ScriptEntry
            final ScriptEntry se = scriptEntry;
            queue.callBack(new Runnable() {
                @Override
                public void run() {
                    se.setFinished(true);
                }
            });
        }

        // Save the queue for script referencing
        scriptEntry.addObject("created_queue", queue);

        // OK, GO!
        queue.start();
    }
}
TOP

Related Classes of net.aufdemrand.denizen.scripts.commands.core.RunCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.