[BREAKING]: Improved [row][col] naming; now always accepts [row][col], breaks old multi-map plugins

This commit is contained in:
Stijn Bannink 2023-08-12 21:35:18 +02:00
parent c390ebbd5e
commit 63ac9bb38e
5 changed files with 89 additions and 71 deletions

View file

@ -24,7 +24,7 @@
<groupId>tech.sbdevelopment</groupId> <groupId>tech.sbdevelopment</groupId>
<artifactId>MapReflectionAPI</artifactId> <artifactId>MapReflectionAPI</artifactId>
<version>1.5.2</version> <version>1.6</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>MapReflectionAPI</name> <name>MapReflectionAPI</name>

View file

@ -33,6 +33,7 @@ import tech.sbdevelopment.mapreflectionapi.utils.ReflectionUtil;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.sql.Ref;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -321,8 +322,10 @@ public class MapWrapper extends AbstractMapWrapper {
Object nmsStack = createCraftItemStack(stack, mapId); Object nmsStack = createCraftItemStack(stack, mapId);
String dataWatcherObjectName; String dataWatcherObjectName;
if (ReflectionUtil.supports(19)) { //1.19 if (ReflectionUtil.supports(19, 3)) { //1.19.3 and 1.20(.1)
dataWatcherObjectName = ReflectionUtil.VER_MINOR == 3 ? "g" : "ao"; //1.19.4 = g, >= 1.19.3 = ao dataWatcherObjectName = "g";
} else if (ReflectionUtil.supports(19)) { //1.19-1.19.2
dataWatcherObjectName = "ao";
} else if (ReflectionUtil.supports(18)) { //1.18 } else if (ReflectionUtil.supports(18)) { //1.18
dataWatcherObjectName = ReflectionUtil.VER_MINOR == 1 ? "ap" : "ao"; //1.18.1 = ap, 1.18(.2) = ao dataWatcherObjectName = ReflectionUtil.VER_MINOR == 1 ? "ap" : "ao"; //1.18.1 = ap, 1.18(.2) = ao
} else if (ReflectionUtil.supports(17)) { //1.17 } else if (ReflectionUtil.supports(17)) { //1.17

View file

@ -86,7 +86,7 @@ public interface MultiMapController extends IMapController {
* Show this {@link MultiMapController} in {@link ItemFrame}s * Show this {@link MultiMapController} in {@link ItemFrame}s
* *
* @param player {@link Player} that will be able to see the maps * @param player {@link Player} that will be able to see the maps
* @param entityIdMatrix 2D-Array of entity-IDs of the {@link ItemFrame}s (<code>int[width][height]</code>) * @param entityIdMatrix 2D-Array of entity-IDs of the {@link ItemFrame}s (<code>int[rows][columns]</code>)
* @see MapController#showInFrame(Player, int) * @see MapController#showInFrame(Player, int)
*/ */
void showInFrames(Player player, Integer[][] entityIdMatrix); void showInFrames(Player player, Integer[][] entityIdMatrix);
@ -95,7 +95,7 @@ public interface MultiMapController extends IMapController {
* Show this {@link MultiMapController} in {@link ItemFrame}s * Show this {@link MultiMapController} in {@link ItemFrame}s
* *
* @param player {@link Player} that will be able to see the maps * @param player {@link Player} that will be able to see the maps
* @param entityIdMatrix 2D-Array of entity-IDs of the {@link ItemFrame}s (<code>int[width][height]</code>) * @param entityIdMatrix 2D-Array of entity-IDs of the {@link ItemFrame}s (<code>int[rows][columns]</code>)
* @param callable {@link DebugCallable} which will be called to display debug information, or <code>null</code> * @param callable {@link DebugCallable} which will be called to display debug information, or <code>null</code>
* @see MapController#showInFrame(Player, int, String) * @see MapController#showInFrame(Player, int, String)
*/ */
@ -105,7 +105,7 @@ public interface MultiMapController extends IMapController {
* Show this {@link MultiMapController} in {@link ItemFrame}s * Show this {@link MultiMapController} in {@link ItemFrame}s
* *
* @param player {@link Player} that will be able to see the maps * @param player {@link Player} that will be able to see the maps
* @param itemFrameMatrix 2D-Array of {@link ItemFrame}s (<code>ItemFrame[width][height]</code>) * @param itemFrameMatrix 2D-Array of {@link ItemFrame}s (<code>ItemFrame[rows][columns]</code>)
* @param force if <code>false</code>, the map will not be shown if there is not Map-Item in the ItemFrames * @param force if <code>false</code>, the map will not be shown if there is not Map-Item in the ItemFrames
* @see MapController#showInFrame(Player, ItemFrame, boolean) * @see MapController#showInFrame(Player, ItemFrame, boolean)
*/ */
@ -115,7 +115,7 @@ public interface MultiMapController extends IMapController {
* Show this {@link MultiMapController} in {@link ItemFrame}s * Show this {@link MultiMapController} in {@link ItemFrame}s
* *
* @param player {@link Player} that will be able to see the maps * @param player {@link Player} that will be able to see the maps
* @param itemFrameMatrix 2D-Array of {@link ItemFrame}s (<code>ItemFrame[width][height]</code>) * @param itemFrameMatrix 2D-Array of {@link ItemFrame}s (<code>ItemFrame[rows][columns]</code>)
* @see MapController#showInFrame(Player, ItemFrame) * @see MapController#showInFrame(Player, ItemFrame)
*/ */
void showInFrames(Player player, ItemFrame[][] itemFrameMatrix); void showInFrames(Player player, ItemFrame[][] itemFrameMatrix);
@ -124,7 +124,7 @@ public interface MultiMapController extends IMapController {
* Clear the frames * Clear the frames
* *
* @param player {@link Player} that will be able to see the cleared frames * @param player {@link Player} that will be able to see the cleared frames
* @param entityIdMatrix 2D-Array of entity-IDs of the {@link ItemFrame}s (<code>int[width][height]</code>) * @param entityIdMatrix 2D-Array of entity-IDs of the {@link ItemFrame}s (<code>int[rows][columns]</code>)
*/ */
void clearFrames(Player player, Integer[][] entityIdMatrix); void clearFrames(Player player, Integer[][] entityIdMatrix);
@ -132,7 +132,7 @@ public interface MultiMapController extends IMapController {
* Clear the frames * Clear the frames
* *
* @param player {@link Player} that will be able to see the cleared frames * @param player {@link Player} that will be able to see the cleared frames
* @param itemFrameMatrix 2D-Array of {@link ItemFrame}s (<code>ItemFrame[width][height]</code>) * @param itemFrameMatrix 2D-Array of {@link ItemFrame}s (<code>ItemFrame[rows][columns]</code>)
*/ */
void clearFrames(Player player, ItemFrame[][] itemFrameMatrix); void clearFrames(Player player, ItemFrame[][] itemFrameMatrix);
@ -144,11 +144,11 @@ public interface MultiMapController extends IMapController {
* Called to get debug information for a frame * Called to get debug information for a frame
* *
* @param controller the {@link MapController} * @param controller the {@link MapController}
* @param x X-Position of the current frame * @param row Row of the current frame
* @param y Y-Position of the current frame * @param column Column of the current frame
* @return {@link String} to show when a player looks at the map, or <code>null</code> * @return {@link String} to show when a player looks at the map, or <code>null</code>
* @see MapController#showInFrame(Player, int, String) * @see MapController#showInFrame(Player, int, String)
*/ */
String call(MapController controller, int x, int y); String call(MapController controller, int row, int column);
} }
} }

View file

@ -25,52 +25,79 @@ import org.jetbrains.annotations.NotNull;
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
import tech.sbdevelopment.mapreflectionapi.api.exceptions.MapLimitExceededException; import tech.sbdevelopment.mapreflectionapi.api.exceptions.MapLimitExceededException;
import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import static tech.sbdevelopment.mapreflectionapi.utils.MainUtil.validateArrayDimensions;
/** /**
* A {@link MultiMapWrapper} wraps one image split in pieces. * A {@link MultiMapWrapper} wraps one image split in pieces.
*/ */
public class MultiMapWrapper extends AbstractMapWrapper { public class MultiMapWrapper extends AbstractMapWrapper {
private final MapWrapper[][] wrapperMatrix; private final MapWrapper[][] wrapperMatrix;
/**
* Creates a new {@link MultiMapWrapper} from the given image.
* The image will be split into the given amount of rows and columns.
*
* @param image The image to wrap
* @param rows The amount of rows
* @param columns The amount of columns
*/
public MultiMapWrapper(BufferedImage image, int rows, int columns) { public MultiMapWrapper(BufferedImage image, int rows, int columns) {
this(splitImage(image, columns, rows)); this(splitImage(image, rows, columns));
} }
/**
* Creates a new {@link MultiMapWrapper} from the given image.
* The image will be split into the given amount of rows and columns.
*
* @param image The image to wrap
* @param rows The amount of rows
* @param columns The amount of columns
*/
public MultiMapWrapper(ArrayImage image, int rows, int columns) { public MultiMapWrapper(ArrayImage image, int rows, int columns) {
this(splitImage(image.toBuffered(), columns, rows)); this(splitImage(image.toBuffered(), rows, columns));
} }
/**
* Creates a new {@link MultiMapWrapper} from the given image.
*
* @param imageMatrix The image matrix to wrap
* @deprecated Use {@link #MultiMapWrapper(ArrayImage, int, int)} instead, this method is meant for internal use only.
*/
@Deprecated(since = "1.6", forRemoval = true)
public MultiMapWrapper(ArrayImage[][] imageMatrix) { public MultiMapWrapper(ArrayImage[][] imageMatrix) {
wrapperMatrix = new MapWrapper[imageMatrix.length][imageMatrix[0].length]; wrapperMatrix = new MapWrapper[imageMatrix.length][imageMatrix[0].length];
for (int x = 0; x < imageMatrix.length; x++) { for (int row = 0; row < imageMatrix.length; row++) {
if (imageMatrix[x].length != imageMatrix[0].length) { if (imageMatrix[row].length != imageMatrix[0].length) {
throw new IllegalArgumentException("An image in a MultiMapWrapper is not rectangular!"); throw new IllegalArgumentException("An image in a MultiMapWrapper is not rectangular!");
} }
for (int y = 0; y < imageMatrix[x].length; y++) { for (int column = 0; column < imageMatrix[row].length; column++) {
wrapperMatrix[x][y] = MapReflectionAPI.getMapManager().wrapImage(imageMatrix[x][y]); wrapperMatrix[row][column] = MapReflectionAPI.getMapManager().wrapImage(imageMatrix[row][column]);
} }
} }
} }
/**
* Creates a new {@link MultiMapWrapper} from the given image.
*
* @param imageMatrix The image matrix to wrap
* @deprecated Use {@link #MultiMapWrapper(BufferedImage, int, int)} instead, this method is meant for internal use only.
*/
@Deprecated(since = "1.6", forRemoval = true)
public MultiMapWrapper(BufferedImage[][] imageMatrix) { public MultiMapWrapper(BufferedImage[][] imageMatrix) {
wrapperMatrix = new MapWrapper[imageMatrix.length][imageMatrix[0].length]; wrapperMatrix = new MapWrapper[imageMatrix.length][imageMatrix[0].length];
for (int x = 0; x < imageMatrix.length; x++) { for (int row = 0; row < imageMatrix.length; row++) {
if (imageMatrix[x].length != imageMatrix[0].length) { if (imageMatrix[row].length != imageMatrix[0].length) {
throw new IllegalArgumentException("An image in a MultiMapWrapper is not rectangular!"); throw new IllegalArgumentException("An image in a MultiMapWrapper is not rectangular!");
} }
for (int y = 0; y < imageMatrix[x].length; y++) { for (int column = 0; column < imageMatrix[row].length; column++) {
wrapperMatrix[x][y] = MapReflectionAPI.getMapManager().wrapImage(imageMatrix[x][y]); wrapperMatrix[row][column] = MapReflectionAPI.getMapManager().wrapImage(imageMatrix[row][column]);
} }
} }
} }
@ -117,10 +144,10 @@ public class MultiMapWrapper extends AbstractMapWrapper {
@Override @Override
public void update(@NotNull ArrayImage content) { public void update(@NotNull ArrayImage content) {
ArrayImage[][] split = splitImage(content.toBuffered(), wrapperMatrix[0].length, wrapperMatrix.length); ArrayImage[][] split = splitImage(content.toBuffered(), wrapperMatrix.length, wrapperMatrix[0].length);
for (int x = 0; x < wrapperMatrix.length; x++) { for (int row = 0; row < wrapperMatrix.length; row++) {
for (int y = 0; y < wrapperMatrix[x].length; y++) { for (int column = 0; column < wrapperMatrix[row].length; column++) {
wrapperMatrix[x][y].getController().update(split[x][y]); wrapperMatrix[row][column].getController().update(split[row][column]);
} }
} }
} }
@ -150,33 +177,27 @@ public class MultiMapWrapper extends AbstractMapWrapper {
@Override @Override
public void showInFrames(Player player, Integer[][] entityIdMatrix) { public void showInFrames(Player player, Integer[][] entityIdMatrix) {
validateArrayDimensions(wrapperMatrix, entityIdMatrix); for (int row = 0; row < entityIdMatrix.length; row++) {
for (int column = 0; column < entityIdMatrix[row].length; column++) {
for (int x = 0; x < entityIdMatrix.length; x++) { wrapperMatrix[row][column].getController().showInFrame(player, entityIdMatrix[row][column]);
for (int y = 0; y < entityIdMatrix[x].length; y++) {
wrapperMatrix[y][x].getController().showInFrame(player, entityIdMatrix[x][wrapperMatrix.length - 1 - y]);
} }
} }
} }
@Override @Override
public void showInFrames(Player player, Integer[][] entityIdMatrix, DebugCallable callable) { public void showInFrames(Player player, Integer[][] entityIdMatrix, DebugCallable callable) {
validateArrayDimensions(wrapperMatrix, entityIdMatrix); for (int row = 0; row < entityIdMatrix.length; row++) {
for (int column = 0; column < entityIdMatrix[row].length; column++) {
for (int x = 0; x < entityIdMatrix.length; x++) { wrapperMatrix[row][column].getController().showInFrame(player, entityIdMatrix[row][column], callable.call(wrapperMatrix[row][column].getController(), row, column));
for (int y = 0; y < entityIdMatrix[x].length; y++) {
wrapperMatrix[y][x].getController().showInFrame(player, entityIdMatrix[x][wrapperMatrix.length - 1 - y], callable.call(wrapperMatrix[y][x].getController(), x, y));
} }
} }
} }
@Override @Override
public void showInFrames(Player player, ItemFrame[][] itemFrameMatrix, boolean force) { public void showInFrames(Player player, ItemFrame[][] itemFrameMatrix, boolean force) {
validateArrayDimensions(wrapperMatrix, itemFrameMatrix); for (int row = 0; row < itemFrameMatrix.length; row++) {
for (int column = 0; column < itemFrameMatrix[row].length; column++) {
for (int x = 0; x < itemFrameMatrix.length; x++) { wrapperMatrix[row][column].getController().showInFrame(player, itemFrameMatrix[row][column], force);
for (int y = 0; y < itemFrameMatrix[x].length; y++) {
wrapperMatrix[y][x].getController().showInFrame(player, itemFrameMatrix[x][wrapperMatrix.length - 1 - y], force);
} }
} }
} }
@ -188,47 +209,47 @@ public class MultiMapWrapper extends AbstractMapWrapper {
@Override @Override
public void clearFrames(Player player, Integer[][] entityIdMatrix) { public void clearFrames(Player player, Integer[][] entityIdMatrix) {
validateArrayDimensions(wrapperMatrix, entityIdMatrix); for (int row = 0; row < entityIdMatrix.length; row++) {
for (int column = 0; column < entityIdMatrix[row].length; column++) {
for (int x = 0; x < entityIdMatrix.length; x++) { wrapperMatrix[row][column].getController().clearFrame(player, entityIdMatrix[row][column]);
for (int y = 0; y < entityIdMatrix[x].length; y++) {
wrapperMatrix[y][x].getController().clearFrame(player, entityIdMatrix[x][y]);
} }
} }
} }
@Override @Override
public void clearFrames(Player player, ItemFrame[][] itemFrameMatrix) { public void clearFrames(Player player, ItemFrame[][] itemFrameMatrix) {
validateArrayDimensions(wrapperMatrix, itemFrameMatrix); for (int row = 0; row < itemFrameMatrix.length; row++) {
for (int column = 0; column < itemFrameMatrix[row].length; column++) {
for (int x = 0; x < itemFrameMatrix.length; x++) { wrapperMatrix[row][column].getController().clearFrame(player, itemFrameMatrix[row][column]);
for (int y = 0; y < itemFrameMatrix[x].length; y++) {
wrapperMatrix[y][x].getController().clearFrame(player, itemFrameMatrix[x][y]);
} }
} }
} }
}; };
/* /**
* Modified Method from http://kalanir.blogspot.de/2010/02/how-to-split-image-into-chunks-java.html * Splits a BufferedImage into a matrix of ArrayImages.
*
* @param image The image to split
* @param rows The number of rows
* @param columns The number of columns
* @return The matrix of ArrayImages
*/ */
private static ArrayImage[][] splitImage(final BufferedImage image, final int columns, final int rows) { private static ArrayImage[][] splitImage(final BufferedImage image, final int rows, final int columns) {
int chunkWidth = image.getWidth() / columns; int chunkWidth = image.getWidth() / columns;
int chunkHeight = image.getHeight() / rows; int chunkHeight = image.getHeight() / rows;
ArrayImage[][] images = new ArrayImage[rows][columns]; ArrayImage[][] images = new ArrayImage[rows][columns];
for (int x = 0; x < rows; x++) {
for (int y = 0; y < columns; y++) {
BufferedImage raw = new BufferedImage(chunkWidth, chunkHeight, image.getType());
Graphics2D gr = raw.createGraphics(); for (int i = 0; i < rows; i++) {
gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null); for (int j = 0; j < columns; j++) {
gr.dispose(); int x = j * chunkWidth;
int y = i * chunkHeight;
images[x][y] = new ArrayImage(raw); BufferedImage raw = image.getSubimage(x, y, chunkWidth, chunkHeight);
raw.flush(); images[i][j] = new ArrayImage(raw);
} }
} }
return images; return images;
} }

View file

@ -35,10 +35,4 @@ public class MainUtil {
return true; return true;
} }
} }
public static <A, B> void validateArrayDimensions(A[][] arrayOne, B[][] arrayTwo) {
if (arrayOne.length != arrayTwo.length || arrayOne[0].length != arrayTwo[0].length) {
throw new IllegalArgumentException("The dimensions of two provided arrays (" + arrayOne.getClass().getName() + ", " + arrayTwo.getClass().getName() + ") do not match!");
}
}
} }