diff --git a/patches/api/0009-Optimise-Bukkit-s-MapPalette.patch b/patches/api/0009-Optimise-Bukkit-s-MapPalette.patch index f6120ef1..aad8675e 100644 --- a/patches/api/0009-Optimise-Bukkit-s-MapPalette.patch +++ b/patches/api/0009-Optimise-Bukkit-s-MapPalette.patch @@ -1,54 +1,207 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: epserv -Date: Mon, 21 Dec 2020 23:12:15 +0500 +Date: Thu, 11 Mar 2021 23:55:36 +0500 Subject: [PATCH] Optimise Bukkit's MapPalette diff --git a/src/main/java/org/bukkit/map/MapPalette.java b/src/main/java/org/bukkit/map/MapPalette.java -index 95fe3f4d081053a6cf484e4ef07b474f2dc2ab02..04e1a902a0db732ba69ad60b03a34de69f425071 100644 +index 95fe3f4d081053a6cf484e4ef07b474f2dc2ab02..08334ea141624a843ce4b5dcb0de17ba360f0d7f 100644 --- a/src/main/java/org/bukkit/map/MapPalette.java +++ b/src/main/java/org/bukkit/map/MapPalette.java -@@ -23,6 +23,8 @@ public final class MapPalette { - } +@@ -1,12 +1,17 @@ + package org.bukkit.map; - private static double getDistance(@NotNull Color c1, @NotNull Color c2) { -+ // Yatopia start - faster method -+ /* - double rmean = (c1.getRed() + c2.getRed()) / 2.0; - double r = c1.getRed() - c2.getRed(); - double g = c1.getGreen() - c2.getGreen(); -@@ -31,6 +33,19 @@ public final class MapPalette { - double weightG = 4.0; - double weightB = 2 + (255 - rmean) / 256.0; - return weightR * r * r + weightG * g * g + weightB * b * b; -+ */ -+ if (c1.getRGB() == c2.getRGB()) { // check if colors are same -+ return 0; -+ } -+ // sqrt( (r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2 ) -+ double rdiff = c2.getRed() - c1.getRed(), -+ gdiff = c2.getGreen() - c1.getGreen(), -+ bdiff = c2.getBlue() - c1.getBlue(); -+ double rsq = rdiff * rdiff, -+ gsq = gdiff * gdiff, -+ bsq = bdiff * bdiff; -+ return Math.sqrt(rsq + gsq + bsq); -+ // Yatopia end - } +-import java.awt.Color; +-import java.awt.Graphics2D; +-import java.awt.Image; +-import java.awt.image.BufferedImage; ++import com.comphenix.tinyprotocol.Reflection; ++import com.google.common.util.concurrent.AtomicDouble; ++import org.apache.commons.lang.ArrayUtils; + import org.jetbrains.annotations.NotNull; + import org.jetbrains.annotations.Nullable; - @NotNull -@@ -95,6 +110,51 @@ public final class MapPalette { - c(60, 31, 43), c(74, 37, 53), c(86, 44, 62), c(45, 23, 32), - c(14, 127, 93), c(17, 155, 114), c(20, 180, 133), c(10, 95, 70) - }; -+ // Yatopia start ++import java.awt.*; ++import java.awt.image.BufferedImage; ++import java.util.Arrays; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.stream.Stream; ++ + /** + * Represents the palette that map items use. + *

+@@ -14,89 +19,6 @@ import org.jetbrains.annotations.Nullable; + * colors of varying shades with values entry to entry + 3. + */ + public final class MapPalette { +- // Internal mechanisms +- private MapPalette() {} +- +- @NotNull +- private static Color c(int r, int g, int b) { +- return new Color(r, g, b); +- } +- +- private static double getDistance(@NotNull Color c1, @NotNull Color c2) { +- double rmean = (c1.getRed() + c2.getRed()) / 2.0; +- double r = c1.getRed() - c2.getRed(); +- double g = c1.getGreen() - c2.getGreen(); +- int b = c1.getBlue() - c2.getBlue(); +- double weightR = 2 + rmean / 256.0; +- double weightG = 4.0; +- double weightB = 2 + (255 - rmean) / 256.0; +- return weightR * r * r + weightG * g * g + weightB * b * b; +- } +- +- @NotNull +- static final Color[] colors = { +- c(0, 0, 0), c(0, 0, 0), c(0, 0, 0), c(0, 0, 0), +- c(89, 125, 39), c(109, 153, 48), c(127, 178, 56), c(67, 94, 29), +- c(174, 164, 115), c(213, 201, 140), c(247, 233, 163), c(130, 123, 86), +- c(140, 140, 140), c(171, 171, 171), c(199, 199, 199), c(105, 105, 105), +- c(180, 0, 0), c(220, 0, 0), c(255, 0, 0), c(135, 0, 0), +- c(112, 112, 180), c(138, 138, 220), c(160, 160, 255), c(84, 84, 135), +- c(117, 117, 117), c(144, 144, 144), c(167, 167, 167), c(88, 88, 88), +- c(0, 87, 0), c(0, 106, 0), c(0, 124, 0), c(0, 65, 0), +- c(180, 180, 180), c(220, 220, 220), c(255, 255, 255), c(135, 135, 135), +- c(115, 118, 129), c(141, 144, 158), c(164, 168, 184), c(86, 88, 97), +- c(106, 76, 54), c(130, 94, 66), c(151, 109, 77), c(79, 57, 40), +- c(79, 79, 79), c(96, 96, 96), c(112, 112, 112), c(59, 59, 59), +- c(45, 45, 180), c(55, 55, 220), c(64, 64, 255), c(33, 33, 135), +- c(100, 84, 50), c(123, 102, 62), c(143, 119, 72), c(75, 63, 38), +- c(180, 177, 172), c(220, 217, 211), c(255, 252, 245), c(135, 133, 129), +- c(152, 89, 36), c(186, 109, 44), c(216, 127, 51), c(114, 67, 27), +- c(125, 53, 152), c(153, 65, 186), c(178, 76, 216), c(94, 40, 114), +- c(72, 108, 152), c(88, 132, 186), c(102, 153, 216), c(54, 81, 114), +- c(161, 161, 36), c(197, 197, 44), c(229, 229, 51), c(121, 121, 27), +- c(89, 144, 17), c(109, 176, 21), c(127, 204, 25), c(67, 108, 13), +- c(170, 89, 116), c(208, 109, 142), c(242, 127, 165), c(128, 67, 87), +- c(53, 53, 53), c(65, 65, 65), c(76, 76, 76), c(40, 40, 40), +- c(108, 108, 108), c(132, 132, 132), c(153, 153, 153), c(81, 81, 81), +- c(53, 89, 108), c(65, 109, 132), c(76, 127, 153), c(40, 67, 81), +- c(89, 44, 125), c(109, 54, 153), c(127, 63, 178), c(67, 33, 94), +- c(36, 53, 125), c(44, 65, 153), c(51, 76, 178), c(27, 40, 94), +- c(72, 53, 36), c(88, 65, 44), c(102, 76, 51), c(54, 40, 27), +- c(72, 89, 36), c(88, 109, 44), c(102, 127, 51), c(54, 67, 27), +- c(108, 36, 36), c(132, 44, 44), c(153, 51, 51), c(81, 27, 27), +- c(17, 17, 17), c(21, 21, 21), c(25, 25, 25), c(13, 13, 13), +- c(176, 168, 54), c(215, 205, 66), c(250, 238, 77), c(132, 126, 40), +- c(64, 154, 150), c(79, 188, 183), c(92, 219, 213), c(48, 115, 112), +- c(52, 90, 180), c(63, 110, 220), c(74, 128, 255), c(39, 67, 135), +- c(0, 153, 40), c(0, 187, 50), c(0, 217, 58), c(0, 114, 30), +- c(91, 60, 34), c(111, 74, 42), c(129, 86, 49), c(68, 45, 25), +- c(79, 1, 0), c(96, 1, 0), c(112, 2, 0), c(59, 1, 0), +- c(147, 124, 113), c(180, 152, 138), c(209, 177, 161), c(110, 93, 85), +- c(112, 57, 25), c(137, 70, 31), c(159, 82, 36), c(84, 43, 19), +- c(105, 61, 76), c(128, 75, 93), c(149, 87, 108), c(78, 46, 57), +- c(79, 76, 97), c(96, 93, 119), c(112, 108, 138), c(59, 57, 73), +- c(131, 93, 25), c(160, 114, 31), c(186, 133, 36), c(98, 70, 19), +- c(72, 82, 37), c(88, 100, 45), c(103, 117, 53), c(54, 61, 28), +- c(112, 54, 55), c(138, 66, 67), c(160, 77, 78), c(84, 40, 41), +- c(40, 28, 24), c(49, 35, 30), c(57, 41, 35), c(30, 21, 18), +- c(95, 75, 69), c(116, 92, 84), c(135, 107, 98), c(71, 56, 51), +- c(61, 64, 64), c(75, 79, 79), c(87, 92, 92), c(46, 48, 48), +- c(86, 51, 62), c(105, 62, 75), c(122, 73, 88), c(64, 38, 46), +- c(53, 43, 64), c(65, 53, 79), c(76, 62, 92), c(40, 32, 48), +- c(53, 35, 24), c(65, 43, 30), c(76, 50, 35), c(40, 26, 18), +- c(53, 57, 29), c(65, 70, 36), c(76, 82, 42), c(40, 43, 22), +- c(100, 42, 32), c(122, 51, 39), c(142, 60, 46), c(75, 31, 24), +- c(26, 15, 11), c(31, 18, 13), c(37, 22, 16), c(19, 11, 8), +- c(133, 33, 34), c(163, 41, 42), c(189, 48, 49), c(100, 25, 25), +- c(104, 44, 68), c(127, 54, 83), c(148, 63, 97), c(78, 33, 51), +- c(64, 17, 20), c(79, 21, 25), c(92, 25, 29), c(48, 13, 15), +- c(15, 88, 94), c(18, 108, 115), c(22, 126, 134), c(11, 66, 70), +- c(40, 100, 98), c(50, 122, 120), c(58, 142, 140), c(30, 75, 74), +- c(60, 31, 43), c(74, 37, 53), c(86, 44, 62), c(45, 23, 32), +- c(14, 127, 93), c(17, 155, 114), c(20, 180, 133), c(10, 95, 70) +- }; +- +- // Interface + /** + * @deprecated Magic value + */ +@@ -142,6 +64,9 @@ public final class MapPalette { + */ + @Deprecated + public static final byte WHITE = 32; ++ // Yatopia end ++ ++ // Interface + /** + * @deprecated Magic value + */ +@@ -167,6 +92,156 @@ public final class MapPalette { + */ + @Deprecated + public static final byte DARK_BROWN = 52; + @NotNull ++ static final Color[] colors = { ++ c(0, 0, 0), c(0, 0, 0), c(0, 0, 0), c(0, 0, 0), ++ c(89, 125, 39), c(109, 153, 48), c(127, 178, 56), c(67, 94, 29), ++ c(174, 164, 115), c(213, 201, 140), c(247, 233, 163), c(130, 123, 86), ++ c(140, 140, 140), c(171, 171, 171), c(199, 199, 199), c(105, 105, 105), ++ c(180, 0, 0), c(220, 0, 0), c(255, 0, 0), c(135, 0, 0), ++ c(112, 112, 180), c(138, 138, 220), c(160, 160, 255), c(84, 84, 135), ++ c(117, 117, 117), c(144, 144, 144), c(167, 167, 167), c(88, 88, 88), ++ c(0, 87, 0), c(0, 106, 0), c(0, 124, 0), c(0, 65, 0), ++ c(180, 180, 180), c(220, 220, 220), c(255, 255, 255), c(135, 135, 135), ++ c(115, 118, 129), c(141, 144, 158), c(164, 168, 184), c(86, 88, 97), ++ c(106, 76, 54), c(130, 94, 66), c(151, 109, 77), c(79, 57, 40), ++ c(79, 79, 79), c(96, 96, 96), c(112, 112, 112), c(59, 59, 59), ++ c(45, 45, 180), c(55, 55, 220), c(64, 64, 255), c(33, 33, 135), ++ c(100, 84, 50), c(123, 102, 62), c(143, 119, 72), c(75, 63, 38), ++ c(180, 177, 172), c(220, 217, 211), c(255, 252, 245), c(135, 133, 129), ++ c(152, 89, 36), c(186, 109, 44), c(216, 127, 51), c(114, 67, 27), ++ c(125, 53, 152), c(153, 65, 186), c(178, 76, 216), c(94, 40, 114), ++ c(72, 108, 152), c(88, 132, 186), c(102, 153, 216), c(54, 81, 114), ++ c(161, 161, 36), c(197, 197, 44), c(229, 229, 51), c(121, 121, 27), ++ c(89, 144, 17), c(109, 176, 21), c(127, 204, 25), c(67, 108, 13), ++ c(170, 89, 116), c(208, 109, 142), c(242, 127, 165), c(128, 67, 87), ++ c(53, 53, 53), c(65, 65, 65), c(76, 76, 76), c(40, 40, 40), ++ c(108, 108, 108), c(132, 132, 132), c(153, 153, 153), c(81, 81, 81), ++ c(53, 89, 108), c(65, 109, 132), c(76, 127, 153), c(40, 67, 81), ++ c(89, 44, 125), c(109, 54, 153), c(127, 63, 178), c(67, 33, 94), ++ c(36, 53, 125), c(44, 65, 153), c(51, 76, 178), c(27, 40, 94), ++ c(72, 53, 36), c(88, 65, 44), c(102, 76, 51), c(54, 40, 27), ++ c(72, 89, 36), c(88, 109, 44), c(102, 127, 51), c(54, 67, 27), ++ c(108, 36, 36), c(132, 44, 44), c(153, 51, 51), c(81, 27, 27), ++ c(17, 17, 17), c(21, 21, 21), c(25, 25, 25), c(13, 13, 13), ++ c(176, 168, 54), c(215, 205, 66), c(250, 238, 77), c(132, 126, 40), ++ c(64, 154, 150), c(79, 188, 183), c(92, 219, 213), c(48, 115, 112), ++ c(52, 90, 180), c(63, 110, 220), c(74, 128, 255), c(39, 67, 135), ++ c(0, 153, 40), c(0, 187, 50), c(0, 217, 58), c(0, 114, 30), ++ c(91, 60, 34), c(111, 74, 42), c(129, 86, 49), c(68, 45, 25), ++ c(79, 1, 0), c(96, 1, 0), c(112, 2, 0), c(59, 1, 0), ++ c(147, 124, 113), c(180, 152, 138), c(209, 177, 161), c(110, 93, 85), ++ c(112, 57, 25), c(137, 70, 31), c(159, 82, 36), c(84, 43, 19), ++ c(105, 61, 76), c(128, 75, 93), c(149, 87, 108), c(78, 46, 57), ++ c(79, 76, 97), c(96, 93, 119), c(112, 108, 138), c(59, 57, 73), ++ c(131, 93, 25), c(160, 114, 31), c(186, 133, 36), c(98, 70, 19), ++ c(72, 82, 37), c(88, 100, 45), c(103, 117, 53), c(54, 61, 28), ++ c(112, 54, 55), c(138, 66, 67), c(160, 77, 78), c(84, 40, 41), ++ c(40, 28, 24), c(49, 35, 30), c(57, 41, 35), c(30, 21, 18), ++ c(95, 75, 69), c(116, 92, 84), c(135, 107, 98), c(71, 56, 51), ++ c(61, 64, 64), c(75, 79, 79), c(87, 92, 92), c(46, 48, 48), ++ c(86, 51, 62), c(105, 62, 75), c(122, 73, 88), c(64, 38, 46), ++ c(53, 43, 64), c(65, 53, 79), c(76, 62, 92), c(40, 32, 48), ++ c(53, 35, 24), c(65, 43, 30), c(76, 50, 35), c(40, 26, 18), ++ c(53, 57, 29), c(65, 70, 36), c(76, 82, 42), c(40, 43, 22), ++ c(100, 42, 32), c(122, 51, 39), c(142, 60, 46), c(75, 31, 24), ++ c(26, 15, 11), c(31, 18, 13), c(37, 22, 16), c(19, 11, 8), ++ c(133, 33, 34), c(163, 41, 42), c(189, 48, 49), c(100, 25, 25), ++ c(104, 44, 68), c(127, 54, 83), c(148, 63, 97), c(78, 33, 51), ++ c(64, 17, 20), c(79, 21, 25), c(92, 25, 29), c(48, 13, 15), ++ c(15, 88, 94), c(18, 108, 115), c(22, 126, 134), c(11, 66, 70), ++ c(40, 100, 98), c(50, 122, 120), c(58, 142, 140), c(30, 75, 74), ++ c(60, 31, 43), c(74, 37, 53), c(86, 44, 62), c(45, 23, 32), ++ c(14, 127, 93), c(17, 155, 114), c(20, 180, 133), c(10, 95, 70) ++ }; ++ // Yatopia start + private static final int[] modifiers = {180, 220, 255, 135}; // vanilla color modifiers + @NotNull + static Color[] vanillaColors; // vanilla colors + @NotNull + static Color[][] doubleColors; // two-dimensional array where doubleColors[index] is an array of possible modifications of vanillaColors[index] -+ @NotNull + static int[] rgbColors; // an array of rgb values of each color + + static { @@ -56,8 +209,10 @@ index 95fe3f4d081053a6cf484e4ef07b474f2dc2ab02..04e1a902a0db732ba69ad60b03a34de6 + rgbColors = java.util.Arrays.stream(colors).mapToInt(Color::getRGB).toArray(); + + try { -+ Class materialMapColorClass = MapPalette.class.getClassLoader().loadClass("net.minecraft.server.MaterialMapColor"); -+ Object[] vanillaColorObjects = (Object[]) java.util.Arrays.stream(materialMapColorClass.getFields()).filter(f -> f.getType().isArray() && f.getType().getComponentType().equals(materialMapColorClass)).findAny().get().get(null); ++ Class materialMapColorClass = Reflection.getMinecraftClass("MaterialMapColor"); ++ Object[] vanillaColorObjects = (Object[]) java.util.Arrays.stream(materialMapColorClass.getFields()) ++ .filter(f -> f.getType().isArray() && f.getType().getComponentType().equals(materialMapColorClass)) ++ .findAny().get().get(null); + // get MaterialMapColor.rgb instance field + java.lang.reflect.Field rgbField = materialMapColorClass.getDeclaredField("rgb"); + rgbField.setAccessible(true); @@ -85,65 +240,161 @@ index 95fe3f4d081053a6cf484e4ef07b474f2dc2ab02..04e1a902a0db732ba69ad60b03a34de6 + throw new RuntimeException(ex); + } + } -+ // Yatopia end ++ // Internal mechanisms ++ private MapPalette() { ++ } ++ ++ @NotNull ++ private static Color c(int r, int g, int b) { ++ return new Color(r, g, b); ++ } ++ ++ public static double getDistanceSquared(@NotNull Color c1, @NotNull Color c2) { ++ if (c1.getRGB() == c2.getRGB()) { // check if colors are same ++ return 0; ++ } ++ ++ // (r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2 ++ double redDiff = c2.getRed() - c1.getRed(), ++ greenDiff = c2.getGreen() - c1.getGreen(), ++ blueDiff = c2.getBlue() - c1.getBlue(); ++ double rsq = redDiff * redDiff, ++ gsq = greenDiff * greenDiff, ++ bsq = blueDiff * blueDiff; ++ ++ return rsq + gsq + bsq; ++ } ++ ++ public static double getDistance(@NotNull Color c1, @NotNull Color c2) { ++ // Yatopia start - faster method ++ /* ++ double rmean = (c1.getRed() + c2.getRed()) / 2.0; ++ double r = c1.getRed() - c2.getRed(); ++ double g = c1.getGreen() - c2.getGreen(); ++ int b = c1.getBlue() - c2.getBlue(); ++ double weightR = 2 + rmean / 256.0; ++ double weightG = 4.0; ++ double weightB = 2 + (255 - rmean) / 256.0; ++ return weightR * r * r + weightG * g * g + weightB * b * b; ++ */ ++ if (c1.getRGB() == c2.getRGB()) { // check if colors are same ++ return 0; ++ } ++ // sqrt( (r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2 ) ++ return Math.sqrt(getDistanceSquared(c1, c2)); ++ // Yatopia end ++ } - // Interface /** -@@ -238,6 +298,8 @@ public final class MapPalette { - int index = 0; - double best = -1; + * Resize an image to 128x128. +@@ -191,21 +266,17 @@ public final class MapPalette { + * @deprecated Magic value + */ + @Deprecated +- @NotNull +- public static byte[] imageToBytes(@NotNull Image image) { +- BufferedImage temp = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); ++ public static byte[] imageToBytes(@NotNull BufferedImage image) { ++ BufferedImage temp = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = temp.createGraphics(); + graphics.drawImage(image, 0, 0, null); + graphics.dispose(); +- int[] pixels = new int[temp.getWidth() * temp.getHeight()]; +- temp.getRGB(0, 0, temp.getWidth(), temp.getHeight(), pixels, 0, temp.getWidth()); ++ int[] pixels = new int[image.getWidth() * image.getHeight()]; ++ image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); + +- byte[] result = new byte[temp.getWidth() * temp.getHeight()]; +- for (int i = 0; i < pixels.length; i++) { +- result[i] = matchColor(new Color(pixels[i], true)); +- } +- return result; ++ return ArrayUtils.toPrimitive(Arrays.stream(pixels).parallel().mapToObj(pixel -> new Color(pixel, true)) ++ .map(MapPalette::matchColor).toArray(Byte[]::new)); + } + + /** +@@ -235,9 +306,8 @@ public final class MapPalette { + public static byte matchColor(@NotNull Color color) { + if (color.getAlpha() < 128) return 0; + +- int index = 0; +- double best = -1; +- + // Yatopia start - foreach a maximum of 62 colors instead of 236 per pixel + /* for (int i = 4; i < colors.length; i++) { double distance = getDistance(color, colors[i]); if (distance < best || best == -1) { -@@ -245,9 +307,43 @@ public final class MapPalette { +@@ -245,9 +315,64 @@ public final class MapPalette { index = i; } } + */ -+ for (int i = 0; i < vanillaColors.length; i++) { -+ double distance = getDistance(color, vanillaColors[i]); -+ if (distance == 0) { -+ index = i; -+ best = 0; -+ break; -+ } -+ if (distance < best || best == -1) { -+ best = distance; -+ index = i; ++ ++ Stream vanillaStream = java.util.Arrays.stream(vanillaColors).parallel(); ++ AtomicInteger atomicIndex = new AtomicInteger(0); ++ AtomicDouble atomicBest = new AtomicDouble(-1); ++ ++ vanillaStream.takeWhile(predicateColor -> atomicBest.get() != 0).forEach(c -> { ++ if (atomicBest.get() != 0) { ++ double distance = getDistanceSquared(color, c); ++ if (distance == 0) { ++ atomicIndex.set(ArrayUtils.indexOf(vanillaColors, c)); ++ atomicBest.set(0); ++ return; ++ } ++ ++ double tempBest = atomicBest.get(); ++ if (distance < tempBest || tempBest == -1) { ++ atomicBest.set(distance); ++ atomicIndex.set(ArrayUtils.indexOf(vanillaColors, c)); ++ } + } ++ }); ++ ++ if (atomicBest.get() == 0d) { ++ int i = com.google.common.primitives.Ints.indexOf(rgbColors, vanillaColors[atomicIndex.get()].getRGB()); ++ if (i <= 3) ++ i = 118; ++ return (byte) (i < 128 ? i : i - 256); + } + -+ if (best == 0) { -+ index = com.google.common.primitives.Ints.indexOf(rgbColors, vanillaColors[index].getRGB()); -+ return (byte) (index < 128 ? index : index - 256); -+ } ++ if (atomicIndex.get() == 0) ++ return (byte) 118; + -+ Color[] modColors = doubleColors[index]; -+ best = -1; -+ for (int i = 0; i < modColors.length; i++) { -+ double distance = getDistance(color, modColors[i]); -+ if (distance == 0) { -+ index = i; -+ break; ++ Color[] modColors = doubleColors[atomicIndex.get()]; ++ Stream modStream = java.util.Arrays.stream(modColors).parallel(); ++ atomicBest.set(-1); ++ modStream.forEach(c -> { ++ if (atomicBest.get() != 0) { ++ double distance = getDistanceSquared(color, c); ++ if (distance == 0) { ++ atomicIndex.set(ArrayUtils.indexOf(modColors, c)); ++ atomicBest.set(0); ++ return; ++ } ++ double tempBest = atomicBest.get(); ++ if (distance < tempBest || tempBest == -1) { ++ atomicBest.set(distance); ++ atomicIndex.set(ArrayUtils.indexOf(modColors, c)); ++ } + } -+ if (distance < best || best == -1) { -+ best = distance; -+ index = i; -+ } -+ } -+ index = com.google.common.primitives.Ints.indexOf(rgbColors, modColors[index].getRGB()); -+ // Yatopia end ++ }); ++ ++ int i = com.google.common.primitives.Ints.indexOf(rgbColors, modColors[atomicIndex.get()].getRGB()); ++ ++ if (i <= 3) ++ i = 118; // black - // Minecraft has 143 colors, some of which have negative byte representations +- // Minecraft has 143 colors, some of which have negative byte representations - return (byte) (index < 128 ? index : -129 + (index - 127)); -+ return (byte) (index < 128 ? index : index - 256); // Yatopia ++ return (byte) (i < 128 ? i : i - 256); } /** -@@ -260,7 +356,7 @@ public final class MapPalette { +@@ -260,7 +385,7 @@ public final class MapPalette { @Deprecated @NotNull public static Color getColor(byte index) {