diff --git a/pom.xml b/pom.xml index df341f9..a365b5f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,13 +3,13 @@ 4.0.0 fr.moribus ImageOnMap - 3.1 + 4.0 jar UTF-8 - 1.7 - 1.7 + 1.8 + 1.8 @@ -46,7 +46,7 @@ spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ zDevelopers @@ -58,7 +58,7 @@ org.bukkit bukkit - 1.8.3-R0.1-SNAPSHOT + 1.13.2-R0.1-SNAPSHOT fr.zcraft diff --git a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java index f16aa90..51ee371 100644 --- a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java +++ b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java @@ -18,13 +18,7 @@ package fr.moribus.imageonmap; -import fr.moribus.imageonmap.commands.maptool.DeleteCommand; -import fr.moribus.imageonmap.commands.maptool.ExploreCommand; -import fr.moribus.imageonmap.commands.maptool.GetCommand; -import fr.moribus.imageonmap.commands.maptool.GetRemainingCommand; -import fr.moribus.imageonmap.commands.maptool.ListCommand; -import fr.moribus.imageonmap.commands.maptool.MigrateCommand; -import fr.moribus.imageonmap.commands.maptool.NewCommand; +import fr.moribus.imageonmap.commands.maptool.*; import fr.moribus.imageonmap.image.ImageIOExecutor; import fr.moribus.imageonmap.image.ImageRendererExecutor; import fr.moribus.imageonmap.image.MapInitEvent; @@ -64,7 +58,7 @@ public final class ImageOnMap extends ZPlugin public File getImagesDirectory() {return imagesDirectory;} public File getMapsDirectory() {return mapsDirectory;} - public File getImageFile(short mapID) + public File getImageFile(int mapID) { return new File(imagesDirectory, "map"+mapID+".png"); } @@ -79,7 +73,7 @@ public final class ImageOnMap extends ZPlugin imagesDirectory = checkPluginDirectory(imagesDirectory, V3Migrator.getOldImagesDirectory(this)); checkPluginDirectory(mapsDirectory); } - catch(IOException ex) + catch(final IOException ex) { PluginLogger.error("FATAL: " + ex.getMessage()); this.setEnabled(false); diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java index 1019c7b..d8c75a2 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/ListCommand.java @@ -74,7 +74,7 @@ public class ListCommand extends IoMCommand .then(map.getId()) .color(ChatColor.WHITE) .command(GetCommand.class, map.getId()) - .hover(new ItemStackBuilder(Material.MAP) + .hover(new ItemStackBuilder(Material.FILLED_MAP) .title(ChatColor.GREEN + "" + ChatColor.BOLD + map.getName()) .lore(ChatColor.GRAY + map.getId() + ", " + size) .lore("") diff --git a/src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java b/src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java index 706b627..a556c56 100644 --- a/src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java +++ b/src/main/java/fr/moribus/imageonmap/gui/ConfirmDeleteMapGui.java @@ -29,13 +29,9 @@ import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.PluginLogger; import fr.zcraft.zlib.tools.items.ItemStackBuilder; import org.bukkit.ChatColor; -import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.material.Dye; -import java.util.Arrays; import java.util.Random; @@ -106,7 +102,7 @@ public class ConfirmDeleteMapGui extends ActionGui /* ** Item representation of the image being deleted ** */ - action("", 13, new ItemStackBuilder(Material.EMPTY_MAP) + action("", 13, new ItemStackBuilder(Material.FILLED_MAP) /// The title of the map deletion item .title(I.t(getPlayerLocale(), "{red}You're about to destroy this map...")) /// The end, in the lore, of a title starting with “You're about to destroy this map...”. @@ -134,32 +130,21 @@ public class ConfirmDeleteMapGui extends ActionGui private ItemStack createDeleteSubButton() { - // Orange? Nooo. In the real world this is red. True story. - return createSubButton(DyeColor.ORANGE, ChatColor.RED + "Delete the map", DELETE_MESSAGES); + return createSubButton(Material.RED_STAINED_GLASS_PANE, ChatColor.RED + "Delete the map", DELETE_MESSAGES); } private ItemStack createCancelSubButton() { - // YES. Purple = lime. BECAUSE. Just accept it. - return createSubButton(DyeColor.PURPLE, ChatColor.GREEN + "Cancel", CANCEL_MESSAGES); + return createSubButton(Material.LIME_STAINED_GLASS_PANE, ChatColor.GREEN + "Cancel", CANCEL_MESSAGES); } - private ItemStack createSubButton(DyeColor color, String title, String[] messages) + private ItemStack createSubButton(Material color, String title, String[] messages) { - Dye pane = new Dye(Material.STAINED_GLASS_PANE); - pane.setColor(color); - - ItemStack subButton = pane.toItemStack(1); - ItemMeta meta = subButton.getItemMeta(); - - meta.setDisplayName(title); - meta.setLore(Arrays.asList( - "", - ChatColor.GRAY + messages[random.nextInt(messages.length)] - )); - - subButton.setItemMeta(meta); - return subButton; + return new ItemStackBuilder(color) + .title(title) + .loreSeparator() + .longLore(ChatColor.GRAY + messages[random.nextInt(messages.length)]) + .item(); } @GuiAction ("cancel") diff --git a/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java b/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java index f7e48ce..2c3f286 100644 --- a/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java +++ b/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java @@ -35,7 +35,7 @@ import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -public class MapDetailGui extends ExplorerGui +public class MapDetailGui extends ExplorerGui { private final ImageMap map; @@ -47,7 +47,7 @@ public class MapDetailGui extends ExplorerGui @Override protected ItemStack getViewItem(int x, int y) { - final Material partMaterial = y % 2 == x % 2 ? Material.EMPTY_MAP : Material.PAPER; + final Material partMaterial = y % 2 == x % 2 ? Material.MAP : Material.PAPER; final ItemStackBuilder builder = new ItemStackBuilder(partMaterial) .title(I.t(getPlayerLocale(), "{green}Map part")) @@ -61,10 +61,10 @@ public class MapDetailGui extends ExplorerGui } @Override - protected ItemStack getViewItem(Short mapId) + protected ItemStack getViewItem(Integer mapId) { final int index = ((PosterMap) map).getIndex(mapId); - final Material partMaterial = index % 2 == 0 ? Material.EMPTY_MAP : Material.PAPER; + final Material partMaterial = index % 2 == 0 ? Material.MAP : Material.PAPER; final ItemStackBuilder builder = new ItemStackBuilder(partMaterial) .title(I.t(getPlayerLocale(), "{green}Map part")) @@ -95,7 +95,7 @@ public class MapDetailGui extends ExplorerGui } @Override - protected ItemStack getPickedUpItem(Short mapId) + protected ItemStack getPickedUpItem(Integer mapId) { if (!Permissions.GET.grantedTo(getPlayer())) return null; @@ -149,7 +149,7 @@ public class MapDetailGui extends ExplorerGui if (canRename) { - action("rename", renameSlot, new ItemStackBuilder(Material.BOOK_AND_QUILL) + action("rename", renameSlot, new ItemStackBuilder(Material.WRITABLE_BOOK) .title(I.t(getPlayerLocale(), "{blue}Rename this image")) .longLore(I.t(getPlayerLocale(), "{gray}Click here to rename this image; this is used for your own organization.")) ); diff --git a/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java b/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java index 51dc27d..9f60a7b 100644 --- a/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java +++ b/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java @@ -29,8 +29,10 @@ import fr.zcraft.zlib.components.gui.ExplorerGui; import fr.zcraft.zlib.components.gui.Gui; import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.items.ItemStackBuilder; +import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.MapMeta; public class MapListGui extends ExplorerGui @@ -58,34 +60,41 @@ public class MapListGui extends ExplorerGui mapDescription = I.t(getPlayerLocale(), "{white}Poster map ({0} parts)", poster.getMapCount()); } } - ItemStackBuilder builder = new ItemStackBuilder(Material.MAP) + + ItemStackBuilder builder = new ItemStackBuilder(Material.FILLED_MAP) /// Displayed title of a map on the list GUI - .title(I.t(getPlayerLocale(), "{green}{bold}{0}", map.getName())) + .title(I.tl(getPlayerLocale(), "{green}{bold}{0}", map.getName())) .lore(mapDescription) .loreLine() /// Map ID displayed in the tooltip of a map on the list GUI - .lore(I.t(getPlayerLocale(), "{gray}Map ID: {0}", map.getId())) + .lore(I.tl(getPlayerLocale(), "{gray}Map ID: {0}", map.getId())) .loreLine(); if (Permissions.GET.grantedTo(getPlayer())) - builder.lore(I.t(getPlayerLocale(), "{gray}» {white}Left-click{gray} to get this map")); + builder.lore(I.tl(getPlayerLocale(), "{gray}» {white}Left-click{gray} to get this map")); - builder.lore(I.t(getPlayerLocale(), "{gray}» {white}Right-click{gray} for details and options")); + builder.lore(I.tl(getPlayerLocale(), "{gray}» {white}Right-click{gray} for details and options")); - return builder.item(); + final ItemStack mapItem = builder.item(); + + final MapMeta meta = (MapMeta) mapItem.getItemMeta(); + meta.setColor(Color.GREEN); + mapItem.setItemMeta(meta); + + return mapItem; } @Override protected ItemStack getEmptyViewItem() { ItemStackBuilder builder = new ItemStackBuilder(Material.BARRIER) - .title(I.t(getPlayerLocale(), "{red}You don't have any map.")); + .title(I.tl(getPlayerLocale(), "{red}You don't have any map.")); if (Permissions.NEW.grantedTo(getPlayer())) - builder.longLore(I.t(getPlayerLocale(), "{gray}Get started by creating a new one using {white}/tomap [resize]{gray}!")); + builder.longLore(I.tl(getPlayerLocale(), "{gray}Get started by creating a new one using {white}/tomap [resize]{gray}!")); else - builder.longLore(I.t(getPlayerLocale(), "{gray}Unfortunately, you are not allowed to create one.")); + builder.longLore(I.tl(getPlayerLocale(), "{gray}Unfortunately, you are not allowed to create one.")); return builder.item(); } @@ -104,7 +113,7 @@ public class MapListGui extends ExplorerGui if (map instanceof SingleMap) { - return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName()); + return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName(), false); } else if (map instanceof PosterMap) { @@ -128,7 +137,7 @@ public class MapListGui extends ExplorerGui setData(maps); /// The maps list GUI title - setTitle(I.t(getPlayerLocale(), "{black}Your maps {reset}({0})", maps.length)); + setTitle(I.tl(getPlayerLocale(), "{black}Your maps {reset}({0})", maps.length)); setKeepHorizontalScrollingSpace(true); diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageIOExecutor.java b/src/main/java/fr/moribus/imageonmap/image/ImageIOExecutor.java index 64f2045..b2df051 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageIOExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageIOExecutor.java @@ -60,12 +60,12 @@ public class ImageIOExecutor extends Worker }); } - static public void saveImage(short mapID, BufferedImage image) + static public void saveImage(int mapID, BufferedImage image) { saveImage(ImageOnMap.getPlugin().getImageFile(mapID), image); } - static public void saveImage(short[] mapsIDs, PosterImage image) + static public void saveImage(int[] mapsIDs, PosterImage image) { for(int i = 0, c = mapsIDs.length; i < c; i++) { @@ -75,7 +75,7 @@ public class ImageIOExecutor extends Worker static public void deleteImage(ImageMap map) { - short[] mapsIDs = map.getMapsIDs(); + int[] mapsIDs = map.getMapsIDs(); for(int i = 0, c = mapsIDs.length; i < c; i++) { deleteImage(ImageOnMap.getPlugin().getImageFile(mapsIDs[i])); diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java index 2b47a8c..acd6749 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java @@ -77,16 +77,16 @@ public class ImageRendererExecutor extends Worker static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable { MapManager.checkMapLimit(1, playerUUID); - final Future futureMapID = submitToMainThread(new Callable() + final Future futureMapID = submitToMainThread(new Callable() { @Override - public Short call() throws Exception + public Integer call() throws Exception { return MapManager.getNewMapsIds(1)[0]; } }); - final short mapID = futureMapID.get(); + final int mapID = futureMapID.get(); ImageIOExecutor.saveImage(mapID, image); submitToMainThread(new Callable() @@ -108,10 +108,10 @@ public class ImageRendererExecutor extends Worker final int mapCount = poster.getImagesCount(); MapManager.checkMapLimit(mapCount, playerUUID); - final Future futureMapsIds = submitToMainThread(new Callable() + final Future futureMapsIds = submitToMainThread(new Callable() { @Override - public short[] call() throws Exception + public int[] call() throws Exception { return MapManager.getNewMapsIds(mapCount); } @@ -119,7 +119,7 @@ public class ImageRendererExecutor extends Worker poster.splitImages(); - final short[] mapsIDs = futureMapsIds.get(); + final int[] mapsIDs = futureMapsIds.get(); ImageIOExecutor.saveImage(mapsIDs, poster); diff --git a/src/main/java/fr/moribus/imageonmap/image/MapInitEvent.java b/src/main/java/fr/moribus/imageonmap/image/MapInitEvent.java index ca8e078..6424bad 100644 --- a/src/main/java/fr/moribus/imageonmap/image/MapInitEvent.java +++ b/src/main/java/fr/moribus/imageonmap/image/MapInitEvent.java @@ -19,25 +19,26 @@ package fr.moribus.imageonmap.image; import fr.moribus.imageonmap.ImageOnMap; +import fr.moribus.imageonmap.map.MapManager; import fr.zcraft.zlib.core.ZLib; -import java.io.File; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.entity.Entity; +import org.bukkit.entity.HumanEntity; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerItemHeldEvent; -import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.map.MapView; +import java.io.File; + public class MapInitEvent implements Listener { static public void init() @@ -54,7 +55,7 @@ public class MapInitEvent implements Listener for(Player player : Bukkit.getOnlinePlayers()) { - initMap(player.getItemInHand()); + initMap(player.getInventory().getItemInMainHand()); } } @@ -78,10 +79,10 @@ public class MapInitEvent implements Listener } @EventHandler - public void onPlayerPickup(PlayerPickupItemEvent event) + public void onPlayerPickup(EntityPickupItemEvent event) { - ItemStack item = event.getItem().getItemStack(); - initMap(item); + if (!(event.getEntity() instanceof HumanEntity)) return; + initMap(event.getItem().getItemStack()); } @EventHandler @@ -99,15 +100,15 @@ public class MapInitEvent implements Listener static public void initMap(ItemStack item) { - if (item != null && item.getType() == Material.MAP) + if (item != null && item.getType() == Material.FILLED_MAP) { - initMap(item.getDurability()); + initMap(MapManager.getMapIdFromItemStack(item)); } } - static public void initMap(short id) + static public void initMap(int id) { - initMap(Bukkit.getMap(id)); + initMap(Bukkit.getServer().getMap(id)); } static public void initMap(MapView map) diff --git a/src/main/java/fr/moribus/imageonmap/image/Renderer.java b/src/main/java/fr/moribus/imageonmap/image/Renderer.java index 1aa306f..ace2643 100644 --- a/src/main/java/fr/moribus/imageonmap/image/Renderer.java +++ b/src/main/java/fr/moribus/imageonmap/image/Renderer.java @@ -19,13 +19,14 @@ package fr.moribus.imageonmap.image; import fr.zcraft.zlib.tools.PluginLogger; -import java.awt.image.BufferedImage; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.map.MapCanvas; import org.bukkit.map.MapRenderer; import org.bukkit.map.MapView; +import java.awt.image.BufferedImage; + public class Renderer extends MapRenderer { static public boolean isHandled(MapView map) @@ -38,7 +39,7 @@ public class Renderer extends MapRenderer return false; } - static public void installRenderer(PosterImage image, short[] mapsIds) + static public void installRenderer(PosterImage image, int[] mapsIds) { for(int i = 0; i < mapsIds.length; i++) { @@ -46,12 +47,12 @@ public class Renderer extends MapRenderer } } - static public void installRenderer(BufferedImage image, short mapID) + static public void installRenderer(BufferedImage image, int mapID) { MapView map = Bukkit.getMap(mapID); if(map == null) { - PluginLogger.warning("Could not install renderer for map {0} : the Minecraft map does not exist", mapID); + PluginLogger.warning("Could not install renderer for map {0}: the Minecraft map does not exist", mapID); } else { diff --git a/src/main/java/fr/moribus/imageonmap/map/ImageMap.java b/src/main/java/fr/moribus/imageonmap/map/ImageMap.java index bd71fad..b74e587 100644 --- a/src/main/java/fr/moribus/imageonmap/map/ImageMap.java +++ b/src/main/java/fr/moribus/imageonmap/map/ImageMap.java @@ -68,15 +68,15 @@ public abstract class ImageMap implements ConfigurationSerializable } - public abstract short[] getMapsIDs(); - public abstract boolean managesMap(short mapID); + public abstract int[] getMapsIDs(); + public abstract boolean managesMap(int mapID); public abstract int getMapCount(); public boolean managesMap(ItemStack item) { if(item == null) return false; - if(item.getType() != Material.MAP) return false; - return managesMap(item.getDurability()); + if(item.getType() != Material.FILLED_MAP) return false; + return managesMap(MapManager.getMapIdFromItemStack(item)); } public boolean give(Player player) diff --git a/src/main/java/fr/moribus/imageonmap/map/MapManager.java b/src/main/java/fr/moribus/imageonmap/map/MapManager.java index fa58f99..b3e8969 100644 --- a/src/main/java/fr/moribus/imageonmap/map/MapManager.java +++ b/src/main/java/fr/moribus/imageonmap/map/MapManager.java @@ -28,6 +28,8 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.MapMeta; import org.bukkit.scheduler.BukkitTask; import java.io.File; @@ -53,7 +55,7 @@ abstract public class MapManager if(autosaveTask != null) autosaveTask.cancel(); } - static public boolean managesMap(short mapID) + static public boolean managesMap(int mapID) { synchronized(playerMaps) { @@ -68,7 +70,7 @@ abstract public class MapManager static public boolean managesMap(ItemStack item) { if(item == null) return false; - if(item.getType() != Material.MAP) return false; + if(item.getType() != Material.FILLED_MAP) return false; synchronized(playerMaps) { @@ -80,14 +82,14 @@ abstract public class MapManager return false; } - static public ImageMap createMap(UUID playerUUID, short mapID) throws MapManagerException + static public ImageMap createMap(UUID playerUUID, int mapID) throws MapManagerException { ImageMap newMap = new SingleMap(playerUUID, mapID); addMap(newMap); return newMap; } - static public ImageMap createMap(PosterImage image, UUID playerUUID, short[] mapsIDs) throws MapManagerException + static public ImageMap createMap(PosterImage image, UUID playerUUID, int[] mapsIDs) throws MapManagerException { ImageMap newMap; if(image.getImagesCount() == 1) @@ -102,15 +104,28 @@ abstract public class MapManager return newMap; } - static public short[] getNewMapsIds(int amount) + static public int[] getNewMapsIds(int amount) { - short[] mapsIds = new short[amount]; + int[] mapsIds = new int[amount]; for(int i = 0; i < amount; i++) { mapsIds[i] = Bukkit.createMap(Bukkit.getWorlds().get(0)).getId(); } return mapsIds; } + + /** + * Returns the map ID from an ItemStack + * @param item The item stack + * @return The map ID, or 0 if invalid. + */ + static public int getMapIdFromItemStack(final ItemStack item) + { + final ItemMeta meta = item.getItemMeta(); + if (!(meta instanceof MapMeta)) return 0; + + return ((MapMeta) meta).hasMapId() ? ((MapMeta) meta).getMapId() : 0; + } static public void addMap(ImageMap map) throws MapManagerException { @@ -173,7 +188,7 @@ abstract public class MapManager * @param mapId The ID of the Minecraft map. * @return The {@link ImageMap}. */ - static public ImageMap getMap(short mapId) + static public ImageMap getMap(int mapId) { synchronized(playerMaps) { @@ -204,8 +219,8 @@ abstract public class MapManager static public ImageMap getMap(ItemStack item) { if(item == null) return null; - if(item.getType() != Material.MAP) return null; - return getMap(item.getDurability()); + if(item.getType() != Material.FILLED_MAP) return null; + return getMap(getMapIdFromItemStack(item)); } static public void clear(Inventory inventory) @@ -312,7 +327,7 @@ abstract public class MapManager * @param mapId the map ID. * @return true if the given map ID is valid and exists in the current save, false otherwise. */ - static public boolean mapIdExists(short mapId) + static public boolean mapIdExists(int mapId) { try { diff --git a/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java b/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java index 0c8d531..5819a5d 100644 --- a/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java +++ b/src/main/java/fr/moribus/imageonmap/map/PlayerMapStore.java @@ -50,7 +50,7 @@ public class PlayerMapStore implements ConfigurationSerializable this.playerUUID = playerUUID; } - public synchronized boolean managesMap(short mapID) + public synchronized boolean managesMap(int mapID) { for(ImageMap map : mapList) { @@ -62,7 +62,7 @@ public class PlayerMapStore implements ConfigurationSerializable public synchronized boolean managesMap(ItemStack item) { if(item == null) return false; - if(item.getType() != Material.MAP) return false; + if(item.getType() != Material.FILLED_MAP) return false; for(ImageMap map : mapList) { diff --git a/src/main/java/fr/moribus/imageonmap/map/PosterMap.java b/src/main/java/fr/moribus/imageonmap/map/PosterMap.java index 37199ef..e425bb5 100644 --- a/src/main/java/fr/moribus/imageonmap/map/PosterMap.java +++ b/src/main/java/fr/moribus/imageonmap/map/PosterMap.java @@ -26,11 +26,11 @@ import java.util.UUID; public class PosterMap extends ImageMap { - protected final short[] mapsIDs; + protected final int[] mapsIDs; protected final int columnCount; protected final int rowCount; - public PosterMap(UUID userUUID, short[] mapsIDs, String id, String name, int columnCount, int rowCount) + public PosterMap(UUID userUUID, int[] mapsIDs, String id, String name, int columnCount, int rowCount) { super(userUUID, Type.POSTER, id, name); this.mapsIDs = mapsIDs; @@ -38,19 +38,19 @@ public class PosterMap extends ImageMap this.rowCount = Math.max(rowCount, 0); } - public PosterMap(UUID userUUID, short[] mapsIDs, int columnCount, int rowCount) + public PosterMap(UUID userUUID, int[] mapsIDs, int columnCount, int rowCount) { this(userUUID, mapsIDs, null, null, columnCount, rowCount); } @Override - public short[] getMapsIDs() + public int[] getMapsIDs() { return mapsIDs; } @Override - public boolean managesMap(short mapID) + public boolean managesMap(int mapID) { for(int i = 0; i < mapsIDs.length; i++) { @@ -70,10 +70,10 @@ public class PosterMap extends ImageMap rowCount = getFieldValue(map, "rows"); List idList = getFieldValue(map, "mapsIDs"); - mapsIDs = new short[idList.size()]; + mapsIDs = new int[idList.size()]; for(int i = 0, c = idList.size(); i < c; i++) { - mapsIDs[i] = (short) ((int) idList.get(i)); + mapsIDs[i] = (int) idList.get(i); } } @@ -131,19 +131,19 @@ public class PosterMap extends ImageMap * * @throws ArrayIndexOutOfBoundsException if the given coordinates are too big (out of the poster). */ - public short getMapIdAt(int x, int y) + public int getMapIdAt(int x, int y) { return mapsIDs[y * columnCount + x]; } - public short getMapIdAtReverseY(int index) + public int getMapIdAtReverseY(int index) { int x = index % (columnCount); int y = index / (columnCount); return getMapIdAt(x, rowCount - y - 1); } - public short getMapIdAt(int index) + public int getMapIdAt(int index) { return mapsIDs[index]; } @@ -159,7 +159,7 @@ public class PosterMap extends ImageMap return mapsIDs.length; } - public int getIndex(short mapID) + public int getIndex(int mapID) { for(int i = 0; i < mapsIDs.length; i++) { diff --git a/src/main/java/fr/moribus/imageonmap/map/SingleMap.java b/src/main/java/fr/moribus/imageonmap/map/SingleMap.java index 1695161..ad8c67f 100644 --- a/src/main/java/fr/moribus/imageonmap/map/SingleMap.java +++ b/src/main/java/fr/moribus/imageonmap/map/SingleMap.java @@ -18,33 +18,34 @@ package fr.moribus.imageonmap.map; +import org.bukkit.configuration.InvalidConfigurationException; + import java.util.Map; import java.util.UUID; -import org.bukkit.configuration.InvalidConfigurationException; public class SingleMap extends ImageMap { - protected final short mapID; + protected final int mapID; - public SingleMap(UUID ownerUUID, short mapID, String id, String name) + public SingleMap(UUID ownerUUID, int mapID, String id, String name) { super(ownerUUID, Type.SINGLE, id, name); this.mapID = mapID; } - public SingleMap(UUID ownerUUID, short mapID) + public SingleMap(UUID ownerUUID, int mapID) { this(ownerUUID, mapID, null, null); } @Override - public short[] getMapsIDs() + public int[] getMapsIDs() { - return new short[]{mapID}; + return new int[]{mapID}; } @Override - public boolean managesMap(short mapID) + public boolean managesMap(int mapID) { return this.mapID == mapID; } @@ -60,8 +61,7 @@ public class SingleMap extends ImageMap public SingleMap(Map map, UUID userUUID) throws InvalidConfigurationException { super(map, userUUID, Type.SINGLE); - int _mapID = getFieldValue(map, "mapID"); - mapID = (short) _mapID;//Meh + mapID = getFieldValue(map, "mapID"); } @Override diff --git a/src/main/java/fr/moribus/imageonmap/migration/OldSavedPoster.java b/src/main/java/fr/moribus/imageonmap/migration/OldSavedPoster.java index 0c1b7d5..6746d75 100644 --- a/src/main/java/fr/moribus/imageonmap/migration/OldSavedPoster.java +++ b/src/main/java/fr/moribus/imageonmap/migration/OldSavedPoster.java @@ -21,12 +21,14 @@ package fr.moribus.imageonmap.migration; import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.PosterMap; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import org.bukkit.configuration.Configuration; import org.bukkit.configuration.InvalidConfigurationException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + class OldSavedPoster { private final String userName; @@ -78,7 +80,11 @@ class OldSavedPoster public ImageMap toImageMap(UUID userUUID) { - return new PosterMap(userUUID, mapsIds, null, "poster", 0, 0); + // Converts the maps IDs to int as MC 1.13.2+ uses integer ids + final int[] mapsIdsInt = new int[mapsIds.length]; + Arrays.setAll(mapsIdsInt, i -> mapsIds[i]); + + return new PosterMap(userUUID, mapsIdsInt, null, "poster", 0, 0); } public void serialize(Configuration configuration) diff --git a/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java b/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java index 3c37e97..db4b6f1 100644 --- a/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java +++ b/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java @@ -23,6 +23,8 @@ import fr.moribus.imageonmap.map.MapManager; import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.tools.PluginLogger; import fr.zcraft.zlib.tools.mojang.UUIDFetcher; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -37,14 +39,8 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.UUID; -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.StringUtils; +import java.util.*; +import java.util.stream.Collectors; /** * This class represents and executes the ImageOnMap v3.x migration process @@ -427,7 +423,7 @@ public class V3Migrator implements Runnable ArrayDeque remainingMaps = new ArrayDeque<>(); ArrayDeque remainingPosters = new ArrayDeque<>(); - ArrayDeque missingMapIds = new ArrayDeque<>(); + ArrayDeque missingMapIds = new ArrayDeque<>(); UUID playerUUID; OldSavedMap map; @@ -441,7 +437,7 @@ public class V3Migrator implements Runnable } else if(!map.isMapValid()) { - missingMapIds.add(map.getMapId()); + missingMapIds.add((int) map.getMapId()); } else { @@ -461,7 +457,7 @@ public class V3Migrator implements Runnable } else if(!poster.isMapValid()) { - missingMapIds.addAll(Arrays.asList(ArrayUtils.toObject(poster.getMapsIds()))); + missingMapIds.addAll(Arrays.stream(ArrayUtils.toObject(poster.getMapsIds())).map(id -> (int) id).collect(Collectors.toList())); } else { diff --git a/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java b/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java index 6f9309b..282bbe7 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java +++ b/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java @@ -22,10 +22,14 @@ 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.attributes.Attributes; import fr.zcraft.zlib.components.i18n.I; import fr.zcraft.zlib.core.ZLib; +import fr.zcraft.zlib.tools.PluginLogger; import fr.zcraft.zlib.tools.items.ItemStackBuilder; import fr.zcraft.zlib.tools.items.ItemUtils; +import fr.zcraft.zlib.tools.reflection.NMSException; +import org.bukkit.Color; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.entity.ItemFrame; @@ -37,6 +41,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.MapMeta; import java.util.ArrayDeque; import java.util.HashMap; @@ -114,54 +119,77 @@ public class MapItemManager implements Listener return givenItemsCount; } - static private boolean give(Player player, ItemStack item) + static private boolean give(final Player player, final ItemStack item) { - if(player.getInventory().firstEmpty() <= -1) + final int freeSlot = player.getInventory().firstEmpty(); + if (freeSlot != -1) { - getCache(player).add(item); - return true; + player.getInventory().setItem(freeSlot, item); + + // If this is a splatter map, we have to re-add the splatter attribute, because + // for some reason, the `addItem` or `setItem` methods removes the attribute in + // Minecraft 1.14+, breaking the auto-deploy feature. + if (SplatterMapManager.hasSplatterAttributes(item)) + { + try + { + Attributes.set(player.getInventory().getItem(freeSlot), new SplatterMapManager.Attribute()); + } + catch (NMSException e) + { + PluginLogger.error("Unable to add back attribute to splatter map"); + } + } + + return false; } else { - player.getInventory().addItem(item); - return false; + ItemUtils.drop(player.getLocation(), item); + return true; } } static public ItemStack createMapItem(SingleMap map) { - return createMapItem(map.getMapsIDs()[0], map.getName()); + return createMapItem(map.getMapsIDs()[0], map.getName(), false); } static public ItemStack createMapItem(PosterMap map, int index) { - /// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index. - return createMapItem(map.getMapIdAt(index), getMapTitle(map, index)); + return createMapItem(map.getMapIdAt(index), getMapTitle(map, index), true); } static public ItemStack createMapItem(PosterMap map, int x, int y) { - /// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column. - return createMapItem(map.getMapIdAt(x, y), getMapTitle(map, y, x)); + return createMapItem(map.getMapIdAt(x, y), getMapTitle(map, y, x), true); } static public String getMapTitle(PosterMap map, int row, int column) { + /// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = row; 2 = column. return I.t("{0} (row {1}, column {2})", map.getName(), row + 1, column + 1); } static public String getMapTitle(PosterMap map, int index) { + /// The name of a map item given to a player, if splatter maps are not used. 0 = map name; 1 = index. return I.t("{0} (part {1})", map.getName(), index + 1); } - static public ItemStack createMapItem(short mapID, String text) + static public ItemStack createMapItem(int mapID, String text, boolean isMapPart) { - return new ItemStackBuilder(Material.MAP) - .data(mapID) + final ItemStack mapItem = new ItemStackBuilder(Material.FILLED_MAP) .title(text) .hideAttributes() .item(); + + final MapMeta meta = (MapMeta) mapItem.getItemMeta(); + meta.setMapId(mapID); + meta.setColor(isMapPart ? Color.LIME : Color.GREEN); + mapItem.setItemMeta(meta); + + return mapItem; } /** @@ -188,7 +216,7 @@ public class MapItemManager implements Listener throw new ArrayIndexOutOfBoundsException(); // Coherence } - return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName()); + return createMapItem(map.getMapsIDs()[0], map.getName(), false); } } @@ -218,7 +246,7 @@ public class MapItemManager implements Listener else { PosterMap poster = (PosterMap) map; - int index = poster.getIndex(item.getDurability()); + int index = poster.getIndex(MapManager.getMapIdFromItemStack(item)); if(poster.hasColumnData()) return getMapTitle(poster, poster.getRowAt(index), poster.getColumnAt(index)); @@ -228,19 +256,20 @@ public class MapItemManager implements Listener static private void onItemFramePlace(ItemFrame frame, Player player, PlayerInteractEntityEvent event) { + final ItemStack mapItem = player.getInventory().getItemInMainHand(); + if(frame.getItem().getType() != Material.AIR) return; - if(!MapManager.managesMap(player.getItemInHand())) return; + if(!MapManager.managesMap(mapItem)) return; event.setCancelled(true); - - if(SplatterMapManager.hasSplatterAttributes(player.getItemInHand())) + + if(SplatterMapManager.hasSplatterAttributes(mapItem)) { if(!SplatterMapManager.placeSplatterMap(frame, player)) return; } else { - ItemStack is = new ItemStack(Material.MAP, 1, player.getItemInHand().getDurability()); - frame.setItem(is); + frame.setItem(player.getInventory().getItemInMainHand()); } ItemUtils.consumeItem(player); @@ -249,7 +278,7 @@ public class MapItemManager implements Listener static private void onItemFrameRemove(ItemFrame frame, Player player, EntityDamageByEntityEvent event) { ItemStack item = frame.getItem(); - if(frame.getItem().getType() != Material.MAP) return; + if(frame.getItem().getType() != Material.FILLED_MAP) return; if(player.isSneaking()) { @@ -274,22 +303,19 @@ public class MapItemManager implements Listener } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) static public void onEntityDamage(EntityDamageByEntityEvent event) { - if(event.isCancelled()) return; if(!(event.getEntity() instanceof ItemFrame)) return; if(!(event.getDamager() instanceof Player)) return; onItemFrameRemove((ItemFrame)event.getEntity(), (Player)event.getDamager(), event); } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) static public void onEntityInteract(PlayerInteractEntityEvent event) { - if(event.isCancelled()) return; if(!(event.getRightClicked() instanceof ItemFrame)) return; - onItemFramePlace((ItemFrame)event.getRightClicked(), event.getPlayer(), event); } } diff --git a/src/main/java/fr/moribus/imageonmap/ui/PosterWall.java b/src/main/java/fr/moribus/imageonmap/ui/PosterWall.java index 8db4630..157cf9b 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/PosterWall.java +++ b/src/main/java/fr/moribus/imageonmap/ui/PosterWall.java @@ -70,7 +70,7 @@ public class PosterWall } - static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, short mapId) + static public ItemFrame[] getMatchingMapFrames(PosterMap map, FlatLocation location, int mapId) { int mapIndex = map.getIndex(mapId); int x = map.getColumnAt(mapIndex), y = map.getRowAt(mapIndex); @@ -111,7 +111,7 @@ public class PosterWall ItemFrame frame = (ItemFrame) entity; if(frame.getFacing() != location.getFacing()) continue; ItemStack item = frame.getItem(); - if(item.getType() != Material.MAP) continue; + if(item.getType() != Material.FILLED_MAP) continue; if(!map.managesMap(item)) continue; return frame; } diff --git a/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java b/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java index ba7b930..fc35b29 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java +++ b/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java @@ -18,21 +18,28 @@ package fr.moribus.imageonmap.ui; +import com.google.common.collect.ImmutableMap; import fr.moribus.imageonmap.image.MapInitEvent; import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.MapManager; import fr.moribus.imageonmap.map.PosterMap; -import fr.zcraft.zlib.components.gui.GuiUtils; +import fr.zcraft.zlib.components.attributes.Attributes; import fr.zcraft.zlib.components.i18n.I; -import fr.zcraft.zlib.tools.items.GlowEffect; +import fr.zcraft.zlib.components.nbt.NBTException; +import fr.zcraft.zlib.tools.PluginLogger; import fr.zcraft.zlib.tools.items.ItemStackBuilder; +import fr.zcraft.zlib.tools.reflection.NMSException; import fr.zcraft.zlib.tools.world.FlatLocation; import org.bukkit.ChatColor; +import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.MapMeta; + +import java.util.UUID; abstract public class SplatterMapManager { @@ -40,8 +47,7 @@ abstract public class SplatterMapManager static public ItemStack makeSplatterMap(PosterMap map) { - return new ItemStackBuilder(Material.MAP) - .data(map.getMapIdAt(0)) + final ItemStack splatter = new ItemStackBuilder(Material.FILLED_MAP) .title(ChatColor.GOLD, map.getName()).title(ChatColor.DARK_GRAY, " - ").title(ChatColor.GRAY, I.t("Splatter Map")) .loreLine(ChatColor.GRAY, map.getId()) .loreLine() @@ -52,17 +58,32 @@ abstract public class SplatterMapManager .loreLine() /// Title in a splatter map tooltip .loreLine(ChatColor.BLUE, I.t("How to use this?")) - .lore(GuiUtils.generateLore(ChatColor.GRAY + I.t("Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map."))) + .longLore(ChatColor.GRAY + I.t("Place empty item frames on a wall, enough to host the whole map. Then, right-click on the bottom-left frame with this map.")) .loreLine() - .lore(GuiUtils.generateLore(ChatColor.GRAY + I.t("Shift-click one of the placed maps to remove the whole poster in one shot."))) - .glow() + .longLore(ChatColor.GRAY + I.t("Shift-click one of the placed maps to remove the whole poster in one shot.")) .hideAttributes() - .item(); + .craftItem(); + + final MapMeta meta = (MapMeta) splatter.getItemMeta(); + meta.setMapId(map.getMapIdAt(0)); + meta.setColor(Color.GREEN); + splatter.setItemMeta(meta); + + try + { + Attributes.set(splatter, new Attribute()); + } + catch (NBTException | NMSException e) + { + PluginLogger.error("Unable to set Splatter Map attribute on item", e); + } + + return splatter; } static public boolean hasSplatterAttributes(ItemStack itemStack) { - return GlowEffect.hasGlow(itemStack); + return Attribute.hasAttribute(itemStack); } static public boolean isSplatterMap(ItemStack itemStack) @@ -86,10 +107,11 @@ abstract public class SplatterMapManager static public boolean placeSplatterMap(ItemFrame startFrame, Player player) { - ImageMap map = MapManager.getMap(player.getItemInHand()); - if(map == null || !(map instanceof PosterMap)) return false; + ImageMap map = MapManager.getMap(player.getInventory().getItemInMainHand()); + + if(!(map instanceof PosterMap)) return false; PosterMap poster = (PosterMap) map; - + FlatLocation startLocation = new FlatLocation(startFrame.getLocation(), startFrame.getFacing()); FlatLocation endLocation = startLocation.clone().add(poster.getColumnCount(), poster.getRowCount()); PosterWall wall = new PosterWall(); @@ -106,8 +128,8 @@ abstract public class SplatterMapManager int i = 0; for(ItemFrame frame : wall.frames) { - short id = poster.getMapIdAtReverseY(i); - frame.setItem(new ItemStack(Material.MAP, 1, id)); + int id = poster.getMapIdAtReverseY(i); + frame.setItem(new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem()); MapInitEvent.initMap(id); ++i; } @@ -117,12 +139,12 @@ abstract public class SplatterMapManager static public PosterMap removeSplatterMap(ItemFrame startFrame) { - ImageMap map = MapManager.getMap(startFrame.getItem()); - if(map == null || !(map instanceof PosterMap)) return null; + final ImageMap map = MapManager.getMap(startFrame.getItem()); + if(!(map instanceof PosterMap)) return null; PosterMap poster = (PosterMap) map; if(!poster.hasColumnData()) return null; FlatLocation loc = new FlatLocation(startFrame.getLocation(), startFrame.getFacing()); - ItemFrame[] matchingFrames = PosterWall.getMatchingMapFrames(poster, loc, startFrame.getItem().getDurability()); + ItemFrame[] matchingFrames = PosterWall.getMatchingMapFrames(poster, loc, MapManager.getMapIdFromItemStack(startFrame.getItem())); if(matchingFrames == null) return null; for(ItemFrame frame : matchingFrames) @@ -132,4 +154,29 @@ abstract public class SplatterMapManager return poster; } + + + static public class Attribute extends fr.zcraft.zlib.components.attributes.Attribute + { + static public final UUID SPLATTER_MAP_UUID = UUID.fromString("260ae1b3-4b24-40a0-a30d-67ad84b7bdb2"); + + Attribute() + { + setUUID(SPLATTER_MAP_UUID); + setCustomData("splatter-map"); + } + + static boolean hasAttribute(final ItemStack item) + { + try + { + return Attributes.get(item, SPLATTER_MAP_UUID) != null; + } + catch (NMSException | NBTException ex) + { + PluginLogger.warning("Error while retrieving SplatterMap Attribute data", ex); + return false; + } + } + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 17bd4fe..2dbc918 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,7 @@ name: ImageOnMap main: fr.moribus.imageonmap.ImageOnMap -version: 3.1 +version: "4.0" +api-version: "1.13" commands: tomap: