From 83f1ea98ceaac2875438d01d14e9ca753e345bca Mon Sep 17 00:00:00 2001 From: "H. Boyd" <8950185+hboyd2003@users.noreply.github.com> Date: Sun, 4 Oct 2026 14:59:39 -0400 Subject: [PATCH 1/3] Make Color implement ARGBLike --- paper-api/src/main/java/org/bukkit/Color.java | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/paper-api/src/main/java/org/bukkit/Color.java b/paper-api/src/main/java/org/bukkit/Color.java index 1720800720b4..aa9cff66c4e1 100644 --- a/paper-api/src/main/java/org/bukkit/Color.java +++ b/paper-api/src/main/java/org/bukkit/Color.java @@ -6,10 +6,12 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; +import net.kyori.adventure.util.ARGBLike; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; /** * A container for a color palette. This class is immutable; the set methods @@ -17,7 +19,7 @@ * but subject to change. */ @SerializableAs("Color") -public final class Color implements ConfigurationSerializable { +public final class Color implements ConfigurationSerializable, ARGBLike { private static final int BIT_MASK = 0xff; private static final int DEFAULT_ALPHA = 255; @@ -221,6 +223,16 @@ public int getAlpha() { return BIT_MASK & alpha; } + /** + * Gets the alpha component + * + * @return alpha component, from 0 to 255 + */ + @Override + public int alpha() { + return getAlpha(); + } + /** * Creates a new Color object with specified component * @@ -241,6 +253,16 @@ public int getRed() { return BIT_MASK & red; } + /** + * Gets the red component + * + * @return red component, from 0 to 255 + */ + @Override + public int red() { + return getRed(); + } + /** * Creates a new Color object with specified component * @@ -261,6 +283,16 @@ public int getGreen() { return BIT_MASK & green; } + /** + * Gets the green component + * + * @return green component, from 0 to 255 + */ + @Override + public int green() { + return getGreen(); + } + /** * Creates a new Color object with specified component * @@ -281,6 +313,16 @@ public int getBlue() { return BIT_MASK & blue; } + /** + * Gets the blue component + * + * @return blue component, from 0 to 255 + */ + @Override + public int blue() { + return getBlue(); + } + /** * Creates a new Color object with specified component * From 8c787b1670b0bb6806f987da8913de79b521f013 Mon Sep 17 00:00:00 2001 From: "H. Boyd" <8950185+hboyd2003@users.noreply.github.com> Date: Mon, 5 Oct 2026 23:17:37 -0400 Subject: [PATCH 2/3] Add range annotations to Color methods --- paper-api/src/main/java/org/bukkit/Color.java | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Color.java b/paper-api/src/main/java/org/bukkit/Color.java index aa9cff66c4e1..f0886543fa8e 100644 --- a/paper-api/src/main/java/org/bukkit/Color.java +++ b/paper-api/src/main/java/org/bukkit/Color.java @@ -124,7 +124,12 @@ public final class Color implements ConfigurationSerializable, ARGBLike { * @throws IllegalArgumentException if any value is strictly {@literal >255 or <0} */ @NotNull - public static Color fromARGB(int alpha, int red, int green, int blue) throws IllegalArgumentException { + public static Color fromARGB( + @Range(from = 0, to = 255) int alpha, + @Range(from = 0, to = 255) int red, + @Range(from = 0, to = 255) int green, + @Range(from = 0, to = 255) int blue + ) throws IllegalArgumentException { return new Color(alpha, red, green, blue); } @@ -138,7 +143,11 @@ public static Color fromARGB(int alpha, int red, int green, int blue) throws Ill * @throws IllegalArgumentException if any value is strictly {@literal >255 or <0} */ @NotNull - public static Color fromRGB(int red, int green, int blue) throws IllegalArgumentException { + public static Color fromRGB( + @Range(from = 0, to = 255) int red, + @Range(from = 0, to = 255) int green, + @Range(from = 0, to = 255) int blue + ) throws IllegalArgumentException { return new Color(DEFAULT_ALPHA, red, green, blue); } @@ -152,7 +161,11 @@ public static Color fromRGB(int red, int green, int blue) throws IllegalArgument * @throws IllegalArgumentException if any value is strictly {@literal >255 or <0} */ @NotNull - public static Color fromBGR(int blue, int green, int red) throws IllegalArgumentException { + public static Color fromBGR( + @Range(from = 0, to = 255) int blue, + @Range(from = 0, to = 255) int green, + @Range(from = 0, to = 255) int red + ) throws IllegalArgumentException { return new Color(DEFAULT_ALPHA, red, green, blue); } @@ -219,7 +232,7 @@ private Color(int alpha, int red, int green, int blue) { * * @return alpha component, from 0 to 255 */ - public int getAlpha() { + public @Range(from = 0, to = 255) int getAlpha() { return BIT_MASK & alpha; } @@ -229,7 +242,7 @@ public int getAlpha() { * @return alpha component, from 0 to 255 */ @Override - public int alpha() { + public @Range(from = 0, to = 255) int alpha() { return getAlpha(); } @@ -240,7 +253,7 @@ public int alpha() { * @return a new color object with the alpha component */ @NotNull - public Color setAlpha(int alpha) { + public Color setAlpha(@Range(from = 0, to = 255) int alpha) { return fromARGB(alpha, getRed(), getGreen(), getBlue()); } @@ -249,7 +262,7 @@ public Color setAlpha(int alpha) { * * @return red component, from 0 to 255 */ - public int getRed() { + public @Range(from = 0, to = 255) int getRed() { return BIT_MASK & red; } @@ -259,7 +272,7 @@ public int getRed() { * @return red component, from 0 to 255 */ @Override - public int red() { + public @Range(from = 0, to = 255) int red() { return getRed(); } @@ -270,7 +283,7 @@ public int red() { * @return a new color object with the red component */ @NotNull - public Color setRed(int red) { + public Color setRed(@Range(from = 0, to = 255) int red) { return fromARGB(getAlpha(), red, getGreen(), getBlue()); } @@ -279,7 +292,7 @@ public Color setRed(int red) { * * @return green component, from 0 to 255 */ - public int getGreen() { + public @Range(from = 0, to = 255) int getGreen() { return BIT_MASK & green; } @@ -289,7 +302,7 @@ public int getGreen() { * @return green component, from 0 to 255 */ @Override - public int green() { + public @Range(from = 0, to = 255) int green() { return getGreen(); } @@ -300,7 +313,7 @@ public int green() { * @return a new color object with the green component */ @NotNull - public Color setGreen(int green) { + public Color setGreen(@Range(from = 0, to = 255) int green) { return fromARGB(getAlpha(), getRed(), green, getBlue()); } @@ -309,7 +322,7 @@ public Color setGreen(int green) { * * @return blue component, from 0 to 255 */ - public int getBlue() { + public @Range(from = 0, to = 255) int getBlue() { return BIT_MASK & blue; } @@ -319,7 +332,7 @@ public int getBlue() { * @return blue component, from 0 to 255 */ @Override - public int blue() { + public @Range(from = 0, to = 255) int blue() { return getBlue(); } @@ -330,7 +343,7 @@ public int blue() { * @return a new color object with the blue component */ @NotNull - public Color setBlue(int blue) { + public Color setBlue(@Range(from = 0, to = 255) int blue) { return fromARGB(getAlpha(), getRed(), getGreen(), blue); } From c73eae63c66675188b3bdc85470996ecad862fa9 Mon Sep 17 00:00:00 2001 From: Doc Date: Wed, 21 Oct 2026 23:29:05 -0300 Subject: [PATCH 3/3] Cleanup --- paper-api/src/main/java/org/bukkit/Color.java | 143 +++++++++--------- 1 file changed, 71 insertions(+), 72 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Color.java b/paper-api/src/main/java/org/bukkit/Color.java index f0886543fa8e..ccc0e9ecde43 100644 --- a/paper-api/src/main/java/org/bukkit/Color.java +++ b/paper-api/src/main/java/org/bukkit/Color.java @@ -125,10 +125,10 @@ public final class Color implements ConfigurationSerializable, ARGBLike { */ @NotNull public static Color fromARGB( - @Range(from = 0, to = 255) int alpha, - @Range(from = 0, to = 255) int red, - @Range(from = 0, to = 255) int green, - @Range(from = 0, to = 255) int blue + final @Range(from = 0, to = 255) int alpha, + final @Range(from = 0, to = 255) int red, + final @Range(from = 0, to = 255) int green, + final @Range(from = 0, to = 255) int blue ) throws IllegalArgumentException { return new Color(alpha, red, green, blue); } @@ -144,9 +144,9 @@ public static Color fromARGB( */ @NotNull public static Color fromRGB( - @Range(from = 0, to = 255) int red, - @Range(from = 0, to = 255) int green, - @Range(from = 0, to = 255) int blue + final @Range(from = 0, to = 255) int red, + final @Range(from = 0, to = 255) int green, + final @Range(from = 0, to = 255) int blue ) throws IllegalArgumentException { return new Color(DEFAULT_ALPHA, red, green, blue); } @@ -162,9 +162,9 @@ public static Color fromRGB( */ @NotNull public static Color fromBGR( - @Range(from = 0, to = 255) int blue, - @Range(from = 0, to = 255) int green, - @Range(from = 0, to = 255) int red + final @Range(from = 0, to = 255) int blue, + final @Range(from = 0, to = 255) int green, + final @Range(from = 0, to = 255) int red ) throws IllegalArgumentException { return new Color(DEFAULT_ALPHA, red, green, blue); } @@ -179,7 +179,7 @@ public static Color fromBGR( * bits */ @NotNull - public static Color fromRGB(int rgb) throws IllegalArgumentException { + public static Color fromRGB(final int rgb) throws IllegalArgumentException { Preconditions.checkArgument((rgb >> 24) == 0, "Extraneous data in: %s", rgb); return fromRGB(rgb >> 16 & BIT_MASK, rgb >> 8 & BIT_MASK, rgb & BIT_MASK); } @@ -192,7 +192,7 @@ public static Color fromRGB(int rgb) throws IllegalArgumentException { * @return a new color object for specified values */ @NotNull - public static Color fromARGB(int argb) { + public static Color fromARGB(final int argb) { return fromARGB(argb >> 24 & BIT_MASK, argb >> 16 & BIT_MASK, argb >> 8 & BIT_MASK, argb & BIT_MASK); } @@ -206,16 +206,16 @@ public static Color fromARGB(int argb) { * bits */ @NotNull - public static Color fromBGR(int bgr) throws IllegalArgumentException { + public static Color fromBGR(final int bgr) throws IllegalArgumentException { Preconditions.checkArgument((bgr >> 24) == 0, "Extrenuous data in: %s", bgr); return fromBGR(bgr >> 16 & BIT_MASK, bgr >> 8 & BIT_MASK, bgr & BIT_MASK); } - private Color(int red, int green, int blue) { + private Color(final int red, final int green, final int blue) { this(DEFAULT_ALPHA, red, green, blue); } - private Color(int alpha, int red, int green, int blue) { + private Color(final int alpha, final int red, final int green, final int blue) { Preconditions.checkArgument(alpha >= 0 && alpha <= 0xff, "Alpha[%s] is not between 0-255", alpha); Preconditions.checkArgument(red >= 0 && red <= 0xff, "Red[%s] is not between 0-255", red); Preconditions.checkArgument(green >= 0 && green <= 0xff, "Green[%s] is not between 0-255", green); @@ -228,7 +228,7 @@ private Color(int alpha, int red, int green, int blue) { } /** - * Gets the alpha component + * Gets the alpha component. * * @return alpha component, from 0 to 255 */ @@ -237,114 +237,114 @@ private Color(int alpha, int red, int green, int blue) { } /** - * Gets the alpha component + * Gets the alpha component. * * @return alpha component, from 0 to 255 */ @Override public @Range(from = 0, to = 255) int alpha() { - return getAlpha(); + return this.getAlpha(); } /** - * Creates a new Color object with specified component + * Creates a new Color object with a specified component. * * @param alpha the alpha component, from 0 to 255 * @return a new color object with the alpha component */ @NotNull - public Color setAlpha(@Range(from = 0, to = 255) int alpha) { - return fromARGB(alpha, getRed(), getGreen(), getBlue()); + public Color setAlpha(final @Range(from = 0, to = 255) int alpha) { + return fromARGB(alpha, this.getRed(), this.getGreen(), this.getBlue()); } /** - * Gets the red component + * Gets the red component. * * @return red component, from 0 to 255 */ public @Range(from = 0, to = 255) int getRed() { - return BIT_MASK & red; + return BIT_MASK & this.red; } /** - * Gets the red component + * Gets the red component. * * @return red component, from 0 to 255 */ @Override public @Range(from = 0, to = 255) int red() { - return getRed(); + return this.getRed(); } /** - * Creates a new Color object with specified component + * Creates a new Color object with a specified component. * * @param red the red component, from 0 to 255 * @return a new color object with the red component */ @NotNull - public Color setRed(@Range(from = 0, to = 255) int red) { - return fromARGB(getAlpha(), red, getGreen(), getBlue()); + public Color setRed(final @Range(from = 0, to = 255) int red) { + return fromARGB(this.getAlpha(), red, this.getGreen(), this.getBlue()); } /** - * Gets the green component + * Gets the green component. * * @return green component, from 0 to 255 */ public @Range(from = 0, to = 255) int getGreen() { - return BIT_MASK & green; + return BIT_MASK & this.green; } /** - * Gets the green component + * Gets the green component. * * @return green component, from 0 to 255 */ @Override public @Range(from = 0, to = 255) int green() { - return getGreen(); + return this.getGreen(); } /** - * Creates a new Color object with specified component + * Creates a new Color object with a specified component. * * @param green the green component, from 0 to 255 * @return a new color object with the green component */ @NotNull - public Color setGreen(@Range(from = 0, to = 255) int green) { - return fromARGB(getAlpha(), getRed(), green, getBlue()); + public Color setGreen(final @Range(from = 0, to = 255) int green) { + return fromARGB(this.getAlpha(), this.getRed(), green, this.getBlue()); } /** - * Gets the blue component + * Gets the blue component. * * @return blue component, from 0 to 255 */ public @Range(from = 0, to = 255) int getBlue() { - return BIT_MASK & blue; + return BIT_MASK & this.blue; } /** - * Gets the blue component + * Gets the blue component. * * @return blue component, from 0 to 255 */ @Override public @Range(from = 0, to = 255) int blue() { - return getBlue(); + return this.getBlue(); } /** - * Creates a new Color object with specified component + * Creates a new Color object with a specified component. * * @param blue the blue component, from 0 to 255 * @return a new color object with the blue component */ @NotNull - public Color setBlue(@Range(from = 0, to = 255) int blue) { - return fromARGB(getAlpha(), getRed(), getGreen(), blue); + public Color setBlue(final @Range(from = 0, to = 255) int blue) { + return fromARGB(this.getAlpha(), this.getRed(), this.getGreen(), blue); } /** @@ -353,7 +353,7 @@ public Color setBlue(@Range(from = 0, to = 255) int blue) { * @return An integer representation of this color, as 0xRRGGBB */ public int asRGB() { - return getRed() << 16 | getGreen() << 8 | getBlue(); + return this.getRed() << 16 | this.getGreen() << 8 | this.getBlue(); } /** @@ -362,7 +362,7 @@ public int asRGB() { * @return An integer representation of this color, as 0xAARRGGBB */ public int asARGB() { - return getAlpha() << 24 | getRed() << 16 | getGreen() << 8 | getBlue(); + return this.getAlpha() << 24 | this.getRed() << 16 | this.getGreen() << 8 | this.getBlue(); } /** @@ -371,33 +371,33 @@ public int asARGB() { * @return An integer representation of this color, as 0xBBGGRR */ public int asBGR() { - return getBlue() << 16 | getGreen() << 8 | getRed(); + return this.getBlue() << 16 | this.getGreen() << 8 | this.getRed(); } /** * Creates a new color with its RGB components changed as if it was dyed - * with the colors passed in, replicating vanilla workbench dyeing + * with the colors passed in, replicating vanilla workbench dyeing. * * @param colors The DyeColors to dye with * @return A new color with the changed rgb components */ // TODO: Javadoc what this method does, not what it mimics. API != Implementation @NotNull - public Color mixDyes(@NotNull DyeColor... colors) { + public Color mixDyes(final @NotNull DyeColor... colors) { Preconditions.checkArgument(colors != null && Arrays.stream(colors).allMatch(Objects::nonNull), "DyeColor cannot be null or contain null values"); - Color[] toPass = new Color[colors.length]; + final Color[] toPass = new Color[colors.length]; for (int i = 0; i < colors.length; i++) { toPass[i] = colors[i].getColor(); } - return mixColors(toPass); + return this.mixColors(toPass); } /** * Creates a new color with its RGB components changed as if it was dyed * with the colors passed in, replicating vanilla workbench dyeing. - * + *
* Note that this method does not currently take into account alpha * components. * @@ -406,7 +406,7 @@ public Color mixDyes(@NotNull DyeColor... colors) { */ // TODO: Javadoc what this method does, not what it mimics. API != Implementation @NotNull - public Color mixColors(@NotNull Color... colors) { + public Color mixColors(final @NotNull Color... colors) { Preconditions.checkArgument(colors != null && Arrays.stream(colors).allMatch(Objects::nonNull), "Colors cannot be null"); int totalRed = this.getRed(); @@ -420,44 +420,43 @@ public Color mixColors(@NotNull Color... colors) { totalMax += Math.max(Math.max(color.getRed(), color.getGreen()), color.getBlue()); } - float averageRed = totalRed / (colors.length + 1); - float averageGreen = totalGreen / (colors.length + 1); - float averageBlue = totalBlue / (colors.length + 1); - float averageMax = totalMax / (colors.length + 1); + final float averageRed = totalRed / (colors.length + 1); + final float averageGreen = totalGreen / (colors.length + 1); + final float averageBlue = totalBlue / (colors.length + 1); + final float averageMax = totalMax / (colors.length + 1); - float maximumOfAverages = Math.max(Math.max(averageRed, averageGreen), averageBlue); - float gainFactor = averageMax / maximumOfAverages; + final float maximumOfAverages = Math.max(Math.max(averageRed, averageGreen), averageBlue); + final float gainFactor = averageMax / maximumOfAverages; return Color.fromRGB((int) (averageRed * gainFactor), (int) (averageGreen * gainFactor), (int) (averageBlue * gainFactor)); } @Override - public boolean equals(Object o) { - if (!(o instanceof Color)) { + public boolean equals(final Object o) { + if (!(o instanceof Color that)) { return false; } - final Color that = (Color) o; return this.alpha == that.alpha && this.blue == that.blue && this.green == that.green && this.red == that.red; } @Override public int hashCode() { - return asARGB() ^ Color.class.hashCode(); + return this.asARGB() ^ Color.class.hashCode(); } @Override @NotNull public Map serialize() { return ImmutableMap.of( - "ALPHA", getAlpha(), - "RED", getRed(), - "BLUE", getBlue(), - "GREEN", getGreen() + "ALPHA", this.getAlpha(), + "RED", this.getRed(), + "BLUE", this.getBlue(), + "GREEN", this.getGreen() ); } @NotNull - public static Color deserialize(@NotNull Map map) { + public static Color deserialize(final @NotNull Map map) { return fromARGB( asInt("ALPHA", map, DEFAULT_ALPHA), asInt("RED", map), @@ -466,23 +465,23 @@ public static Color deserialize(@NotNull Map map) { ); } - private static int asInt(@NotNull String string, @NotNull Map map) { + private static int asInt(final @NotNull String string, final @NotNull Map map) { return asInt(string, map, null); } - private static int asInt(@NotNull String string, @NotNull Map map, @Nullable Object defaultValue) { - Object value = map.getOrDefault(string, defaultValue); + private static int asInt(final @NotNull String string, final @NotNull Map map, final @Nullable Object defaultValue) { + final Object value = map.getOrDefault(string, defaultValue); if (value == null) { throw new IllegalArgumentException(string + " not in map " + map); } - if (!(value instanceof Number)) { + if (!(value instanceof Number number)) { throw new IllegalArgumentException(string + '(' + value + ") is not a number"); } - return ((Number) value).intValue(); + return number.intValue(); } @Override public String toString() { - return "Color:[argb0x" + Integer.toHexString(asARGB()).toUpperCase(Locale.ROOT) + "]"; + return "Color:[argb0x" + Integer.toHexString(this.asARGB()).toUpperCase(Locale.ROOT) + "]"; } }