From 7af1b3dcc87d95bda0e969e3b515272085d669ed Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Fri, 7 Sep 2018 06:40:13 +1000 Subject: [PATCH] Add heightmap web util command --- .../fawe/bukkit/regions/FreeBuildRegion.java | 7 +- .../main/java/com/boydti/fawe/config/BBC.java | 3 +- .../java/com/boydti/fawe/util/MainUtil.java | 9 +-- .../com/boydti/fawe/util/image/ImageUtil.java | 10 +-- .../worldedit/command/UtilityCommands.java | 72 +++++++++++++++++++ 5 files changed, 85 insertions(+), 16 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/FreeBuildRegion.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/FreeBuildRegion.java index 130899b39..1ef42cdcb 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/FreeBuildRegion.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/regions/FreeBuildRegion.java @@ -5,7 +5,6 @@ import com.boydti.fawe.bukkit.wrapper.AsyncWorld; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.queue.NullFaweQueue; import com.boydti.fawe.regions.FaweMask; -import com.boydti.fawe.regions.FaweMaskManager; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.regions.CuboidRegion; @@ -14,13 +13,10 @@ import com.sk89q.worldedit.world.block.BlockTypes; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.block.Block; import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; import org.bukkit.event.EventException; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.plugin.RegisteredListener; import java.util.ArrayList; @@ -81,9 +77,10 @@ public class FreeBuildRegion extends BukkitMaskManager { @Override public Region getRegion() { return new CuboidRegion(vec1, vec2) { + @Override public boolean contains(int x, int z) { - return contains(x, 77, z); + return contains(x, 127, z); } private int lastX = Integer.MIN_VALUE, lastZ = Integer.MIN_VALUE; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/config/BBC.java b/worldedit-core/src/main/java/com/boydti/fawe/config/BBC.java index 7461584c1..6725a1080 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/config/BBC.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/config/BBC.java @@ -77,7 +77,6 @@ public enum BBC { COMMAND_PASTE("The clipboard has been pasted at %s0", "WorldEdit.Paste"), - COMMAND_ROTATE("The clipboard has been rotated", "WorldEdit.Rotate"), COMMAND_FLIPPED("The clipboard has been flipped", "WorldEdit.Flip"), @@ -500,7 +499,7 @@ public enum BBC { public static String stripColor(String string) { - return StringMan.removeFromSet(string, replacements.keySet()); + return StringMan.removeFromSet(string, replacements.values()); } public String s() { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java index 5dae1ec71..5b845346f 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/MainUtil.java @@ -32,6 +32,7 @@ import java.util.concurrent.ForkJoinPool; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.regex.Pattern; import java.util.zip.*; import javax.imageio.ImageIO; @@ -889,7 +890,7 @@ public class MainUtil { return isInSubDirectory(dir, file.getParentFile()); } - public static void iterateFiles(File directory, RunnableVal task) { + public static void iterateFiles(File directory, Consumer task) { if (directory.exists()) { File[] files = directory.listFiles(); if (null != files) { @@ -897,7 +898,7 @@ public class MainUtil { if (files[i].isDirectory()) { iterateFiles(files[i], task); } else { - task.run(files[i]); + task.accept(files[i]); } } } @@ -1054,9 +1055,9 @@ public class MainUtil { public static void deleteOlder(File directory, final long timeDiff, boolean printDebug) { final long now = System.currentTimeMillis(); ForkJoinPool pool = new ForkJoinPool(); - iterateFiles(directory, new RunnableVal() { + iterateFiles(directory, new Consumer() { @Override - public void run(File file) { + public void accept(File file) { long age = now - file.lastModified(); if (age > timeDiff) { pool.submit(() -> file.delete()); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java index 84c2db655..771dbfb0a 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java @@ -32,14 +32,14 @@ public class ImageUtil { } int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; - BufferedImage ret = (BufferedImage)img; + BufferedImage ret = img; int w, h; if (higherQuality) { // Use multi-step technique: start with original size, then // scale down in multiple passes with drawImage() // until the target size is reached - w = img.getWidth(); - h = img.getHeight(); + w = ret.getWidth(); + h = ret.getHeight(); } else { // Use one-step technique: scale directly from original // size to target size with a single drawImage() call @@ -53,14 +53,14 @@ public class ImageUtil { if (w < targetWidth) { w = targetWidth; } - } + } else if (w < targetWidth) w = targetWidth; if (higherQuality && h > targetHeight) { h /= 2; if (h < targetHeight) { h = targetHeight; } - } + } else if (h < targetHeight) h = targetHeight; BufferedImage tmp = new BufferedImage(w, h, type); Graphics2D g2 = tmp.createGraphics(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 0502f77b1..72c5456f2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -28,6 +28,7 @@ import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.DelegateConsumer; import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal3; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MathMan; @@ -35,6 +36,7 @@ import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.chat.Message; import com.boydti.fawe.util.chat.UsageMessage; import com.boydti.fawe.util.gui.FormBuilder; +import com.boydti.fawe.util.image.ImageUtil; import com.sk89q.minecraft.util.commands.*; import com.sk89q.worldedit.*; import com.sk89q.worldedit.Vector; @@ -73,11 +75,17 @@ import com.sk89q.worldedit.util.command.parametric.ParameterData; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockTypes; +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; import java.io.File; import java.io.FileFilter; +import java.io.IOException; import java.lang.reflect.Type; import java.net.URI; +import java.nio.file.Files; import java.util.*; +import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; @@ -163,6 +171,70 @@ public class UtilityCommands extends MethodCommands { } } + @Command( + aliases = {"/heightmapinterface"}, + desc = "Generate the heightmap interface: https://github.com/boy0001/HeightMap", + max = 0 + ) + public void heightmapInterface(FawePlayer player) throws IOException { + player.sendMessage("Please wait while we generate the minified heightmaps."); + File srcFolder = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HEIGHTMAP); + + int min = 100; + int max = 200; + + File webSrc = new File(Fawe.imp().getDirectory(), "web" + File.separator + "heightmap"); + File minImages = new File(webSrc, "images" + File.separator + "min"); + File maxImages = new File(webSrc, "images" + File.separator + "max"); + final int sub = srcFolder.getAbsolutePath().length(); + List images = new ArrayList<>(); + MainUtil.iterateFiles(srcFolder, new Consumer() { + @Override + public void accept(File file) { + switch (file.getName().substring(file.getName().lastIndexOf('.')).toLowerCase()) { + case ".png": + case ".jpeg": + break; + default: + return; + } + try { + String name = file.getAbsolutePath().substring(sub); + if (name.startsWith(File.separator)) name = name.replaceFirst(java.util.regex.Pattern.quote(File.separator), ""); + BufferedImage img = MainUtil.readImage(file); + BufferedImage minImg = ImageUtil.getScaledInstance(img, min, min, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); + BufferedImage maxImg = ImageUtil.getScaledInstance(img, max, max, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); + player.sendMessage("Writing " + name); + File minFile = new File(minImages, name); + File maxFile = new File(maxImages, name); + minFile.getParentFile().mkdirs(); + maxFile.getParentFile().mkdirs(); + ImageIO.write(minImg, "png", minFile); + ImageIO.write(maxImg, "png", maxFile); + images.add(name); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + StringBuilder config = new StringBuilder(); + config.append("var images = [\n"); + for (String image : images) { + config.append('"' + image.replace(File.separator, "/") + "\",\n"); + } + config.append("];\n"); + config.append("// The low res images (they should all be the same size)\n"); + config.append("var src_min = \"images/min/\";\n"); + config.append("// The max resolution images (Use the same if there are no higher resolution ones available)\n"); + config.append("var src_max = \"images/max/\";\n"); + config.append("// The local source for the image (used in commands)\n"); + config.append("var src_local = \"file://\";\n"); + File configFile = new File(webSrc, "config.js"); + player.sendMessage("Writing " + configFile); + Files.write(configFile.toPath(), config.toString().getBytes()); + player.sendMessage("Done! See: `FastAsyncWorldEdit/web/heightmap`"); + } + @Command( aliases = {"/cancel", "fcancel"}, desc = "Cancel your current command",