From 219869c82b50b7d5ab5acfebc7fb4fb614141ae5 Mon Sep 17 00:00:00 2001 From: Vlammar Date: Wed, 8 Jul 2020 09:06:54 +0200 Subject: [PATCH 01/15] added images flush and removed useless gc.dispose --- .../imageonmap/image/ImageIOExecutor.java | 5 +- .../image/ImageRendererExecutor.java | 22 ++++--- .../moribus/imageonmap/image/ImageUtils.java | 60 ++++++++++++------- .../moribus/imageonmap/image/PosterImage.java | 25 ++++++-- 4 files changed, 72 insertions(+), 40 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageIOExecutor.java b/src/main/java/fr/moribus/imageonmap/image/ImageIOExecutor.java index 7ff54ce..38fc787 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageIOExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageIOExecutor.java @@ -61,6 +61,7 @@ public class ImageIOExecutor extends Worker { BufferedImage image = ImageIO.read(file); mapRenderer.setImage(image); + image.flush();//Safe to free return null; } }); @@ -88,7 +89,9 @@ public class ImageIOExecutor extends Worker { for(int i = 0, c = mapsIDs.length; i < c; i++) { - ImageIOExecutor.saveImage(ImageOnMap.getPlugin().getImageFile(mapsIDs[i]), image.getImageAt(i)); + BufferedImage img=image.getImageAt(i); + ImageIOExecutor.saveImage(ImageOnMap.getPlugin().getImageFile(mapsIDs[i]), img); + img.flush();//Safe to free } } diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java index b49f57e..e2a5928 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java @@ -92,7 +92,7 @@ public class ImageRendererExecutor extends Worker BufferedImage image=null; //If the link is an imgur one - if (url.toString().contains("https://imgur.com/")) { + if (url.toString().startsWith("https://imgur.com/")) { //Not handled, can't with the hash only access the image in i.imgur.com/. @@ -148,10 +148,13 @@ public class ImageRendererExecutor extends Worker if (scaling != ImageUtils.ScalingType.NONE && height <= 1 && width <= 1) { - return renderSingle(scaling.resize(image, ImageMap.WIDTH, ImageMap.HEIGHT), playerUUID); + ImageMap ret=renderSingle(scaling.resize(image, ImageMap.WIDTH, ImageMap.HEIGHT), playerUUID); + image.flush();//Safe to free + return ret; } final BufferedImage resizedImage = scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height); - //image.flush(); + image.flush();//Safe to free + return renderPoster(resizedImage, playerUUID); } }, callback); @@ -171,19 +174,16 @@ public class ImageRendererExecutor extends Worker }); final int mapID = futureMapID.get(); - //ImageIOExecutor.saveImage(mapID, image); - + ImageIOExecutor.saveImage(mapID,image); submitToMainThread(new Callable() { @Override public Void call() throws Exception { Renderer.installRenderer(image, mapID); - //image.flush(); return null; } }); - //image.flush(); return MapManager.createMap(playerUUID, mapID); } @@ -201,10 +201,10 @@ public class ImageRendererExecutor extends Worker } }); poster.splitImages(); + final int[] mapsIDs = futureMapsIds.get(); - // ImageIOExecutor.saveImage(mapsIDs, poster); - + ImageIOExecutor.saveImage(mapsIDs,poster); if (PluginConfiguration.SAVE_FULL_IMAGE.get()) { ImageIOExecutor.saveImage(ImageMap.getFullImageFile(mapsIDs[0], mapsIDs[mapsIDs.length - 1]), image); @@ -220,9 +220,7 @@ public class ImageRendererExecutor extends Worker } }); - - // image.flush(); - + poster.getImage().flush();//Safe? return MapManager.createMap(poster, playerUUID, mapsIDs); } } diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageUtils.java b/src/main/java/fr/moribus/imageonmap/image/ImageUtils.java index 560c657..8c27d31 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageUtils.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageUtils.java @@ -36,9 +36,12 @@ package fr.moribus.imageonmap.image; +import fr.zcraft.zlib.tools.PluginLogger; + import java.awt.*; import java.awt.image.BufferedImage; +//import java.awt.*; /** * Various image-related utilities */ @@ -57,6 +60,7 @@ public class ImageUtils { case COVERED: return ImageUtils.resize(source, destinationW, destinationH, true); case STRETCHED: return resizeStretched(source, destinationW, destinationH); default: return source; + } } } @@ -70,28 +74,31 @@ public class ImageUtils { */ static private BufferedImage resize(BufferedImage source, int destinationW, int destinationH, boolean covered) { - float ratioW = (float)destinationW / (float)source.getWidth(); - float ratioH = (float)destinationH / (float)source.getHeight(); - int finalW, finalH; - int x, y; + try { + float ratioW = (float) destinationW / (float) source.getWidth(); + float ratioH = (float) destinationH / (float) source.getHeight(); + int finalW, finalH; + int x, y; - if(covered ? ratioW > ratioH : ratioW < ratioH) - { - finalW = destinationW; - finalH = (int)(source.getHeight() * ratioW); + if (covered ? ratioW > ratioH : ratioW < ratioH) { + finalW = destinationW; + finalH = (int) (source.getHeight() * ratioW); + } else { + finalW = (int) (source.getWidth() * ratioH); + finalH = destinationH; + } + + x = (destinationW - finalW) / 2; + y = (destinationH - finalH) / 2; + + return drawImage(source, + destinationW, destinationH, + x, y, finalW, finalH); } - else - { - finalW = (int)(source.getWidth() * ratioH); - finalH = destinationH; + catch(final Throwable e){ + throw e; } - x = (destinationW - finalW) / 2; - y = (destinationH - finalH) / 2; - - return drawImage(source, - destinationW, destinationH, - x, y, finalW, finalH); } /** @@ -123,11 +130,22 @@ public class ImageUtils { int bufferW, int bufferH, int posX, int posY, int sourceW, int sourceH) { - BufferedImage newImage = new BufferedImage(bufferW, bufferH, BufferedImage.TYPE_INT_ARGB); + Graphics graphics=null; + BufferedImage newImage= null; + try{ + newImage = new BufferedImage(bufferW, bufferH, BufferedImage.TYPE_INT_ARGB); - Graphics graphics = newImage.getGraphics(); + graphics = newImage.getGraphics(); graphics.drawImage(source, posX, posY, sourceW, sourceH, null); - graphics.dispose(); + return newImage; + } + catch(final Throwable e) { + PluginLogger.warning("Exception/error at drawImage"); + if(newImage!=null ) + newImage.flush();//Safe to free + throw e; + } + } } \ No newline at end of file diff --git a/src/main/java/fr/moribus/imageonmap/image/PosterImage.java b/src/main/java/fr/moribus/imageonmap/image/PosterImage.java index 60589c0..1ddf79d 100644 --- a/src/main/java/fr/moribus/imageonmap/image/PosterImage.java +++ b/src/main/java/fr/moribus/imageonmap/image/PosterImage.java @@ -36,7 +36,7 @@ package fr.moribus.imageonmap.image; -import java.awt.Graphics; +import java.awt.*; import java.awt.image.BufferedImage; /** @@ -83,6 +83,7 @@ public class PosterImage public void splitImages() { + try{ cutImages = new BufferedImage[cutImagesCount]; int imageX; @@ -97,8 +98,16 @@ public class PosterImage } imageY += HEIGHT; } - - originalImage = null; + } + catch(final Throwable e){ + if(cutImages!=null) + for(BufferedImage bi: cutImages){ + if(bi!=null){ + bi.flush();//Safe to free + } + } + throw e;} + } /** @@ -109,12 +118,12 @@ public class PosterImage */ private BufferedImage makeSubImage(BufferedImage originalImage, int x, int y) { + BufferedImage newImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB); - + Graphics graphics = newImage.getGraphics(); - + graphics.drawImage(originalImage, -x, -y, null); - graphics.dispose(); return newImage; } @@ -131,6 +140,10 @@ public class PosterImage { return cutImages[i]; } + public BufferedImage getImage() + { + return originalImage; + } public int getColumnAt(int i) { From f0d1d33bb854ce2a026620afb86c71190c2436ea Mon Sep 17 00:00:00 2001 From: Vlammar Date: Thu, 23 Jul 2020 11:06:53 +0200 Subject: [PATCH 02/15] add give command --- .../fr/moribus/imageonmap/ImageOnMap.java | 3 +- .../fr/moribus/imageonmap/Permissions.java | 3 +- .../commands/maptool/GiveCommand.java | 98 +++++++++++++++++++ src/main/resources/plugin.yml | 5 + 4 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java diff --git a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java index 2c1361d..f55d4fd 100644 --- a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java +++ b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java @@ -119,7 +119,8 @@ public final class ImageOnMap extends ZPlugin DeleteCommand.class, GetRemainingCommand.class, ExploreCommand.class, - MigrateCommand.class + MigrateCommand.class, + GiveCommand.class ); Commands.registerShortcut("maptool", NewCommand.class, "tomap"); diff --git a/src/main/java/fr/moribus/imageonmap/Permissions.java b/src/main/java/fr/moribus/imageonmap/Permissions.java index 6667243..8065ee2 100644 --- a/src/main/java/fr/moribus/imageonmap/Permissions.java +++ b/src/main/java/fr/moribus/imageonmap/Permissions.java @@ -46,7 +46,8 @@ public enum Permissions RENAME("imageonmap.rename"), DELETE("imageonmap.delete"), ADMINISTRATIVE("imageonmap.administrative"), - BYPASS_SIZE("imageonmap.bypasssize") + BYPASS_SIZE("imageonmap.bypasssize"), + GIVE("imageonmap.give") ; diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java new file mode 100644 index 0000000..f993a17 --- /dev/null +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java @@ -0,0 +1,98 @@ +/* + * Copyright or © or Copr. Moribus (2013) + * Copyright or © or Copr. ProkopyL (2015) + * Copyright or © or Copr. Amaury Carrade (2016 – 2020) + * Copyright or © or Copr. Vlammar (2019 – 2020) + * + * 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-B 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-B + * 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-B license and that you accept its terms. + */ + +package fr.moribus.imageonmap.commands.maptool; + +import fr.moribus.imageonmap.Permissions; +import fr.moribus.imageonmap.commands.IoMCommand; +import fr.moribus.imageonmap.map.ImageMap; +import fr.moribus.imageonmap.map.MapManager; +import fr.zcraft.zlib.components.commands.CommandException; +import fr.zcraft.zlib.components.commands.CommandInfo; +import fr.zcraft.zlib.components.i18n.I; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + + +@CommandInfo (name = "give", usageParameters = " or ") +public class GiveCommand extends IoMCommand +{ + @Override + protected void run() throws CommandException + { + if(args.length < 2) throwInvalidArgument(I.t("You must give a valid player name and a map name.")); + + final Player p= Bukkit.getPlayer(args[0]); + + ImageMap map; + //TODO does not support map name with space + Player player=null; + if(args.length<4) { + if (args.length == 2) { + player = playerSender(); + } + if (args.length == 3) { + player = Bukkit.getPlayer(args[2]); + if(player==null){ + try{ + playerSender().sendMessage(I.t("Player map store not found")); + } + catch (Exception e){ + + } + return; + } + } + if (p == null) { + player.sendMessage(I.t("Player not found")); + return; + } + map = MapManager.getMap(player.getUniqueId(), args[1]); + if (map == null) { + player.sendMessage(I.t("Map not found")); + return; + } + map.give(p); + } + } + + @Override + public boolean canExecute(CommandSender sender) + { + return Permissions.GIVE.grantedTo(sender); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ef82c43..69db22f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -25,6 +25,7 @@ permissions: imageonmap.rename: true imageonmap.delete: true imageonmap.bypasssize: false + imageonmap.give: false imageonmap.userender: description: "Allows you to use /tomap and related commands (/maptool getremaing). Alias of imageonmap.new." @@ -54,6 +55,10 @@ permissions: description: "Allows you to delete a map you rendered in the past." default: true + imageonmap.give: + description: "Allows you to give a map to a specified player." + default: op + imageonmap.administrative: description: "Allows you to perform administrative tasks (like /maptool migrate)." default: op From 9de9a228a99d5541209ea73aaf299a1bdbe78e94 Mon Sep 17 00:00:00 2001 From: Vlammar <36545324+Vlammar@users.noreply.github.com> Date: Mon, 17 Aug 2020 23:30:29 +0200 Subject: [PATCH 03/15] Update src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java Co-authored-by: Amaury Carrade --- .../fr/moribus/imageonmap/commands/maptool/GiveCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java index f993a17..10d8b2c 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java @@ -56,7 +56,7 @@ public class GiveCommand extends IoMCommand { if(args.length < 2) throwInvalidArgument(I.t("You must give a valid player name and a map name.")); - final Player p= Bukkit.getPlayer(args[0]); + final Player p = getPlayerParameter(0); ImageMap map; //TODO does not support map name with space From 7836aa8e9547a7f0da46317c9af633897551ced6 Mon Sep 17 00:00:00 2001 From: Vlammar <36545324+Vlammar@users.noreply.github.com> Date: Mon, 17 Aug 2020 23:30:48 +0200 Subject: [PATCH 04/15] Update src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java Co-authored-by: Amaury Carrade --- .../fr/moribus/imageonmap/commands/maptool/GiveCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java index 10d8b2c..eecea47 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java @@ -66,7 +66,7 @@ public class GiveCommand extends IoMCommand player = playerSender(); } if (args.length == 3) { - player = Bukkit.getPlayer(args[2]); + player = getPlayerParameter(2); if(player==null){ try{ playerSender().sendMessage(I.t("Player map store not found")); From 40479e2a3794f7ffad03d11595f4aa30e54a6962 Mon Sep 17 00:00:00 2001 From: Vlammar <36545324+Vlammar@users.noreply.github.com> Date: Mon, 17 Aug 2020 23:33:30 +0200 Subject: [PATCH 05/15] Update src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java Co-authored-by: Amaury Carrade --- .../java/fr/moribus/imageonmap/image/ImageRendererExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java index e2a5928..218ae5e 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java @@ -92,7 +92,7 @@ public class ImageRendererExecutor extends Worker BufferedImage image=null; //If the link is an imgur one - if (url.toString().startsWith("https://imgur.com/")) { + if (url.toString().toLowerCase().startsWith("https://imgur.com/")) { //Not handled, can't with the hash only access the image in i.imgur.com/. From dc58e366bc34976f3be54d3179626259c500f448 Mon Sep 17 00:00:00 2001 From: Vlammar <36545324+Vlammar@users.noreply.github.com> Date: Mon, 17 Aug 2020 23:53:47 +0200 Subject: [PATCH 06/15] Update src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java Co-authored-by: Amaury Carrade --- .../fr/moribus/imageonmap/commands/maptool/GiveCommand.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java index eecea47..c2bd3b3 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java @@ -77,10 +77,6 @@ public class GiveCommand extends IoMCommand return; } } - if (p == null) { - player.sendMessage(I.t("Player not found")); - return; - } map = MapManager.getMap(player.getUniqueId(), args[1]); if (map == null) { player.sendMessage(I.t("Map not found")); From 4cb22312aa8438bb2d923dee115f3cce6c3c2d58 Mon Sep 17 00:00:00 2001 From: Vlammar <36545324+Vlammar@users.noreply.github.com> Date: Mon, 17 Aug 2020 23:56:46 +0200 Subject: [PATCH 07/15] Update src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java Co-authored-by: Amaury Carrade --- .../fr/moribus/imageonmap/commands/maptool/GiveCommand.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java index c2bd3b3..f4e13b7 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java @@ -79,8 +79,7 @@ public class GiveCommand extends IoMCommand } map = MapManager.getMap(player.getUniqueId(), args[1]); if (map == null) { - player.sendMessage(I.t("Map not found")); - return; + throwInvalidArgument(I.t("Map not found")); } map.give(p); } From 29b7c99595fafc61ea5a86770016d8c3d91cd679 Mon Sep 17 00:00:00 2001 From: Vlammar <36545324+Vlammar@users.noreply.github.com> Date: Tue, 18 Aug 2020 00:28:24 +0200 Subject: [PATCH 08/15] Update ImageOnMap.java --- src/main/java/fr/moribus/imageonmap/ImageOnMap.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java index f55d4fd..e558c32 100644 --- a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java +++ b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java @@ -117,10 +117,10 @@ public final class ImageOnMap extends ZPlugin ListCommand.class, GetCommand.class, DeleteCommand.class, + GiveCommand.class, GetRemainingCommand.class, ExploreCommand.class, - MigrateCommand.class, - GiveCommand.class + MigrateCommand.class ); Commands.registerShortcut("maptool", NewCommand.class, "tomap"); From 61a2f4eb2f0dd15b2e5df0d75819416da90e6d17 Mon Sep 17 00:00:00 2001 From: Vlammar <36545324+Vlammar@users.noreply.github.com> Date: Tue, 18 Aug 2020 00:36:01 +0200 Subject: [PATCH 09/15] Apply suggestions from code review Co-authored-by: Amaury Carrade --- .../moribus/imageonmap/commands/maptool/GiveCommand.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java index f4e13b7..6db0308 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java @@ -67,15 +67,6 @@ public class GiveCommand extends IoMCommand } if (args.length == 3) { player = getPlayerParameter(2); - if(player==null){ - try{ - playerSender().sendMessage(I.t("Player map store not found")); - } - catch (Exception e){ - - } - return; - } } map = MapManager.getMap(player.getUniqueId(), args[1]); if (map == null) { From 06cdb97be2d7b88c11789acd21f0f10e07b93aba Mon Sep 17 00:00:00 2001 From: Vlammar Date: Thu, 20 Aug 2020 23:50:55 +0200 Subject: [PATCH 10/15] add an alias for give command --- src/main/java/fr/moribus/imageonmap/ImageOnMap.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java index e558c32..3ee1ea3 100644 --- a/src/main/java/fr/moribus/imageonmap/ImageOnMap.java +++ b/src/main/java/fr/moribus/imageonmap/ImageOnMap.java @@ -125,6 +125,7 @@ public final class ImageOnMap extends ZPlugin Commands.registerShortcut("maptool", NewCommand.class, "tomap"); Commands.registerShortcut("maptool", ExploreCommand.class, "maps"); + Commands.registerShortcut("maptool", GiveCommand.class, "mapgive"); if (PluginConfiguration.CHECK_FOR_UPDATES.get()) { From f4cfe934a74666c61a50651b74cafb5dba5dd68e Mon Sep 17 00:00:00 2001 From: Vlammar Date: Thu, 20 Aug 2020 23:55:16 +0200 Subject: [PATCH 11/15] fixed indent --- .../image/ImageRendererExecutor.java | 74 ++++------ .../moribus/imageonmap/image/PosterImage.java | 135 ++++++++---------- 2 files changed, 84 insertions(+), 125 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java index 218ae5e..2da4df4 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageRendererExecutor.java @@ -59,44 +59,34 @@ import java.util.concurrent.Callable; import java.util.concurrent.Future; @WorkerAttributes(name = "Image Renderer", queriesMainThread = true) -public class ImageRendererExecutor extends Worker -{ - private static URLConnection connecting(URL url)throws IOException{ +public class ImageRendererExecutor extends Worker { + private static URLConnection connecting(URL url) throws IOException { final URLConnection connection = url.openConnection(); connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0"); connection.connect(); - if (connection instanceof HttpURLConnection) - { + if (connection instanceof HttpURLConnection) { final HttpURLConnection httpConnection = (HttpURLConnection) connection; final int httpCode = httpConnection.getResponseCode(); - if ((httpCode / 100) != 2) - { + if ((httpCode / 100) != 2) { throw new IOException(I.t("HTTP error: {0} {1}", httpCode, httpConnection.getResponseMessage())); } } return connection; } - private enum extension{ - png, jpg, jpeg, gif - } - - static public void render(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final int width, final int height, WorkerCallback callback) - { - submitQuery(new WorkerRunnable() - { + static public void render(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final int width, final int height, WorkerCallback callback) { + submitQuery(new WorkerRunnable() { @Override public ImageMap run() throws Throwable { - BufferedImage image=null; + BufferedImage image = null; //If the link is an imgur one if (url.toString().toLowerCase().startsWith("https://imgur.com/")) { //Not handled, can't with the hash only access the image in i.imgur.com/. - if (url.toString().contains("gallery/")) { throw new IOException("We do not support imgur gallery yet, please use direct link to image instead. Right click on the picture you want to use then select copy picture link:) "); } @@ -117,12 +107,10 @@ public class ImageRendererExecutor extends Worker } - } //If not an Imgur link else { - //Try connecting URLConnection connection = connecting(url); @@ -130,8 +118,6 @@ public class ImageRendererExecutor extends Worker image = ImageIO.read(stream); - - } if (image == null) throw new IOException(I.t("The given URL is not a valid image")); // Limits are in place and the player does NOT have rights to avoid them. @@ -148,7 +134,7 @@ public class ImageRendererExecutor extends Worker if (scaling != ImageUtils.ScalingType.NONE && height <= 1 && width <= 1) { - ImageMap ret=renderSingle(scaling.resize(image, ImageMap.WIDTH, ImageMap.HEIGHT), playerUUID); + ImageMap ret = renderSingle(scaling.resize(image, ImageMap.WIDTH, ImageMap.HEIGHT), playerUUID); image.flush();//Safe to free return ret; } @@ -160,26 +146,20 @@ public class ImageRendererExecutor extends Worker }, callback); } - - static private ImageMap renderSingle(final BufferedImage image, final UUID playerUUID) throws Throwable - { + 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 Integer call() throws Exception - { + public Integer call() throws Exception { return MapManager.getNewMapsIds(1)[0]; } }); final int mapID = futureMapID.get(); - ImageIOExecutor.saveImage(mapID,image); - submitToMainThread(new Callable() - { + ImageIOExecutor.saveImage(mapID, image); + submitToMainThread(new Callable() { @Override - public Void call() throws Exception - { + public Void call() throws Exception { Renderer.installRenderer(image, mapID); return null; } @@ -187,16 +167,13 @@ public class ImageRendererExecutor extends Worker return MapManager.createMap(playerUUID, mapID); } - static private ImageMap renderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable - { + static private ImageMap renderPoster(final BufferedImage image, final UUID playerUUID) throws Throwable { final PosterImage poster = new PosterImage(image); final int mapCount = poster.getImagesCount(); MapManager.checkMapLimit(mapCount, playerUUID); - final Future futureMapsIds = submitToMainThread(new Callable() - { + final Future futureMapsIds = submitToMainThread(new Callable() { @Override - public int[] call() throws Exception - { + public int[] call() throws Exception { return MapManager.getNewMapsIds(mapCount); } }); @@ -204,23 +181,24 @@ public class ImageRendererExecutor extends Worker final int[] mapsIDs = futureMapsIds.get(); - ImageIOExecutor.saveImage(mapsIDs,poster); - if (PluginConfiguration.SAVE_FULL_IMAGE.get()) - { + ImageIOExecutor.saveImage(mapsIDs, poster); + if (PluginConfiguration.SAVE_FULL_IMAGE.get()) { ImageIOExecutor.saveImage(ImageMap.getFullImageFile(mapsIDs[0], mapsIDs[mapsIDs.length - 1]), image); } - submitToMainThread(new Callable() - { + submitToMainThread(new Callable() { @Override - public Void call() throws Exception - { + public Void call() throws Exception { Renderer.installRenderer(poster, mapsIDs); return null; } }); - poster.getImage().flush();//Safe? + poster.getImage().flush();//Safe to free return MapManager.createMap(poster, playerUUID, mapsIDs); } + + private enum extension { + png, jpg, jpeg, gif + } } diff --git a/src/main/java/fr/moribus/imageonmap/image/PosterImage.java b/src/main/java/fr/moribus/imageonmap/image/PosterImage.java index 1ddf79d..9ede73e 100644 --- a/src/main/java/fr/moribus/imageonmap/image/PosterImage.java +++ b/src/main/java/fr/moribus/imageonmap/image/PosterImage.java @@ -36,88 +36,84 @@ package fr.moribus.imageonmap.image; -import java.awt.*; + +import java.awt.Graphics; import java.awt.image.BufferedImage; /** * This class represents an image split into pieces */ -public class PosterImage -{ +public class PosterImage { static private final int WIDTH = 128; static private final int HEIGHT = 128; - + private BufferedImage originalImage; private BufferedImage[] cutImages; private int lines; private int columns; private int cutImagesCount; private int remainderX, remainderY; - + /** * Creates a new Poster from an entire image + * * @param originalImage the original image */ - public PosterImage(BufferedImage originalImage) - { + public PosterImage(BufferedImage originalImage) { this.originalImage = originalImage; calculateDimensions(); } - - private void calculateDimensions() - { + + private void calculateDimensions() { int originalWidth = originalImage.getWidth(); int originalHeight = originalImage.getHeight(); - + columns = (int) Math.ceil(originalWidth / WIDTH); lines = (int) Math.ceil(originalHeight / HEIGHT); - + remainderX = originalWidth % WIDTH; remainderY = originalHeight % HEIGHT; - - if(remainderX > 0) columns++; - if(remainderY > 0) lines++; - + + if (remainderX > 0) columns++; + if (remainderY > 0) lines++; + cutImagesCount = columns * lines; } - - public void splitImages() - { - try{ - cutImages = new BufferedImage[cutImagesCount]; - - int imageX; - int imageY = remainderY == 0 ? 0 :(remainderY - HEIGHT) / 2; - for(int i = 0; i < lines; i++) - { - imageX = remainderX == 0 ? 0 :(remainderX - WIDTH) / 2; - for(int j = 0; j < columns; j++) - { - cutImages[i * columns + j] = makeSubImage(originalImage, imageX, imageY); - imageX += WIDTH; + + public void splitImages() { + try { + cutImages = new BufferedImage[cutImagesCount]; + + int imageX; + int imageY = remainderY == 0 ? 0 : (remainderY - HEIGHT) / 2; + for (int i = 0; i < lines; i++) { + imageX = remainderX == 0 ? 0 : (remainderX - WIDTH) / 2; + for (int j = 0; j < columns; j++) { + cutImages[i * columns + j] = makeSubImage(originalImage, imageX, imageY); + imageX += WIDTH; + } + imageY += HEIGHT; } - imageY += HEIGHT; - } - } - catch(final Throwable e){ - if(cutImages!=null) - for(BufferedImage bi: cutImages){ - if(bi!=null){ + } catch (final Throwable e) { + if (cutImages != null) + for (BufferedImage bi : cutImages) { + if (bi != null) { bi.flush();//Safe to free } } - throw e;} + throw e; + } } - + /** * Generates the subimage that intersects with the given map rectangle. + * * @param x X coordinate of top-left point of the map. * @param y Y coordinate of top-left point of the map. * @return the requested subimage. */ - private BufferedImage makeSubImage(BufferedImage originalImage, int x, int y) - { + private BufferedImage makeSubImage(BufferedImage originalImage, int x, int y) { BufferedImage newImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB); @@ -126,79 +122,64 @@ public class PosterImage graphics.drawImage(originalImage, -x, -y, null); return newImage; } - + /** - * * @return the split images */ - public BufferedImage[] getImages() - { + public BufferedImage[] getImages() { return cutImages; } - - public BufferedImage getImageAt(int i) - { + + public BufferedImage getImageAt(int i) { return cutImages[i]; } - public BufferedImage getImage() - { + + public BufferedImage getImage() { return originalImage; } - - public int getColumnAt(int i) - { + + public int getColumnAt(int i) { return i % columns; } - - public int getLineAt(int i) - { + + public int getLineAt(int i) { return i / columns; } - + /** - * * @return the number of lines of the poster */ - public int getLines() - { + public int getLines() { return lines; } - + /** - * * @return the number of columns of the poster */ - public int getColumns() - { + public int getColumns() { return columns; } - + /** - * * @return the number of split images */ - public int getImagesCount() - { + public int getImagesCount() { return cutImagesCount; } - public int getRemainderX() - { + public int getRemainderX() { return remainderX; } - public void setRemainderX(int remainderX) - { + public void setRemainderX(int remainderX) { this.remainderX = remainderX; } - public int getRemainderY() - { + public int getRemainderY() { return remainderY; } - public void setRemainderY(int remainderY) - { + public void setRemainderY(int remainderY) { this.remainderY = remainderY; } } From 2260cd4890d7dee9f39b94b0f0ac2f16feb58266 Mon Sep 17 00:00:00 2001 From: Vlammar Date: Fri, 21 Aug 2020 00:13:07 +0200 Subject: [PATCH 12/15] indent, and checked flushing --- .../moribus/imageonmap/image/ImageUtils.java | 124 +++++++++--------- 1 file changed, 60 insertions(+), 64 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/image/ImageUtils.java b/src/main/java/fr/moribus/imageonmap/image/ImageUtils.java index 8c27d31..94b6237 100644 --- a/src/main/java/fr/moribus/imageonmap/image/ImageUtils.java +++ b/src/main/java/fr/moribus/imageonmap/image/ImageUtils.java @@ -41,68 +41,42 @@ import fr.zcraft.zlib.tools.PluginLogger; import java.awt.*; import java.awt.image.BufferedImage; -//import java.awt.*; /** * Various image-related utilities */ public class ImageUtils { - public enum ScalingType { - NONE, - CONTAINED, - COVERED, - STRETCHED, - ; - - public BufferedImage resize(BufferedImage source, int destinationW, int destinationH) { - switch(this) { - case CONTAINED: return ImageUtils.resize(source, destinationW, destinationH, false); - case COVERED: return ImageUtils.resize(source, destinationW, destinationH, true); - case STRETCHED: return resizeStretched(source, destinationW, destinationH); - default: return source; - - } - } - } - /** * Generates a resized buffer of the given source + * * @param source * @param destinationW * @param destinationH * @return */ - static private BufferedImage resize(BufferedImage source, int destinationW, int destinationH, boolean covered) - { - try { - float ratioW = (float) destinationW / (float) source.getWidth(); - float ratioH = (float) destinationH / (float) source.getHeight(); - int finalW, finalH; - int x, y; + static private BufferedImage resize(BufferedImage source, int destinationW, int destinationH, boolean covered) { + float ratioW = (float) destinationW / (float) source.getWidth(); + float ratioH = (float) destinationH / (float) source.getHeight(); + int finalW, finalH; + int x, y; - if (covered ? ratioW > ratioH : ratioW < ratioH) { - finalW = destinationW; - finalH = (int) (source.getHeight() * ratioW); - } else { - finalW = (int) (source.getWidth() * ratioH); - finalH = destinationH; - } - - x = (destinationW - finalW) / 2; - y = (destinationH - finalH) / 2; - - return drawImage(source, - destinationW, destinationH, - x, y, finalW, finalH); - } - catch(final Throwable e){ - throw e; + if (covered ? ratioW > ratioH : ratioW < ratioH) { + finalW = destinationW; + finalH = (int) (source.getHeight() * ratioW); + } else { + finalW = (int) (source.getWidth() * ratioH); + finalH = destinationH; } + x = (destinationW - finalW) / 2; + y = (destinationH - finalH) / 2; + + return drawImage(source, + destinationW, destinationH, + x, y, finalW, finalH); } /** - * * @param source * @param destinationW * @param destinationH @@ -117,35 +91,57 @@ public class ImageUtils { /** * Draws the source image on a new buffer, and returns it. * The source buffer can be drawn at any size and position in the new buffer. - * @param source The source buffer to draw + * + * @param source The source buffer to draw * @param bufferW The width of the new buffer * @param bufferH The height of the new buffer - * @param posX The X position of the source buffer - * @param posY The Y position of the source buffer + * @param posX The X position of the source buffer + * @param posY The Y position of the source buffer * @param sourceW The width of the source buffer * @param sourceH The height of the source buffer * @return The new buffer, with the source buffer drawn on it */ static private BufferedImage drawImage(BufferedImage source, - int bufferW, int bufferH, - int posX, int posY, - int sourceW, int sourceH) { - Graphics graphics=null; - BufferedImage newImage= null; - try{ - newImage = new BufferedImage(bufferW, bufferH, BufferedImage.TYPE_INT_ARGB); + int bufferW, int bufferH, + int posX, int posY, + int sourceW, int sourceH) { + Graphics graphics = null; + BufferedImage newImage = null; + try { + newImage = new BufferedImage(bufferW, bufferH, BufferedImage.TYPE_INT_ARGB); - graphics = newImage.getGraphics(); - graphics.drawImage(source, posX, posY, sourceW, sourceH, null); + graphics = newImage.getGraphics(); + graphics.drawImage(source, posX, posY, sourceW, sourceH, null); - return newImage; - } - catch(final Throwable e) { - PluginLogger.warning("Exception/error at drawImage"); - if(newImage!=null ) - newImage.flush();//Safe to free - throw e; - } + return newImage; + } catch (final Throwable e) { + PluginLogger.warning("Exception/error at drawImage"); + if (newImage != null) + newImage.flush();//Safe to free + throw e; + } } + + public enum ScalingType { + NONE, + CONTAINED, + COVERED, + STRETCHED, + ; + + public BufferedImage resize(BufferedImage source, int destinationW, int destinationH) { + switch (this) { + case CONTAINED: + return ImageUtils.resize(source, destinationW, destinationH, false); + case COVERED: + return ImageUtils.resize(source, destinationW, destinationH, true); + case STRETCHED: + return resizeStretched(source, destinationW, destinationH); + default: + return source; + + } + } + } } \ No newline at end of file From a41f0359ce23f55c6193ffd887f1426daccb59e0 Mon Sep 17 00:00:00 2001 From: Vlammar Date: Fri, 21 Aug 2020 00:23:24 +0200 Subject: [PATCH 13/15] updated pluggin.yml for the new alias mapgive --- src/main/resources/plugin.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 69db22f..a721aed 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -11,6 +11,9 @@ commands: description: Manage maps maps: description: Manage maps through a GUI + mapgive: + description: give a map to a player from a player map store, by default take from the player that make the command + usage: / player_to map_name [player_from] permissions: imageonmap.*: From f5e0ea9a793d8be634cb66b207042c5073e206a6 Mon Sep 17 00:00:00 2001 From: Vlammar Date: Fri, 21 Aug 2020 01:15:03 +0200 Subject: [PATCH 14/15] added prefix player and uuid --- .../commands/maptool/GiveCommand.java | 81 ++++++++++++++++--- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java index 6db0308..440d55b 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java @@ -43,30 +43,88 @@ import fr.moribus.imageonmap.map.MapManager; import fr.zcraft.zlib.components.commands.CommandException; import fr.zcraft.zlib.components.commands.CommandInfo; import fr.zcraft.zlib.components.i18n.I; +import fr.zcraft.zlib.tools.PluginLogger; import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.io.IOException; +import java.util.UUID; + + +@CommandInfo(name = "give", usageParameters = " or ") +public class GiveCommand extends IoMCommand { + /** + * Parse an argument given at a specific index, it will return a player depending on the given prefixe. Can be player: or uuid: + * + * @param index The index. + * @return The retrieved player. + * @throws CommandException If the value is invalid. + * @throws InterruptedException . + * @throws IOException + */ + private OfflinePlayer parse(int index) throws CommandException { + + String s = args[index].trim(); + + String[] subs = s.split(":"); + try { + // + if (subs.length == 1) { + return getOfflinePlayerParameter(index); + } + + switch (subs[0]) { + case "player": + return getOfflinePlayerParameter(subs[1]); + + case "uuid": + StringBuffer string = new StringBuffer(subs[1].toLowerCase()); + //if there are no '-' + if (string.length() == 32) { + //we try to fix it by adding - at pos 8,12,16,20 + Integer[] pos={20,16,12,8}; + for(int i:pos) + string = string.insert(i, "-"); + } + + //if the given uuid is well formed with 8-4-4-4-12 = 36 chars in length (including '-') + if (string.length() == 36) + return Bukkit.getOfflinePlayer(UUID.fromString(string.toString())); + + throwInvalidArgument(I.t("Invalid uuid, please provide an uuid of this form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")); + + case "bank": + throwInvalidArgument(I.t("Not supported yet")); + break; + + default: + throwInvalidArgument(I.t("Invalid prefix, valid one are: player | uuid")); + } + } catch (InterruptedException | IOException e) { + PluginLogger.warning(I.t("Can't access to mojang API to check the player UUID")); + } + return null; + } -@CommandInfo (name = "give", usageParameters = " or ") -public class GiveCommand extends IoMCommand -{ @Override - protected void run() throws CommandException - { - if(args.length < 2) throwInvalidArgument(I.t("You must give a valid player name and a map name.")); + protected void run() throws CommandException { + + if (args.length < 2) throwInvalidArgument(I.t("You must give a valid player name and a map name.")); final Player p = getPlayerParameter(0); ImageMap map; - //TODO does not support map name with space - Player player=null; - if(args.length<4) { + //TODO add support for map name with spaces "cool name" or name or "name" "cool name with a \" and some stuff" should work + OfflinePlayer player = null; + + if (args.length < 4) { if (args.length == 2) { player = playerSender(); } if (args.length == 3) { - player = getPlayerParameter(2); + player = parse(2); } map = MapManager.getMap(player.getUniqueId(), args[1]); if (map == null) { @@ -77,8 +135,7 @@ public class GiveCommand extends IoMCommand } @Override - public boolean canExecute(CommandSender sender) - { + public boolean canExecute(CommandSender sender) { return Permissions.GIVE.grantedTo(sender); } } From c013cbbce5bdd71346cff0bb2a07846e55d96438 Mon Sep 17 00:00:00 2001 From: Vlammar Date: Wed, 4 Nov 2020 17:37:58 +0100 Subject: [PATCH 15/15] updated exception catch --- .../fr/moribus/imageonmap/commands/maptool/GiveCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java index 440d55b..3921d87 100644 --- a/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java +++ b/src/main/java/fr/moribus/imageonmap/commands/maptool/GiveCommand.java @@ -51,6 +51,7 @@ import org.bukkit.entity.Player; import java.io.IOException; import java.util.UUID; +import java.util.concurrent.ExecutionException; @CommandInfo(name = "give", usageParameters = " or ") @@ -67,7 +68,6 @@ public class GiveCommand extends IoMCommand { private OfflinePlayer parse(int index) throws CommandException { String s = args[index].trim(); - String[] subs = s.split(":"); try { // @@ -102,7 +102,7 @@ public class GiveCommand extends IoMCommand { default: throwInvalidArgument(I.t("Invalid prefix, valid one are: player | uuid")); } - } catch (InterruptedException | IOException e) { + } catch (InterruptedException | ExecutionException e) { PluginLogger.warning(I.t("Can't access to mojang API to check the player UUID")); } return null;