com.gmail.gkovalechyn.automaticevents.events.Event.java Source code

Java tutorial

Introduction

Here is the source code for com.gmail.gkovalechyn.automaticevents.events.Event.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.gmail.gkovalechyn.automaticevents.events;

import com.gmail.gkovalechyn.automaticevents.AutomaticEvents;
import com.gmail.gkovalechyn.automaticevents.api.Addon;
import com.gmail.gkovalechyn.automaticevents.parsing.Variable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;

/**
 *
 * @author Gabriel K
 */
public class Event implements Runnable {

    public final AutomaticEvents plugin;

    private final String yamlFileName;
    private final FileConfiguration yamlFile;

    private final Map<String, Variable> vars = new HashMap<>();
    private final List<Objective> objectives = new ArrayList<>();

    private final List<Addon> addons = new LinkedList<>();
    private final List<Addon> greedyAddons = new LinkedList<>();

    private final EventOptions opts = new EventOptions();
    private EventMessager messager;

    private boolean broken = false;
    private boolean cancel = false;
    private boolean started = false;

    public final boolean canJoinInMiddle;

    private final Set<Player> players = new HashSet<>();

    public Event(AutomaticEvents plugin, String fileName, FileConfiguration yamlFile) {
        this.plugin = plugin;
        this.yamlFile = yamlFile;
        this.canJoinInMiddle = yamlFile.getBoolean("canJoinInMiddle");
        this.yamlFileName = fileName;
        this.setupOptions();
    }

    public void start() {
        if (!started) {
            List<Objective> enabled = new ArrayList<>();

            for (Objective o : objectives) {
                o.onStart(this, this.getObjectiveArgs(o.getName()));

                if (!this.broken) {
                    enabled.add(o);
                } else {
                    for (Objective obj : enabled) {
                        obj.onComplete();
                    }
                    return;
                }
            }

            if (!broken) {
                //execute the onStart commands
                List<String> onStartPlayers = this.yamlFile.getStringList("onStart.playerCommands");
                List<String> onStart = this.yamlFile.getStringList("onStart.startCommands");
                this.replaceVariables(onStart, onStartPlayers);

                //greedy addons
                for (Addon a : this.greedyAddons) {
                    a.onStart();
                }

                //commands
                this.executeCommands(onStart);

                for (Player p : this.players) {
                    this.executeCommands(p, onStartPlayers);
                }

                //execute the onStart of the addons
                for (Addon a : this.addons) {
                    a.onStart();
                }

                plugin.getServer().getScheduler().runTaskAsynchronously(plugin, this);
            }
        }
    }

    public void cancel() {
        this.cancel = true;
    }

    @Override
    public void run() {
        boolean won = false;
        Player winner = null;
        List<String> endCommands = this.yamlFile.getStringList("onEnd.endCommands");

        this.replaceVariables(endCommands);

        while (!cancel && !broken && players.size() > 0) {
            started = true;

            synchronized (players) {
                for (Player p : players) {
                    won = true;

                    for (Objective o : objectives) {
                        if (!o.isComplete(p)) {
                            won = false;
                            break;
                        }
                    }

                    if (won) {
                        winner = p;
                        break;
                    }
                }
            }

            if (broken || cancel) {
                List<String> cmds = this.yamlFile.getStringList("onEnd.forOthers");

                this.replaceVariables(cmds);

                //Execute the commands
                if (this.opts.executeOnEndIfBroken) {
                    this.executeCommands(endCommands);
                }

                for (Player p : players) {
                    this.executeCommands(p, cmds);
                }

                //execute the onEnd of the addons with null because it broke.
                for (Addon a : this.greedyAddons) {
                    a.onComplete(null);
                }

                for (Addon a : this.addons) {
                    a.onComplete(null);
                }

            } else if (won) {//Won
                List<String> others = this.yamlFile.getStringList("onEnd.forOthers");
                List<String> wonCmds = this.yamlFile.getStringList("onEnd.forWinner");

                //replace the variables in the commands
                this.replaceVariables(wonCmds, others);

                //Execute the commands
                this.executeCommands(endCommands);

                for (Player p : players) {
                    if (winner != p) {
                        this.executeCommands(p, others);
                    } else {
                        //greedy addons
                        for (Addon addon : this.greedyAddons) {
                            addon.onComplete(winner);
                        }

                        //commands
                        this.executeCommands(p, wonCmds);

                        //normal addons
                        for (Addon addon : this.addons) {
                            addon.onComplete(winner);
                        }
                    }
                } //end of command execution
            } //else if (won)

            if (!won) {
                try {
                    Thread.sleep(200); //10 ticks
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    this.broken = true;
                }
            } else {
                break;
            }
        } //end of main event loop

        //Execute the onEnd of the objectives
        for (Objective o : objectives) {
            o.onComplete();
        }

        this.reset();
    }

    public FileConfiguration getEventYaml() {
        return this.yamlFile;
    }

    public boolean isBroken() {
        return broken;
    }

    public void setBroken(boolean broken) {
        this.broken = broken;
    }

    public boolean isInEvent(String player) {
        return isInEvent(Bukkit.getPlayer(player));
    }

    public boolean isInEvent(Player p) {
        return this.players.contains(p);
    }

    public void addPlayer(Player p) {
        this.addPlayer(p, false);
    }

    public void addPlayer(Player p, boolean forceCommands) {
        synchronized (players) {
            this.players.add(p);
        }
        //greedy addons
        for (Addon a : this.greedyAddons) {
            a.onPlayerJoin(p);
        }
        //commands
        if (started || forceCommands) {
            List<String> onStart = this.yamlFile.getStringList("onStart");
            this.replaceVariables(onStart);
            this.executeCommands(p, onStart);
        }
        //normal addons
        for (Addon a : this.addons) {
            a.onPlayerJoin(p);
        }
    }

    public void removePlayer(Player p) {
        this.removePlayer(p, false);
    }

    public void removePlayer(Player p, boolean forceCommands) {
        synchronized (players) {
            this.players.remove(p);
        }
        //greedy addons
        for (Addon a : this.greedyAddons) {
            a.onPlayerQuit(p);
        }
        //commands
        if (started || forceCommands) {
            List<String> cmds = this.yamlFile.getStringList("onEnd.forOthers");
            //Replace the commands
            this.replaceVariables(cmds);

            this.executeCommands(p, cmds);
        }
        //normal addons
        for (Addon a : this.addons) {
            a.onPlayerQuit(p);
        }
    }

    public void setVar(String var, Variable val) {
        this.vars.put(var, val);
    }

    public Variable getVar(String var) {
        return this.vars.get(var);
    }

    private void executeCommands(Player player, List<String> cmds) {
        CommandSender sender = Bukkit.getServer().getConsoleSender();

        for (String cmd : cmds) {
            Bukkit.getServer().dispatchCommand(sender, cmd.replaceAll("%player", player.getName()));
        }
    }

    private void executeCommands(List<String> cmds) {
        CommandSender sender = Bukkit.getServer().getConsoleSender();

        for (String cmd : cmds) {
            Bukkit.getServer().dispatchCommand(sender, cmd);
        }
    }

    public void addObjective(Objective o) {
        this.objectives.add(o);
    }

    private String[] getObjectiveArgs(String objectiveName) {
        for (String s : this.yamlFile.getStringList("objectives.list")) {
            //name args
            String[] a = s.split(" ");
            if (a.length > 1 && a[0].equals(objectiveName)) {
                String[] args = new String[a.length - 1];
                System.arraycopy(a, 1, args, 0, args.length);
                return args;
            }
        }

        return new String[0];
    }

    public boolean isRunning() {
        return this.started;
    }

    public Map<String, Variable> getVariables() {
        return new HashMap<>(vars);
    }

    public List<Objective> getObjectives() {
        synchronized (objectives) {//Maybe not neccessary?
            return new ArrayList<>(objectives);
        }
    }

    public Set<Player> getPlayers() {
        return this.players;
    }

    private void reset() {
        if (started) {
            this.started = false;
            this.cancel = false;
            this.players.clear();
            plugin.manager.closeEvent(plugin.manager.getEventName(this));
        }
    }

    public boolean isCancelled() {
        return this.cancel;
    }

    public String getYamlFileName() {
        return this.yamlFileName;
    }

    private void setupOptions() {
        this.opts.maxPlayers = this.yamlFile.getInt("options.maxPlayers", 16);
        this.opts.minPlayers = this.yamlFile.getInt("options.minPlayers", 4);
        this.opts.executeOnEndIfBroken = this.yamlFile.getBoolean("options.commands.executeEndCommandsIfBroken",
                true);
    }

    public boolean canStart() {
        return this.players.size() >= this.opts.minPlayers;
    }

    public boolean canJoin(Player p) {
        return this.players.size() < this.opts.maxPlayers && (this.isRunning() ? this.canJoinInMiddle : true);
    }

    public void resetFailedStart() {
        List<String> cmds = this.yamlFile.getStringList("onFailedStart");
        this.replaceVariables(cmds);

        for (Player p : this.players) {
            this.executeCommands(p, cmds);
        }

        this.players.clear();
    }

    private void replaceVariables(List<String>... lists) {
        for (Map.Entry<String, Variable> entry : vars.entrySet()) {
            String var = StringUtils.join(entry.getValue().toArgs(), " ");

            for (List<String> list : lists) {
                for (int i = 0; i < list.size(); i++) {
                    list.set(i, list.get(i).replaceAll(entry.getKey(), var));
                }
            }
        }
    }

    public void addAddon(Addon a) {
        if (a.isGreedy()) {
            this.greedyAddons.add(a);
        } else {
            this.addons.add(a);
        }

        a.onAssign(this);
    }

    /**
     * @return The max amount of players allowed in this event.
     */
    public int getMaxPlayers() {
        return this.opts.maxPlayers;
    }

    /**
     *
     * @return The max minimum of players allowed in this event.
     */
    public int getMinPlayers() {
        return this.opts.minPlayers;
    }

    public void setMessager(EventMessager messager) {
        this.messager = messager;
    }

    public EventMessager getMessager() {
        return this.messager;
    }

    private class EventOptions {

        public int maxPlayers;
        public int minPlayers;
        public boolean executeOnEndIfBroken;
    }

    public interface EventMessager {

        public String getNextMessage();
    }

}