Package net.aufdemrand.denizen.events

Source Code of net.aufdemrand.denizen.events.EventManager

package net.aufdemrand.denizen.events;

import net.aufdemrand.denizen.BukkitScriptEntryData;
import net.aufdemrand.denizen.events.bukkit.ScriptReloadEvent;
import net.aufdemrand.denizen.events.core.*;
import net.aufdemrand.denizen.objects.aH;
import net.aufdemrand.denizen.objects.dNPC;
import net.aufdemrand.denizen.objects.dObject;
import net.aufdemrand.denizen.objects.dPlayer;
import net.aufdemrand.denizen.scripts.ScriptBuilder;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.scripts.commands.core.DetermineCommand;
import net.aufdemrand.denizen.scripts.containers.core.WorldScriptContainer;
import net.aufdemrand.denizen.scripts.queues.ScriptQueue;
import net.aufdemrand.denizen.scripts.queues.core.InstantQueue;
import net.aufdemrand.denizen.utilities.DenizenAPI;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizencore.utilities.YamlConfiguration;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap;
import org.bukkit.command.PluginCommand;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.SimplePluginManager;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class EventManager implements Listener {


    public EventManager() {
        DenizenAPI.getCurrentInstance().getServer().getPluginManager()
                .registerEvents(this, DenizenAPI.getCurrentInstance());
    }


    ///////////////////
    //  MAPS
    ////////////


    // Map for keeping the WorldScriptContainers
    public static Map<String, WorldScriptContainer> world_scripts =
            new ConcurrentHashMap<String, WorldScriptContainer>(8, 0.9f, 1);

    // Map for keeping the names of events
    public static Map<String, List<WorldScriptContainer>> events =
            new HashMap<String, List<WorldScriptContainer>>();

    // Map for keeping track of registered smart_events
    public static Set<SmartEvent> smart_events = new HashSet<SmartEvent>();

    //////////////////
    // PERFORMANCE
    ///////////


    @EventHandler
    public void scanWorldEvents(ScriptReloadEvent event) {
        try {
            // Build a Map of scripts keyed by 'world events name'.

            // Loop through each world script
            dB.log("Scanning " + world_scripts.size() + " world scripts...");
            for (WorldScriptContainer script : world_scripts.values()) {
                if (script == null) {
                    dB.echoError("Null world script?!");
                    continue;
                }

                // ...and through each event inside the script.
                if (script.contains("EVENTS")) {
                    YamlConfiguration configSection = script.getConfigurationSection("EVENTS");
                    if (configSection == null) {
                        dB.echoError("Script '" + script.getName() + "' has an invalid events block!");
                        break;
                    }
                    Set<String> keys = configSection.getKeys(false);
                    if (keys == null) {
                        dB.echoError("Script '" + script.getName() + "' has an empty events block!");
                        break;
                    }
                    for (String eventName : keys) {
                        List<WorldScriptContainer> list;
                        if (events.containsKey(eventName))
                            list = events.get(eventName);
                        else
                            list = new ArrayList<WorldScriptContainer>();
                        list.add(script);
                        events.put(eventName, list);
                    }
                }
                else {
                    dB.echoError("Script '" + script.getName() + "' does not have an events block!");
                }
            }
            // dB.echoApproval("Built events map: " + events);

            // Breakdown all SmartEvents (if still being used, they will reinitialize next)
            for (SmartEvent smartEvent : smart_events)
                smartEvent.breakDown();

            // Pass these along to each SmartEvent so they can determine whether they can be enabled or not
            for (SmartEvent smartEvent : smart_events) {
                // If it should initialize, run _initialize!
                if (smartEvent.shouldInitialize(events.keySet()))
                    smartEvent._initialize();
            }
        }
        catch (Exception e) {
            dB.echoError(e);
        }
    }


    private Plugin plugin = DenizenAPI.getCurrentInstance();


    public void registerCommand(String... aliases) {
        PluginCommand command = getCommand(aliases[0], plugin);

        command.setAliases(Arrays.asList(aliases));
        getCommandMap().register(plugin.getDescription().getName(), command);
    }


    private static PluginCommand getCommand(String name, Plugin plugin) {
        PluginCommand command = null;

        try {
            Constructor<PluginCommand> c = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
            c.setAccessible(true);

            command = c.newInstance(name, plugin);
        } catch (Exception e) {
            dB.echoError(e);
        }

        return command;
    }


    private static CommandMap getCommandMap() {
        CommandMap commandMap = null;

        try {
            if (Bukkit.getPluginManager() instanceof SimplePluginManager) {
                Field f = SimplePluginManager.class.getDeclaredField("commandMap");
                f.setAccessible(true);

                commandMap = (CommandMap) f.get(Bukkit.getPluginManager());
            }
        } catch (NoSuchFieldException e) {
            dB.echoError(e);
        } catch (SecurityException e) {
            dB.echoError(e);
        } catch (IllegalArgumentException e) {
            dB.echoError(e);
        } catch (IllegalAccessException e) {
            dB.echoError(e);
        }

        return commandMap;
    }


    public static List<String> trimEvents(List<String> original) {
        List<String> event = new ArrayList<String>();
        event.addAll(original);
        List<String> parsed = new ArrayList<String>();

        if (dB.showEventsTrimming) dB.echoApproval("Trimming world events '" + event.toString() + '\'');

        // Remove any duplicate event names
        for (int i = 0; i < event.size(); i++) {
            for (int x = 0; x < event.size(); x++) {
                if (i != x && event.get(i).equalsIgnoreCase(event.get(x))) {
                    event.remove(i);
                    i--;
                    break;
                }
            }
        }

        // Create a new list, only containing events that have existing scripts
        for (String e : event)
            if (events.containsKey("ON " + e.toUpperCase()))
                parsed.add(e);

        return parsed;
    }


    public static boolean eventExists(String original) {
        return events.containsKey("ON " + original.toUpperCase());
    }

    ///////////////////
    //  COMPATIBILITY
    //////////////


    /**
     *
     * @deprecated this was just a temporary place holder and will be removed soon.
     */
    @Deprecated
    public static String doEvents(List<String> eventNames, dNPC npc, dPlayer player, Map<String, dObject> context,
                                  boolean usesIdentifiers, int Use_dPlayer) {

        // If a list of events uses identifiers, also add those events to the list
        // with their identifiers stripped
        return doEvents(usesIdentifiers ? addAlternates(eventNames)
                : eventNames,
                npc, player, context);
    }

    public static String doEvents(List<String> eventNames, dNPC npc, dPlayer player, Map<String, dObject> context,
                                  boolean usesIdentifiers) {

        // If a list of events uses identifiers, also add those events to the list
        // with their identifiers stripped
        return doEvents(usesIdentifiers ? addAlternates(eventNames)
                : eventNames,
                npc, player, context);
    }


    public static List<String> addAlternates(List<String> events) {

        // Strip object identifiers from world event names and add the results
        // to the original list of world event names without any duplicates

        Set<String> newEvents = new HashSet<String>();

        for (String event : events) {
            // NOTE: The below code deletes [a-z]{1,2}\@
            if (event.indexOf('@') != -1) {
                StringBuilder sb = new StringBuilder();
                int len = event.length();
                char[] data = event.toCharArray();
                for (int i = 0; i < len; i++) {
                    if (data[i] >= 'a' && data[i] <= 'z' && i + 1 < len) {
                        if (i + 2 < len && data[i + 2] == '@') {
                            i += 2;
                            continue;
                        }
                        if (data[i + 1] == '@') {
                            i++;
                            continue;
                        }
                    }
                    sb.append(data[i]);
                }
                newEvents.add(sb.toString());
            }
        }

        List<String> finalEvents = new ArrayList<String>();
        finalEvents.addAll(events);
        finalEvents.addAll(newEvents);
        return finalEvents;
    }


    public static String StripIdentifiers(String original) {
        if (original.matches(".*?[a-z]{1,2}@[\\w ]+"))
            return original.replaceAll("[a-z]{1,2}@", "");
        else
            return original;
    }

    ///////////////////
    //  MECHANICS
    ///////////////


    /**
     *
     * @deprecated this was just a temporary place holder and will be removed soon.
     */
    @Deprecated
    public static String doEvents(List<String> eventNames, dNPC npc, dPlayer player, Map<String, dObject> context, int Use_dPlayer) {
        return doEvents(eventNames, npc, player, context);
    }

    public static String doEvents(List<String> eventNames, dNPC npc, dPlayer player, Map<String, dObject> context) {

        try {
            String determination = "none";

            // Trim again to catch events that don't trim internally.
            eventNames = trimEvents(eventNames);

            for (String eventName : eventNames) {

                if (events.containsKey("ON " + eventName.toUpperCase()))

                    for (WorldScriptContainer script : events.get("ON " + eventName.toUpperCase())) {

                        if (script == null) continue;

                        // Fetch script from Event
                        List<ScriptEntry> entries = script.getEntries(new BukkitScriptEntryData(player, npc), "events.on " + eventName);

                        if (entries.isEmpty()) continue;

                        dB.report(script, "Event",
                                aH.debugObj("Type", "on " + eventName)
                                        + script.getAsScriptArg().debug()
                                        + (npc != null ? aH.debugObj("NPC", npc.toString()) : "")
                                        + (player != null ? aH.debugObj("Player", player.getName()) : "")
                                        + (context != null ? aH.debugObj("Context", context.toString()) : ""));

                        dB.echoDebug(script, dB.DebugElement.Header, "Building event 'ON " + eventName.toUpperCase()
                                + "' for " + script.getName());

                        // Create new ID -- this is what we will look for when determining an outcome
                        long id = DetermineCommand.getNewId();

                        // Add the reqId to each of the entries for the determine command
                        ScriptBuilder.addObjectToEntries(entries, "ReqId", id);

                        // Add entries and context to the queue
                        ScriptQueue queue = InstantQueue.getQueue(ScriptQueue.getNextId(script.getName())).addEntries(entries).setReqId(id);

                        if (context != null) {
                            for (Map.Entry<String, dObject> entry : context.entrySet()) {
                                queue.addContext(entry.getKey(), entry.getValue());
                            }
                        }

                        // Start the queue!
                        queue.start();

                        // Check the determination
                        if (DetermineCommand.hasOutcome(id))
                            determination =  DetermineCommand.getOutcome(id);
                    }
            }

            return determination;
        }
        catch (Exception e) {
            dB.echoError(e);
            return "none";
        }
    }

    ////////////////////
    //  REGISTRATION
    //////////////


    public void registerCoreMembers() {
        // Register all the 'Core' SmartEvents. This is called by Denizen's onEnable().
        registerSmartEvent(new AsyncChatSmartEvent());
        registerSmartEvent(new BiomeEnterExitSmartEvent());
        registerSmartEvent(new BlockFallsSmartEvent());
        registerSmartEvent(new BlockPhysicsSmartEvent());
        registerSmartEvent(new ChunkLoadSmartEvent());
        registerSmartEvent(new ChunkUnloadSmartEvent());
        registerSmartEvent(new CommandSmartEvent());
        registerSmartEvent(new CuboidEnterExitSmartEvent());
        registerSmartEvent(new EntityCombustSmartEvent());
        registerSmartEvent(new EntityDamageSmartEvent());
        registerSmartEvent(new EntityDeathSmartEvent());
        registerSmartEvent(new EntityInteractSmartEvent());
        registerSmartEvent(new EntitySpawnSmartEvent());
        registerSmartEvent(new FlagSmartEvent());
        registerSmartEvent(new ItemMoveSmartEvent());
        registerSmartEvent(new ItemScrollSmartEvent());
        registerSmartEvent(new ListPingSmartEvent());
        registerSmartEvent(new NPCNavigationSmartEvent());
        registerSmartEvent(new PlayerEquipsArmorSmartEvent());
        registerSmartEvent(new PlayerJumpSmartEvent());
        registerSmartEvent(new PlayerStepsOnSmartEvent());
        registerSmartEvent(new PlayerWalkSmartEvent());
        registerSmartEvent(new RedstoneSmartEvent());
        registerSmartEvent(new SyncChatSmartEvent());
        registerSmartEvent(new VehicleCollisionSmartEvent());
    }


    public static void registerSmartEvent(SmartEvent event) {
        // Seems simple enough
        if (event != null)
            smart_events.add(event);
    }
}

TOP

Related Classes of net.aufdemrand.denizen.events.EventManager

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.