toReturn = new ArrayList<>();
+ Profile profile = Profile.getByPlayer(player);
+
+ for (String line : configFile.getStringList("LINES")) {
+
+ if (line.contains("%HOME%")) {
+ ProfileTeleportTask teleportTask = profile.getTeleportWarmup();
+
+ if (teleportTask != null && teleportTask.getEvent().getTeleportType() == ProfileTeleportType.HOME_TELEPORT) {
+ toReturn.add(line.replace("%HOME%", SECONDS_FORMATTER.format(((teleportTask.getEvent().getInit() + (teleportTask.getEvent().getTime() * 1000) + 50) - System.currentTimeMillis()) / 1000)));
+ }
+
+ continue;
+ }
+
+ if (line.contains("%STUCK%")) {
+ ProfileTeleportTask teleportTask = profile.getTeleportWarmup();
+
+ if (teleportTask != null && teleportTask.getEvent().getTeleportType() == ProfileTeleportType.STUCK_TELEPORT) {
+ toReturn.add(line.replace("%STUCK%", DurationFormatUtils.formatDuration((long) ((teleportTask.getEvent().getInit() + (teleportTask.getEvent().getTime() * 1000) + 500) - System.currentTimeMillis()), "mm:ss")));
+ }
+
+ continue;
+ }
+
+ if (line.contains("%KOTH%")) {
+ for (Event event : EventManager.getInstance().getEvents()) {
+ if (event instanceof KothEvent && event.isActive()) {
+ toReturn.addAll(event.getScoreboardText());
+ }
+ }
+
+ continue;
+ }
+
+ if (line.contains("%SOTW%")) {
+ for (Mode mode : Mode.getModes()) {
+ if (mode.getModeType() == ModeType.SOTW && mode.isActive()) {
+ toReturn.addAll(mode.getScoreboardText());
+ break;
+ }
+ }
+
+ continue;
+ }
+ /* if (line.contains("%VANISH%")) {
+ if (Basic.getPlugin().getModModeManager().isInStaffMode(player))
+ toReturn.add(line.replace("%VANISH%", ChatColor.YELLOW + "Vanish: " + (Basic.getPlugin().getVanishManager().isVanished(player.getUniqueId()) ? ChatColor.GREEN + "Vanished" : ChatColor.RED + "Visible")));
+ continue;
+ }*/
+
+
+ if (line.contains("%KILLS%")) {
+ toReturn.add(line.replace("%KILLS%", profile.getKillCount() + ""));
+ continue;
+ }
+
+ if (line.contains("%DEATHS%")) {
+ toReturn.add(line.replace("%DEATHS%", profile.getDeathCount() + ""));
+ continue;
+ }
+
+ if (line.contains("%KILL_STREAK%")) {
+ toReturn.add(line.replace("%KILL_STREAK%", profile.getKillStreak() + ""));
+ continue;
+ }
+
+ if (line.contains("%BALANCE%")) {
+ toReturn.add(line.replace("%BALANCE%", profile.getBalance() + ""));
+ continue;
+ }
+
+ if (line.contains("%LOGOUT%")) {
+ ProfileCooldown cooldown = profile.getCooldownByType(ProfileCooldownType.LOGOUT);
+
+ if (cooldown != null) {
+ toReturn.add(line.replace("%LOGOUT%", cooldown.getTimeLeft()));
+ }
+
+ continue;
+ }
+
+ if (line.contains("%ARCHER_TAG%")) {
+ ProfileCooldown cooldown = profile.getCooldownByType(ProfileCooldownType.ARCHER_TAG);
+
+ if (cooldown != null) {
+ toReturn.add(line.replace("%ARCHER_TAG%", cooldown.getTimeLeft()));
+ }
+
+ continue;
+ }
+
+ if (line.contains("%SPAWN_TAG%")) {
+ ProfileCooldown cooldown = profile.getCooldownByType(ProfileCooldownType.SPAWN_TAG);
+
+ if (cooldown != null) {
+ toReturn.add(line.replace("%SPAWN_TAG%", cooldown.getTimeLeft()));
+ }
+
+ continue;
+ }
+
+ if (line.contains("%ENDER_PEARL%")) {
+ ProfileCooldown cooldown = profile.getCooldownByType(ProfileCooldownType.ENDER_PEARL);
+
+ if (cooldown != null) {
+ toReturn.add(line.replace("%ENDER_PEARL%", cooldown.getTimeLeft()));
+ }
+
+ continue;
+ }
+
+ if (line.contains("%GOLDEN_APPLE%")) {
+ ProfileCooldown cooldown = profile.getCooldownByType(ProfileCooldownType.GOLDEN_APPLE);
+
+ if (cooldown != null) {
+ toReturn.add(line.replace("%GOLDEN_APPLE%", cooldown.getTimeLeft()));
+ }
+
+ continue;
+ }
+
+ if (line.contains("%PVP_PROTECTION%")) {
+ if (profile.getProtection() != null) {
+ toReturn.add(line.replace("%PVP_PROTECTION%", profile.getProtection().getTimeLeft()));
+ }
+ continue;
+ }
+
+ if (line.contains("%CLASS%") || line.contains("%CLASS_WARMUP%")) {
+ if (profile.getKitWarmup() != null) {
+
+ if (profile.getKitWarmup().getKit() != null) {
+ toReturn.add(line.replace("%CLASS%", profile.getKitWarmup().getKit().getName()).replace("%CLASS_WARMUP%", profile.getKitWarmup().getTimeLeft()));
+ }
+ }
+ continue;
+ }
+
+ if (line.contains("%BARD%")) {
+ if (profile.getEnergy() != null && profile.getEnergy().getEnergy() > 0.0D) {
+ for (String string : main.getScoreboardConfig().getStringList("PLACE_HOLDER.BARD")) {
+ toReturn.add(string.replace("%ENERGY%", profile.getEnergy().getFormattedString()));
+ }
+ }
+ continue;
+ }
+
+ toReturn.add(line);
+ }
+
+ if (toReturn.size() <= 2)
+
+ {
+ return null;
+ }
+
+ return toReturn;
+ }
+}
diff --git a/src/main/java/com/amberpvp/hcfactions/util/GsonFactory.java b/src/main/java/com/amberpvp/hcfactions/util/GsonFactory.java
new file mode 100644
index 0000000..65cdde5
--- /dev/null
+++ b/src/main/java/com/amberpvp/hcfactions/util/GsonFactory.java
@@ -0,0 +1,481 @@
+package com.amberpvp.hcfactions.util;
+
+import com.google.gson.ExclusionStrategy;
+import com.google.gson.FieldAttributes;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.TypeAdapter;
+import com.google.gson.annotations.Expose;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Type;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.minecraft.server.v1_8_R3.MojangsonParseException;
+import net.minecraft.server.v1_8_R3.MojangsonParser;
+import net.minecraft.server.v1_8_R3.NBTTagCompound;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.configuration.serialization.ConfigurationSerializable;
+import org.bukkit.configuration.serialization.ConfigurationSerialization;
+import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
+import org.bukkit.craftbukkit.v1_8_R3.util.CraftMagicNumbers;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+/* *
+* Created by Joshua Bell (RingOfStorms)
+*
+* Post explaining here: [URL]http://bukkit.org/threads/gsonfactory-gson-that-works-on-itemstack-potioneffect-location-objects.331161/[/URL]
+* */
+public class GsonFactory {
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.FIELD})
+ public static @interface Ignore {}
+
+ /*
+ - I want to not use Bukkit parsing for most objects... it's kind of clunky
+ - Instead... I want to start using any of Mojang's tags
+ - They're really well documented + built into MC, and handled by them.
+ - Rather than kill your old code, I'm going to write TypeAdapaters using Mojang's stuff.
+ */
+
+ private static Gson g = new Gson();
+
+ private final static String CLASS_KEY = "SERIAL-ADAPTER-CLASS-KEY";
+
+ private static Gson prettyGson;
+ private static Gson compactGson;
+
+ /**
+ * Returns a Gson instance for use anywhere with new line pretty printing
+ *
+ * Use @GsonIgnore in order to skip serialization and deserialization
+ *
+ * @return a Gson instance
+ */
+ public static Gson getPrettyGson () {
+ if (prettyGson == null)
+ prettyGson = new GsonBuilder().addSerializationExclusionStrategy(new ExposeExlusion())
+ .addDeserializationExclusionStrategy(new ExposeExlusion())
+ .registerTypeHierarchyAdapter(ItemStack.class, new ItemStackGsonAdapter())
+ .registerTypeAdapter(PotionEffect.class, new PotionEffectGsonAdapter())
+ .registerTypeAdapter(Location.class, new LocationGsonAdapter())
+ .registerTypeAdapter(Date.class, new DateGsonAdapter())
+ .setPrettyPrinting()
+ .disableHtmlEscaping()
+ .create();
+ return prettyGson;
+ }
+
+ /**
+ * Returns a Gson instance for use anywhere with one line strings
+ *
+ * Use @GsonIgnore in order to skip serialization and deserialization
+ *
+ * @return a Gson instance
+ */
+ public static Gson getCompactGson () {
+ if(compactGson == null)
+ compactGson = new GsonBuilder().addSerializationExclusionStrategy(new ExposeExlusion())
+ .addDeserializationExclusionStrategy(new ExposeExlusion())
+ .registerTypeHierarchyAdapter(ItemStack.class, new ItemStackGsonAdapter())
+ .registerTypeAdapter(PotionEffect.class, new PotionEffectGsonAdapter())
+ .registerTypeAdapter(Location.class, new LocationGsonAdapter())
+ .registerTypeAdapter(Date.class, new DateGsonAdapter())
+ .disableHtmlEscaping()
+ .create();
+ return compactGson;
+ }
+
+ /**
+ * Creates a new instance of Gson for use anywhere
+ *
+ * Use @GsonIgnore in order to skip serialization and deserialization
+ *
+ * @return a Gson instance
+ */
+ public static Gson getNewGson(boolean prettyPrinting) {
+ GsonBuilder builder = new GsonBuilder().addSerializationExclusionStrategy(new ExposeExlusion())
+ .addDeserializationExclusionStrategy(new ExposeExlusion())
+ .registerTypeHierarchyAdapter(ItemStack.class, new NewItemStackAdapter())
+ .disableHtmlEscaping();
+ if (prettyPrinting)
+ builder.setPrettyPrinting();
+ return builder.create();
+ }
+
+ private static Map recursiveSerialization (ConfigurationSerializable o) {
+ Map originalMap = o.serialize();
+ Map map = new HashMap();
+ for(Entry entry : originalMap.entrySet()) {
+ Object o2 = entry.getValue();
+ if(o2 instanceof ConfigurationSerializable) {
+ ConfigurationSerializable serializable = (ConfigurationSerializable) o2;
+ Map newMap = recursiveSerialization(serializable);
+ newMap.put(CLASS_KEY, ConfigurationSerialization.getAlias(serializable.getClass()));
+ map.put(entry.getKey(), newMap);
+ }
+ }
+ map.put(CLASS_KEY, ConfigurationSerialization.getAlias(o.getClass()));
+ return map;
+ }
+
+ private static Map recursiveDoubleToInteger (Map originalMap) {
+ Map map = new HashMap();
+ for(Entry entry : originalMap.entrySet()) {
+ Object o = entry.getValue();
+ if(o instanceof Double) {
+ Double d = (Double) o;
+ Integer i = d.intValue();
+ map.put(entry.getKey(), i);
+ } else if (o instanceof Map) {
+ Map subMap = (Map) o;
+ map.put(entry.getKey(), recursiveDoubleToInteger(subMap));
+ } else {
+ map.put(entry.getKey(), o);
+ }
+ }
+ return map;
+ }
+
+ private static class ExposeExlusion implements ExclusionStrategy {
+ @Override
+ public boolean shouldSkipField(FieldAttributes fieldAttributes) {
+ final Ignore ignore = fieldAttributes.getAnnotation(Ignore.class);
+ if(ignore != null)
+ return true;
+ final Expose expose = fieldAttributes.getAnnotation(Expose.class);
+ return expose != null && (!expose.serialize() || !expose.deserialize());
+ }
+
+ @Override
+ public boolean shouldSkipClass(Class> aClass) {
+ return false;
+ }
+ }
+
+ private static String nbtToString(NBTTagCompound base) {
+ return base.toString().replace(",}", "}").replace(",]", "]").replaceAll("[0-9]+\\:", "");
+ }
+
+ private static net.minecraft.server.v1_8_R3.ItemStack removeSlot(ItemStack item) {
+ if (item == null)
+ return null;
+ net.minecraft.server.v1_8_R3.ItemStack nmsi = CraftItemStack.asNMSCopy(item);
+ if (nmsi == null)
+ return null;
+ NBTTagCompound nbtt = nmsi.getTag();
+ if (nbtt != null) {
+ nbtt.remove("Slot");
+ nmsi.setTag(nbtt);
+ }
+ return nmsi;
+ }
+
+ private static ItemStack removeSlotNBT (ItemStack item) {
+ if (item == null)
+ return null;
+ net.minecraft.server.v1_8_R3.ItemStack nmsi = CraftItemStack.asNMSCopy(item);
+ if (nmsi == null)
+ return null;
+ NBTTagCompound nbtt = nmsi.getTag();
+ if(nbtt != null) {
+ nbtt.remove("Slot");
+ nmsi.setTag(nbtt);
+ }
+ return CraftItemStack.asBukkitCopy(nmsi);
+ }
+
+ private static class NewItemStackAdapter extends TypeAdapter