diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java index 36a2a84..d651e78 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/NewCommand.java @@ -123,79 +123,74 @@ public class NewCommand extends IoMCommand { throwInvalidArgument(I.t("Invalid URL.")); return; } - + boolean isPlayer = sender != null; // TODO Add a per-player toggle for the GUI. - if (args.length >= 2) { - ImageRendererExecutor.renderAndNotify(url, scaling, player.getUniqueId(), width, height); - } else { + if (args.length < 2 && isPlayer) { Gui.open(player, new RenderGui(url)); - } - //I try to test if the gui is run correctly - //keep the following as a fallback and for cmd made by console - - /* - if (args.length >= 2) { - if (args.length >= 3) { - try { - if (args.length >= 4) { - width = Integer.parseInt(args[2]); - height = Integer.parseInt(args[3]); - } else { - String[] size; - if (args[2].contains("*") && !args[2].contains("x")) { - size = args[2].split("\\*"); - width = Integer.parseInt(size[0]); - height = Integer.parseInt(size[1]); - } - if (!args[2].contains("*") && args[2].contains("x")) { - size = args[2].split("x"); - width = Integer.parseInt(size[0]); - height = Integer.parseInt(size[1]); - } - } - } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { - throwInvalidArgument(I.t("resize dimension as to be in format or or .")); - return; - } - } - scaling = resizeMode(); - } - if (width < 0 || height < 0) { - throwInvalidArgument(I.t("You need to specify a valid size. e.g. resize 4 5")); - return; - } - try { - ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Rendering...")); - ImageRendererExecutor - .render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback() { - @Override - public void finished(ImageMap result) { - ActionBar.removeMessage(player); - MessageSender - .sendActionBarMessage(player, ChatColor.DARK_GREEN + I.t("Rendering finished!")); - - if (result.give(player) - && (result instanceof PosterMap && !((PosterMap) result).hasColumnData())) { - info(I.t("The rendered map was too big to fit in your inventory.")); - info(I.t("Use '/maptool getremaining' to get the remaining maps.")); + } else { + //ImageRendererExecutor.renderAndNotify(url, scaling, player.getUniqueId(), width, height); + if (args.length >= 2) { + if (args.length >= 3) { + try { + if (args.length >= 4) { + width = Integer.parseInt(args[2]); + height = Integer.parseInt(args[3]); + } else { + String[] size; + if (args[2].contains("*") && !args[2].contains("x")) { + size = args[2].split("\\*"); + width = Integer.parseInt(size[0]); + height = Integer.parseInt(size[1]); + } + if (!args[2].contains("*") && args[2].contains("x")) { + size = args[2].split("x"); + width = Integer.parseInt(size[0]); + height = Integer.parseInt(size[1]); } } + } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { + throwInvalidArgument(I.t("resize dimension as to be in format or or .")); + return; + } + } + scaling = resizeMode(); + } + if (width < 0 || height < 0) { + throwInvalidArgument(I.t("You need to specify a valid size. e.g. resize 4 5")); + return; + } + try { + ActionBar.sendPermanentMessage(player, ChatColor.DARK_GREEN + I.t("Rendering...")); + ImageRendererExecutor + .render(url, scaling, player.getUniqueId(), width, height, new WorkerCallback() { + @Override + public void finished(ImageMap result) { + ActionBar.removeMessage(player); + MessageSender + .sendActionBarMessage(player, + ChatColor.DARK_GREEN + I.t("Rendering finished!")); - @Override - public void errored(Throwable exception) { - player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage())); + if (result.give(player) + && (result instanceof PosterMap && !((PosterMap) result).hasColumnData())) { + info(I.t("The rendered map was too big to fit in your inventory.")); + info(I.t("Use '/maptool getremaining' to get the remaining maps.")); + } + } - PluginLogger.warning("Rendering from {0} failed: {1}: {2}", - player.getName(), - exception.getClass().getCanonicalName(), - exception.getMessage()); - } - }); - } finally { - ActionBar.removeMessage(player); + @Override + public void errored(Throwable exception) { + player.sendMessage(I.t("{ce}Map rendering failed: {0}", exception.getMessage())); + + PluginLogger.warning("Rendering from {0} failed: {1}: {2}", + player.getName(), + exception.getClass().getCanonicalName(), + exception.getMessage()); + } + }); + } finally { + ActionBar.removeMessage(player); + } } - */ - } @Override diff --git a/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java b/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java index fb7ff80..b196efb 100644 --- a/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java +++ b/src/main/java/fr/moribus/imageonmap/gui/MapDetailGui.java @@ -39,7 +39,6 @@ package fr.moribus.imageonmap.gui; import fr.moribus.imageonmap.Permissions; import fr.moribus.imageonmap.map.ImageMap; import fr.moribus.imageonmap.map.PosterMap; -import fr.moribus.imageonmap.map.SingleMap; import fr.moribus.imageonmap.ui.MapItemManager; import fr.zcraft.quartzlib.components.gui.ExplorerGui; import fr.zcraft.quartzlib.components.gui.Gui; @@ -105,9 +104,7 @@ public class MapDetailGui extends ExplorerGui { return null; } - if (map instanceof SingleMap) { - return MapItemManager.createMapItem((SingleMap) map, true); - } else if (map instanceof PosterMap) { + if (map instanceof PosterMap) { return MapItemManager.createMapItem((PosterMap) map, x, y); } @@ -124,15 +121,11 @@ public class MapDetailGui extends ExplorerGui { return MapItemManager.createMapItem(poster, poster.getIndex(mapId)); } - @Override - protected ItemStack getEmptyViewItem() { - if (map instanceof SingleMap) { - return getViewItem(0, 0); - } else { + /* @Override + protected ItemStack getEmptyViewItem() { return super.getEmptyViewItem(); } - } - + */ @Override protected void onUpdate() { /// Title of the map details GUI diff --git a/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java b/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java index 5ee374b..996a5a2 100644 --- a/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java +++ b/src/main/java/fr/moribus/imageonmap/gui/MapListGui.java @@ -41,7 +41,6 @@ import fr.moribus.imageonmap.PluginConfiguration; 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.moribus.imageonmap.ui.MapItemManager; import fr.moribus.imageonmap.ui.SplatterMapManager; import fr.zcraft.quartzlib.components.gui.ExplorerGui; @@ -72,19 +71,14 @@ public class MapListGui extends ExplorerGui { @Override protected ItemStack getViewItem(ImageMap map) { String mapDescription; - if (map instanceof SingleMap) { - /// Displayed subtitle description of a single map on the list GUI - mapDescription = I.tl(getPlayerLocale(), "{white}Single map"); + PosterMap poster = (PosterMap) map; + if (poster.hasColumnData()) { + /// Displayed subtitle description of a poster map on the list GUI (columns × rows in english) + mapDescription = I.tl(getPlayerLocale(), "{white}Poster map ({0} × {1})", poster.getColumnCount(), + poster.getRowCount()); } else { - PosterMap poster = (PosterMap) map; - if (poster.hasColumnData()) { - /// Displayed subtitle description of a poster map on the list GUI (columns × rows in english) - mapDescription = I.tl(getPlayerLocale(), "{white}Poster map ({0} × {1})", poster.getColumnCount(), - poster.getRowCount()); - } else { - /// Displayed subtitle description of a poster map without column data on the list GUI - mapDescription = I.tl(getPlayerLocale(), "{white}Poster map ({0} parts)", poster.getMapCount()); - } + /// Displayed subtitle description of a poster map without column data on the list GUI + mapDescription = I.tl(getPlayerLocale(), "{white}Poster map ({0} parts)", poster.getMapCount()); } ItemStackBuilder builder = new ItemStackBuilder(Material.FILLED_MAP) @@ -147,9 +141,7 @@ public class MapListGui extends ExplorerGui { return null; } - if (map instanceof SingleMap) { - return MapItemManager.createMapItem(map.getMapsIDs()[0], map.getName(), false, true); - } else if (map instanceof PosterMap) { + if (map instanceof PosterMap) { PosterMap poster = (PosterMap) map; if (poster.hasColumnData()) { diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java index 50ea7fa..a3fa03b 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java @@ -65,7 +65,6 @@ import org.bukkit.ChatColor; import org.bukkit.entity.Player; - @WorkerAttributes(name = "Image Renderer", queriesMainThread = true) public class ImageRendererExecutor extends Worker { public static void renderAndNotify(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, @@ -189,14 +188,10 @@ public class ImageRendererExecutor extends Worker { // Limits are in place and the player does NOT have rights to avoid them. checkSizeLimit(playerUUID, image); final BufferedImage resizedImage; - if (scaling != ImageUtils.ScalingType.NONE && height <= 1 && width <= 1) { - resizedImage = scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height); - image.flush();//Safe to free - return renderSingle(resizedImage, playerUUID); - } - resizedImage = - scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height); + + resizedImage = scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height); image.flush();//Safe to free + return renderPoster(resizedImage, playerUUID); } }, callback); @@ -249,27 +244,6 @@ public class ImageRendererExecutor extends Worker { }); } - private static ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable { - MapManager.checkMapLimit(1, playerUUID); - final Future futureMapID = submitToMainThread(new Callable() { - @Override - public Integer call() throws Exception { - return MapManager.getNewMapsIds(1)[0]; - } - }); - - final int mapID = futureMapID.get(); - ImageIOExecutor.saveImage(mapID, image); - submitToMainThread(new Callable() { - @Override - public Void call() throws Exception { - Renderer.installRenderer(image, mapID); - return null; - } - }); - return MapManager.createMap(playerUUID, mapID); - } - private static ImageMap renderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable { final PosterImage poster = new PosterImage(image); final int mapCount = poster.getImagesCount(); diff --git a/src/main/java/fr/moribus/imageonmap/map/ImageMap.java b/src/main/java/fr/moribus/imageonmap/map/ImageMap.java index 54a74e8..8f53249 100644 --- a/src/main/java/fr/moribus/imageonmap/map/ImageMap.java +++ b/src/main/java/fr/moribus/imageonmap/map/ImageMap.java @@ -91,7 +91,7 @@ public abstract class ImageMap implements ConfigurationSerializable { } public static ImageMap fromConfig(Map map, UUID userUUID) throws InvalidConfigurationException { - Type mapType; + Type mapType;//TODO refactor this try { mapType = Type.valueOf((String) map.get("type")); } catch (ClassCastException ex) { @@ -100,7 +100,6 @@ public abstract class ImageMap implements ConfigurationSerializable { switch (mapType) { case SINGLE: - return new SingleMap(map, userUUID); case POSTER: return new PosterMap(map, userUUID); default: diff --git a/src/main/java/fr/moribus/imageonmap/map/MapManager.java b/src/main/java/fr/moribus/imageonmap/map/MapManager.java index 22db80f..1207fd2 100644 --- a/src/main/java/fr/moribus/imageonmap/map/MapManager.java +++ b/src/main/java/fr/moribus/imageonmap/map/MapManager.java @@ -102,8 +102,10 @@ public abstract class MapManager { } public static ImageMap createMap(UUID playerUUID, int mapID) throws MapManagerException { - ImageMap newMap = new SingleMap(playerUUID, mapID); - addMap(newMap); + //ImageMap newMap = new SingleMap(playerUUID, mapID); + int[] ids = new int[] {mapID}; + ImageMap newMap = new PosterMap(playerUUID, ids, 1, 1); + addMap(newMap);//TODO refactor this return newMap; } @@ -111,7 +113,8 @@ public abstract class MapManager { ImageMap newMap; if (image.getImagesCount() == 1) { - newMap = new SingleMap(playerUUID, mapsIDs[0]); + newMap = new PosterMap(playerUUID, mapsIDs, 1, 1);//TODO refactor this + //newMap = new SingleMap(playerUUID, mapsIDs[0]); } else { newMap = new PosterMap(playerUUID, mapsIDs, image.getColumns(), image.getLines()); } diff --git a/src/main/java/fr/moribus/imageonmap/map/SingleMap.java b/src/main/java/fr/moribus/imageonmap/map/SingleMap.java deleted file mode 100644 index adbaeb1..0000000 --- a/src/main/java/fr/moribus/imageonmap/map/SingleMap.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright or © or Copr. Moribus (2013) - * Copyright or © or Copr. ProkopyL (2015) - * Copyright or © or Copr. Amaury Carrade (2016 – 2022) - * Copyright or © or Copr. Vlammar (2019 – 2022) - * - * This software is a computer program whose purpose is to allow insertion of - * custom images in a Minecraft world. - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ - -package fr.moribus.imageonmap.map; - -import java.util.Map; -import java.util.UUID; -import org.bukkit.configuration.InvalidConfigurationException; - -public class SingleMap extends ImageMap { - protected final int mapID; - - public SingleMap(UUID ownerUUID, int mapID, String id, String name) { - super(ownerUUID, Type.SINGLE, id, name); - this.mapID = mapID; - } - - public SingleMap(UUID ownerUUID, int mapID) { - this(ownerUUID, mapID, null, null); - } - - public SingleMap(Map map, UUID userUUID) throws InvalidConfigurationException { - super(map, userUUID, Type.SINGLE); - mapID = getFieldValue(map, "mapID"); - } - - @Override - public int[] getMapsIDs() { - return new int[] {mapID}; - } - - @Override - public boolean managesMap(int mapID) { - return this.mapID == mapID; - } - - /* ====== Serialization methods ====== */ - - @Override - public int getMapCount() { - return 1; - } - - @Override - protected void postSerialize(Map map) { - map.put("mapID", mapID); - } - -} diff --git a/src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java b/src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java index d06b1ad..f4f45c8 100644 --- a/src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/migration/MigratorExecutor.java @@ -36,7 +36,6 @@ package fr.moribus.imageonmap.migration; -import fr.moribus.imageonmap.ImageOnMap; import fr.zcraft.quartzlib.components.i18n.I; import fr.zcraft.quartzlib.tools.PluginLogger; @@ -49,7 +48,7 @@ public class MigratorExecutor { PluginLogger.error(I.t("Migration is already running.")); return; } - migratorThread = new Thread(new V3Migrator(ImageOnMap.getPlugin()), "ImageOnMap-Migration"); + //migratorThread = new Thread(new V3Migrator(ImageOnMap.getPlugin()), "ImageOnMap-Migration"); migratorThread.start(); } diff --git a/src/main/java/fr/moribus/imageonmap/migration/OldSavedMap.java b/src/main/java/fr/moribus/imageonmap/migration/OldSavedMap.java deleted file mode 100644 index c1df51c..0000000 --- a/src/main/java/fr/moribus/imageonmap/migration/OldSavedMap.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright or © or Copr. Moribus (2013) - * Copyright or © or Copr. ProkopyL (2015) - * Copyright or © or Copr. Amaury Carrade (2016 – 2022) - * Copyright or © or Copr. Vlammar (2019 – 2022) - * - * This software is a computer program whose purpose is to allow insertion of - * custom images in a Minecraft world. - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ - -package fr.moribus.imageonmap.migration; - -import fr.moribus.imageonmap.map.ImageMap; -import fr.moribus.imageonmap.map.MapManager; -import fr.moribus.imageonmap.map.SingleMap; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import org.bukkit.configuration.Configuration; -import org.bukkit.configuration.InvalidConfigurationException; - -class OldSavedMap { - private final short mapId; - private final String mapName; - private final String userName; - - public OldSavedMap(Object rawData) throws InvalidConfigurationException { - List data; - try { - data = (List) rawData; - } catch (ClassCastException ex) { - throw new InvalidConfigurationException("Invalid map data : " + ex.getMessage()); - } - - if (data.size() < 3) { - throw new InvalidConfigurationException("Map data too short (given : " + data.size() + ", expected 3)"); - } - try { - mapId = Short.parseShort(data.get(0)); - } catch (NumberFormatException ex) { - throw new InvalidConfigurationException("Invalid map ID : " + ex.getMessage()); - } - - mapName = data.get(1); - userName = data.get(2); - } - - public ImageMap toImageMap(UUID userUUID) { - return new SingleMap(userUUID, mapId, null, mapName); - } - - public void serialize(Configuration configuration) { - ArrayList data = new ArrayList<>(); - data.add(Short.toString(mapId)); - data.add(mapName); - data.add(userName); - configuration.set(mapName, data); - } - - public boolean isMapValid() { - return MapManager.mapIdExists(mapId); - } - - public short getMapId() { - return mapId; - } - - public String getUserName() { - return userName; - } -} diff --git a/src/main/java/fr/moribus/imageonmap/migration/OldSavedPoster.java b/src/main/java/fr/moribus/imageonmap/migration/OldSavedPoster.java deleted file mode 100644 index 6049b9c..0000000 --- a/src/main/java/fr/moribus/imageonmap/migration/OldSavedPoster.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright or © or Copr. Moribus (2013) - * Copyright or © or Copr. ProkopyL (2015) - * Copyright or © or Copr. Amaury Carrade (2016 – 2022) - * Copyright or © or Copr. Vlammar (2019 – 2022) - * - * This software is a computer program whose purpose is to allow insertion of - * custom images in a Minecraft world. - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ - -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.Arrays; -import java.util.List; -import java.util.UUID; -import org.bukkit.configuration.Configuration; -import org.bukkit.configuration.InvalidConfigurationException; - -class OldSavedPoster { - private final String userName; - private final String posterName; - private final short[] mapsIds; - - public OldSavedPoster(Object rawData, String key) throws InvalidConfigurationException { - posterName = key; - List data; - try { - data = (List) rawData; - } catch (ClassCastException ex) { - throw new InvalidConfigurationException("Invalid map data : " + ex.getMessage()); - } - - if (data.size() < 2) { - throw new InvalidConfigurationException( - "Poster data too short (given : " + data.size() + ", expected at least 2)"); - } - userName = data.get(0); - mapsIds = new short[data.size() - 1]; - - for (int i = 1, c = data.size(); i < c; i++) { - try { - mapsIds[i - 1] = Short.parseShort(data.get(i)); - } catch (NumberFormatException ex) { - throw new InvalidConfigurationException("Invalid map ID : " + ex.getMessage()); - } - } - } - - public boolean contains(OldSavedMap map) { - short mapId = map.getMapId(); - - for (short mapsId : mapsIds) { - if (mapsId == mapId) { - return true; - } - } - - return false; - } - - public ImageMap toImageMap(UUID userUUID) { - // 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) { - ArrayList data = new ArrayList<>(); - data.add(userName); - - for (short mapId : mapsIds) { - data.add(Short.toString(mapId)); - } - - configuration.set(posterName, data); - - } - - public boolean isMapValid() { - for (short mapId : mapsIds) { - if (!MapManager.mapIdExists(mapId)) { - return false; - } - } - return true; - } - - public String getUserName() { - return userName; - } - - public short[] getMapsIds() { - return mapsIds; - } -} diff --git a/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java b/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java deleted file mode 100644 index 0305cab..0000000 --- a/src/main/java/fr/moribus/imageonmap/migration/V3Migrator.java +++ /dev/null @@ -1,619 +0,0 @@ -/* - * Copyright or © or Copr. Moribus (2013) - * Copyright or © or Copr. ProkopyL (2015) - * Copyright or © or Copr. Amaury Carrade (2016 – 2022) - * Copyright or © or Copr. Vlammar (2019 – 2022) - * - * This software is a computer program whose purpose is to allow insertion of - * custom images in a Minecraft world. - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - */ - -package fr.moribus.imageonmap.migration; - -import fr.moribus.imageonmap.ImageOnMap; -import fr.moribus.imageonmap.map.MapManager; -import fr.zcraft.quartzlib.components.i18n.I; -import fr.zcraft.quartzlib.tools.PluginLogger; -import fr.zcraft.quartzlib.tools.mojang.UUIDFetcher; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -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 java.util.stream.Collectors; -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; -import org.bukkit.plugin.Plugin; - -/** - * This class represents and executes the ImageOnMap v3.x migration process - */ -public class V3Migrator implements Runnable { - /** - * The name of the former images directory - */ - private static final String OLD_IMAGES_DIRECTORY_NAME = "Image"; - - /** - * The name of the former file that contained all the maps definitions (including posters) - */ - private static final String OLD_MAPS_FILE_NAME = "map.yml"; - - /** - * The name of the former file that contained all the posters definitions - */ - private static final String OLD_POSTERS_FILE_NAME = "poster.yml"; - - /** - * The name of the backup directory that will contain the pre-v3 files that - * were present before the migration started - */ - private static final String BACKUPS_PREV3_DIRECTORY_NAME = "backups_pre-v3"; - - /** - * The name of the backup directory that will contain the post-v3 files that - * were present before the migration started - */ - private static final String BACKUPS_POSTV3_DIRECTORY_NAME = "backups_post-v3"; - /** - * The plugin that is running the migration - */ - private final ImageOnMap plugin; - /** - * The backup directory that will contain the pre-v3 files that - * were present before the migration started - */ - private final File backupsPrev3Directory; - /** - * The backup directory that will contain the post-v3 files that - * were present before the migration started - */ - private final File backupsPostv3Directory; - /** - * The list of all the posters to migrate - */ - private final ArrayDeque postersToMigrate; - /** - * The list of all the single maps to migrate - */ - private final ArrayDeque mapsToMigrate; - /** - * The set of all the user names to retreive the UUID from Mojang - */ - private final HashSet userNamesToFetch; - /** - * The former file that contained all the posters definitions - */ - private File oldPostersFile; - /** - * The former file that contained all the maps definitions (including posters) - */ - private File oldMapsFile; - /** - * The map of all the usernames and their corresponding UUIDs - */ - private Map usersUUIDs; - /** - * Defines if the migration process is currently running - */ - private boolean isRunning = false; - - public V3Migrator(ImageOnMap plugin) { - this.plugin = plugin; - - File dataFolder = plugin.getDataFolder(); - - oldPostersFile = new File(dataFolder, OLD_POSTERS_FILE_NAME); - oldMapsFile = new File(dataFolder, OLD_MAPS_FILE_NAME); - - backupsPrev3Directory = new File(dataFolder, BACKUPS_PREV3_DIRECTORY_NAME); - backupsPostv3Directory = new File(dataFolder, BACKUPS_POSTV3_DIRECTORY_NAME); - - postersToMigrate = new ArrayDeque<>(); - mapsToMigrate = new ArrayDeque<>(); - userNamesToFetch = new HashSet<>(); - } - - /** - * Returns the former images directory of a given plugin - * - * @param plugin The plugin. - * @return the corresponding 'Image' directory - */ - public static File getOldImagesDirectory(Plugin plugin) { - return new File(plugin.getDataFolder(), OLD_IMAGES_DIRECTORY_NAME); - } - - /** - * Makes a standard file copy, and checks the integrity of the destination - * file after the copy - * - * @param sourceFile The file to copy - * @param destinationFile The destination file - * @throws IOException If the copy failed, if the integrity check failed, or if the destination file already exists - */ - private static void verifiedBackupCopy(File sourceFile, File destinationFile) throws IOException { - if (destinationFile.exists()) { - throw new IOException( - "Backup copy failed : destination file (" + destinationFile.getName() + ") already exists."); - } - - long sourceSize = sourceFile.length(); - String sourceCheckSum = fileCheckSum(sourceFile, "SHA1"); - - Path sourcePath = Paths.get(sourceFile.getAbsolutePath()); - Path destinationPath = Paths.get(destinationFile.getAbsolutePath()); - Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING); - - long destinationSize = destinationFile.length(); - String destinationCheckSum = fileCheckSum(destinationFile, "SHA1"); - - if (sourceSize != destinationSize || !sourceCheckSum.equals(destinationCheckSum)) { - throw new IOException("Backup copy failed : source and destination files (" - + sourceFile.getName() - + ") differ after copy."); - } - - } - - /* ****** Actions ***** */ - - /** - * Calculates the checksum of a given file - * - * @param file The file to calculate the checksum of - * @param algorithmName The name of the algorithm to use - * @return The resulting checksum in hexadecimal format - * @throws IOException - **/ - private static String fileCheckSum(File file, String algorithmName) throws IOException { - MessageDigest instance; - try { - instance = MessageDigest.getInstance(algorithmName); - } catch (NoSuchAlgorithmException ex) { - throw new IOException( - "Could not check file integrity because of NoSuchAlgorithmException : " + ex.getMessage()); - } - - FileInputStream inputStream = new FileInputStream(file); - - byte[] data = new byte[1024]; - int read = 0; - - while ((read = inputStream.read(data)) != -1) { - instance.update(data); - } - - byte[] hashBytes = instance.digest(); - - StringBuilder buffer = new StringBuilder(); - char hexChar; - for (int i = 0; i < hashBytes.length; i++) { - hexChar = Integer.toHexString((hashBytes[i] & 0xff) + 0x100).charAt(0); - buffer.append(hexChar); - } - - return buffer.toString(); - } - - /** - * Executes the full migration - */ - private void migrate() { - try { - if (!spotFilesToMigrate()) { - return; - } - if (checkForExistingBackups()) { - return; - } - if (!loadOldFiles()) { - return; - } - backupMapData(); - fetchUUIDs(); - if (!fetchMissingUUIDs()) { - return; - } - } catch (Exception ex) { - PluginLogger.error(I.t("Error while preparing migration")); - PluginLogger.error(I.t("Aborting migration. No change has been made."), ex); - return; - } - - try { - mergeMapData(); - saveChanges(); - cleanup(); - } catch (Exception ex) { - PluginLogger.error(I.t("Error while migrating"), ex); - PluginLogger.error(I.t("Aborting migration. Some changes may already have been made.")); - PluginLogger.error(I.t( - "Before trying to migrate again, you must recover player files from the backups," - + " and then move the backups away from the plugin directory to avoid overwriting them.")); - } - } - - /** - * Checks if there is any of the former files to be migrated - * - * @return true if any former map or poster file exists, false otherwise - */ - private boolean spotFilesToMigrate() { - PluginLogger.info(I.t("Looking for configuration files to migrate...")); - - if (!oldPostersFile.exists()) { - oldPostersFile = null; - } else { - PluginLogger.info(I.t("Detected former posters file {0}", OLD_POSTERS_FILE_NAME)); - } - - if (!oldMapsFile.exists()) { - oldMapsFile = null; - } else { - PluginLogger.info(I.t("Detected former maps file {0}", OLD_MAPS_FILE_NAME)); - } - - if (oldPostersFile == null && oldMapsFile == null) { - PluginLogger.info(I.t("There is nothing to migrate. Stopping.")); - return false; - } else { - PluginLogger.info(I.t("Done.")); - return true; - } - } - - /** - * Checks if any existing backup directories exists - * - * @return true if a non-empty backup directory exists, false otherwise - */ - private boolean checkForExistingBackups() { - if ((backupsPrev3Directory.exists() && backupsPrev3Directory.list().length == 0) - || (backupsPostv3Directory.exists() && backupsPostv3Directory.list().length == 0)) { - PluginLogger.error(I.t("Backup directories already exists.")); - PluginLogger.error(I.t("This means that a migration has already been done," - + " or may not have ended well.")); - PluginLogger.error(I.t( - "To start a new migration," - + " you must move away the backup directories so they are not overwritten.")); - - return true; - } - return false; - } - - /** - * Creates backups of the former map files, and of the existing map stores - * - * @throws IOException - **/ - private void backupMapData() throws IOException { - PluginLogger.info(I.t("Backing up map data before migrating...")); - - if (!backupsPrev3Directory.exists()) { - backupsPrev3Directory.mkdirs(); - } - if (!backupsPostv3Directory.exists()) { - backupsPostv3Directory.mkdirs(); - } - - if (oldMapsFile != null && oldMapsFile.exists()) { - File oldMapsFileBackup = new File(backupsPrev3Directory, oldMapsFile.getName()); - verifiedBackupCopy(oldMapsFile, oldMapsFileBackup); - } - - if (oldPostersFile != null && oldPostersFile.exists()) { - File oldPostersFileBackup = new File(backupsPrev3Directory, oldPostersFile.getName()); - verifiedBackupCopy(oldPostersFile, oldPostersFileBackup); - } - - File backupFile; - for (File mapFile : plugin.getMapsDirectory().listFiles()) { - backupFile = new File(backupsPostv3Directory, mapFile.getName()); - verifiedBackupCopy(mapFile, backupFile); - } - - PluginLogger.info(I.t("Backup complete.")); - } - - /** - * An utility function to check if a map is actually part of a loaded poster - * - * @param map The single map. - * @return true if the map is part of a poster, false otherwise - */ - private boolean posterContains(OldSavedMap map) { - for (OldSavedPoster poster : postersToMigrate) { - if (poster.contains(map)) { - return true; - } - } - - return false; - } - - /** - * Loads the former files into the corresponding arrays - * Also fetches the names of all the users that have maps - * - * @return true if any of the files contained readable map data, false otherwise - */ - private boolean loadOldFiles() { - if (oldPostersFile != null) { - FileConfiguration oldPosters = YamlConfiguration.loadConfiguration(oldPostersFile); - - OldSavedPoster oldPoster; - for (String key : oldPosters.getKeys(false)) { - if ("IdCount".equals(key)) { - continue; - } - try { - oldPoster = new OldSavedPoster(oldPosters.get(key), key); - postersToMigrate.add(oldPoster); - if (!userNamesToFetch.contains(oldPoster.getUserName())) { - userNamesToFetch.add(oldPoster.getUserName()); - } - } catch (InvalidConfigurationException ex) { - PluginLogger.warning("Could not read poster data for key {0}", ex, key); - } - } - } - - if (oldMapsFile != null) { - FileConfiguration oldMaps = YamlConfiguration.loadConfiguration(oldMapsFile); - OldSavedMap oldMap; - - for (String key : oldMaps.getKeys(false)) { - try { - if ("IdCount".equals(key)) { - continue; - } - oldMap = new OldSavedMap(oldMaps.get(key)); - - if (!posterContains(oldMap)) { - mapsToMigrate.add(oldMap); - } - - if (!userNamesToFetch.contains(oldMap.getUserName())) { - userNamesToFetch.add(oldMap.getUserName()); - } - } catch (InvalidConfigurationException ex) { - PluginLogger.warning("Could not read poster data for key '{0}'", ex, key); - } - } - } - - return (postersToMigrate.size() > 0) || (mapsToMigrate.size() > 0); - } - - /** - * Fetches all the needed UUIDs from Mojang's UUID conversion service - * - * @throws IOException if the fetcher could not connect to Mojang's servers - * @throws InterruptedException if the thread was interrupted while fetching UUIDs - */ - private void fetchUUIDs() throws IOException, InterruptedException { - PluginLogger.info(I.t("Fetching UUIDs from Mojang...")); - try { - usersUUIDs = UUIDFetcher.fetch(new ArrayList(userNamesToFetch)); - } catch (IOException ex) { - PluginLogger.error(I.t("An error occurred while fetching the UUIDs from Mojang"), ex); - throw ex; - } catch (InterruptedException ex) { - PluginLogger.error(I.t("The migration worker has been interrupted"), ex); - throw ex; - } - PluginLogger.info(I.tn("Fetching done. {0} UUID have been retrieved.", - "Fetching done. {0} UUIDs have been retrieved.", usersUUIDs.size())); - } - - /** - * Fetches the UUIDs that could not be retrieved via Mojang's standard API - * - * @return true if at least one UUID has been retrieved, false otherwise - */ - private boolean fetchMissingUUIDs() throws IOException, InterruptedException { - if (usersUUIDs.size() == userNamesToFetch.size()) { - return true; - } - int remainingUsersCount = userNamesToFetch.size() - usersUUIDs.size(); - PluginLogger.info(I.tn("Mojang did not find UUIDs for {0} player at the current time.", - "Mojang did not find UUIDs for {0} players at the current time.", remainingUsersCount)); - PluginLogger.info(I.t("The Mojang servers limit requests rate at one per second, this may take some time...")); - - try { - UUIDFetcher.fetchRemaining(userNamesToFetch, usersUUIDs); - } catch (IOException ex) { - PluginLogger.error(I.t("An error occurred while fetching the UUIDs from Mojang")); - throw ex; - } catch (InterruptedException ex) { - PluginLogger.error(I.t("The migration worker has been interrupted")); - throw ex; - } - - if (usersUUIDs.size() != userNamesToFetch.size()) { - PluginLogger.warning(I.tn("Mojang did not find player data for {0} player", - "Mojang did not find player data for {0} players", - userNamesToFetch.size() - usersUUIDs.size())); - PluginLogger.warning(I.t("The following players do not exist or do not have paid accounts :")); - - String missingUsersList = ""; - - for (String user : userNamesToFetch) { - if (!usersUUIDs.containsKey(user)) { - missingUsersList += user + ", "; - } - } - missingUsersList = missingUsersList.substring(0, missingUsersList.length()); - - PluginLogger.info(missingUsersList); - } - - if (usersUUIDs.size() <= 0) { - PluginLogger.info(I.t("Mojang could not find any of the registered players.")); - PluginLogger.info(I.t("There is nothing to migrate. Stopping.")); - return false; - } - - return true; - } - - private void mergeMapData() { - PluginLogger.info(I.t("Merging map data...")); - - ArrayDeque remainingMaps = new ArrayDeque<>(); - ArrayDeque remainingPosters = new ArrayDeque<>(); - - ArrayDeque missingMapIds = new ArrayDeque<>(); - - UUID playerUUID; - OldSavedMap map; - while (!mapsToMigrate.isEmpty()) { - map = mapsToMigrate.pop(); - playerUUID = usersUUIDs.get(map.getUserName()); - if (playerUUID == null) { - remainingMaps.add(map); - } else if (!map.isMapValid()) { - missingMapIds.add((int) map.getMapId()); - } else { - MapManager.insertMap(map.toImageMap(playerUUID)); - } - } - mapsToMigrate.addAll(remainingMaps); - - OldSavedPoster poster; - while (!postersToMigrate.isEmpty()) { - poster = postersToMigrate.pop(); - playerUUID = usersUUIDs.get(poster.getUserName()); - if (playerUUID == null) { - remainingPosters.add(poster); - } else if (!poster.isMapValid()) { - missingMapIds.addAll(Arrays.stream(ArrayUtils.toObject(poster.getMapsIds())).map(id -> (int) id) - .collect(Collectors.toList())); - } else { - MapManager.insertMap(poster.toImageMap(playerUUID)); - } - } - postersToMigrate.addAll(remainingPosters); - - if (!missingMapIds.isEmpty()) { - PluginLogger.warning(I.tn("{0} registered minecraft map is missing from the save.", - "{0} registered minecraft maps are missing from the save.", missingMapIds.size())); - PluginLogger.warning( - I.t("These maps will not be migrated," - + " but this could mean the save has been altered or corrupted.")); - PluginLogger.warning(I.t("The following maps are missing : {0} ", - StringUtils.join(missingMapIds, ','))); - } - } - - /* ****** Utils ***** */ - - private void saveChanges() { - PluginLogger.info(I.t("Saving changes...")); - MapManager.save(); - } - - private void cleanup() throws IOException { - PluginLogger.info(I.t("Cleaning up old data files...")); - - //Cleaning maps file - if (oldMapsFile != null) { - if (mapsToMigrate.isEmpty()) { - PluginLogger.info(I.t("Deleting old map data file...")); - oldMapsFile.delete(); - } else { - PluginLogger.info(I.tn("{0} map could not be migrated.", "{0} maps could not be migrated.", - mapsToMigrate.size())); - YamlConfiguration mapConfig = new YamlConfiguration(); - mapConfig.set("IdCount", mapsToMigrate.size()); - - for (OldSavedMap map : mapsToMigrate) { - map.serialize(mapConfig); - } - - mapConfig.save(oldMapsFile); - } - } - - //Cleaning posters file - if (oldPostersFile != null) { - if (postersToMigrate.isEmpty()) { - PluginLogger.info(I.t("Deleting old poster data file...")); - oldPostersFile.delete(); - } else { - PluginLogger.info(I.tn("{0} poster could not be migrated.", "{0} posters could not be migrated.", - postersToMigrate.size())); - YamlConfiguration posterConfig = new YamlConfiguration(); - posterConfig.set("IdCount", postersToMigrate.size()); - - for (OldSavedPoster poster : postersToMigrate) { - poster.serialize(posterConfig); - } - - posterConfig.save(oldPostersFile); - } - } - - PluginLogger.info(I.t("Data that has not been migrated will be kept in the old data files.")); - } - - public synchronized boolean isRunning() { - return isRunning; - } - - private synchronized void setRunning(boolean running) { - this.isRunning = running; - } - - /** - * Executes the full migration, and defines the running status of the migration - */ - @Override - public void run() { - setRunning(true); - migrate(); - setRunning(false); - } - -} diff --git a/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java b/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java index c5c82eb..66d25f8 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java +++ b/src/main/java/fr/moribus/imageonmap/ui/MapItemManager.java @@ -40,7 +40,6 @@ import fr.moribus.imageonmap.Permissions; 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.quartzlib.components.i18n.I; import fr.zcraft.quartzlib.core.QuartzLib; import fr.zcraft.quartzlib.tools.items.ItemStackBuilder; @@ -88,15 +87,10 @@ public class MapItemManager implements Listener { public static boolean give(Player player, ImageMap map) { if (map instanceof PosterMap) { return give(player, (PosterMap) map); - } else if (map instanceof SingleMap) { - return give(player, (SingleMap) map); } return false; } - public static boolean give(Player player, SingleMap map) { - return give(player, createMapItem(map, true)); - } public static boolean give(Player player, PosterMap map) { if (!map.hasColumnData()) { @@ -141,14 +135,6 @@ public class MapItemManager implements Listener { return givenItemsCount; } - public static ItemStack createMapItem(SingleMap map) { - return createMapItem(map.getMapsIDs()[0], map.getName(), false); - } - - public static ItemStack createMapItem(SingleMap map, boolean goldTitle) { - return createMapItem(map.getMapsIDs()[0], map.getName(), false, goldTitle); - } - public static ItemStack createMapItem(PosterMap map, int index) { return createMapItem(map.getMapIdAt(index), getMapTitle(map, index), true); } @@ -163,17 +149,24 @@ public class MapItemManager implements Listener { public static ItemStack createMapItem(int mapID, String text, boolean isMapPart, boolean goldTitle) { ItemStack mapItem; - if (goldTitle) { + if (text == "") { mapItem = new ItemStackBuilder(Material.FILLED_MAP) - .title(ChatColor.GOLD, text) .hideAllAttributes() .item(); } else { - mapItem = new ItemStackBuilder(Material.FILLED_MAP) - .title(text) - .hideAllAttributes() - .item(); + if (goldTitle) { + mapItem = new ItemStackBuilder(Material.FILLED_MAP) + .title(ChatColor.GOLD, text) + .hideAllAttributes() + .item(); + } else { + mapItem = new ItemStackBuilder(Material.FILLED_MAP) + .title(text) + .hideAllAttributes() + .item(); + } } + final MapMeta meta = (MapMeta) mapItem.getItemMeta(); meta.setMapId(mapID); meta.setColor(isMapPart ? Color.LIME : Color.GREEN); @@ -193,17 +186,14 @@ public class MapItemManager implements Listener { private static 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(MapManager.getMapIdFromItemStack(item)); - if (poster.hasColumnData()) { - return getMapTitle(poster, poster.getRowAt(index), poster.getColumnAt(index)); - } - - return getMapTitle(poster, index); + PosterMap poster = (PosterMap) map; + int index = poster.getIndex(MapManager.getMapIdFromItemStack(item)); + if (poster.hasColumnData()) { + return getMapTitle(poster, poster.getRowAt(index), poster.getColumnAt(index)); } + + return getMapTitle(poster, index); + //} } // @@ -296,19 +286,19 @@ public class MapItemManager implements Listener { return; } - if (Permissions.REMOVE_SPLATTER_MAP.grantedTo(player)) { - if (player.isSneaking()) { - PosterMap poster = SplatterMapManager.removeSplatterMap(frame, player); - if (poster != null) { - event.setCancelled(true); + if (Permissions.REMOVE_SPLATTER_MAP.grantedTo(player) && player.isSneaking()) { - if (player.getGameMode() != GameMode.CREATIVE - || !SplatterMapManager.hasSplatterMap(player, poster)) { - poster.give(player); - } - return; + PosterMap poster = SplatterMapManager.removeSplatterMap(frame, player); + if (poster != null) { + event.setCancelled(true); + + if (player.getGameMode() != GameMode.CREATIVE + || !SplatterMapManager.hasSplatterMap(player, poster)) { + poster.give(player); } + return; } + } if (!MapManager.managesMap(frame.getItem())) { diff --git a/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java b/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java index 4d20185..404d2af 100644 --- a/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java +++ b/src/main/java/fr/moribus/imageonmap/ui/SplatterMapManager.java @@ -57,6 +57,7 @@ import org.bukkit.Material; import org.bukkit.Rotation; import org.bukkit.attribute.AttributeModifier; import org.bukkit.block.BlockFace; +import org.bukkit.entity.Item; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerInteractEntityEvent; @@ -66,7 +67,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.MapMeta; //TODO rework splatter effect, using ID is far more stable than nbt tags. -// To update when adding small picture previsualization. +// To update when adding small picture snapshot. public abstract class SplatterMapManager { private SplatterMapManager() { } @@ -318,8 +319,9 @@ public abstract class SplatterMapManager { RunTask.later(() -> { addPropertiesToFrames(player, frame); - frame.setItem( - new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem()); + + ItemStack item = MapItemManager.createMapItem(id, "", true, false); + frame.setItem(item); }, 5L);