diff --git a/core/src/main/java/com/boydti/fawe/object/brush/ImageBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/ImageBrush.java index 862442df..74c33cfe 100644 --- a/core/src/main/java/com/boydti/fawe/object/brush/ImageBrush.java +++ b/core/src/main/java/com/boydti/fawe/object/brush/ImageBrush.java @@ -1,6 +1,7 @@ package com.boydti.fawe.object.brush; import com.boydti.fawe.object.collection.SummedColorTable; +import com.boydti.fawe.object.mask.SurfaceMask; import com.boydti.fawe.util.TextureUtil; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; @@ -73,7 +74,7 @@ public class ImageBrush implements Brush { final int cx = position.getBlockX(); final int cy = position.getBlockY(); final int cz = position.getBlockZ(); - final SolidBlockMask solid = new SolidBlockMask(editSession); + final Mask solid = new SurfaceMask(editSession); double scale = Math.max(width, height) / sizeDouble; diff --git a/core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java b/core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java index c8092dd2..89921a9f 100644 --- a/core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java +++ b/core/src/main/java/com/boydti/fawe/util/image/ImageUtil.java @@ -10,7 +10,11 @@ import java.awt.Transparency; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; public class ImageUtil { @@ -177,4 +181,58 @@ public class ImageUtil { throw new ParameterException(e); } } + + public static BufferedImage load(URI uri) throws ParameterException { + try { + String uriStr = uri.toString(); + if (uriStr.startsWith("file:/")) { + File file = new File(uri.getPath()); + return MainUtil.readImage(file); + } + return MainUtil.readImage(new URL(uriStr)); + } catch (IOException e) { + throw new ParameterException(e); + } + } + + public static InputStream getInputStream(URI uri) throws ParameterException { + try { + String uriStr = uri.toString(); + if (uriStr.startsWith("file:/")) { + File file = new File(uri.getPath()); + return new FileInputStream(file); + } + return new URL(uriStr).openStream(); + } catch (IOException e) { + throw new ParameterException(e); + } + } + + + public static URI getImageURI(String arg) throws ParameterException { + try { + if (arg.startsWith("http")) { + if (arg.contains("imgur.com") && !arg.contains("i.imgur.com")) { + arg = "https://i.imgur.com/" + arg.split("imgur.com/")[1] + ".png"; + } + return new URL(arg).toURI(); + } else if (arg.startsWith("file:/")) { + arg = arg.replaceFirst("file:/+", ""); + File file = MainUtil.getFile(MainUtil.getFile(Fawe.imp().getDirectory(), com.boydti.fawe.config.Settings.IMP.PATHS.HEIGHTMAP), arg); + if (!file.exists()) { + throw new ParameterException("File not found " + file); + } + if (file.isDirectory()) { + throw new ParameterException("File is a directory " + file); + } + return file.toURI(); + } else { + throw new ParameterException("Invalid image " + arg); + } + } catch (IOException e) { + throw new ParameterException(e); + } catch (URISyntaxException e) { + throw new ParameterException(e); + } + } } diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 513bc966..69745742 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -58,9 +58,12 @@ import com.sk89q.worldedit.util.command.InvalidUsageException; import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.util.command.parametric.ParameterException; + import java.awt.Color; import java.awt.image.BufferedImage; import java.io.*; +import java.net.URI; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; @@ -360,7 +363,7 @@ public class BrushCommands extends BrushProcessor { max = -1 ) @CommandPermissions("worldedit.brush.stencil") - public BrushSettings stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate, CommandContext context) throws WorldEditException { + public BrushSettings stencilBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('w') boolean onlyWhite, @Switch('r') boolean randomRotate, CommandContext context) throws WorldEditException, FileNotFoundException, ParameterException { checkMaxBrushRadius(radius); InputStream stream = getHeightmapStream(image); HeightBrush brush; @@ -701,7 +704,7 @@ public class BrushCommands extends BrushProcessor { max = 4 ) @CommandPermissions("worldedit.brush.height") - public BrushSettings heightBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException { + public BrushSettings heightBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException, FileNotFoundException, ParameterException { return terrainBrush(player, session, radius, image, rotation, yscale, false, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context); } @@ -719,7 +722,7 @@ public class BrushCommands extends BrushProcessor { max = 4 ) @CommandPermissions("worldedit.brush.height") - public BrushSettings cliffBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException { + public BrushSettings cliffBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException, FileNotFoundException, ParameterException { return terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CYLINDER, context); } @@ -736,11 +739,11 @@ public class BrushCommands extends BrushProcessor { max = 4 ) @CommandPermissions("worldedit.brush.height") - public BrushSettings flattenBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException { + public BrushSettings flattenBrush(Player player, LocalSession session, @Optional("5") Expression radius, @Optional("") final String image, @Optional("0") @Step(90) @Range(min=0, max=360) final int rotation, @Optional("1") final double yscale, @Switch('r') boolean randomRotate, @Switch('l') boolean layers, @Switch('s') boolean dontSmooth, CommandContext context) throws WorldEditException, FileNotFoundException, ParameterException { return terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers, !dontSmooth, ScalableHeightMap.Shape.CONE, context); } - private BrushSettings terrainBrush(Player player, LocalSession session, Expression radius, String image, int rotation, double yscale, boolean flat, boolean randomRotate, boolean layers, boolean smooth, ScalableHeightMap.Shape shape, CommandContext context) throws WorldEditException { + private BrushSettings terrainBrush(Player player, LocalSession session, Expression radius, String image, int rotation, double yscale, boolean flat, boolean randomRotate, boolean layers, boolean smooth, ScalableHeightMap.Shape shape, CommandContext context) throws WorldEditException, FileNotFoundException, ParameterException { checkMaxBrushRadius(radius); InputStream stream = getHeightmapStream(image); HeightBrush brush; @@ -765,35 +768,12 @@ public class BrushCommands extends BrushProcessor { .setSize(radius); } - private InputStream getHeightmapStream(String filename) { + private InputStream getHeightmapStream(String filename) throws FileNotFoundException, ParameterException { String filenamePng = (filename.endsWith(".png") ? filename : filename + ".png"); File file = new File(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HEIGHTMAP + File.separator + filenamePng); - if (!file.exists()) { - if (!filename.equals("#clipboard") && filename.length() >= 7) { - try { - URL url; - if (filename.startsWith("http")) { - url = new URL(filename); - if (!url.getHost().equals("i.imgur.com")) { - throw new FileNotFoundException(filename); - } - } else { - url = new URL("https://i.imgur.com/" + filenamePng); - } - ReadableByteChannel rbc = Channels.newChannel(url.openStream()); - return Channels.newInputStream(rbc); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } else if (!filename.equalsIgnoreCase("#clipboard")) { - try { - return new FileInputStream(file); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - } - return null; + if (file.exists()) return new FileInputStream(file); + URI uri = ImageUtil.getImageURI(filename); + return ImageUtil.getInputStream(uri); }