Package net.aufdemrand.denizen.utilities

Source Code of net.aufdemrand.denizen.utilities.ScoreboardHelper

package net.aufdemrand.denizen.utilities;

import java.util.*;

import com.google.common.base.Splitter;
import net.aufdemrand.denizen.objects.aH.Argument;
import net.aufdemrand.denizen.objects.dPlayer;

import net.aufdemrand.denizen.scripts.commands.server.ScoreboardCommand;
import net.aufdemrand.denizen.utilities.debugging.dB;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.scoreboard.*;

/**
* Creates, saves and loads scoreboards
*
* @author David Cernat
*/

public class ScoreboardHelper {

    public static ScoreboardManager manager = Bukkit.getScoreboardManager();

    // A map with scoreboard IDs as keys and scoreboards as values
    public static Map<String, Scoreboard> scoreboardMap = new HashMap<String, Scoreboard>();
    // A map with viewer names as keys and scoreboard IDs as values
    public static Map<String, String> viewerMap = new HashMap<String, String>();

    /*
     * Called on server startup or /denizen reload saves
     */
    public static void _recallScoreboards() {

        // Clear every existing ingame scoreboard
        for (Map.Entry<String, Scoreboard> entry : scoreboardMap.entrySet()) {
            clearScoreboard(entry.getValue());
        }

        Scoreboard emptyBoard = createScoreboard();

        // Clear every viewer's set scoreboard
        for (Map.Entry<String, String> entry : viewerMap.entrySet()) {
            OfflinePlayer player = ScoreboardCommand.getOfflinePlayer(entry.getKey());
            if (player.isOnline()) {
                player.getPlayer().setScoreboard(emptyBoard);
            }
        }

        // Delete the contents of the scoreboardMap and viewerMap
        scoreboardMap.clear();
        viewerMap.clear();

        ConfigurationSection rootSection = DenizenAPI.getCurrentInstance()
                .getScoreboards().getConfigurationSection("Scoreboards");

        // Go no further if we have no scoreboards saved
        if (rootSection == null) return;

        Scoreboard board = null;

        // Iterate through scoreboards
        for (String id : rootSection.getKeys(false)) {
            // Create a scoreboard with this id
            board = createScoreboard(id);

            // Get the list of viewers
            List<String> viewerList = rootSection.getStringList(id + ".Viewers");

            // Iterate through viewers, store them in the viewerMap,
            // and make them see this scoreboard if they are online
            for (String viewer : viewerList) {
                if (dPlayer.matches(viewer)) {
                    dPlayer player = dPlayer.valueOf(viewer);
                    viewerMap.put(player.getName(), id);

                    if (player.isOnline())
                        player.getPlayerEntity().setScoreboard(board);
                }
            }

            ConfigurationSection objSection = rootSection
                    .getConfigurationSection(id + ".Objectives");

            // Go no further if we have no objectives saved
            if (objSection == null) return;

            // Iterate through objectives
            for (String obj : objSection.getKeys(false)) {
                // Get display slot and criteria for this objective
                String displaySlot = objSection.getString(obj + ".Display slot");
                String criteria = objSection.getString(obj + ".Criteria");

                // Use default criteria if necessary
                if (criteria == null)
                    criteria = "dummy";
                // Use default display slot if necessary
                if (displaySlot == null)
                    displaySlot = "NONE";

                // Register the objective and set it up
                Objective o = board.registerNewObjective(obj, criteria);
                o.setDisplayName(obj);

                // Only set display slot if it's valid
                if (Argument.valueOf(displaySlot).matchesEnum(DisplaySlot.values())) {
                    o.setDisplaySlot(DisplaySlot.valueOf(displaySlot.toUpperCase()));
                }

                ConfigurationSection scoreSection = objSection
                        .getConfigurationSection(obj + ".Scores");

                if (scoreSection != null) {
                    // Iterate through scores and add them to this objective
                    for (String scoreName : scoreSection.getKeys(false)) {
                        int scoreInt = scoreSection.getInt(scoreName);
                        addScore(o, ScoreboardCommand.getOfflinePlayer(scoreName), scoreInt);
                    }
                }
            }
        }
    }

    /*
     * Called on server shutdown or /denizen save
     */
    public static void _saveScoreboards() {

        try {
        // Clear scoreboards.yml
        DenizenAPI.getCurrentInstance().getScoreboards()
            .set("Scoreboards", null);

        // Iterate through scoreboards map
        for (Map.Entry<String, Scoreboard> scoreboardEntry : scoreboardMap.entrySet()) {

            String id = scoreboardEntry.getKey();
            List<String> viewerList = new ArrayList<String>();

            // Find all of the viewers that are viewing this scoreboard
            // and put them on a list
            for (Map.Entry<String, String> viewerEntry : viewerMap.entrySet()) {
                if (id.equalsIgnoreCase(viewerEntry.getValue())) {
                    viewerList.add(viewerEntry.getKey());
                }
            }

            // Save viewer list
            DenizenAPI.getCurrentInstance().getScoreboards()
                .set("Scoreboards." + id + ".Viewers", viewerList);

            // Iterate through objectives
            for (Objective obj : scoreboardEntry.getValue().getObjectives()) {
                String objPath = "Scoreboards." + id + ".Objectives."
                                 + obj.getName();

                // Save criteria for this objective
                DenizenAPI.getCurrentInstance().getScoreboards()
                    .set(objPath + ".Criteria", obj.getCriteria());

                String displaySlot;
                // If the display slot is null, save it as "NONE";
                // otherwise, save it with its regular name
                if (obj.getDisplaySlot() != null)
                    displaySlot = obj.getDisplaySlot().name();
                else
                    displaySlot = "NONE";

                DenizenAPI.getCurrentInstance().getScoreboards()
                    .set(objPath + ".Display slot", displaySlot);

                // There is no method for getting an objective's
                // scores, so iterate through all of the scoreboard's
                // players, check if they have a score for this
                // objective, and save it if they do
                for (String player : scoreboardEntry.getValue().getEntries()) {

                    int score = obj.getScore(player).getScore();
                    Team team = scoreboardEntry.getValue().getTeam(player);
                    // TODO: Properly save and load teams
                    player = (team != null && team.getPrefix() != null ? team.getPrefix(): "") + player + (team != null && team.getSuffix() != null ? team.getSuffix(): "");

                    // If a player has no score for this objective,
                    // getScore() will return 0, so ignore scores
                    // of 0
                    if (score != 0) {
                        DenizenAPI.getCurrentInstance().getScoreboards()
                            .set(objPath + ".Scores." + player, score);
                    }
                }
            }
        }
        }
        catch (Exception e) {
            dB.echoError(e);
        }
    }


    /////////////////////
    //   OBJECTIVE METHODS
    /////////////////

    /**
     * Add a score to an Objective for an OfflinePlayer.
     *
     * @param o  the Objective to add the score to
     * @param player  the OfflinePlayer to set the score for
     * @param score  the score
     *
     */
    public static void addScore(Objective o, OfflinePlayer player, int score) {
        Score sc;
        if (player.getName().length() <= 16) {
            sc = o.getScore(player.getName());
        }
        else {
            Map.Entry<Team, String> teamData = createTeam(o.getScoreboard(), player.getName());
            sc = o.getScore(teamData.getValue());
            teamData.getKey().addPlayer(ScoreboardCommand.getOfflinePlayer(teamData.getValue()));
        }

        // If the score is 0, it won't normally be displayed at first,
        // so force it to be displayed by using setScore() like below on it
        if (score == 0) {
            sc.setScore(1); sc.setScore(0);
        }
        else sc.setScore(score);
    }

    /**
     * Remove a score from an Objective for an OfflinePlayer.
     *
     * @param o  the Objective to remove the score from
     * @param player  the OfflinePlayer to remove the score for
     *
     */
    public static void removeScore(Objective o, OfflinePlayer player) {

        // There is no method to remove a single score from an
        // objective, as confirmed here:
        // https://bukkit.atlassian.net/browse/BUKKIT-4014
        //
        // So use crazy workaround below
        Scoreboard board = o.getScoreboard();
        Map<String, Integer> scoreMap = new HashMap<String, Integer>();

        // Go through every score for this (real or fake) player
        // and put it in scoreMap if it doesn't belong to the
        // objective we want to remove the score from
        String name = createTeam(board, player.getName()).getValue();
        // TODO: Properly remove when teams are involved
        for (Score sc : board.getScores(name)) {
            if (!sc.getObjective().equals(o)) {
                scoreMap.put(sc.getObjective().getName(), sc.getScore());
            }
        }

        // Remove all the scores for this (real or fake) player
        board.resetScores(player.getName());

        // Go through scoreMap and add back all the scores we saved
        // for this (real or fake) player
        for (Map.Entry<String, Integer> entry : scoreMap.entrySet()) {
            board.getObjective(entry.getKey())
                 .getScore(player.getName()).setScore(entry.getValue());
        }
    }

    private static Map.Entry<Team, String> createTeam(Scoreboard scoreboard, String text) {
        if (text.length() <= 16)
            return new HashMap.SimpleEntry<Team, String>(null, text);
        Team team = scoreboard.registerNewTeam("text-" + scoreboard.getTeams().size());
        Iterator<String> iterator = Splitter.fixedLength(16).split(text).iterator();
        team.setPrefix(iterator.next());
        String result = iterator.next();
        if (text.length() > 32)
            team.setSuffix(iterator.next());
        return new HashMap.SimpleEntry<Team, String>(team, result);
    }

    /////////////////////
    //   SCOREBOARD METHODS
    /////////////////

    /**
     * Clears all the objectives from a Scoreboard, making
     * it empty.
     *
     * @param board  the Scoreboard to clear
     *
     */
    public static void clearScoreboard(Scoreboard board) {
        for (Objective o : board.getObjectives()) {
            o.unregister();
        }
    }

    /**
     * Creates an anonymous new Scoreboard that isn't
     * saved anywhere.
     *
     * @return  the new Scoreboard
     *
     */
    public static Scoreboard createScoreboard() {
        return manager.getNewScoreboard();
    }

    /**
     * Creates a new Scoreboard with a certain id and
     * stories it in the scoreboards map.
     *
     * @param id  the id of the new Scoreboard
     * @return  the new Scoreboard
     *
     */
    public static Scoreboard createScoreboard(String id) {
        Scoreboard board = manager.getNewScoreboard();
        scoreboardMap.put(id.toUpperCase(), board);
        return board;
    }

    /**
     * Deletes a Scoreboard, clearing it and removing it from
     * the scoreboards map, unless it is the server's main
     * scoreboard, in which case it is just cleared.
     *
     * @param id  the id of the Scoreboard
     *
     */
    public static void deleteScoreboard(String id) {
        if (id.equalsIgnoreCase("main"))
            clearScoreboard(getMain());
        else {
            clearScoreboard(getScoreboard(id));
            scoreboardMap.remove(id.toUpperCase());
        }
    }

    /**
     * Returns the server's main scoreboard, that isn't stored
     * in the scoreboards map because Bukkit already saves it
     * by itself.
     *
     * @return  the main Scoreboard
     *
     */
    public static Scoreboard getMain() {
        return manager.getMainScoreboard();
    }

    /**
     * Returns a Scoreboard from the scoreboards map.
     *
     * @param id  the id of the Scoreboard
     * @return  the Scoreboard returned
     *
     */
    public static Scoreboard getScoreboard(String id) {
        return scoreboardMap.get(id.toUpperCase());
    }

    /**
     * Returns true if the scoreboards map contains a certain
     * scoreboard id.
     *
     * @param id  the id of the Scoreboard
     * @return  true or false
     *
     */
    public static boolean hasScoreboard(String id) {
        return scoreboardMap.containsKey(id.toUpperCase());
    }

    /**
     * Removes all the scores of an OfflinePlayer from a
     * Scoreboard.
     *
     * @param id  the id of the Scoreboard
     * @param player  the OfflinePlayer
     *
     */
    public static void removePlayer(String id, OfflinePlayer player) {
        scoreboardMap.get(id.toUpperCase()).resetScores(player.getName());
    }
}
TOP

Related Classes of net.aufdemrand.denizen.utilities.ScoreboardHelper

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.