Map API cleanup

This commit is contained in:
themode 2020-10-13 16:50:03 +02:00
parent 0e5831cdc3
commit 6e954082e1
13 changed files with 125 additions and 133 deletions

View File

@ -21,11 +21,17 @@ public class NotificationCenter {
private static final String IDENTIFIER = "minestom:notification"; private static final String IDENTIFIER = "minestom:notification";
/** /**
* Can't create an instance * Can't create an instance, use the static methods instead.
*/ */
private NotificationCenter() { private NotificationCenter() {
} }
/**
* Send a {@link Notification} to one player.
*
* @param notification the {@link Notification} to send
* @param player the player to send the notification to
*/
public static void send(Notification notification, Player player) { public static void send(Notification notification, Player player) {
final PlayerConnection playerConnection = player.getPlayerConnection(); final PlayerConnection playerConnection = player.getPlayerConnection();
@ -34,6 +40,12 @@ public class NotificationCenter {
playerConnection.sendPacket(AdvancementUtils.getRemovePacket(new String[]{IDENTIFIER})); playerConnection.sendPacket(AdvancementUtils.getRemovePacket(new String[]{IDENTIFIER}));
} }
/**
* Send a {@link Notification} to a collection of players.
*
* @param notification the {@link Notification} to send
* @param players the collection of players to send the notification to
*/
public static void send(Notification notification, Collection<Player> players) { public static void send(Notification notification, Collection<Player> players) {
// Can't use PacketWriterUtils before we need the packets to come in the correct order // Can't use PacketWriterUtils before we need the packets to come in the correct order
players.forEach(player -> { players.forEach(player -> {
@ -42,7 +54,7 @@ public class NotificationCenter {
} }
/** /**
* Create the packet responsible for showing the Toast to players * Create the {@link AdvancementsPacket} responsible for showing the Toast to players
* *
* @param notification the notification * @param notification the notification
* @return the packet used to show the Toast * @return the packet used to show the Toast

View File

@ -19,7 +19,13 @@ import java.util.concurrent.ConcurrentHashMap;
import static net.minestom.server.MinecraftServer.*; import static net.minestom.server.MinecraftServer.*;
public class BenchmarkManager { /**
* Small monitoring tools that can be used to check the current memory usage and Minestom threads CPU usage.
* <p>
* Needs to be enabled with {@link #enable(UpdateOption)}. Memory can then be accessed with {@link #getUsedMemory()}
* and the CPUs usage with {@link #getResultMap()} or {@link #getCpuMonitoringMessage()}.
*/
public final class BenchmarkManager {
public static ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); public static ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
private static List<String> threads = new ArrayList<>(); private static List<String> threads = new ArrayList<>();
@ -40,7 +46,7 @@ public class BenchmarkManager {
private final Long2LongMap lastWaitedMap = new Long2LongOpenHashMap(); private final Long2LongMap lastWaitedMap = new Long2LongOpenHashMap();
private final Long2LongMap lastBlockedMap = new Long2LongOpenHashMap(); private final Long2LongMap lastBlockedMap = new Long2LongOpenHashMap();
private Map<String, ThreadResult> resultMap = new ConcurrentHashMap<>(); private final Map<String, ThreadResult> resultMap = new ConcurrentHashMap<>();
private boolean enabled = false; private boolean enabled = false;
private volatile boolean stop = false; private volatile boolean stop = false;
@ -115,7 +121,7 @@ public class BenchmarkManager {
private void refreshData() { private void refreshData() {
ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds()); ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds());
for (ThreadInfo threadInfo2 : threadInfo) { for (ThreadInfo threadInfo2 : threadInfo) {
String name = threadInfo2.getThreadName(); final String name = threadInfo2.getThreadName();
boolean shouldBenchmark = false; boolean shouldBenchmark = false;
for (String thread : threads) { for (String thread : threads) {
if (name.startsWith(thread)) { if (name.startsWith(thread)) {
@ -126,32 +132,32 @@ public class BenchmarkManager {
if (!shouldBenchmark) if (!shouldBenchmark)
continue; continue;
long id = threadInfo2.getThreadId(); final long id = threadInfo2.getThreadId();
long lastCpuTime = lastCpuTimeMap.getOrDefault(id, 0L); final long lastCpuTime = lastCpuTimeMap.getOrDefault(id, 0L);
long lastUserTime = lastUserTimeMap.getOrDefault(id, 0L); final long lastUserTime = lastUserTimeMap.getOrDefault(id, 0L);
long lastWaitedTime = lastWaitedMap.getOrDefault(id, 0L); final long lastWaitedTime = lastWaitedMap.getOrDefault(id, 0L);
long lastBlockedTime = lastBlockedMap.getOrDefault(id, 0L); final long lastBlockedTime = lastBlockedMap.getOrDefault(id, 0L);
long blockedTime = threadInfo2.getBlockedTime(); final long blockedTime = threadInfo2.getBlockedTime();
long waitedTime = threadInfo2.getWaitedTime(); final long waitedTime = threadInfo2.getWaitedTime();
long cpuTime = threadMXBean.getThreadCpuTime(id); final long cpuTime = threadMXBean.getThreadCpuTime(id);
long userTime = threadMXBean.getThreadUserTime(id); final long userTime = threadMXBean.getThreadUserTime(id);
lastCpuTimeMap.put(id, cpuTime); lastCpuTimeMap.put(id, cpuTime);
lastUserTimeMap.put(id, userTime); lastUserTimeMap.put(id, userTime);
lastWaitedMap.put(id, waitedTime); lastWaitedMap.put(id, waitedTime);
lastBlockedMap.put(id, blockedTime); lastBlockedMap.put(id, blockedTime);
double totalCpuTime = (double) (cpuTime - lastCpuTime) / 1000000D; final double totalCpuTime = (double) (cpuTime - lastCpuTime) / 1000000D;
double totalUserTime = (double) (userTime - lastUserTime) / 1000000D; final double totalUserTime = (double) (userTime - lastUserTime) / 1000000D;
long totalBlocked = blockedTime - lastBlockedTime; final long totalBlocked = blockedTime - lastBlockedTime;
long totalWaited = waitedTime - lastWaitedTime; final long totalWaited = waitedTime - lastWaitedTime;
double cpuPercentage = totalCpuTime / (double) time * 100L; final double cpuPercentage = totalCpuTime / (double) time * 100L;
double userPercentage = totalUserTime / (double) time * 100L; final double userPercentage = totalUserTime / (double) time * 100L;
double waitedPercentage = totalWaited / (double) time * 100L; final double waitedPercentage = totalWaited / (double) time * 100L;
double blockedPercentage = totalBlocked / (double) time * 100L; final double blockedPercentage = totalBlocked / (double) time * 100L;
ThreadResult threadResult = new ThreadResult(cpuPercentage, userPercentage, waitedPercentage, blockedPercentage); ThreadResult threadResult = new ThreadResult(cpuPercentage, userPercentage, waitedPercentage, blockedPercentage);
resultMap.put(name, threadResult); resultMap.put(name, threadResult);

View File

@ -2,7 +2,7 @@ package net.minestom.server.benchmark;
public class ThreadResult { public class ThreadResult {
private double cpuPercentage, userPercentage, waitedPercentage, blockedPercentage; private final double cpuPercentage, userPercentage, waitedPercentage, blockedPercentage;
protected ThreadResult(double cpuPercentage, double userPercentage, double waitedPercentage, double blockedPercentage) { protected ThreadResult(double cpuPercentage, double userPercentage, double waitedPercentage, double blockedPercentage) {
this.cpuPercentage = cpuPercentage; this.cpuPercentage = cpuPercentage;

View File

@ -18,15 +18,15 @@ public interface Framebuffer {
default void preparePacket(MapDataPacket packet, int minX, int minY, int width, int height) { default void preparePacket(MapDataPacket packet, int minX, int minY, int width, int height) {
byte[] colors; byte[] colors;
if(minX == 0 && minY == 0 && width == WIDTH && height == HEIGHT) { if (minX == 0 && minY == 0 && width == WIDTH && height == HEIGHT) {
colors = toMapColors(); colors = toMapColors();
} else { } else {
colors = new byte[width*height]; colors = new byte[width * height];
byte[] mapColors = toMapColors(); final byte[] mapColors = toMapColors();
for (int y = minY; y < Math.min(HEIGHT, minY+height); y++) { for (int y = minY; y < Math.min(HEIGHT, minY + height); y++) {
for (int x = minX; x < Math.min(WIDTH, minX+width); x++) { for (int x = minX; x < Math.min(WIDTH, minX + width); x++) {
byte color = mapColors[index(x, y, WIDTH)]; byte color = mapColors[index(x, y, WIDTH)];
colors[index(x-minX, y-minY, width)] = color; colors[index(x - minX, y - minY, width)] = color;
} }
} }
} }
@ -44,7 +44,7 @@ public interface Framebuffer {
} }
static int index(int x, int z, int stride) { static int index(int x, int z, int stride) {
return z*stride + x; return z * stride + x;
} }
} }

View File

@ -3,19 +3,22 @@ package net.minestom.server.map;
import net.minestom.server.network.packet.server.play.MapDataPacket; import net.minestom.server.network.packet.server.play.MapDataPacket;
/** /**
* Framebuffer that is meant to be split in sub-framebuffers. Contrary to Framebuffer, LargeFramebuffer supports sizes over 128x128 pixels. * Framebuffer that is meant to be split in sub-framebuffers.
* Contrary to {@link Framebuffer}, LargeFramebuffer supports sizes over 128x128 pixels.
*/ */
public interface LargeFramebuffer { public interface LargeFramebuffer {
int width(); int width();
int height(); int height();
/** /**
* Returns a new Framebuffer that represent a 128x128 sub-view of this framebuffer. * Returns a new {@link Framebuffer} that represent a 128x128 sub-view of this framebuffer.
* Implementations are free (but not guaranteed) to throw exceptions if left &amp; top produces out-of-bounds coordinates. * Implementations are free (but not guaranteed) to throw exceptions if left &amp; top produces out-of-bounds coordinates.
*
* @param left * @param left
* @param top * @param top
* @return * @return the sub-view {@link Framebuffer}
*/ */
Framebuffer createSubView(int left, int top); Framebuffer createSubView(int left, int top);
@ -23,18 +26,19 @@ public interface LargeFramebuffer {
/** /**
* Prepares the packet to render a 128x128 sub view of this framebuffer * Prepares the packet to render a 128x128 sub view of this framebuffer
* @param packet *
* @param packet the {@link MapDataPacket} to prepare
* @param left * @param left
* @param top * @param top
*/ */
default void preparePacket(MapDataPacket packet, int left, int top) { default void preparePacket(MapDataPacket packet, int left, int top) {
byte[] colors = new byte[Framebuffer.WIDTH*Framebuffer.WIDTH]; byte[] colors = new byte[Framebuffer.WIDTH * Framebuffer.WIDTH];
int width = Math.min(width(), left+Framebuffer.WIDTH) - left; final int width = Math.min(width(), left + Framebuffer.WIDTH) - left;
int height = Math.min(height(), top+Framebuffer.HEIGHT) - top; final int height = Math.min(height(), top + Framebuffer.HEIGHT) - top;
for (int y = top; y < height; y++) { for (int y = top; y < height; y++) {
for (int x = left; x < width; x++) { for (int x = left; x < width; x++) {
byte color = getMapColor(left, top); final byte color = getMapColor(left, top);
colors[Framebuffer.index(x-left, y-top)] = color; colors[Framebuffer.index(x - left, y - top)] = color;
} }
} }

View File

@ -7,7 +7,7 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Function; import java.util.function.Function;
public enum MapColors { public enum MapColors {
NONE(0,0,0), NONE(0, 0, 0),
GRASS(127, 178, 56), GRASS(127, 178, 56),
SAND(247, 233, 163), SAND(247, 233, 163),
WOOL(199, 199, 199), WOOL(199, 199, 199),
@ -65,8 +65,7 @@ public enum MapColors {
WARPED_NYLIUM(22, 126, 134), WARPED_NYLIUM(22, 126, 134),
WARPED_STEM(58, 142, 140), WARPED_STEM(58, 142, 140),
WARPED_HYPHAE(86, 44, 62), WARPED_HYPHAE(86, 44, 62),
WARPED_WART_BLOCK(20, 180, 133), WARPED_WART_BLOCK(20, 180, 133);
;
private final int red; private final int red;
private final int green; private final int green;
@ -85,13 +84,13 @@ public enum MapColors {
static { static {
ColorMappingStrategy strategy; ColorMappingStrategy strategy;
String strategyStr = System.getProperty(MAPPING_ARGUMENT); String strategyStr = System.getProperty(MAPPING_ARGUMENT);
if(strategyStr == null) { if (strategyStr == null) {
strategy = ColorMappingStrategy.LAZY; strategy = ColorMappingStrategy.LAZY;
} else { } else {
try { try {
strategy = ColorMappingStrategy.valueOf(strategyStr.toUpperCase()); strategy = ColorMappingStrategy.valueOf(strategyStr.toUpperCase());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
System.err.println("Unknown color mapping strategy: "+strategyStr); System.err.println("Unknown color mapping strategy: " + strategyStr);
System.err.println("Defaulting to LAZY."); System.err.println("Defaulting to LAZY.");
strategy = ColorMappingStrategy.LAZY; strategy = ColorMappingStrategy.LAZY;
} }
@ -100,16 +99,16 @@ public enum MapColors {
int reduction = 10; int reduction = 10;
String reductionStr = System.getProperty(REDUCTION_ARGUMENT); String reductionStr = System.getProperty(REDUCTION_ARGUMENT);
if(reductionStr != null) { if (reductionStr != null) {
try { try {
reduction = Integer.parseInt(reductionStr); reduction = Integer.parseInt(reductionStr);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.err.println("Invalid integer in reduction argument: "+reductionStr); System.err.println("Invalid integer in reduction argument: " + reductionStr);
e.printStackTrace(); e.printStackTrace();
} }
if(reduction < 0 || reduction >= 255) { if (reduction < 0 || reduction >= 255) {
System.err.println("Reduction was found to be invalid: "+reduction+". Must in 0-255, defaulting to 10."); System.err.println("Reduction was found to be invalid: " + reduction + ". Must in 0-255, defaulting to 10.");
reduction = 10; reduction = 10;
} }
} }
@ -133,14 +132,14 @@ public enum MapColors {
* Returns the color index with RGB multiplied by 0.53, to use on a map * Returns the color index with RGB multiplied by 0.53, to use on a map
*/ */
public byte multiply53() { public byte multiply53() {
return (byte) ((ordinal() << 2) +3); return (byte) ((ordinal() << 2) + 3);
} }
/** /**
* Returns the color index with RGB multiplied by 0.86, to use on a map * Returns the color index with RGB multiplied by 0.86, to use on a map
*/ */
public byte multiply86() { public byte multiply86() {
return (byte) ((ordinal() << 2) +1); return (byte) ((ordinal() << 2) + 1);
} }
/** /**
@ -154,7 +153,7 @@ public enum MapColors {
* Returns the color index to use on a map * Returns the color index to use on a map
*/ */
public byte baseColor() { public byte baseColor() {
return (byte) ((ordinal() << 2) +2); return (byte) ((ordinal() << 2) + 2);
} }
public int red() { public int red() {
@ -170,14 +169,14 @@ public enum MapColors {
} }
private static void fillRGBMap() { private static void fillRGBMap() {
for(MapColors base : values()) { for (MapColors base : values()) {
if(base == NONE) if (base == NONE)
continue; continue;
for(Multiplier m : Multiplier.values()) { for (Multiplier m : Multiplier.values()) {
PreciseMapColor preciseMapColor = new PreciseMapColor(base, m); PreciseMapColor preciseMapColor = new PreciseMapColor(base, m);
int rgb = preciseMapColor.toRGB(); int rgb = preciseMapColor.toRGB();
if(mappingStrategy == ColorMappingStrategy.APPROXIMATE) { if (mappingStrategy == ColorMappingStrategy.APPROXIMATE) {
rgb = reduceColor(rgb); rgb = reduceColor(rgb);
} }
rgbMap.put(rgb, preciseMapColor); rgbMap.put(rgb, preciseMapColor);
@ -186,7 +185,7 @@ public enum MapColors {
} }
private static void fillRGBArray() { private static void fillRGBArray() {
rgbArray = new PreciseMapColor[0xFFFFFF+1]; rgbArray = new PreciseMapColor[0xFFFFFF + 1];
MinestomThread threads = new MinestomThread(Runtime.getRuntime().availableProcessors(), "RGBMapping", true); MinestomThread threads = new MinestomThread(Runtime.getRuntime().availableProcessors(), "RGBMapping", true);
for (int rgb = 0; rgb <= 0xFFFFFF; rgb++) { for (int rgb = 0; rgb <= 0xFFFFFF; rgb++) {
int finalRgb = rgb; int finalRgb = rgb;
@ -204,23 +203,23 @@ public enum MapColors {
public static PreciseMapColor closestColor(int argb) { public static PreciseMapColor closestColor(int argb) {
int noAlpha = argb & 0xFFFFFF; int noAlpha = argb & 0xFFFFFF;
if (mappingStrategy == ColorMappingStrategy.PRECISE) { if (mappingStrategy == ColorMappingStrategy.PRECISE) {
if(rgbArray == null) { if (rgbArray == null) {
synchronized (MapColors.class) { synchronized (MapColors.class) {
if(rgbArray == null) { if (rgbArray == null) {
fillRGBArray(); fillRGBArray();
} }
} }
} }
return rgbArray[noAlpha]; return rgbArray[noAlpha];
} }
if(rgbMap.isEmpty()) { if (rgbMap.isEmpty()) {
synchronized (rgbMap) { synchronized (rgbMap) {
if(rgbMap.isEmpty()) { if (rgbMap.isEmpty()) {
fillRGBMap(); fillRGBMap();
} }
} }
} }
if(mappingStrategy == ColorMappingStrategy.APPROXIMATE) { if (mappingStrategy == ColorMappingStrategy.APPROXIMATE) {
noAlpha = reduceColor(noAlpha); noAlpha = reduceColor(noAlpha);
} }
return rgbMap.computeIfAbsent(noAlpha, MapColors::mapColor); return rgbMap.computeIfAbsent(noAlpha, MapColors::mapColor);
@ -231,32 +230,32 @@ public enum MapColors {
int green = (rgb >> 8) & 0xFF; int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF; int blue = rgb & 0xFF;
red = red/colorReduction; red = red / colorReduction;
green = green/colorReduction; green = green / colorReduction;
blue = blue/colorReduction; blue = blue / colorReduction;
return (red << 16) | (green << 8) | blue; return (red << 16) | (green << 8) | blue;
} }
private static PreciseMapColor mapColor(int rgb) { private static PreciseMapColor mapColor(int rgb) {
PreciseMapColor closest = null; PreciseMapColor closest = null;
int closestDistance = Integer.MAX_VALUE; int closestDistance = Integer.MAX_VALUE;
for(MapColors base : values()) { for (MapColors base : values()) {
if (base == NONE) if (base == NONE)
continue; continue;
for (Multiplier m : Multiplier.values()) { for (Multiplier m : Multiplier.values()) {
int rgbKey = PreciseMapColor.toRGB(base, m); final int rgbKey = PreciseMapColor.toRGB(base, m);
int redKey = (rgbKey >> 16) & 0xFF; final int redKey = (rgbKey >> 16) & 0xFF;
int greenKey = (rgbKey >> 8) & 0xFF; final int greenKey = (rgbKey >> 8) & 0xFF;
int blueKey = rgbKey & 0xFF; final int blueKey = rgbKey & 0xFF;
int red = (rgb >> 16) & 0xFF; final int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF; final int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF; final int blue = rgb & 0xFF;
int dr = redKey - red; final int dr = redKey - red;
int dg = greenKey - green; final int dg = greenKey - green;
int db = blueKey - blue; final int db = blueKey - blue;
int dist = (dr * dr + dg * dg + db * db); final int dist = (dr * dr + dg * dg + db * db);
if (dist < closestDistance) { if (dist < closestDistance) {
closest = new PreciseMapColor(base, m); closest = new PreciseMapColor(base, m);
closestDistance = dist; closestDistance = dist;
@ -267,8 +266,8 @@ public enum MapColors {
} }
public static class PreciseMapColor { public static class PreciseMapColor {
private MapColors baseColor; private final MapColors baseColor;
private Multiplier multiplier; private final Multiplier multiplier;
PreciseMapColor(MapColors base, Multiplier multiplier) { PreciseMapColor(MapColors base, Multiplier multiplier) {
this.baseColor = base; this.baseColor = base;
@ -300,9 +299,9 @@ public enum MapColors {
g *= multiplier.multiplier(); g *= multiplier.multiplier();
b *= multiplier.multiplier(); b *= multiplier.multiplier();
int red = (int) r; final int red = (int) r;
int green = (int) g; final int green = (int) g;
int blue = (int) b; final int blue = (int) b;
return (red << 16) | (green << 8) | blue; return (red << 16) | (green << 8) | blue;
} }
} }
@ -311,8 +310,7 @@ public enum MapColors {
x1_00(MapColors::baseColor, 1.00), x1_00(MapColors::baseColor, 1.00),
x0_53(MapColors::multiply53, 0.53), x0_53(MapColors::multiply53, 0.53),
x0_71(MapColors::multiply71, 0.71), x0_71(MapColors::multiply71, 0.71),
x0_86(MapColors::multiply86, 0.86), x0_86(MapColors::multiply86, 0.86);
;
private final Function<MapColors, Byte> indexGetter; private final Function<MapColors, Byte> indexGetter;
private final double multiplier; private final double multiplier;

View File

@ -1,14 +0,0 @@
package net.minestom.server.map;
public class MapHandle {
private int mapId;
protected MapHandle(int mapId) {
this.mapId = mapId;
}
public int getMapId() {
return mapId;
}
}

View File

@ -1,14 +0,0 @@
package net.minestom.server.map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class MapManager {
private Int2ObjectMap<MapHandle> objectMap = new Int2ObjectOpenHashMap<>();
public MapHandle getMap(int mapId) {
return objectMap.computeIfAbsent(mapId, id -> new MapHandle(id));
}
}

View File

@ -3,14 +3,15 @@ package net.minestom.server.map.framebuffers;
import net.minestom.server.map.Framebuffer; import net.minestom.server.map.Framebuffer;
/** /**
* Framebuffer with direct access to the colors array * {@link Framebuffer} with direct access to the colors array
*/ */
public class DirectFramebuffer implements Framebuffer { public class DirectFramebuffer implements Framebuffer {
private final byte[] colors = new byte[WIDTH*HEIGHT]; private final byte[] colors = new byte[WIDTH * HEIGHT];
/** /**
* Mutable colors array * Mutable colors array
*
* @return * @return
*/ */
public byte[] getColors() { public byte[] getColors() {

View File

@ -1,7 +1,6 @@
package net.minestom.server.map.framebuffers; package net.minestom.server.map.framebuffers;
import net.minestom.server.map.Framebuffer; import net.minestom.server.map.Framebuffer;
import net.minestom.server.map.LargeFramebuffer;
import net.minestom.server.map.MapColors; import net.minestom.server.map.MapColors;
import java.awt.*; import java.awt.*;
@ -9,18 +8,18 @@ import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt; import java.awt.image.DataBufferInt;
/** /**
* Framebuffer that embeds a BufferedImage, allowing for rendering directly via Graphics2D or its pixel array * {@link Framebuffer} that embeds a BufferedImage, allowing for rendering directly via Graphics2D or its pixel array.
*/ */
public class Graphics2DFramebuffer implements Framebuffer { public class Graphics2DFramebuffer implements Framebuffer {
private final byte[] colors = new byte[WIDTH*HEIGHT]; private final byte[] colors = new byte[WIDTH * HEIGHT];
private final BufferedImage backingImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); private final BufferedImage backingImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private final Graphics2D renderer; private final Graphics2D renderer;
private final int[] pixels; private final int[] pixels;
public Graphics2DFramebuffer() { public Graphics2DFramebuffer() {
renderer = backingImage.createGraphics(); renderer = backingImage.createGraphics();
pixels = ((DataBufferInt)backingImage.getRaster().getDataBuffer()).getData(); pixels = ((DataBufferInt) backingImage.getRaster().getDataBuffer()).getData();
} }
public Graphics2D getRenderer() { public Graphics2D getRenderer() {
@ -32,11 +31,11 @@ public class Graphics2DFramebuffer implements Framebuffer {
} }
public int get(int x, int z) { public int get(int x, int z) {
return pixels[x+z*WIDTH]; // stride is always the width of the image return pixels[x + z * WIDTH]; // stride is always the width of the image
} }
public Graphics2DFramebuffer set(int x, int z, int rgb) { public Graphics2DFramebuffer set(int x, int z, int rgb) {
pixels[x+z*WIDTH] = rgb; pixels[x + z * WIDTH] = rgb;
return this; return this;
} }

View File

@ -5,8 +5,8 @@ import net.minestom.server.map.LargeFramebuffer;
import net.minestom.server.map.MapColors; import net.minestom.server.map.MapColors;
/** /**
* Large framebuffer with direct access to the colors array. * {@link LargeFramebuffer} with direct access to the colors array.
* * <p>
* This implementation does not throw errors when accessing out-of-bounds coordinates through sub-views, and will instead * This implementation does not throw errors when accessing out-of-bounds coordinates through sub-views, and will instead
* use {@link MapColors#NONE}. This is only the case for sub-views, access through {@link #setMapColor(int, int, byte)} * use {@link MapColors#NONE}. This is only the case for sub-views, access through {@link #setMapColor(int, int, byte)}
* and {@link #getMapColor(int, int)} will throw an exception if out-of-bounds coordinates are inputted. * and {@link #getMapColor(int, int)} will throw an exception if out-of-bounds coordinates are inputted.
@ -19,13 +19,14 @@ public class LargeDirectFramebuffer implements LargeFramebuffer {
/** /**
* Creates a new {@link LargeDirectFramebuffer} with the desired size * Creates a new {@link LargeDirectFramebuffer} with the desired size
*
* @param width * @param width
* @param height * @param height
*/ */
public LargeDirectFramebuffer(int width, int height) { public LargeDirectFramebuffer(int width, int height) {
this.width = width; this.width = width;
this.height = height; this.height = height;
this.colors = new byte[width*height]; this.colors = new byte[width * height];
} }
@Override @Override
@ -44,15 +45,15 @@ public class LargeDirectFramebuffer implements LargeFramebuffer {
} }
public LargeDirectFramebuffer setMapColor(int x, int y, byte color) { public LargeDirectFramebuffer setMapColor(int x, int y, byte color) {
if(!bounds(x, y)) throw new IndexOutOfBoundsException("Invalid x;y coordinate: "+x+";"+y); if (!bounds(x, y)) throw new IndexOutOfBoundsException("Invalid x;y coordinate: " + x + ";" + y);
colors[y*width+x] = color; colors[y * width + x] = color;
return this; return this;
} }
@Override @Override
public byte getMapColor(int x, int y) { public byte getMapColor(int x, int y) {
if(!bounds(x, y)) throw new IndexOutOfBoundsException("Invalid x;y coordinate: "+x+";"+y); if (!bounds(x, y)) throw new IndexOutOfBoundsException("Invalid x;y coordinate: " + x + ";" + y);
return colors[y*width+x]; return colors[y * width + x];
} }
private boolean bounds(int x, int y) { private boolean bounds(int x, int y) {

View File

@ -9,11 +9,11 @@ import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt; import java.awt.image.DataBufferInt;
/** /**
* LargeFramebuffer that embeds a BufferedImage, allowing for rendering directly via Graphics2D or its pixel array * {@link LargeFramebuffer} that embeds a {@link BufferedImage},
* allowing for rendering directly via {@link Graphics2D} or its pixel array.
*/ */
public class LargeGraphics2DFramebuffer implements LargeFramebuffer { public class LargeGraphics2DFramebuffer implements LargeFramebuffer {
private final byte[] colors;
private final BufferedImage backingImage; private final BufferedImage backingImage;
private final Graphics2D renderer; private final Graphics2D renderer;
private final int[] pixels; private final int[] pixels;
@ -23,10 +23,9 @@ public class LargeGraphics2DFramebuffer implements LargeFramebuffer {
public LargeGraphics2DFramebuffer(int width, int height) { public LargeGraphics2DFramebuffer(int width, int height) {
this.width = width; this.width = width;
this.height = height; this.height = height;
colors = new byte[width*height];
backingImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); backingImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
renderer = backingImage.createGraphics(); renderer = backingImage.createGraphics();
pixels = ((DataBufferInt)backingImage.getRaster().getDataBuffer()).getData(); pixels = ((DataBufferInt) backingImage.getRaster().getDataBuffer()).getData();
} }
public Graphics2D getRenderer() { public Graphics2D getRenderer() {
@ -38,11 +37,11 @@ public class LargeGraphics2DFramebuffer implements LargeFramebuffer {
} }
public int get(int x, int z) { public int get(int x, int z) {
return pixels[x+z*width]; // stride is always the width of the image return pixels[x + z * width]; // stride is always the width of the image
} }
public LargeGraphics2DFramebuffer set(int x, int z, int rgb) { public LargeGraphics2DFramebuffer set(int x, int z, int rgb) {
pixels[x+z*width] = rgb; pixels[x + z * width] = rgb;
return this; return this;
} }

View File

@ -9,7 +9,7 @@ public final class AdvancementUtils {
} }
/** /**
* Get an {@link AdvancementsPacket} which remove the specified identifiers * Get an {@link AdvancementsPacket} which remove the specified identifiers.
* *
* @param identifiers the identifiers to remove * @param identifiers the identifiers to remove
* @return the packet to remove all the identifiers * @return the packet to remove all the identifiers