package net.glowstone.scoreboard;
import net.glowstone.util.nbt.CompoundTag;
import net.glowstone.util.nbt.NBTInputStream;
import net.glowstone.util.nbt.TagType;
import org.bukkit.ChatColor;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Team;
import java.io.*;
import java.util.List;
public class NbtScoreboardIoReader {
public static GlowScoreboard readMainScoreboard(File path) throws IOException {
CompoundTag root;
try (NBTInputStream nbt = new NBTInputStream(getDataInputStream(path), true)) {
root = nbt.readCompound().getCompound("data");
}
GlowScoreboard scoreboard = new GlowScoreboard();
registerObjectives(root, scoreboard);
registerScores(root, scoreboard);
registerTeams(root, scoreboard);
registerDisplaySlots(root, scoreboard);
return scoreboard;
}
private static DataInputStream getDataInputStream(File path) throws FileNotFoundException {
return new DataInputStream(new FileInputStream(path));
}
private static void registerObjectives(CompoundTag root, GlowScoreboard scoreboard) {
if (root.containsKey("Objectives")) {
List<CompoundTag> objectives = root.getCompoundList("Objectives");
for (CompoundTag objective : objectives) {
registerObjective(objective, scoreboard);
}
}
}
private static void registerObjective(CompoundTag data, GlowScoreboard scoreboard) {
String criteria = data.getString("CriteriaName");
String displayName = data.getString("DisplayName");
String name = data.getString("Name");
String renderType = data.getString("RenderType");
GlowObjective objective = (GlowObjective) scoreboard.registerNewObjective(name, criteria);
objective.setDisplayName(displayName);
objective.setRenderType(renderType);
}
private static void registerScores(CompoundTag root, GlowScoreboard scoreboard) {
if (root.containsKey("PlayerScores")) {
List<CompoundTag> scores = root.getCompoundList("PlayerScores");
for (CompoundTag score : scores) {
registerScore(score, scoreboard);
}
}
}
private static void registerScore(CompoundTag data, GlowScoreboard scoreboard) {
int scoreNum = data.getInt("Score");
String name = data.getString("Name");
String objective = data.getString("Objective");
boolean locked = data.getByte("Locked") == 1;
Score score = scoreboard.getObjective(objective).getScore(name);
score.setScore(scoreNum);
score.setLocked(locked);
}
private static void registerTeams(CompoundTag root, GlowScoreboard scoreboard) {
if (root.containsKey("Teams")) {
List<CompoundTag> teams = root.getCompoundList("Teams");
for (CompoundTag team : teams) {
registerTeam(team, scoreboard);
}
}
}
private static void registerTeam(CompoundTag data, GlowScoreboard scoreboard) {
boolean allowFriendlyFire = data.getByte("AllowFriendlyFire") == 1;
boolean seeFriendlyInvisibles = data.getByte("SeeFriendlyInvisibles") == 1;
Team.OptionStatus nameTagVisibility = Team.OptionStatus.valueOf(data.getString("NameTagVisibility").toUpperCase());
Team.OptionStatus deathMessageVisibility = Team.OptionStatus.ALWAYS;
switch (data.getString("DeathMessageVisibility")) {
case "never":
deathMessageVisibility = Team.OptionStatus.NEVER;
break;
case "hideForOtherTeams":
deathMessageVisibility = Team.OptionStatus.FOR_OTHER_TEAMS;
break;
case "hideForOwnTeam":
deathMessageVisibility = Team.OptionStatus.FOR_OWN_TEAM;
break;
}
Team.OptionStatus collisionRule = Team.OptionStatus.ALWAYS;
switch (data.getString("CollisionRule")) {
case "never":
collisionRule = Team.OptionStatus.NEVER;
break;
case "pushOtherTeams":
collisionRule = Team.OptionStatus.FOR_OTHER_TEAMS;
break;
case "pushOwnTeam":
collisionRule = Team.OptionStatus.FOR_OWN_TEAM;
break;
}
String displayName = data.getString("DisplayName");
String name = data.getString("Name");
String prefix = data.getString("Prefix");
String suffix = data.getString("Suffix");
ChatColor teamColor = null;
if (data.containsKey("TeamColor")) {
teamColor = ChatColor.valueOf(data.getString("TeamColor").toUpperCase());
}
List<String> players = data.getList("Players", TagType.STRING);
GlowTeam team = (GlowTeam) scoreboard.registerNewTeam(name);
team.setDisplayName(displayName);
team.setPrefix(prefix);
team.setSuffix(suffix);
team.setAllowFriendlyFire(allowFriendlyFire);
team.setCanSeeFriendlyInvisibles(seeFriendlyInvisibles);
team.setOption(Team.Option.NAME_TAG_VISIBILITY, nameTagVisibility);
team.setOption(Team.Option.DEATH_MESSAGE_VISIBILITY, deathMessageVisibility);
team.setOption(Team.Option.COLLISION_RULE, collisionRule);
if (teamColor != null) {
team.setColor(teamColor);
}
players.forEach(team::addEntry);
}
private static String getOrNull(String key, CompoundTag tag) {
if (tag.isString(key)) {
return tag.getString(key);
}
return null;
}
private static void registerDisplaySlots(CompoundTag root, GlowScoreboard scoreboard) {
if (root.containsKey("DisplaySlots")) {
CompoundTag data = root.getCompound("DisplaySlots");
String list = getOrNull("slot_0", data);
String sidebar = getOrNull("slot_1", data);
String belowName = getOrNull("slot_2", data);
if (list != null) {
scoreboard.getObjective(list).setDisplaySlot(DisplaySlot.PLAYER_LIST);
}
if (sidebar != null) {
scoreboard.getObjective(sidebar).setDisplaySlot(DisplaySlot.SIDEBAR);
}
if (belowName != null) {
scoreboard.getObjective(belowName).setDisplaySlot(DisplaySlot.BELOW_NAME);
}
/* TODO: anything need to be done with team slots?
String teamBlack = getOrNull("slot_3", data);
String teamDarkBlue = getOrNull("slot_4", data);
String teamDarkGreen = getOrNull("slot_5", data);
String teamDarkAqua = getOrNull("slot_6", data);
String teamDarkRed = getOrNull("slot_7", data);
String teamDarkPurple = getOrNull("slot_8", data);
String teamGold = getOrNull("slot_9", data);
String teamGray = getOrNull("slot_10", data);
String teamDarkGray = getOrNull("slot_11", data);
String teamBlue = getOrNull("slot_12", data);
String teamGreen = getOrNull("slot_13", data);
String teamAqua = getOrNull("slot_14", data);
String teamRed = getOrNull("slot_15", data);
String teamLightPurple = getOrNull("slot_16", data);
String teamYellow = getOrNull("slot_17", data);
String teamWhite = getOrNull("slot_18", data);
*/
}
}
}