Merge pull request #119 from zDevelopers/feature_give_command

Add give command
This commit is contained in:
Vlammar 2020-12-09 21:59:58 +01:00 committed by GitHub
commit 509e379386
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 302 additions and 157 deletions

View File

@ -124,6 +124,7 @@ public final class ImageOnMap extends QuartzPlugin
RenameCommand.class, RenameCommand.class,
DeleteCommand.class, DeleteCommand.class,
DeleteOtherCommand.class, DeleteOtherCommand.class,
GiveCommand.class,
GetRemainingCommand.class, GetRemainingCommand.class,
ExploreCommand.class, ExploreCommand.class,
ExploreOtherCommand.class, ExploreOtherCommand.class,
@ -133,6 +134,7 @@ public final class ImageOnMap extends QuartzPlugin
Commands.registerShortcut("maptool", NewCommand.class, "tomap"); Commands.registerShortcut("maptool", NewCommand.class, "tomap");
Commands.registerShortcut("maptool", ExploreCommand.class, "maps"); Commands.registerShortcut("maptool", ExploreCommand.class, "maps");
Commands.registerShortcut("maptool", GiveCommand.class, "mapgive");
if (PluginConfiguration.CHECK_FOR_UPDATES.get()) if (PluginConfiguration.CHECK_FOR_UPDATES.get())
{ {

View File

@ -53,9 +53,8 @@ public enum Permissions
UPDATE("imageonmap.update"), UPDATE("imageonmap.update"),
UPDATEOTHER("imageonmap.updateother"), UPDATEOTHER("imageonmap.updateother"),
ADMINISTRATIVE("imageonmap.administrative"), ADMINISTRATIVE("imageonmap.administrative"),
BYPASS_SIZE("imageonmap.bypasssize") BYPASS_SIZE("imageonmap.bypasssize"),
GIVE("imageonmap.give")
; ;
private final String permission; private final String permission;

View File

@ -0,0 +1,141 @@
/*
* Copyright or © or Copr. Moribus (2013)
* Copyright or © or Copr. ProkopyL <prokopylmc@gmail.com> (2015)
* Copyright or © or Copr. Amaury Carrade <amaury@carrade.eu> (2016 2020)
* Copyright or © or Copr. Vlammar <valentin.jabre@gmail.com> (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 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;
import java.util.concurrent.ExecutionException;
@CommandInfo(name = "give", usageParameters = "<Player> <MapName> or <Player> <MapName> <Player where to find the map>")
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:<username> or uuid:<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 | ExecutionException e) {
PluginLogger.warning(I.t("Can't access to mojang API to check the player UUID"));
}
return null;
}
@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 = getPlayerParameter(0);
ImageMap map;
//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 = parse(2);
}
map = MapManager.getMap(player.getUniqueId(), args[1]);
if (map == null) {
throwInvalidArgument(I.t("Map not found"));
}
map.give(p);
}
}
@Override
public boolean canExecute(CommandSender sender) {
return Permissions.GIVE.grantedTo(sender);
}
}

View File

@ -61,6 +61,7 @@ public class ImageIOExecutor extends Worker
{ {
BufferedImage image = ImageIO.read(file); BufferedImage image = ImageIO.read(file);
mapRenderer.setImage(image); mapRenderer.setImage(image);
image.flush();//Safe to free
return null; return null;
} }
}); });
@ -88,7 +89,9 @@ public class ImageIOExecutor extends Worker
{ {
for(int i = 0, c = mapsIDs.length; i < c; i++) 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
} }
} }

View File

@ -59,20 +59,16 @@ import java.util.concurrent.Callable;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@WorkerAttributes(name = "Image Renderer", queriesMainThread = true) @WorkerAttributes(name = "Image Renderer", queriesMainThread = true)
public class ImageRendererExecutor extends Worker public class ImageRendererExecutor extends Worker {
{ private static URLConnection connecting(URL url) throws IOException {
private static URLConnection connecting(URL url)throws IOException{
final URLConnection connection = url.openConnection(); 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.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
connection.connect(); connection.connect();
if (connection instanceof HttpURLConnection) if (connection instanceof HttpURLConnection) {
{
final HttpURLConnection httpConnection = (HttpURLConnection) connection; final HttpURLConnection httpConnection = (HttpURLConnection) connection;
final int httpCode = httpConnection.getResponseCode(); 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())); throw new IOException(I.t("HTTP error: {0} {1}", httpCode, httpConnection.getResponseMessage()));
} }
} }
@ -106,13 +102,12 @@ public class ImageRendererExecutor extends Worker
@Override @Override
public ImageMap run() throws Throwable { public ImageMap run() throws Throwable {
BufferedImage image=null; BufferedImage image = null;
//If the link is an imgur one //If the link is an imgur one
if (url.toString().contains("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/<hash>.<extension> //Not handled, can't with the hash only access the image in i.imgur.com/<hash>.<extension>
if (url.toString().contains("gallery/")) { 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:) "); 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:) ");
} }
@ -133,7 +128,6 @@ public class ImageRendererExecutor extends Worker
} }
} }
//If not an Imgur link //If not an Imgur link
else { else {
@ -148,16 +142,17 @@ public class ImageRendererExecutor extends Worker
// Limits are in place and the player does NOT have rights to avoid them. // Limits are in place and the player does NOT have rights to avoid them.
checkSizeLimit(playerUUID, image); checkSizeLimit(playerUUID, image);
if (scaling != ImageUtils.ScalingType.NONE && height <= 1 && width <= 1) { 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); final BufferedImage resizedImage = scaling.resize(image, ImageMap.WIDTH * width, ImageMap.HEIGHT * height);
image.flush(); image.flush();//Safe to free
return renderPoster(resizedImage, playerUUID); return renderPoster(resizedImage, playerUUID);
} }
}, callback); }, callback);
} }
public static void update(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final ImageMap map, final int width, final int height, WorkerCallback<ImageMap> callback) { public static void update(final URL url, final ImageUtils.ScalingType scaling, final UUID playerUUID, final ImageMap map, final int width, final int height, WorkerCallback<ImageMap> callback) {
submitQuery(new WorkerRunnable<ImageMap>() submitQuery(new WorkerRunnable<ImageMap>()
{ {
@ -210,42 +205,32 @@ public class ImageRendererExecutor extends Worker
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); MapManager.checkMapLimit(1, playerUUID);
final Future<Integer> futureMapID = submitToMainThread(new Callable<Integer>() final Future<Integer> futureMapID = submitToMainThread(new Callable<Integer>() {
{
@Override @Override
public Integer call() throws Exception public Integer call() throws Exception {
{
return MapManager.getNewMapsIds(1)[0]; return MapManager.getNewMapsIds(1)[0];
} }
}); });
final int mapID = futureMapID.get(); final int mapID = futureMapID.get();
ImageIOExecutor.saveImage(mapID, image); ImageIOExecutor.saveImage(mapID, image);
submitToMainThread(new Callable<Void>() {
submitToMainThread(new Callable<Void>()
{
@Override @Override
public Void call() throws Exception public Void call() throws Exception {
{
Renderer.installRenderer(image, mapID); Renderer.installRenderer(image, mapID);
image.flush();
return null; return null;
} }
}); });
image.flush();
return MapManager.createMap(playerUUID, mapID); 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 PosterImage poster = new PosterImage(image);
final int mapCount = poster.getImagesCount(); final int mapCount = poster.getImagesCount();
MapManager.checkMapLimit(mapCount, playerUUID); MapManager.checkMapLimit(mapCount, playerUUID);
final Future<int[]> futureMapsIds = submitToMainThread(new Callable<int[]>() final Future<int[]> futureMapsIds = submitToMainThread(new Callable<int[]>() {
{
@Override @Override
public int[] call() throws Exception public int[] call() throws Exception {
{
return MapManager.getNewMapsIds(mapCount); return MapManager.getNewMapsIds(mapCount);
} }
}); });
@ -253,27 +238,26 @@ public class ImageRendererExecutor extends Worker
final int[] mapsIDs = futureMapsIds.get(); final int[] mapsIDs = futureMapsIds.get();
ImageIOExecutor.saveImage(mapsIDs, poster); ImageIOExecutor.saveImage(mapsIDs, poster);
final int[] mapsIDs = futureMapsIds.get();
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); ImageIOExecutor.saveImage(ImageMap.getFullImageFile(mapsIDs[0], mapsIDs[mapsIDs.length - 1]), image);
} }
submitToMainThread(new Callable<Void>() submitToMainThread(new Callable<Void>() {
{
@Override @Override
public Void call() throws Exception public Void call() throws Exception {
{
Renderer.installRenderer(poster, mapsIDs); Renderer.installRenderer(poster, mapsIDs);
return null; return null;
} }
}); });
poster.getImage().flush();//Safe to free
image.flush();
return MapManager.createMap(poster, playerUUID, mapsIDs); return MapManager.createMap(poster, playerUUID, mapsIDs);
} }
private enum extension {
png, jpg, jpeg, gif
}
} }

View File

@ -36,6 +36,8 @@
package fr.moribus.imageonmap.image; package fr.moribus.imageonmap.image;
import fr.zcraft.zlib.tools.PluginLogger;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@ -44,45 +46,25 @@ import java.awt.image.BufferedImage;
*/ */
public class ImageUtils { 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 * Generates a resized buffer of the given source
*
* @param source * @param source
* @param destinationW * @param destinationW
* @param destinationH * @param destinationH
* @return * @return
*/ */
static private BufferedImage resize(BufferedImage source, int destinationW, int destinationH, boolean covered) static private BufferedImage resize(BufferedImage source, int destinationW, int destinationH, boolean covered) {
{ float ratioW = (float) destinationW / (float) source.getWidth();
float ratioW = (float)destinationW / (float)source.getWidth(); float ratioH = (float) destinationH / (float) source.getHeight();
float ratioH = (float)destinationH / (float)source.getHeight();
int finalW, finalH; int finalW, finalH;
int x, y; int x, y;
if(covered ? ratioW > ratioH : ratioW < ratioH) if (covered ? ratioW > ratioH : ratioW < ratioH) {
{
finalW = destinationW; finalW = destinationW;
finalH = (int)(source.getHeight() * ratioW); finalH = (int) (source.getHeight() * ratioW);
} } else {
else finalW = (int) (source.getWidth() * ratioH);
{
finalW = (int)(source.getWidth() * ratioH);
finalH = destinationH; finalH = destinationH;
} }
@ -95,7 +77,6 @@ public class ImageUtils {
} }
/** /**
*
* @param source * @param source
* @param destinationW * @param destinationW
* @param destinationH * @param destinationH
@ -110,24 +91,57 @@ public class ImageUtils {
/** /**
* Draws the source image on a new buffer, and returns it. * 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. * 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 bufferW The width of the new buffer
* @param bufferH The height of the new buffer * @param bufferH The height of the new buffer
* @param posX The X position of the source buffer * @param posX The X position of the source buffer
* @param posY The Y position of the source buffer * @param posY The Y position of the source buffer
* @param sourceW The width of the source buffer * @param sourceW The width of the source buffer
* @param sourceH The height of the source buffer * @param sourceH The height of the source buffer
* @return The new buffer, with the source buffer drawn on it * @return The new buffer, with the source buffer drawn on it
*/ */
static private BufferedImage drawImage(BufferedImage source, static private BufferedImage drawImage(BufferedImage source,
int bufferW, int bufferH, int bufferW, int bufferH,
int posX, int posY, int posX, int posY,
int sourceW, int sourceH) { 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.drawImage(source, posX, posY, sourceW, sourceH, null);
graphics.dispose();
return newImage; 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;
}
}
} }
} }

View File

@ -36,156 +36,150 @@
package fr.moribus.imageonmap.image; package fr.moribus.imageonmap.image;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
/** /**
* This class represents an image split into pieces * This class represents an image split into pieces
*/ */
public class PosterImage public class PosterImage {
{
static private final int WIDTH = 128; static private final int WIDTH = 128;
static private final int HEIGHT = 128; static private final int HEIGHT = 128;
private BufferedImage originalImage; private BufferedImage originalImage;
private BufferedImage[] cutImages; private BufferedImage[] cutImages;
private int lines; private int lines;
private int columns; private int columns;
private int cutImagesCount; private int cutImagesCount;
private int remainderX, remainderY; private int remainderX, remainderY;
/** /**
* Creates a new Poster from an entire image * Creates a new Poster from an entire image
*
* @param originalImage the original image * @param originalImage the original image
*/ */
public PosterImage(BufferedImage originalImage) public PosterImage(BufferedImage originalImage) {
{
this.originalImage = originalImage; this.originalImage = originalImage;
calculateDimensions(); calculateDimensions();
} }
private void calculateDimensions() private void calculateDimensions() {
{
int originalWidth = originalImage.getWidth(); int originalWidth = originalImage.getWidth();
int originalHeight = originalImage.getHeight(); int originalHeight = originalImage.getHeight();
columns = (int) Math.ceil(originalWidth / WIDTH); columns = (int) Math.ceil(originalWidth / WIDTH);
lines = (int) Math.ceil(originalHeight / HEIGHT); lines = (int) Math.ceil(originalHeight / HEIGHT);
remainderX = originalWidth % WIDTH; remainderX = originalWidth % WIDTH;
remainderY = originalHeight % HEIGHT; remainderY = originalHeight % HEIGHT;
if(remainderX > 0) columns++; if (remainderX > 0) columns++;
if(remainderY > 0) lines++; if (remainderY > 0) lines++;
cutImagesCount = columns * lines; cutImagesCount = columns * lines;
} }
public void splitImages() public void splitImages() {
{ try {
cutImages = new BufferedImage[cutImagesCount]; cutImages = new BufferedImage[cutImagesCount];
int imageX; int imageX;
int imageY = remainderY == 0 ? 0 :(remainderY - HEIGHT) / 2; int imageY = remainderY == 0 ? 0 : (remainderY - HEIGHT) / 2;
for(int i = 0; i < lines; i++) for (int i = 0; i < lines; i++) {
{ imageX = remainderX == 0 ? 0 : (remainderX - WIDTH) / 2;
imageX = remainderX == 0 ? 0 :(remainderX - WIDTH) / 2; for (int j = 0; j < columns; j++) {
for(int j = 0; j < columns; j++) cutImages[i * columns + j] = makeSubImage(originalImage, imageX, imageY);
{ imageX += WIDTH;
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) {
bi.flush();//Safe to free
}
}
throw e;
} }
originalImage = null;
} }
/** /**
* Generates the subimage that intersects with the given map rectangle. * Generates the subimage that intersects with the given map rectangle.
*
* @param x X coordinate of top-left point of the map. * @param x X coordinate of top-left point of the map.
* @param y Y coordinate of top-left point of the map. * @param y Y coordinate of top-left point of the map.
* @return the requested subimage. * @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); BufferedImage newImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = newImage.getGraphics(); Graphics graphics = newImage.getGraphics();
graphics.drawImage(originalImage, -x, -y, null); graphics.drawImage(originalImage, -x, -y, null);
graphics.dispose();
return newImage; return newImage;
} }
/** /**
*
* @return the split images * @return the split images
*/ */
public BufferedImage[] getImages() public BufferedImage[] getImages() {
{
return cutImages; return cutImages;
} }
public BufferedImage getImageAt(int i) public BufferedImage getImageAt(int i) {
{
return cutImages[i]; return cutImages[i];
} }
public int getColumnAt(int i) public BufferedImage getImage() {
{ return originalImage;
}
public int getColumnAt(int i) {
return i % columns; return i % columns;
} }
public int getLineAt(int i) public int getLineAt(int i) {
{
return i / columns; return i / columns;
} }
/** /**
*
* @return the number of lines of the poster * @return the number of lines of the poster
*/ */
public int getLines() public int getLines() {
{
return lines; return lines;
} }
/** /**
*
* @return the number of columns of the poster * @return the number of columns of the poster
*/ */
public int getColumns() public int getColumns() {
{
return columns; return columns;
} }
/** /**
*
* @return the number of split images * @return the number of split images
*/ */
public int getImagesCount() public int getImagesCount() {
{
return cutImagesCount; return cutImagesCount;
} }
public int getRemainderX() public int getRemainderX() {
{
return remainderX; return remainderX;
} }
public void setRemainderX(int remainderX) public void setRemainderX(int remainderX) {
{
this.remainderX = remainderX; this.remainderX = remainderX;
} }
public int getRemainderY() public int getRemainderY() {
{
return remainderY; return remainderY;
} }
public void setRemainderY(int remainderY) public void setRemainderY(int remainderY) {
{
this.remainderY = remainderY; this.remainderY = remainderY;
} }
} }

View File

@ -12,6 +12,9 @@ commands:
description: Manage maps description: Manage maps
maps: maps:
description: Manage maps through a GUI 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: /<command> player_to map_name [player_from]
permissions: permissions:
imageonmap.*: imageonmap.*:
@ -31,6 +34,7 @@ permissions:
imageonmap.delete: true imageonmap.delete: true
imageonmap.deleteother: false imageonmap.deleteother: false
imageonmap.bypasssize: false imageonmap.bypasssize: false
imageonmap.give: false
imageonmap.update: true imageonmap.update: true
imageonmap.updateother: false imageonmap.updateother: false
@ -74,6 +78,10 @@ permissions:
description: "Allows you to delete a map you rendered in the past." description: "Allows you to delete a map you rendered in the past."
default: true default: true
imageonmap.give:
description: "Allows you to give a map to a specified player."
default: op
imageonmap.deleteother: imageonmap.deleteother:
description: "Allows you to delete a map a player rendered in the past." description: "Allows you to delete a map a player rendered in the past."
default: false default: false