From a285d782be509fa417a5fff8733ac6b7e686c603 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz Date: Mon, 11 Apr 2016 22:39:27 +0200 Subject: [PATCH] Maps titles are now hidden when placed on an item frame. * NEW: MapItemManager: now handles item frame events, allowing to hide the map's title only when needed. * NEW: Map files are now all loaded on start, rather than on demand. * NEW: Rewrote DeleteConfirmCommand using the new RawText API. * NEW: Use the new ZLib.registerEvents() API. * OPT: MapManager's and PlayerMapStore's managesMap() methods now return early when given a non-map ItemStack. --- .../fr/moribus/imageonmap/ImageOnMap.java | 2 +- .../maptool/DeleteConfirmCommand.java | 27 ++++++-- .../imageonmap/image/MapInitEvent.java | 6 +- .../fr/moribus/imageonmap/map/MapManager.java | 42 ++++++++++++- .../imageonmap/map/PlayerMapStore.java | 4 ++ .../fr/moribus/imageonmap/map/PosterMap.java | 10 +++ .../moribus/imageonmap/ui/MapItemManager.java | 63 +++++++++++++++++++ 7 files changed, 143 insertions(+), 11 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java index 478d72e..cf68378 100644 --- a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java +++ b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java @@ -92,7 +92,7 @@ public final class ImageOnMap extends ZPlugin PluginConfiguration.init(this); MetricsLite.startMetrics(); MapManager.init(); - MapInitEvent.init(this); + MapInitEvent.init(); MapItemManager.init(); Commands.register( diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java index 9969d4e..102d1b9 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/DeleteConfirmCommand.java @@ -22,8 +22,10 @@ import fr.moribus.imageonmap.commands.IoMCommand; import fr.moribus.imageonmap.map.ImageMap; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.rawtext.RawText; import java.util.List; +import org.bukkit.ChatColor; @CommandInfo (name = "delete", usageParameters = "[tool name]") public class DeleteConfirmCommand extends IoMCommand @@ -32,11 +34,26 @@ public class DeleteConfirmCommand extends IoMCommand protected void run() throws CommandException { ImageMap map = getMapFromArgs(); - String msg ="{\"text\":\"You are going to delete \",\"extra\":[{\"text\":\""+ map.getId() +"\",\"color\":\"gold\"},{\"text\":\". Are you sure ? \",\"color\":\"white\"}," + - "{\"text\":\"[Confirm]\", \"color\":\"green\", \"clickEvent\":{\"action\":\"run_command\",\"value\":\"/maptool delete-noconfirm "+ map.getId() +"\"}, " + - "\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"This map will be deleted \",\"extra\":[{\"text\":\"forever\",\"color\":\"red\",\"bold\":true,\"italic\":true,\"underlined\":true}, {\"text\":\" !\", \"underlined\":true}],\"underlined\":true}}}]}"; - - tellRaw( msg); + + RawText hoverText = new RawText("This map will be deleted ") + .style(ChatColor.UNDERLINE) + .then("forever") + .style(ChatColor.RED, ChatColor.UNDERLINE, ChatColor.ITALIC, ChatColor.BOLD) + .then(" !") + .build(); + + RawText msg = new RawText("You are going to delete ") + .then(map.getId()) + .color(ChatColor.GOLD) + .then(". Are you sure ? ") + .color(ChatColor.WHITE) + .then("[Confirm]") + .color(ChatColor.GREEN) + .hover(hoverText) + .command(DeleteNoConfirmCommand.class, map.getId()) + .build(); + + send(msg); } @Override diff --git a/src/main/java/fr/moribus/imageonmap/image/MapInitEvent.java b/src/main/java/fr/moribus/imageonmap/image/MapInitEvent.java index 67ac34f..4c83978 100644 --- a/src/main/java/fr/moribus/imageonmap/image/MapInitEvent.java +++ b/src/main/java/fr/moribus/imageonmap/image/MapInitEvent.java @@ -19,6 +19,7 @@ package fr.moribus.imageonmap.image; import fr.moribus.imageonmap.ImageOnMap; +import fr.zcraft.zlib.core.ZLib; import java.io.File; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -34,13 +35,12 @@ import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.map.MapView; -import org.bukkit.plugin.Plugin; public class MapInitEvent implements Listener { - static public void init(Plugin plugin) + static public void init() { - plugin.getServer().getPluginManager().registerEvents(new MapInitEvent(), plugin); + ZLib.registerEvents(new MapInitEvent()); for(World world : Bukkit.getWorlds()) { diff --git a/src/main/java/fr/moribus/imageonmap/map/MapManager.java b/src/main/java/fr/moribus/imageonmap/map/MapManager.java index a70e800..e93cc67 100644 --- a/src/main/java/fr/moribus/imageonmap/map/MapManager.java +++ b/src/main/java/fr/moribus/imageonmap/map/MapManager.java @@ -23,6 +23,8 @@ import fr.moribus.imageonmap.PluginConfiguration; import fr.moribus.imageonmap.image.ImageIOExecutor; import fr.moribus.imageonmap.image.PosterImage; import fr.moribus.imageonmap.map.MapManagerException.Reason; +import fr.zcraft.zlib.tools.PluginLogger; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -32,7 +34,7 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitTask; -abstract public class MapManager +abstract public class MapManager { static private final long SAVE_DELAY = 200; static private final ArrayList playerMaps = new ArrayList(); @@ -40,7 +42,7 @@ abstract public class MapManager static public void init() { - + load(); } static public void exit() @@ -64,6 +66,9 @@ abstract public class MapManager static public boolean managesMap(ItemStack item) { + if(item == null) return false; + if(item.getType() != Material.MAP) return false; + synchronized(playerMaps) { for(PlayerMapStore mapStore : playerMaps) @@ -222,6 +227,39 @@ abstract public class MapManager } } + static private UUID getUUIDFromFile(File file) + { + String fileName = file.getName(); + int fileExtPos = fileName.lastIndexOf('.'); + if(fileExtPos <= 0) return null; + + String fileExt = fileName.substring(fileExtPos + 1); + if(!fileExt.equals("yml")) return null; + + try + { + return UUID.fromString(fileName.substring(0, fileExtPos)); + } + catch(IllegalArgumentException ex) + { + return null; + } + } + + static public void load() + { + int loadedFilesCount = 0; + for(File file : ImageOnMap.getPlugin().getMapsDirectory().listFiles()) + { + UUID uuid = getUUIDFromFile(file); + if(uuid == null) continue; + getPlayerMapStore(uuid); + ++loadedFilesCount; + } + + PluginLogger.info("Loaded {0} player map files.", loadedFilesCount); + } + static public void save() { synchronized(playerMaps) diff --git a/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java b/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java index 999965e..2648398 100644 --- a/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java +++ b/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java @@ -36,6 +36,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; +import org.bukkit.Material; public class PlayerMapStore implements ConfigurationSerializable { @@ -60,6 +61,9 @@ public class PlayerMapStore implements ConfigurationSerializable public synchronized boolean managesMap(ItemStack item) { + if(item == null) return false; + if(item.getType() != Material.MAP) return false; + for(ImageMap map : mapList) { if(map.managesMap(item)) return true; diff --git a/src/main/java/fr/moribus/imageonmap/map/PosterMap.java b/src/main/java/fr/moribus/imageonmap/map/PosterMap.java index ba0bf93..e14288b 100644 --- a/src/main/java/fr/moribus/imageonmap/map/PosterMap.java +++ b/src/main/java/fr/moribus/imageonmap/map/PosterMap.java @@ -141,5 +141,15 @@ public class PosterMap extends ImageMap { return mapsIDs.length; } + + public int getIndex(short mapID) + { + for(int i = 0; i < mapsIDs.length; i++) + { + if(mapsIDs[i] == mapID) return i; + } + + throw new IllegalArgumentException("Invalid map ID"); + } } diff --git a/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java b/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java index 7869d79..c01c7e5 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java +++ b/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java @@ -19,9 +19,12 @@ package fr.moribus.imageonmap.ui; import fr.moribus.imageonmap.map.ImageMap; +import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.PosterMap; import fr.moribus.imageonmap.map.SingleMap; import fr.zcraft.zlib.components.gui.GuiUtils; +import fr.zcraft.zlib.core.ZLib; +import fr.zcraft.zlib.tools.items.ItemUtils; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -34,6 +37,10 @@ import java.util.ArrayDeque; import java.util.HashMap; import java.util.Queue; import java.util.UUID; +import org.bukkit.entity.ItemFrame; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; public class MapItemManager implements Listener { @@ -42,6 +49,7 @@ public class MapItemManager implements Listener static public void init() { mapItemCache = new HashMap(); + ZLib.registerEvents(new MapItemManager()); } static public void exit() @@ -195,4 +203,59 @@ public class MapItemManager implements Listener } return cache; } + + static private String getMapTitle(ItemStack item) + { + ImageMap map = MapManager.getMap(item); + if(map instanceof SingleMap) + { + return map.getName(); + } + else + { + PosterMap poster = (PosterMap) map; + int index = poster.getIndex(item.getDurability()); + return map.getName() + " (row " + (poster.getRowAt(index)) + + ", column " + (poster.getColumnAt(index)) + ")"; + } + } + + static private void onItemFramePlace(ItemFrame frame, Player player, PlayerInteractEntityEvent event) + { + if(frame.getItem().getType() != Material.AIR) return; + if(!MapManager.managesMap(player.getItemInHand())) return; + + + event.setCancelled(true); + ItemStack is = new ItemStack(Material.MAP, 1, player.getItemInHand().getDurability()); + frame.setItem(is); + + ItemUtils.consumeItem(player); + } + + static private void onItemFrameRemove(ItemFrame frame, Player player) + { + ItemStack item = frame.getItem(); + if(frame.getItem().getType() != Material.MAP) return; + if(!MapManager.managesMap(frame.getItem())) return; + + frame.setItem(ItemUtils.setDisplayName(item, getMapTitle(item))); + } + + @EventHandler + static public void onEntityDamage(EntityDamageByEntityEvent event) + { + if(!(event.getEntity() instanceof ItemFrame)) return; + if(!(event.getDamager() instanceof Player)) return; + + onItemFrameRemove((ItemFrame)event.getEntity(), (Player)event.getDamager()); + } + + @EventHandler + static public void onEntityInteract(PlayerInteractEntityEvent event) + { + if(!(event.getRightClicked() instanceof ItemFrame)) return; + + onItemFramePlace((ItemFrame)event.getRightClicked(), event.getPlayer(), event); + } }