diff --git a/pom.xml b/pom.xml index e0eb27e..0fe3d4e 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ com.songoda EpicHeads 4.0.0 - 3.2.7 + 3.2.8 clean install EpicHeads-${project.version} diff --git a/src/main/java/com/songoda/epicheads/EpicHeads.java b/src/main/java/com/songoda/epicheads/EpicHeads.java index 6c5daf2..943bc7b 100644 --- a/src/main/java/com/songoda/epicheads/EpicHeads.java +++ b/src/main/java/com/songoda/epicheads/EpicHeads.java @@ -72,13 +72,17 @@ public class EpicHeads extends SongodaPlugin { // Load Economy EconomyManager.load(); + // Setup Managers + this.headManager = new HeadManager(); + this.playerManager = new PlayerManager(); + // Setup Config Settings.setupConfig(); this.setLocale(Settings.LANGUGE_MODE.getString(), false); // Set economy preference String ecoPreference = Settings.ECONOMY_PLUGIN.getString(); - if(ecoPreference.equalsIgnoreCase("item")) { + if (ecoPreference.equalsIgnoreCase("item")) { EconomyManager.getManager().setPreferredHook(itemEconomyHook); } else { EconomyManager.getManager().setPreferredHook(ecoPreference); @@ -101,10 +105,6 @@ public class EpicHeads extends SongodaPlugin { this.storage = new StorageYaml(this); - // Setup Managers - this.headManager = new HeadManager(); - this.playerManager = new PlayerManager(); - // Register Listeners guiManager.init(); PluginManager pluginManager = Bukkit.getPluginManager(); @@ -168,7 +168,8 @@ public class EpicHeads extends SongodaPlugin { private boolean loadHeads() { try { this.headManager.clear(); - this.headManager.addCategory(new Category("Latest Pack", true)); + this.headManager.addCategory(new Category(getLocale() + .getMessage("general.word.latestpack").getMessage(), true)); JSONParser parser = new JSONParser(); JSONArray jsonArray = (JSONArray) parser.parse(new FileReader(getDataFolder() + "/heads.json")); @@ -183,12 +184,11 @@ public class EpicHeads extends SongodaPlugin { int id = Integer.parseInt((String) jsonObject.get("id")); - if (Settings.DISABLED_HEADS.getIntegerList().contains(id)) continue; - Head head = new Head(id, (String) jsonObject.get("name"), (String) jsonObject.get("url"), category, + false, (String) jsonObject.get("pack"), Byte.parseByte((String) jsonObject.get("staff_picked"))); @@ -213,6 +213,7 @@ public class EpicHeads extends SongodaPlugin { row.get("name").asString(), row.get("url").asString(), category, + true, null, (byte) 0); @@ -222,6 +223,20 @@ public class EpicHeads extends SongodaPlugin { } } + if (storage.containsGroup("disabled")) { + for (StorageRow row : storage.getRowsByGroup("disabled")) { + headManager.disableHead(new Head(row.get("id").asInt(), false)); + } + } + + // convert disabled heads + if (config.contains("Main.Disabled Global Heads")) { + for (int id : config.getIntegerList("Main.Disabled Global Heads")) { + EpicHeads.getInstance().getHeadManager().disableHead(new Head(id, false)); + } + config.set("Main.Disabled Global Heads", null); + } + System.out.println("loaded " + headManager.getHeads().size() + " Heads."); } catch (IOException e) { diff --git a/src/main/java/com/songoda/epicheads/commands/CommandAdd.java b/src/main/java/com/songoda/epicheads/commands/CommandAdd.java index 48b68bf..9e28d8f 100644 --- a/src/main/java/com/songoda/epicheads/commands/CommandAdd.java +++ b/src/main/java/com/songoda/epicheads/commands/CommandAdd.java @@ -38,7 +38,7 @@ public class CommandAdd extends AbstractCommand { Category category = categories.isEmpty() ? new Category(categoryStr) : categories.get(0); - headManager.addLocalHead(new Head(headManager.getNextLocalId(), name, url, category, null, (byte) 0)); + headManager.addLocalHead(new Head(headManager.getNextLocalId(), name, url, category, true, null, (byte) 0)); instance.getLocale().getMessage("command.add.success") .processPlaceholder("name", name).sendPrefixedMessage(sender); diff --git a/src/main/java/com/songoda/epicheads/gui/GUIHeads.java b/src/main/java/com/songoda/epicheads/gui/GUIHeads.java index 70cf6a0..260befa 100644 --- a/src/main/java/com/songoda/epicheads/gui/GUIHeads.java +++ b/src/main/java/com/songoda/epicheads/gui/GUIHeads.java @@ -88,7 +88,7 @@ public class GUIHeads extends Gui { if (page - 3 >= 1) { setButton(0, GuiUtils.createButtonItem(CompatibleMaterial.ARROW, page - 3, - ChatColor.RED.toString() + plugin.getLocale().getMessage("general.word.page") + " " + (page - 3)), + ChatColor.RED.toString() + plugin.getLocale().getMessage("general.word.page") + " " + (page - 3)), (event) -> changePage(-3)); } else { clearActions(0); @@ -106,7 +106,7 @@ public class GUIHeads extends Gui { if (page > 1) { setButton(2, GuiUtils.createButtonItem(CompatibleMaterial.ARROW, page - 1, - ChatColor.RED.toString() + plugin.getLocale().getMessage("general.word.page") + " " + (page - 1)), + ChatColor.RED.toString() + plugin.getLocale().getMessage("general.word.page") + " " + (page - 1)), (event) -> changePage(-1)); } else { clearActions(2); @@ -180,9 +180,19 @@ public class GUIHeads extends Gui { if (head.getName() == null) continue; ItemStack item = head.asItemStack(favorites.contains(head.getURL()), free); + ItemMeta meta = item.getItemMeta(); + List lore = item.getItemMeta().getLore(); + lore.add(plugin.getLocale().getMessage("gui.heads.delete").getMessage()); + meta.setLore(lore); + item.setItemMeta(meta); setButton(i + 9, item, (event) -> { - if (event.clickType == ClickType.SHIFT_LEFT || event.clickType == ClickType.SHIFT_RIGHT) { + if (event.clickType == ClickType.MIDDLE && player.hasPermission("epicheads.delete")) { + plugin.getHeadManager().disableHead(head); + heads.remove(head); + showPage(); + return; + } else if (event.clickType == ClickType.SHIFT_LEFT || event.clickType == ClickType.SHIFT_RIGHT) { EPlayer ePlayer = plugin.getPlayerManager().getPlayer(player); boolean isFav = ePlayer.getFavorites().contains(head.getURL()); if (isFav) @@ -207,7 +217,6 @@ public class GUIHeads extends Gui { } ItemStack headItem = item.clone(); - ItemMeta meta = headItem.getItemMeta(); meta.setLore(new ArrayList<>()); headItem.setItemMeta(meta); diff --git a/src/main/java/com/songoda/epicheads/gui/GUIOverview.java b/src/main/java/com/songoda/epicheads/gui/GUIOverview.java index a6fa0b4..301695c 100644 --- a/src/main/java/com/songoda/epicheads/gui/GUIOverview.java +++ b/src/main/java/com/songoda/epicheads/gui/GUIOverview.java @@ -8,7 +8,6 @@ import com.songoda.epicheads.EpicHeads; import com.songoda.epicheads.head.Category; import com.songoda.epicheads.head.Head; import com.songoda.epicheads.settings.Settings; -import com.songoda.epicheads.utils.Methods; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -31,19 +30,19 @@ public class GUIOverview extends Gui { .processPlaceholder("count", plugin.getHeadManager().getHeads().size()) .getMessage()); this.setPrevPage(rows - 1, 1, GuiUtils.createButtonItem(CompatibleMaterial.ARROW, - plugin.getLocale().getMessage("gui.general.previous").getMessage())); + plugin.getLocale().getMessage("gui.general.previous").getMessage())); this.setNextPage(rows - 1, 7, GuiUtils.createButtonItem(CompatibleMaterial.ARROW, - plugin.getLocale().getMessage("gui.general.next").getMessage())); + plugin.getLocale().getMessage("gui.general.next").getMessage())); this.setOnPage((event) -> showPage()); showPage(); } void showPage() { setButton(4, GuiUtils.createButtonItem(CompatibleMaterial.GOLDEN_APPLE, - plugin.getLocale().getMessage("gui.overview.viewfavorites").getMessage(), + plugin.getLocale().getMessage("gui.overview.viewfavorites").getMessage(), plugin.getLocale().getMessage("gui.overview.favoriteslore").getMessage().split("\\|")), (event) -> guiManager.showGUI(player, new GUIHeads(plugin, player, null, GUIHeads.QueryTypes.FAVORITES, - plugin.getPlayerManager().getPlayer(player).getFavoritesAsHeads()))); + plugin.getPlayerManager().getPlayer(player).getFavoritesAsHeads()))); ItemStack glass2 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_2.getMaterial()); ItemStack glass3 = GuiUtils.getBorderItem(Settings.GLASS_TYPE_3.getMaterial()); @@ -67,6 +66,8 @@ public class GUIOverview extends Gui { List heads = category.isLatestPack() ? plugin.getHeadManager().getLatestPack() : plugin.getHeadManager().getHeadsByCategory(category); + if (heads.isEmpty()) continue; + Head firstHead = heads.get(0); if (!player.hasPermission("epicheads.category." + category.getName().replace(" ", "_"))) continue; diff --git a/src/main/java/com/songoda/epicheads/head/Head.java b/src/main/java/com/songoda/epicheads/head/Head.java index a29dd33..34c1a0f 100644 --- a/src/main/java/com/songoda/epicheads/head/Head.java +++ b/src/main/java/com/songoda/epicheads/head/Head.java @@ -10,24 +10,32 @@ import org.bukkit.inventory.meta.ItemMeta; import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class Head { private final int id; - private final String name; - private final String URL; - private final String pack; - private final byte staffPicked; + private String name = null; + private String URL = null; + private String pack = null; + private byte staffPicked = 0; + private final boolean local; - private final Category category; + private Category category; - public Head(int id, String name, String URL, Category category, String pack, byte staffPicked) { + public Head(int id, String name, String URL, Category category, boolean local, String pack, byte staffPicked) { this.id = id; this.name = name; this.URL = URL; this.category = category; this.pack = pack; this.staffPicked = staffPicked; + this.local = local; + } + + public Head(int id, boolean local) { + this.id = id; + this.local = local; } public int getId() { @@ -43,6 +51,8 @@ public class Head { } public String getURL() { + if (URL == null) + return "d23eaefbd581159384274cdbbd576ced82eb72423f2ea887124f9ed33a6872c"; return URL; } @@ -54,6 +64,10 @@ public class Head { return staffPicked; } + public boolean isLocal() { + return local; + } + public ItemStack asItemStack() { return asItemStack(false, false); } @@ -92,15 +106,30 @@ public class Head { return lore; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Head head = (Head) o; + return id == head.id && + local == head.local; + } + + @Override + public int hashCode() { + return Objects.hash(id, local); + } + @Override public String toString() { - return "Head:{" - + "Id:\"" + id + "\"," - + "Name:\"" + name + "\"," - + "URL:\"" + URL + "\"," - + "Category:\"" + category.getName() + "\"," - + "Pack:\"" + pack + "\"," - + "StaffPicked:\"" + staffPicked + "\"" - + "}"; + return "Head{" + + "id=" + id + + ", name='" + name + '\'' + + ", URL='" + URL + '\'' + + ", pack='" + pack + '\'' + + ", staffPicked=" + staffPicked + + ", local=" + local + + ", category=" + category + + '}'; } } diff --git a/src/main/java/com/songoda/epicheads/head/HeadManager.java b/src/main/java/com/songoda/epicheads/head/HeadManager.java index 41328f7..f2a3e4f 100644 --- a/src/main/java/com/songoda/epicheads/head/HeadManager.java +++ b/src/main/java/com/songoda/epicheads/head/HeadManager.java @@ -6,9 +6,10 @@ import java.util.stream.Stream; public class HeadManager { - private static final Set registeredHeads = new HashSet<>(); - private static final List localRegisteredHeads = new ArrayList<>(); - private static final List registeredCategories = new ArrayList<>(); + private final Set registeredHeads = new HashSet<>(); + private final List localRegisteredHeads = new ArrayList<>(); + private final List registeredCategories = new ArrayList<>(); + private final Set disabledHeads = new HashSet<>(); public Head addHead(Head head) { registeredHeads.add(head); @@ -76,6 +77,18 @@ public class HeadManager { return new ArrayList<>(registeredHeads); } + public Head disableHead(Head head) { + if (head.isLocal() && localRegisteredHeads.remove(head)) + return head; + this.disabledHeads.add(head); + this.registeredHeads.remove(head); + return head; + } + + public Set getDisabledHeads() { + return Collections.unmodifiableSet(disabledHeads); + } + public List getLatestPack() { List heads = getHeads().stream().sorted(Comparator.comparingInt(Head::getId)).filter(head -> head.getPack() != null).collect(Collectors.toList()); @@ -106,6 +119,7 @@ public class HeadManager { public void clear() { registeredHeads.clear(); localRegisteredHeads.clear(); + disabledHeads.clear(); registeredCategories.clear(); } } diff --git a/src/main/java/com/songoda/epicheads/listeners/DeathListeners.java b/src/main/java/com/songoda/epicheads/listeners/DeathListeners.java index e51987a..4899180 100644 --- a/src/main/java/com/songoda/epicheads/listeners/DeathListeners.java +++ b/src/main/java/com/songoda/epicheads/listeners/DeathListeners.java @@ -60,7 +60,7 @@ public class DeathListeners implements Listener { Head head = new Head(-1, Methods.formatText(event.getEntity().getType().name().toLowerCase() .replace("_", " "), true), HeadType.valueOf(event.getEntity().getType().name()).getUrl(), - null, null, (byte) 0); + null, true, null, (byte) 0); itemNew = head.asItemStack(); } diff --git a/src/main/java/com/songoda/epicheads/listeners/LoginListeners.java b/src/main/java/com/songoda/epicheads/listeners/LoginListeners.java index cae7a1f..c7aced0 100644 --- a/src/main/java/com/songoda/epicheads/listeners/LoginListeners.java +++ b/src/main/java/com/songoda/epicheads/listeners/LoginListeners.java @@ -2,10 +2,9 @@ package com.songoda.epicheads.listeners; import com.songoda.core.utils.ItemUtils; import com.songoda.epicheads.EpicHeads; +import com.songoda.epicheads.head.Category; import com.songoda.epicheads.head.Head; import com.songoda.epicheads.head.HeadManager; -import com.songoda.epicheads.head.Category; -import com.songoda.epicheads.utils.Methods; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -27,13 +26,13 @@ public class LoginListeners implements Listener { Player player = event.getPlayer(); - String encodededStr = ItemUtils.getSkullTexture(player); + String encodedStr = ItemUtils.getSkullTexture(player); - if (encodededStr == null) return; + if (encodedStr == null) return; - String url = ItemUtils.getDecodedTexture(encodededStr); + String url = ItemUtils.getDecodedTexture(encodedStr); - String tagStr = "Player Heads"; + String tagStr = plugin.getLocale().getMessage("general.word.playerheads").getMessage(); Optional tagOptional = headManager.getCategories() .stream().filter(t -> t.getName().equalsIgnoreCase(tagStr)).findFirst(); @@ -54,7 +53,7 @@ public class LoginListeners implements Listener { headManager.removeLocalHead(head); } - headManager.addLocalHeads(new Head(id, player.getName(), url, tag, null, (byte) 0)); + headManager.addLocalHeads(new Head(id, player.getName(), url, tag, true,null, (byte) 0)); } diff --git a/src/main/java/com/songoda/epicheads/settings/Settings.java b/src/main/java/com/songoda/epicheads/settings/Settings.java index 772acd4..fbd0729 100644 --- a/src/main/java/com/songoda/epicheads/settings/Settings.java +++ b/src/main/java/com/songoda/epicheads/settings/Settings.java @@ -1,11 +1,11 @@ package com.songoda.epicheads.settings; import com.songoda.core.compatibility.CompatibleMaterial; -import com.songoda.core.compatibility.ServerVersion; import com.songoda.core.configuration.Config; import com.songoda.core.configuration.ConfigSetting; import com.songoda.core.hooks.EconomyManager; import com.songoda.epicheads.EpicHeads; +import com.songoda.epicheads.head.Head; import java.util.Arrays; import java.util.stream.Collectors; @@ -43,10 +43,6 @@ public class Settings { "When a player or monster is killed what should be", "the chance that their head drops?"); - public static final ConfigSetting DISABLED_HEADS = new ConfigSetting(config, "Main.Disabled Global Heads", Arrays.asList(34567, 34568, 34569), - "These are head ID's from the global database that are disabled.", - "By default this is filled with non existent ID's."); - public static final ConfigSetting ECONOMY_PLUGIN = new ConfigSetting(config, "Economy.Economy", "Vault", "Which economy plugin should be used?"); @@ -97,7 +93,7 @@ public class Settings { config.set(GLASS_TYPE_3.getKey(), CompatibleMaterial.getGlassPaneColor(color).name()); } - config.setDefault("Economy.Economy", + config.setDefault("Economy.Economy", EconomyManager.getEconomy() == null ? "Vault" : EconomyManager.getEconomy().getName()); config.setComment("Economy.Economy", null, "Which economy plugin should be used?", diff --git a/src/main/java/com/songoda/epicheads/utils/Methods.java b/src/main/java/com/songoda/epicheads/utils/Methods.java index 85938ce..1a8afc7 100644 --- a/src/main/java/com/songoda/epicheads/utils/Methods.java +++ b/src/main/java/com/songoda/epicheads/utils/Methods.java @@ -48,15 +48,4 @@ public class Methods { text = text.substring(0, 1).toUpperCase() + text.substring(1); return ChatColor.translateAlternateColorCodes('&', text); } - - public static String formatTitle(String text) { - if (text == null || text.equals("")) - return ""; - if (!ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) { - if (text.length() > 31) - text = text.substring(0, 29) + "..."; - } - text = formatText(text); - return text; - } } diff --git a/src/main/java/com/songoda/epicheads/utils/storage/Storage.java b/src/main/java/com/songoda/epicheads/utils/storage/Storage.java index c6a35f9..59a00b3 100644 --- a/src/main/java/com/songoda/epicheads/utils/storage/Storage.java +++ b/src/main/java/com/songoda/epicheads/utils/storage/Storage.java @@ -38,6 +38,10 @@ public abstract class Storage { new StorageItem("id", head.getId()), new StorageItem("category", head.getCategory().getName())); } + + for (Head head : instance.getHeadManager().getDisabledHeads()) { + prepareSaveItem("disabled", new StorageItem("id", String.valueOf(head.getId()))); + } } public abstract void doSave(); diff --git a/src/main/java/com/songoda/epicheads/utils/storage/StorageItem.java b/src/main/java/com/songoda/epicheads/utils/storage/StorageItem.java index 9ff4d5c..95e0b78 100644 --- a/src/main/java/com/songoda/epicheads/utils/storage/StorageItem.java +++ b/src/main/java/com/songoda/epicheads/utils/storage/StorageItem.java @@ -23,6 +23,8 @@ public class StorageItem { public String asString() { if (object == null) return null; + if (!(object instanceof String)) + return String.valueOf(object); return (String) object; } @@ -33,6 +35,8 @@ public class StorageItem { public int asInt() { if (object == null) return 0; + if (object instanceof String) + return Integer.parseInt(asString()); return (int) object; } diff --git a/src/main/resources/en_US.lang b/src/main/resources/en_US.lang index 66349c5..8eaedbd 100644 --- a/src/main/resources/en_US.lang +++ b/src/main/resources/en_US.lang @@ -1,48 +1,59 @@ -#General Messages +# General Messages -general.nametag.prefix = "&7[&6EpicHeads&7]" -general.word.page = "Page" -general.word.query = "Query" -general.word.favorites = "Favorites" -general.word.everyone = "everyone" -general.phrase.latestpack = "Latest Pack" - -general.search.global = "&6Enter your search query." -general.search.refine = "&6Enter a search term to refine your search." -general.search.nonefound = "&cNo heads found.." -general.search.canceled = "&cSearch canceled." - -general.head.staffpicked = "&8Staff Favorite" -general.head.id = "&8ID: &7%id%" -general.head.cost = "&8Cost: &7$%cost%" - -gui.heads.refine = "&9Refine Search" -gui.heads.search = "&9Create Search" -gui.heads.categories = "&cBack To Categories" - -gui.general.previous = "&6Previous Page" -gui.general.next = "&6Next Page" - -gui.overview.title = "EpicHeads (%count% heads)" -gui.overview.search = "&a&lSearch" -gui.overview.headname = "&c&l%name%" -gui.overview.headlore = "&e%count% heads" -gui.overview.packlore = "&e%pack%" -gui.overview.viewfavorites = "&6&lView Favorites" -gui.overview.favoriteslore = "&8Shift click any head|&8to save as a favorite." -gui.overview.discord = "&9&lDiscord" -gui.overview.discordlore = "&8Add or request new heads|&8in our discord server." - -event.general.nopermission = "&cYou do not have permission to use that command." -event.buyhead.cannotafford = "&cYou cannot afford this head." - -command.give.notonline = "&cThe player &4%name% &ccould not be found." -command.give.notfound = "&cThe head &4%name%&c could not be found." -command.give.success = "&7You have given &6%player% &7a head named &6%name%&7." -command.give.receive = "&7You have been given a head named &6%name%&7." - -command.add.success = "&7Added the head &6%name% &7successfully." -command.add.exists = "&cThat head already exists." - -command.givetoken.success = "&7You gave &6%player% %amount% &7player head tokens." -command.givetoken.receive = "&7You have been given &6%amount% &7player head tokens." \ No newline at end of file +general: + nametag: + prefix: '&7[&6EpicHeads&7]' + word: + page: Page + query: Query + favorites: Favorites + everyone: everyone + playerheads: Player Heads + latestpack: Latest Pack + phrase: + latestpack: Latest Pack + search: + global: '&6Enter your search query.' + refine: '&6Enter a search term to refine your search.' + nonefound: '&cNo heads found..' + canceled: '&cSearch canceled.' + head: + staffpicked: '&8Staff Favorite' + id: '&8ID: &7%id%' + cost: '&8Cost: &7$%cost%' +gui: + heads: + refine: '&9Refine Search' + search: '&9Create Search' + categories: '&cBack To Categories' + delete: '&cMiddle-Click to delete' + general: + previous: '&6Previous Page' + next: '&6Next Page' + overview: + title: EpicHeads (%count% heads) + search: '&a&lSearch' + headname: '&c&l%name%' + headlore: '&e%count% heads' + packlore: '&e%pack%' + viewfavorites: '&6&lView Favorites' + favoriteslore: '&8Shift click any head|&8to save as a favorite.' + discord: '&9&lDiscord' + discordlore: '&8Add or request new heads|&8in our discord server.' +event: + general: + nopermission: '&cYou do not have permission to use that command.' + buyhead: + cannotafford: '&cYou cannot afford this head.' +command: + give: + notonline: '&cThe player &4%name% &ccould not be found.' + notfound: '&cThe head &4%name%&c could not be found.' + success: '&7You have given &6%player% &7a head named &6%name%&7.' + receive: '&7You have been given a head named &6%name%&7.' + add: + success: '&7Added the head &6%name% &7successfully.' + exists: '&cThat head already exists.' + givetoken: + success: '&7You gave &6%player% %amount% &7player head tokens.' + receive: '&7You have been given &6%amount% &7player head tokens.'