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

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

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

import net.aufdemrand.denizen.BukkitScriptEntryData;
import net.aufdemrand.denizencore.exceptions.CommandExecutionException;
import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.objects.*;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.scripts.commands.AbstractCommand;
import net.aufdemrand.denizen.utilities.DenizenAPI;
import net.aufdemrand.denizen.utilities.debugging.dB;

/**
* <p>Sets a 'cooldown' period on a script. Can be per-player or globally.</p>
*
* @author Jeremy Schroeder
*
*/
public class CooldownCommand extends AbstractCommand {

    private enum Type { GLOBAL, PLAYER }

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

        // Defaults are Type.PLAYER and the attached Script
        scriptEntry.addObject("type", Type.PLAYER);
        scriptEntry.addObject("script", scriptEntry.getScript());

        // Parse arguments.. we need a type, duration, and script.

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

            // Type may be PLAYER or GLOBAL.. must not have a prefix.
            if (!arg.hasPrefix() && arg.matchesEnum(Type.values())) {
                scriptEntry.addObject("type", Type.valueOf(arg.getValue().toUpperCase()));
            }

            // Duration does not need a prefix, but is required.
            else if (!scriptEntry.hasObject("duration")
                    && arg.matchesArgumentType(Duration.class)) {
                scriptEntry.addObject("duration", arg.asType(Duration.class));
            }

            // Require a prefix on the script, since it's optional.
            else if (arg.matchesPrefix("script", "s")) {
                // Check matchesArgumentType afterwards so we don't default
                // to the attached script unintentionally.
                if (arg.matchesArgumentType(dScript.class))
                    scriptEntry.addObject("script", arg.asType(dScript.class));
                else
                    throw new InvalidArgumentsException("Specified an invalid script!");
            }

            else arg.reportUnhandled();
        }

        if (!scriptEntry.hasObject("duration"))
            throw new InvalidArgumentsException("Requires a valid duration!");
    }


    @Override
    public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
        // Fetch objects
        dScript script = (dScript) scriptEntry.getObject("script");
        Duration duration = (Duration) scriptEntry.getObject("duration");
        Type type = (scriptEntry.hasObject("type") ?
                (Type) scriptEntry.getObject("type") : Type.PLAYER);

        // Report to dB
        dB.report(scriptEntry, getName(), aH.debugObj("Type", type.name())
                + script.debug()
                + (type.name().equalsIgnoreCase("player") ? ((BukkitScriptEntryData)scriptEntry.entryData).getPlayer().debug() : "")
                + duration.debug());

        // Perform cooldown
        switch (type) {
            case PLAYER:
                setCooldown(((BukkitScriptEntryData)scriptEntry.entryData).getPlayer(),
                        duration,
                        script.getName(),
                        false);
                break;

            case GLOBAL:
                setCooldown(null,
                        duration,
                        script.getName(),
                        true);
                break;
        }
    }


    /**
     * Gets the duration of a script cool-down.
     *
     * @param player
     *         the Player to check, null if only checking Global.
     * @param scriptName
     *         the name of the script to check
     * @return a Duration of the time remaining
     */
    public static Duration getCooldownDuration(dPlayer player, String scriptName) {

        // Change to UPPERCASE so there's no case-sensitivity.
        scriptName = scriptName.toUpperCase();

        Duration duration = Duration.ZERO;

        // Check current entry GLOBALLY, reset it if necessary
        if (DenizenAPI._saves().contains("Global.Scripts." + scriptName + ".Cooldown Time")) {
            if (System.currentTimeMillis()
                    < DenizenAPI._saves().getLong("Global.Scripts." + scriptName + ".Cooldown Time"))
                duration = new Duration((double) (DenizenAPI._saves().getLong("Global.Scripts." + scriptName
                        + ".Cooldown Time") - System.currentTimeMillis()) / 1000);
        }

        // No player specified? No need to check any further...
        if (player == null)
            return duration;

        // If no entry for the script, return true
        if (!DenizenAPI._saves().contains("Players." + player.getSaveName() + ".Scripts." + scriptName + ".Cooldown Time"))
            return duration;

        // If there is an entry, check against the time
        if (System.currentTimeMillis()
                <= DenizenAPI._saves().getLong("Players." + player.getSaveName() + ".Scripts." + scriptName + ".Cooldown Time")) {
            Duration player_dur = new Duration((double) (DenizenAPI._saves().getLong("Players." + player.getSaveName() + ".Scripts."
                    + scriptName + ".Cooldown Time") - System.currentTimeMillis()) / 1000);
            if (player_dur.getSeconds() > duration.getSeconds())
                return player_dur;
        }

        return duration;
    }


    /**
     * Checks if a script is cooled-down. If a cool-down is currently in progress,
     * its requirements will fail and it will not trigger. If the script is being cooled down
     * globally, this will also return false.
     *
     * @param player
     *         the Player to check, null if only checking Global.
     * @param scriptName
     *         the name of the script to check
     * @return true if the script is cool
     */
    public static boolean checkCooldown(dPlayer player, String scriptName) {

        // Change to UPPERCASE so there's no case-sensitivity.
        scriptName = scriptName.toUpperCase();

        // Check current entry GLOBALLY, reset it if necessary
        if (DenizenAPI._saves().contains("Global.Scripts." + scriptName + ".Cooldown Time")) {
            if (System.currentTimeMillis()
                    < DenizenAPI._saves().getLong("Global.Scripts." + scriptName + ".Cooldown Time"))
                return false;
            else
                DenizenAPI._saves().set("Global.Scripts." + scriptName + ".Cooldown Time", null);
        }

        // No player specified? No need to check any further...
        if (player == null)
            return true;

        // If no entry for the script, return true
        if (!DenizenAPI._saves().contains("Players." + player.getSaveName() + ".Scripts." + scriptName + ".Cooldown Time"))
            return true;

        // If there is an entry, check against the time
        if (System.currentTimeMillis()
                >= DenizenAPI._saves().getLong("Players." + player.getSaveName() + ".Scripts." + scriptName + ".Cooldown Time"))    {
            DenizenAPI._saves().set("Players." + player.getSaveName() + ".Scripts." + scriptName + ".Cooldown Time", null);
            return true;
        }

        return false;
    }


    /**
     * Sets a cooldown for a Denizen Script. Can be for a specific Player, or GLOBAL.
     *
     * @param player
     *         if not a global cooldown, the Player to set the cooldown for
     * @param duration
     *         the duration of the cooldown period, in seconds
     * @param scriptName
     *         the name of the script to cooldown
     * @param global
     *         whether the script should be cooled down globally
     */
    public static void setCooldown(dPlayer player, Duration duration, String scriptName, boolean global) {
        scriptName = scriptName.toUpperCase();
        // Set global cooldown
        if (global) {
            DenizenAPI._saves().set("Global.Scripts." + scriptName + ".Cooldown Time",
                    System.currentTimeMillis()
                            + (duration.getSecondsAsInt() * 1000));

            // or set Player cooldown
        }   else {
            DenizenAPI._saves().set("Players." + player.getSaveName() + ".Scripts." + scriptName + ".Cooldown Time",
                    System.currentTimeMillis()
                            + (duration.getSecondsAsInt() * 1000));
        }
    }
}
TOP

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

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.