/******************************************************************************* * This file is part of ASkyBlock. * * ASkyBlock is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ASkyBlock is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ package com.wasteofplastic.askyblock.panels; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.inventory.Inventory; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.wasteofplastic.askyblock.ASkyBlock; import com.wasteofplastic.askyblock.Island; import com.wasteofplastic.askyblock.Island.SettingsFlag; import com.wasteofplastic.askyblock.Settings; import com.wasteofplastic.askyblock.util.Util; public class SettingsPanel implements Listener { // Island Guard Settings Panel private ASkyBlock plugin; private static boolean hasChorusFruit; private static boolean hasArmorStand; private HashMap<UUID,Long> pvpCoolDown = new HashMap<UUID,Long>(); private static final boolean DEBUG = false; /** * Lookup table of Material to SettingsFlag */ private static BiMap<Material,SettingsFlag> lookup = HashBiMap.create(); static { // Find out if these exist hasChorusFruit = (Material.getMaterial("CHORUS_FRUIT") != null); hasArmorStand = (Material.getMaterial("ARMOR_STAND") != null); // No icon or flag can be the same, they must all be unique because this is a bimap. // Developer - if you add a setting but don't see it appear in the GUI, make sure there's a locale settings for it! if (hasArmorStand) lookup.put(Material.ARMOR_STAND, SettingsFlag.ARMOR_STAND); if (hasChorusFruit) lookup.put(Material.CHORUS_FRUIT, SettingsFlag.CHORUS_FRUIT); lookup.put(Material.ANVIL, SettingsFlag.ANVIL); lookup.put(Material.ARROW, SettingsFlag.PVP); lookup.put(Material.BEACON, SettingsFlag.BEACON); lookup.put(Material.BED, SettingsFlag.BED); lookup.put(Material.BREWING_STAND_ITEM, SettingsFlag.BREWING); lookup.put(Material.BUCKET, SettingsFlag.BUCKET); lookup.put(Material.CARROT_ITEM, SettingsFlag.BREEDING); lookup.put(Material.CHEST, SettingsFlag.CHEST); lookup.put(Material.DIAMOND_BARDING, SettingsFlag.HORSE_RIDING); lookup.put(Material.DIAMOND, SettingsFlag.VISITOR_ITEM_PICKUP); lookup.put(Material.DIRT, SettingsFlag.PLACE_BLOCKS); lookup.put(Material.EGG, SettingsFlag.EGGS); lookup.put(Material.EMERALD, SettingsFlag.VILLAGER_TRADING); lookup.put(Material.ENCHANTMENT_TABLE, SettingsFlag.ENCHANTING); lookup.put(Material.ENDER_PEARL, SettingsFlag.ENDER_PEARL); lookup.put(Material.FENCE_GATE, SettingsFlag.GATE); lookup.put(Material.FLINT_AND_STEEL, SettingsFlag.FIRE); lookup.put(Material.FURNACE, SettingsFlag.FURNACE); lookup.put(Material.GOLD_BARDING, SettingsFlag.HORSE_INVENTORY); lookup.put(Material.GOLD_INGOT, SettingsFlag.VISITOR_ITEM_DROP); lookup.put(Material.GOLD_PLATE, SettingsFlag.PRESSURE_PLATE); lookup.put(Material.ICE, SettingsFlag.FIRE_EXTINGUISH); lookup.put(Material.IRON_SWORD, SettingsFlag.HURT_MONSTERS); lookup.put(Material.JUKEBOX, SettingsFlag.MUSIC); lookup.put(Material.LAVA_BUCKET, SettingsFlag.COLLECT_LAVA); lookup.put(Material.LEASH, SettingsFlag.LEASH); lookup.put(Material.LEVER, SettingsFlag.LEVER_BUTTON); lookup.put(Material.MILK_BUCKET, SettingsFlag.MILKING); lookup.put(Material.MOB_SPAWNER, SettingsFlag.MONSTER_SPAWN); lookup.put(Material.MONSTER_EGG, SettingsFlag.SPAWN_EGGS); lookup.put(Material.NETHERRACK, SettingsFlag.NETHER_PVP); lookup.put(Material.OBSIDIAN, SettingsFlag.PORTAL); lookup.put(Material.POTATO_ITEM, SettingsFlag.MOB_SPAWN); lookup.put(Material.POTION, SettingsFlag.ACID_DAMAGE); lookup.put(Material.REDSTONE_COMPARATOR, SettingsFlag.REDSTONE); lookup.put(Material.SHEARS, SettingsFlag.SHEARING); lookup.put(Material.SIGN, SettingsFlag.ENTER_EXIT_MESSAGES); lookup.put(Material.STONE, SettingsFlag.BREAK_BLOCKS); lookup.put(Material.TNT, SettingsFlag.CREEPER_PAIN); lookup.put(Material.TORCH, SettingsFlag.FIRE_SPREAD); lookup.put(Material.WATER_BUCKET, SettingsFlag.COLLECT_WATER); lookup.put(Material.WHEAT, SettingsFlag.CROP_TRAMPLE); lookup.put(Material.WOOD_DOOR, SettingsFlag.DOOR); lookup.put(Material.WOOD_SWORD, SettingsFlag.HURT_MOBS); lookup.put(Material.WORKBENCH, SettingsFlag.CRAFTING); } public SettingsPanel(ASkyBlock plugin) { this.plugin = plugin; //plugin.getLogger().info("DEBUG: Settings Panel loaded"); } /** * Presents a GUI for toggling or viewing settings * @param player * @return */ public Inventory islandGuardPanel(Player player) { UUID uuid = player.getUniqueId(); // Get the island settings for this player's location Island island = plugin.getGrid().getProtectedIslandAt(player.getLocation()); List<IPItem> ip = new ArrayList<IPItem>(); Inventory newPanel = null; if (island == null) { ip.add(new IPItem(Material.MAP, plugin.myLocale(uuid).igsSettingsGeneralTitle, plugin.myLocale(uuid).igsSettingsGeneralDesc)); // General settings all enum for (SettingsFlag flag : SettingsFlag.values()) { if (flag.equals(SettingsFlag.ACID_DAMAGE) && Settings.acidDamage == 0) continue; if (Settings.defaultWorldSettings.containsKey(flag) && lookup.inverse().containsKey(flag) && plugin.myLocale(uuid).igs.containsKey(flag)) { ip.add(new IPItem(Settings.defaultWorldSettings.get(flag), lookup.inverse().get(flag), plugin.myLocale(uuid).igs.get(flag),uuid)); } } // System settings that are visible to users ip.add(new IPItem(Settings.allowChestDamage, Material.CHEST, plugin.myLocale(uuid).igsChestDamage, uuid)); ip.add(new IPItem(Settings.allowCreeperDamage, Material.SKULL_ITEM, 4, plugin.myLocale(uuid).igsCreeperDamage, uuid)); ip.add(new IPItem(Settings.allowCreeperGriefing, Material.SKULL_ITEM, 4, plugin.myLocale(uuid).igsCreeperGriefing, uuid)); ip.add(new IPItem(!Settings.restrictWither, Material.SKULL_ITEM, 1, plugin.myLocale(uuid).igsWitherDamage, uuid)); ip.add(new IPItem(Settings.allowTNTDamage, Material.TNT, plugin.myLocale(uuid).igsTNT, uuid)); ip.add(new IPItem(Settings.allowVisitorKeepInvOnDeath, Material.IRON_CHESTPLATE, plugin.myLocale(uuid).igsVisitorKeep, uuid)); } else if (island.isSpawn()) { ip.add(new IPItem(Material.MAP, plugin.myLocale(uuid).igsSettingsSpawnTitle, plugin.myLocale(uuid).igsSettingsSpawnDesc)); // Spawn settings for (SettingsFlag flag : Settings.defaultSpawnSettings.keySet()) { //plugin.getLogger().info("DEBUG: " + flag.toString()); if (flag.equals(SettingsFlag.ACID_DAMAGE) && Settings.acidDamage == 0) continue; if (lookup.inverse().containsKey(flag) && plugin.myLocale(uuid).igs.containsKey(flag)) { ip.add(new IPItem(island.getIgsFlag(flag), lookup.inverse().get(flag), plugin.myLocale(uuid).igs.get(flag), uuid)); } } } else { // Standard island //plugin.getLogger().info("DEBUG: Standard island"); ip.add(new IPItem(Material.MAP, plugin.myLocale(uuid).igsSettingsIslandTitle, plugin.myLocale(uuid).igsSettingsIslandDesc)); for (SettingsFlag flag : Settings.visitorSettings.keySet()) { //plugin.getLogger().info("DEBUG: visitor flag = " + flag); if (flag.equals(SettingsFlag.ACID_DAMAGE) && Settings.acidDamage == 0) continue; if (lookup.inverse().get(flag) != null) { if (plugin.myLocale(uuid).igs.containsKey(flag)) { //plugin.getLogger().info("DEBUG: Adding flag"); ip.add(new IPItem(island.getIgsFlag(flag), lookup.inverse().get(flag), plugin.myLocale(uuid).igs.get(flag), uuid)); } } else if (DEBUG) { plugin.getLogger().severe("DEBUG: " + flag + " is missing an icon"); } } } if (ip.size() > 0) { // Make sure size is a multiple of 9 int size = ip.size() + 8; size -= (size % 9); String title = plugin.myLocale(uuid).igsTitle; if (title.length() > 32) { title = title.substring(0, 31); } newPanel = Bukkit.createInventory(null, size, title); // Fill the inventory and return int slot = 0; for (IPItem i : ip) { i.setSlot(slot); newPanel.addItem(i.getItem()); } } return newPanel; } /** * Handle clicks to the Settings panel * @param event */ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true) public void onInventoryClick(InventoryClickEvent event) { Player player = (Player) event.getWhoClicked(); // The player that clicked the item Inventory inventory = event.getInventory(); // The inventory that was clicked in if (inventory.getName() == null) { return; } int slot = event.getRawSlot(); // Check this is the right panel if (!inventory.getName().equals(plugin.myLocale(player.getUniqueId()).igsTitle)) { return; } // Stop removal of items event.setCancelled(true); if (event.getSlotType() == SlotType.OUTSIDE) { player.closeInventory(); inventory.clear(); return; } if (event.getClick().equals(ClickType.SHIFT_RIGHT)) { player.closeInventory(); inventory.clear(); player.updateInventory(); return; } // Check world if (!player.getLocation().getWorld().equals(ASkyBlock.getIslandWorld()) && !player.getLocation().getWorld().equals(ASkyBlock.getNetherWorld())) { return; } // 1.7.x server if (!hasArmorStand && slot > lookup.size()) { return; } // 1.8.x server if (slot > (lookup.size() +1)) { return; } // Get the flag SettingsFlag flag = null; if (lookup.containsKey(event.getCurrentItem().getType())) { // All other items flag = lookup.get(event.getCurrentItem().getType()); } else if (hasArmorStand && event.getCurrentItem().getType() == Material.ARMOR_STAND) { // Special handling to avoid errors on 1.7.x servers flag = SettingsFlag.ARMOR_STAND; } //plugin.getLogger().info("DEBUG: flag is " + flag); // If flag is null, do nothing if (flag == null) { return; } // Players can only do something if they own the island or are op Island island = plugin.getGrid().getIslandAt(player.getLocation()); if (island != null && (player.isOp() || (island.getOwner() != null && island.getOwner().equals(player.getUniqueId())))) { //plugin.getLogger().info("DEBUG: Check perm " + flag.toString()); // Check perms if (player.hasPermission(Settings.PERMPREFIX + "settings." + flag.toString())) { //plugin.getLogger().info("DEBUG: Player has perm " + flag.toString()); if (flag.equals(SettingsFlag.PVP) || flag.equals(SettingsFlag.NETHER_PVP)) { // PVP always results in an inventory closure player.closeInventory(); inventory.clear(); // Check if the player is allowed to toggle // PVP activation if (!island.getIgsFlag(flag)) { // Attempt to activate PVP //plugin.getLogger().info("DEBUG: attempt to activate PVP"); if (pvpCoolDown.containsKey(player.getUniqueId())) { //plugin.getLogger().info("DEBUG: player is in the cooldown list"); long setTime = pvpCoolDown.get(player.getUniqueId()); //plugin.getLogger().info("DEBUG: set time is " + setTime); long secondsLeft = Settings.pvpRestartCooldown - (System.currentTimeMillis() - setTime) / 1000; //plugin.getLogger().info("DEBUG: seconds left = " + secondsLeft); if (secondsLeft > 0) { Util.sendMessage(player, ChatColor.RED + "You must wait " + secondsLeft + " seconds until you can do that again!"); return; } // Tidy up pvpCoolDown.remove(player.getUniqueId()); } // Warn players on the island for (Player p : plugin.getServer().getOnlinePlayers()) { if (island.onIsland(p.getLocation())) { if (flag.equals(SettingsFlag.NETHER_PVP)) { Util.sendMessage(p, ChatColor.RED + "" + ChatColor.BOLD + plugin.myLocale(p.getUniqueId()).igs.get(SettingsFlag.NETHER_PVP) + " " + plugin.myLocale(p.getUniqueId()).igsAllowed); } else { Util.sendMessage(p, ChatColor.RED + "" + ChatColor.BOLD + plugin.myLocale(p.getUniqueId()).igs.get(SettingsFlag.PVP) + " " + plugin.myLocale(p.getUniqueId()).igsAllowed); } if (plugin.getServer().getVersion().contains("(MC: 1.8") || plugin.getServer().getVersion().contains("(MC: 1.7")) { player.getWorld().playSound(player.getLocation(), Sound.valueOf("ARROW_HIT"), 1F, 1F); } else { player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ARROW_HIT, 1F, 1F); } } } // Toggle the flag island.toggleIgs(flag); // Update warp signs final List<UUID> members = island.getMembers(); // Run one tick later because text gets updated at the end of tick plugin.getServer().getScheduler().runTask(plugin, new Runnable() { @Override public void run() { for (UUID playerUUID : members) { plugin.getWarpPanel().updateWarp(playerUUID); } }}); return; } else { // PVP deactivation // Store this deactivation time pvpCoolDown.put(player.getUniqueId(), System.currentTimeMillis()); // Immediately toggle the setting island.toggleIgs(flag); // Update warp signs final List<UUID> members = island.getMembers(); // Run one tick later because text gets updated at the end of tick plugin.getServer().getScheduler().runTask(plugin, new Runnable() { @Override public void run() { for (UUID playerUUID : members) { plugin.getWarpPanel().updateWarp(playerUUID); } }}); // Warn players of change for (Player p : plugin.getServer().getOnlinePlayers()) { if (island.onIsland(p.getLocation())) { // Deactivate PVP if (flag.equals(SettingsFlag.NETHER_PVP)) { Util.sendMessage(p, ChatColor.GREEN + plugin.myLocale(p.getUniqueId()).igs.get(SettingsFlag.NETHER_PVP) + " " + plugin.myLocale(p.getUniqueId()).igsDisallowed); } else { Util.sendMessage(p, ChatColor.GREEN + plugin.myLocale(p.getUniqueId()).igs.get(SettingsFlag.PVP) + " " + plugin.myLocale(p.getUniqueId()).igsDisallowed); } if (plugin.getServer().getVersion().contains("(MC: 1.8") || plugin.getServer().getVersion().contains("(MC: 1.7")) { p.getWorld().playSound(p.getLocation(), Sound.valueOf("FIREWORK_TWINKLE"), 1F, 1F); } else { p.getWorld().playSound(p.getLocation(), Sound.ENTITY_FIREWORK_TWINKLE, 1F, 1F); } } } } } else { island.toggleIgs(flag); } } //player.closeInventory(); inventory.clear(); player.openInventory(islandGuardPanel(player)); } } }