mirror of
https://github.com/NEZNAMY/TAB.git
synced 2026-11-12 20:22:01 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c486899dcf | ||
|
|
b212f0d5be | ||
|
|
caa534ff7f | ||
|
|
9c2fac6749 | ||
|
|
2a4f918a10 | ||
|
|
b45e2afe4c | ||
|
|
2c7237e5d9 | ||
|
|
26477e3150 |
No files matched your search
+1
-1
@@ -4,7 +4,7 @@ plugins {
|
||||
|
||||
allprojects {
|
||||
group = "me.neznamy"
|
||||
version = "5.0.4"
|
||||
version = "5.0.5"
|
||||
description = "An all-in-one solution that works"
|
||||
|
||||
ext.set("id", "tab")
|
||||
|
||||
@@ -2,7 +2,7 @@ package me.neznamy.tab.platforms.paper;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@ import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection;
|
||||
import me.neznamy.tab.shared.ProtocolVersion;
|
||||
import me.neznamy.tab.shared.features.injection.NettyPipelineInjector;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection;
|
||||
import me.neznamy.tab.platforms.bukkit.nms.converter.ComponentConverter;
|
||||
import me.neznamy.tab.platforms.bukkit.nms.PacketSender;
|
||||
import me.neznamy.tab.shared.chat.TabComponent;
|
||||
import me.neznamy.tab.shared.util.BiFunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.BiFunctionWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package me.neznamy.tab.platforms.bukkit.nms;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -2,7 +2,7 @@ package me.neznamy.tab.platforms.bukkit.nms;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer;
|
||||
import me.neznamy.tab.shared.util.BiConsumerWithException;
|
||||
import me.neznamy.tab.shared.util.function.BiConsumerWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package me.neznamy.tab.platforms.bukkit.nms;
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.bukkit.BukkitTabPlayer;
|
||||
import me.neznamy.tab.platforms.bukkit.BukkitUtils;
|
||||
import me.neznamy.tab.shared.util.ToIntFunction;
|
||||
import me.neznamy.tab.shared.util.function.ToIntFunction;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package me.neznamy.tab.platforms.bukkit.nms.converter;
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection;
|
||||
import me.neznamy.tab.shared.chat.*;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import me.neznamy.tab.platforms.bukkit.scoreboard.packet.PacketScoreboard;
|
||||
import me.neznamy.tab.shared.ProtocolVersion;
|
||||
import me.neznamy.tab.shared.platform.Scoreboard;
|
||||
import me.neznamy.tab.shared.platform.impl.DummyScoreboard;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ import lombok.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection;
|
||||
import me.neznamy.tab.shared.platform.Scoreboard;
|
||||
import me.neznamy.tab.shared.util.BiFunctionWithException;
|
||||
import me.neznamy.tab.shared.util.QuintFunction;
|
||||
import me.neznamy.tab.shared.util.function.BiFunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.QuintFunction;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import me.neznamy.tab.shared.platform.decorators.SafeScoreboard.Team;
|
||||
import me.neznamy.tab.shared.platform.Scoreboard;
|
||||
import me.neznamy.tab.shared.platform.Scoreboard.TeamAction;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.util.BiConsumerWithException;
|
||||
import me.neznamy.tab.shared.util.function.BiConsumerWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import me.neznamy.tab.platforms.bukkit.nms.PacketSender;
|
||||
import me.neznamy.tab.shared.Limitations;
|
||||
import me.neznamy.tab.shared.chat.TabComponent;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import me.neznamy.tab.shared.util.TriFunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.TriFunctionWithException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import me.neznamy.tab.platforms.bukkit.nms.BukkitReflection;
|
||||
import me.neznamy.tab.shared.ProtocolVersion;
|
||||
import me.neznamy.tab.shared.chat.TabComponent;
|
||||
import me.neznamy.tab.shared.platform.decorators.TrackedTabList;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -143,9 +143,6 @@ public class Property {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply gradients that do not include placeholders to avoid applying them on every refresh
|
||||
rawFormattedValue0 = RGBUtils.getInstance().applyCleanGradients(rawFormattedValue0);
|
||||
|
||||
// Make \n work even if used in '', which snakeyaml does not convert to newline
|
||||
if (rawFormattedValue0.contains("\\n")) {
|
||||
rawFormattedValue0 = rawFormattedValue0.replace("\\n", "\n");
|
||||
|
||||
@@ -52,8 +52,22 @@ public class StructuredComponent extends TabComponent {
|
||||
*/
|
||||
public StructuredComponent(@NotNull String text, @NotNull List<StructuredComponent> components) {
|
||||
this.text = text;
|
||||
if (components.isEmpty()) throw new IllegalArgumentException("Unexpected empty array of components"); //exception taken from minecraft
|
||||
extra = components;
|
||||
if (!components.isEmpty()) {
|
||||
extra = components;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs new instance with given text and color.
|
||||
*
|
||||
* @param text
|
||||
* Component text
|
||||
* @param color
|
||||
* Text color
|
||||
*/
|
||||
public StructuredComponent(@NotNull String text, @Nullable TextColor color) {
|
||||
this.text = text;
|
||||
modifier.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +75,8 @@ public class StructuredComponent extends TabComponent {
|
||||
*
|
||||
* @return list of extra components
|
||||
*/
|
||||
public @NotNull List<StructuredComponent> getExtra() {
|
||||
@NotNull
|
||||
public List<StructuredComponent> getExtra() {
|
||||
if (extra == null) return Collections.emptyList();
|
||||
return extra;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import me.neznamy.tab.shared.ProtocolVersion;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.chat.rgb.RGBUtils;
|
||||
import me.neznamy.tab.shared.hook.AdventureHook;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.TriFunction;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -21,6 +22,35 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public abstract class TabComponent {
|
||||
|
||||
/** Formatter to convert gradient into TAB's #RRGGBB spam */
|
||||
private static final TriFunction<TextColor, String, TextColor, String> TABGradientFormatter = (start, text, end) -> {
|
||||
//lazy support for magic codes in gradients
|
||||
String magicCodes = EnumChatFormat.getLastColors(text);
|
||||
String deColorized = text.substring(magicCodes.length());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int length = deColorized.length();
|
||||
if (length == 1) {
|
||||
sb.append("#");
|
||||
sb.append(start.getHexCode());
|
||||
sb.append(magicCodes);
|
||||
sb.append(deColorized);
|
||||
return sb.toString();
|
||||
}
|
||||
for (int i=0; i<length; i++) {
|
||||
int red = (int) (start.getRed() + (float)(end.getRed() - start.getRed())/(length-1)*i);
|
||||
int green = (int) (start.getGreen() + (float)(end.getGreen() - start.getGreen())/(length-1)*i);
|
||||
int blue = (int) (start.getBlue() + (float)(end.getBlue() - start.getBlue())/(length-1)*i);
|
||||
sb.append("#");
|
||||
sb.append(new TextColor(red, green, blue).getHexCode());
|
||||
sb.append(magicCodes);
|
||||
sb.append(deColorized.charAt(i));
|
||||
}
|
||||
return sb.toString();
|
||||
};
|
||||
|
||||
/** Formatter to convert RGB code to use TAB's #RRGGBB */
|
||||
private static final Function<TextColor, String> TABRGBFormatter = color -> "#" + color.getHexCode();
|
||||
|
||||
/** Pattern for detecting fonts */
|
||||
private static final Pattern fontPattern = Pattern.compile("<font:(.*?)>(.*?)</font>");
|
||||
|
||||
@@ -182,7 +212,7 @@ public abstract class TabComponent {
|
||||
* @return organized component from colored text
|
||||
*/
|
||||
@NotNull
|
||||
public static TabComponent fromColoredText(@NotNull String originalText) {
|
||||
public static StructuredComponent fromColoredText(@NotNull String originalText) {
|
||||
String remainingText = originalText;
|
||||
List<StructuredComponent> components = new ArrayList<>();
|
||||
while (!remainingText.isEmpty()) {
|
||||
@@ -205,16 +235,12 @@ public abstract class TabComponent {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (components.isEmpty()) {
|
||||
return new SimpleComponent("");
|
||||
} else {
|
||||
return new StructuredComponent("", components);
|
||||
}
|
||||
return new StructuredComponent("", components);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<StructuredComponent> toComponentArray(@NotNull String originalText, @Nullable String font) {
|
||||
String text = RGBUtils.getInstance().applyFormats(EnumChatFormat.color(originalText));
|
||||
String text = RGBUtils.getInstance().applyFormats(EnumChatFormat.color(originalText), TABGradientFormatter, TABRGBFormatter);
|
||||
List<StructuredComponent> components = new ArrayList<>();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
StructuredComponent component = new StructuredComponent();
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package me.neznamy.tab.shared.chat.rgb;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.neznamy.tab.shared.chat.rgb.format.*;
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import me.neznamy.tab.shared.chat.rgb.format.BukkitFormat;
|
||||
import me.neznamy.tab.shared.chat.rgb.format.CommonFormatter;
|
||||
import me.neznamy.tab.shared.chat.rgb.format.RGBFormatter;
|
||||
import me.neznamy.tab.shared.chat.rgb.gradient.CMIGradient;
|
||||
import me.neznamy.tab.shared.chat.rgb.gradient.CommonGradient;
|
||||
import me.neznamy.tab.shared.chat.rgb.gradient.GradientPattern;
|
||||
import me.neznamy.tab.shared.chat.rgb.gradient.NexEngineGradient;
|
||||
import me.neznamy.tab.shared.util.function.TriFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -19,52 +24,41 @@ public class RGBUtils {
|
||||
@Getter private static final RGBUtils instance = new RGBUtils();
|
||||
|
||||
/** Registered RGB formatters */
|
||||
private final RGBFormatter[] formats = {
|
||||
new BukkitFormat(),
|
||||
new CMIFormat(),
|
||||
new UnnamedFormat1(),
|
||||
new HtmlFormat(),
|
||||
new KyoriFormat()
|
||||
private final RGBFormatter[] formats = {
|
||||
new BukkitFormat(), // &x&r&r&g&g&b&b
|
||||
new CommonFormatter(Pattern.compile("\\{#[0-9a-fA-F]{6}}"), "{#"), // CMI's {#RRGGBB}
|
||||
new CommonFormatter(Pattern.compile("§#[0-9a-fA-F]{6}"), "§#"), // &#RRGGBB
|
||||
new CommonFormatter(Pattern.compile("#<[0-9a-fA-F]{6}>"), "#<") // #<RRGGBB> // "HTML"
|
||||
};
|
||||
|
||||
/** Registered gradient patterns */
|
||||
private final GradientPattern[] gradients = {
|
||||
new CMIGradient(), //{#RRGGBB>}Text{#RRGGBB<}
|
||||
new CommonGradient(Pattern.compile("<#[0-9a-fA-F]{6}>.*?</#[0-9a-fA-F]{6}>"), "<#", 2, 9, 7), //<#RRGGBB>Text</#RRGGBB>
|
||||
new CommonGradient(Pattern.compile("<\\$#[0-9a-fA-F]{6}>.*?<\\$#[0-9a-fA-F]{6}>"), "<$", 3, 10, 7), //<$#RRGGBB>Text<$#RRGGBB>
|
||||
new CommonGradient(Pattern.compile("<#[0-9a-fA-F]{6}>.*?</#[0-9a-fA-F]{6}>"), "<#", 2, 9, 7), //<#RRGGBB>Text</#RRGGBB> // "HTML"
|
||||
new CommonGradient(Pattern.compile("<\\$#[0-9a-fA-F]{6}>.*?<\\$#[0-9a-fA-F]{6}>"), "<$", 3, 10, 7), //<$#RRGGBB>Text<$#RRGGBB> // ?
|
||||
new NexEngineGradient() // <gradient:#RRGGBB>Text</gradient:#RRGGBB>
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies all RGB formats and gradients to text and returns it.
|
||||
* Applies all gradient formats to text and returns it.
|
||||
*
|
||||
* @param text
|
||||
* original text
|
||||
* @return text where everything is converted to #RRGGBB
|
||||
* @param gradientFunction
|
||||
* Function for reformatting gradient to new text
|
||||
* @param rgbFunction
|
||||
* Function for converting RGB codes to desired format
|
||||
* @return text where all gradients are converted to desired format
|
||||
*/
|
||||
public @NotNull String applyFormats(@NotNull String text) {
|
||||
@NotNull
|
||||
public String applyFormats(@NotNull String text, @NotNull TriFunction<TextColor, String, TextColor, String> gradientFunction,
|
||||
@NotNull Function<TextColor, String> rgbFunction) {
|
||||
String replaced = text;
|
||||
for (GradientPattern pattern : gradients) {
|
||||
replaced = pattern.applyPattern(replaced, false);
|
||||
replaced = pattern.applyPattern(replaced, gradientFunction);
|
||||
}
|
||||
for (RGBFormatter formatter : formats) {
|
||||
replaced = formatter.reformat(replaced);
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies all gradient formats to text and returns it. This only affects
|
||||
* usage where no placeholder is used inside.
|
||||
*
|
||||
* @param text
|
||||
* original text
|
||||
* @return text where all gradients with static text are converted to #RRGGBB
|
||||
*/
|
||||
public @NotNull String applyCleanGradients(@NotNull String text) {
|
||||
String replaced = text;
|
||||
for (GradientPattern pattern : gradients) {
|
||||
replaced = pattern.applyPattern(replaced, true);
|
||||
replaced = formatter.reformat(replaced, rgbFunction);
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.format;
|
||||
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -10,17 +12,18 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class BukkitFormat implements RGBFormatter {
|
||||
|
||||
private final Pattern pattern = Pattern.compile("[§&]x[§&\\p{XDigit}]{12}");
|
||||
private final Pattern pattern = Pattern.compile("§x[§\\p{XDigit}]{12}");
|
||||
|
||||
@Override
|
||||
public @NotNull String reformat(@NotNull String text) {
|
||||
if (!text.contains("&x") && !text.contains("§x")) return text;
|
||||
@NotNull
|
||||
public String reformat(@NotNull String text, @NotNull Function<TextColor, String> rgbFunction) {
|
||||
if (!text.contains("§x")) return text;
|
||||
String replaced = text;
|
||||
Matcher m = pattern.matcher(replaced);
|
||||
while (m.find()) {
|
||||
String hexCode = m.group();
|
||||
String fixed = new String(new char[] {'#', hexCode.charAt(3), hexCode.charAt(5), hexCode.charAt(7), hexCode.charAt(9), hexCode.charAt(11), hexCode.charAt(13)});
|
||||
replaced = replaced.replace(hexCode, fixed);
|
||||
String group = m.group();
|
||||
String hexCode = new String(new char[] {group.charAt(3), group.charAt(5), group.charAt(7), group.charAt(9), group.charAt(11), group.charAt(13)});
|
||||
replaced = replaced.replace(group, rgbFunction.apply(new TextColor(hexCode)));
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.format;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Formatter for {#RRGGBB}
|
||||
*/
|
||||
public class CMIFormat implements RGBFormatter {
|
||||
|
||||
private final Pattern pattern = Pattern.compile("\\{#[0-9a-fA-F]{6}}");
|
||||
|
||||
@Override
|
||||
public @NotNull String reformat(@NotNull String text) {
|
||||
if (!text.contains("{#")) return text;
|
||||
String replaced = text;
|
||||
Matcher m = pattern.matcher(replaced);
|
||||
while (m.find()) {
|
||||
String hexCode = m.group();
|
||||
String fixed = hexCode.substring(2, 8);
|
||||
replaced = replaced.replace(hexCode, "#" + fixed);
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.format;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Common class for various RGB formatters.
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class CommonFormatter implements RGBFormatter {
|
||||
|
||||
/** Pattern for finding the RGB code */
|
||||
private final Pattern pattern;
|
||||
|
||||
/** String to check if the text contains to possibly skip pattern matching for better performance */
|
||||
private final String stringCheck;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String reformat(@NotNull String text, @NotNull Function<TextColor, String> rgbFunction) {
|
||||
if (!text.contains(stringCheck)) return text;
|
||||
String replaced = text;
|
||||
Matcher m = pattern.matcher(replaced);
|
||||
while (m.find()) {
|
||||
String group = m.group();
|
||||
String hexCode = group.substring(2, 8);
|
||||
replaced = replaced.replace(group, rgbFunction.apply(new TextColor(hexCode)));
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.format;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Formatter for #<RRGGBB>
|
||||
*/
|
||||
public class HtmlFormat implements RGBFormatter {
|
||||
|
||||
private final Pattern pattern = Pattern.compile("#<[0-9a-fA-F]{6}>");
|
||||
|
||||
@Override
|
||||
public @NotNull String reformat(@NotNull String text) {
|
||||
if (!text.contains("#<")) return text;
|
||||
Matcher m = pattern.matcher(text);
|
||||
String replaced = text;
|
||||
while (m.find()) {
|
||||
String hexCode = m.group();
|
||||
String fixed = hexCode.substring(2, 8);
|
||||
replaced = replaced.replace(hexCode, "#" + fixed);
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.format;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Formatter for <#RRGGBB>
|
||||
*/
|
||||
public class KyoriFormat implements RGBFormatter {
|
||||
|
||||
private final Pattern pattern = Pattern.compile("<#[0-9a-fA-F]{6}>");
|
||||
|
||||
@Override
|
||||
public @NotNull String reformat(@NotNull String text) {
|
||||
if (!text.contains("<#")) return text;
|
||||
String replaced = text;
|
||||
Matcher m = pattern.matcher(replaced);
|
||||
while (m.find()) {
|
||||
String hexCode = m.group();
|
||||
String fixed = hexCode.substring(2, 8);
|
||||
replaced = replaced.replace(hexCode, "#" + fixed);
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,24 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.format;
|
||||
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Abstract class for different RGB patterns
|
||||
*/
|
||||
public interface RGBFormatter {
|
||||
|
||||
/**
|
||||
* Reformats RGB codes in provided text into #RRGGBB format
|
||||
* Re-formats RGB codes in the provided text using given formatter.
|
||||
*
|
||||
* @param text
|
||||
* text to format
|
||||
* @param rgbFunction
|
||||
* Function for converting RGB codes to desired format
|
||||
* @return reformatted text
|
||||
*/
|
||||
@NotNull String reformat(@NotNull String text);
|
||||
@NotNull
|
||||
String reformat(@NotNull String text, @NotNull Function<TextColor, String> rgbFunction);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.format;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Formatter for {@code &#RRGGBB}.
|
||||
*/
|
||||
public class UnnamedFormat1 implements RGBFormatter {
|
||||
|
||||
@Override
|
||||
public @NotNull String reformat(@NotNull String text) {
|
||||
return text.contains("§#") ? text.replace("§#", "#") : text;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.gradient;
|
||||
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import me.neznamy.tab.shared.util.function.TriFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
@@ -21,7 +23,8 @@ public class CMIGradient extends CommonGradient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String applyPattern(@NotNull String text, boolean ignorePlaceholders) {
|
||||
@NotNull
|
||||
public String applyPattern(@NotNull String text, @NotNull TriFunction<TextColor, String, TextColor, String> gradientFunction) {
|
||||
String replaced = text;
|
||||
if (replaced.contains("<>}")) {
|
||||
Matcher m = shortcutPattern.matcher(replaced);
|
||||
@@ -31,6 +34,6 @@ public class CMIGradient extends CommonGradient {
|
||||
replaced = replaced.replace(format, "{#" + code + "<}{#" + code + ">}");
|
||||
}
|
||||
}
|
||||
return super.applyPattern(replaced, ignorePlaceholders);
|
||||
return super.applyPattern(replaced, gradientFunction);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package me.neznamy.tab.shared.chat.rgb.gradient;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import me.neznamy.tab.shared.util.function.TriFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
@@ -20,18 +21,17 @@ public class CommonGradient implements GradientPattern {
|
||||
private final int endColorStartSub;
|
||||
|
||||
@Override
|
||||
public String applyPattern(@NotNull String text, boolean ignorePlaceholders) {
|
||||
@NotNull
|
||||
public String applyPattern(@NotNull String text, @NotNull TriFunction<TextColor, String, TextColor, String> gradientFunction) {
|
||||
if (!text.contains(containCheck)) return text;
|
||||
String replaced = text;
|
||||
Matcher m = pattern.matcher(replaced);
|
||||
while (m.find()) {
|
||||
String format = m.group();
|
||||
if (ignorePlaceholders && format.contains("%")) continue;
|
||||
TextColor start = new TextColor(format.substring(startColorStart, startColorStart+6));
|
||||
String message = format.substring(messageStart, format.length()-10);
|
||||
TextColor end = new TextColor(format.substring(format.length()-endColorStartSub, format.length()-endColorStartSub+6));
|
||||
String applied = asGradient(start, message, end);
|
||||
replaced = replaced.replace(format, applied);
|
||||
replaced = replaced.replace(format, gradientFunction.apply(start, message, end));
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.gradient;
|
||||
|
||||
import me.neznamy.tab.shared.chat.EnumChatFormat;
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import me.neznamy.tab.shared.util.function.TriFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -14,45 +14,10 @@ public interface GradientPattern {
|
||||
*
|
||||
* @param text
|
||||
* text to be reformatted
|
||||
* @param ignorePlaceholders
|
||||
* Whether text containing "%" should be ignored or not
|
||||
* @param gradientFunction
|
||||
* Function for reformatting gradient to new text
|
||||
* @return reformatted text
|
||||
*/
|
||||
String applyPattern(@NotNull String text, boolean ignorePlaceholders);
|
||||
|
||||
/**
|
||||
* Returns gradient text based on start color, text and end color
|
||||
*
|
||||
* @param start
|
||||
* start color
|
||||
* @param text
|
||||
* text to be reformatted
|
||||
* @param end
|
||||
* end color
|
||||
* @return reformatted text
|
||||
*/
|
||||
default String asGradient(@NotNull TextColor start, @NotNull String text, @NotNull TextColor end) {
|
||||
//lazy support for magic codes in gradients
|
||||
String magicCodes = EnumChatFormat.getLastColors(text);
|
||||
String deColorized = text.substring(magicCodes.length());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int length = deColorized.length();
|
||||
if (length == 1) {
|
||||
sb.append("#");
|
||||
sb.append(start.getHexCode());
|
||||
sb.append(magicCodes);
|
||||
sb.append(deColorized);
|
||||
return sb.toString();
|
||||
}
|
||||
for (int i=0; i<length; i++) {
|
||||
int red = (int) (start.getRed() + (float)(end.getRed() - start.getRed())/(length-1)*i);
|
||||
int green = (int) (start.getGreen() + (float)(end.getGreen() - start.getGreen())/(length-1)*i);
|
||||
int blue = (int) (start.getBlue() + (float)(end.getBlue() - start.getBlue())/(length-1)*i);
|
||||
sb.append("#");
|
||||
sb.append(new TextColor(red, green, blue).getHexCode());
|
||||
sb.append(magicCodes);
|
||||
sb.append(deColorized.charAt(i));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
@NotNull
|
||||
String applyPattern(@NotNull String text, @NotNull TriFunction<TextColor, String, TextColor, String> gradientFunction);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.neznamy.tab.shared.chat.rgb.gradient;
|
||||
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import me.neznamy.tab.shared.util.function.TriFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
@@ -12,18 +13,17 @@ public class NexEngineGradient implements GradientPattern {
|
||||
private final Pattern pattern = Pattern.compile("<gradient:#([A-Fa-f0-9]{6})>(.*?)</gradient:#([A-Fa-f0-9]{6})>");
|
||||
|
||||
@Override
|
||||
public String applyPattern(@NotNull String text, boolean ignorePlaceholders) {
|
||||
@NotNull
|
||||
public String applyPattern(@NotNull String text, @NotNull TriFunction<TextColor, String, TextColor, String> gradientFunction) {
|
||||
if (!text.contains("<grad")) return text;
|
||||
String replaced = text;
|
||||
Matcher matcher = pattern.matcher(replaced);
|
||||
while (matcher.find()) {
|
||||
String format = matcher.group();
|
||||
if ((ignorePlaceholders && format.contains("%"))) continue;
|
||||
TextColor start = new TextColor(matcher.group(1));
|
||||
String content = matcher.group(2);
|
||||
TextColor end = new TextColor(matcher.group(3));
|
||||
String applied = asGradient(start, content, end);
|
||||
replaced = replaced.replace(format, applied);
|
||||
replaced = replaced.replace(format, gradientFunction.apply(start, content, end));
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import me.neznamy.tab.shared.Property;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.TabConstants;
|
||||
import me.neznamy.tab.shared.chat.EnumChatFormat;
|
||||
import me.neznamy.tab.shared.chat.StructuredComponent;
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import me.neznamy.tab.shared.config.file.ConfigurationFile;
|
||||
import me.neznamy.tab.shared.features.sorting.Sorting;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
@@ -12,6 +14,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -190,9 +193,14 @@ public class DebugCommand extends SubCommand {
|
||||
if (disabled) {
|
||||
sendMessage(sender, "&a" + property.getName() + ": &cDisabled for player with condition");
|
||||
} else {
|
||||
String rawValue = property.getCurrentRawValue().replace('§', '&');
|
||||
String value = String.format((EnumChatFormat.color("&a%s: &e\"&r%s&r&e\" &7(Source: %s)")), property.getName(), rawValue, property.getSource());
|
||||
sendRawMessage(sender, value);
|
||||
// Do it this way to avoid sending the "§" symbol to the console to try to color the text (does not work on Velocity)
|
||||
sendMessage(sender, new StructuredComponent("", Arrays.asList(
|
||||
new StructuredComponent(property.getName() + ": ", TextColor.legacy(EnumChatFormat.GREEN)),
|
||||
new StructuredComponent("\"", TextColor.legacy(EnumChatFormat.YELLOW)),
|
||||
new StructuredComponent(property.getCurrentRawValue().replace('§', '&'), TextColor.legacy(EnumChatFormat.WHITE)),
|
||||
new StructuredComponent("\" ", TextColor.legacy(EnumChatFormat.YELLOW)),
|
||||
new StructuredComponent("(Source: " + property.getSource() + ")", TextColor.legacy(EnumChatFormat.GRAY))
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
package me.neznamy.tab.shared.command;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.TabConstants;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Handler for "/tab group" subcommand
|
||||
*/
|
||||
@@ -60,20 +63,20 @@ public class GroupCommand extends PropertyCommand {
|
||||
private void sendGroupInfo(@Nullable TabPlayer sender, @NotNull String group) {
|
||||
sendMessage(sender, "&f=== Group &9" + group + "&f ===");
|
||||
for (Map.Entry<String, Object> entry : TAB.getInstance().getConfiguration().getGroups().getGlobalSettings(group).entrySet()) {
|
||||
sendRawMessage(sender, " " + entry.getKey() + ": " + entry.getValue());
|
||||
sendMessage(sender, " " + entry.getKey() + ": " + entry.getValue());
|
||||
}
|
||||
for (Map.Entry<String, Map<String, Object>> entry : TAB.getInstance().getConfiguration().getGroups().getPerWorldSettings(group).entrySet()) {
|
||||
if (entry.getValue() == null) continue;
|
||||
sendMessage(sender, "&6World " + entry.getKey() + ":&e");
|
||||
for (Map.Entry<String, Object> properties : entry.getValue().entrySet()) {
|
||||
sendRawMessage(sender, " " + properties.getKey() + ": " + properties.getValue());
|
||||
sendMessage(sender, " " + properties.getKey() + ": " + properties.getValue());
|
||||
}
|
||||
}
|
||||
for (Map.Entry<String, Map<String, Object>> entry : TAB.getInstance().getConfiguration().getGroups().getPerServerSettings(group).entrySet()) {
|
||||
if (entry.getValue() == null) continue;
|
||||
sendMessage(sender, "&3Server " + entry.getKey() + ":&b");
|
||||
for (Map.Entry<String, Object> properties : entry.getValue().entrySet()) {
|
||||
sendRawMessage(sender, " " + properties.getKey() + ": " + properties.getValue());
|
||||
sendMessage(sender, " " + properties.getKey() + ": " + properties.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +90,8 @@ public class MySQLCommand extends SubCommand {
|
||||
}
|
||||
TAB.getInstance().getCPUManager().getMysqlThread().execute(() -> {
|
||||
try {
|
||||
YamlPropertyConfigurationFile groupFile = new YamlPropertyConfigurationFile(Configs.class.getClassLoader().getResourceAsStream("config/groups.yml"), new File(TAB.getInstance().getDataFolder(), "config/groups.yml"));
|
||||
YamlPropertyConfigurationFile userFile = new YamlPropertyConfigurationFile(Configs.class.getClassLoader().getResourceAsStream("config/users.yml"), new File(TAB.getInstance().getDataFolder(), "config/users.yml"));
|
||||
YamlPropertyConfigurationFile groupFile = new YamlPropertyConfigurationFile(Configs.class.getClassLoader().getResourceAsStream("config/groups.yml"), new File(TAB.getInstance().getDataFolder(), "groups.yml"));
|
||||
YamlPropertyConfigurationFile userFile = new YamlPropertyConfigurationFile(Configs.class.getClassLoader().getResourceAsStream("config/users.yml"), new File(TAB.getInstance().getDataFolder(), "users.yml"));
|
||||
upload(groupFile, TAB.getInstance().getConfiguration().getGroups());
|
||||
upload(userFile, TAB.getInstance().getConfiguration().getUsers());
|
||||
sendMessage(sender, getMessages().getMySQLUploadSuccess());
|
||||
|
||||
@@ -5,7 +5,9 @@ import me.neznamy.tab.shared.Property;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.TabConstants;
|
||||
import me.neznamy.tab.shared.chat.EnumChatFormat;
|
||||
import me.neznamy.tab.shared.chat.StructuredComponent;
|
||||
import me.neznamy.tab.shared.chat.TabComponent;
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -50,28 +52,37 @@ public class ParseCommand extends SubCommand {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String replaced = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
|
||||
if (!replaced.contains("%")) {
|
||||
sendMessage(sender, "&cThe provided input (" + replaced + ") does not contain any placeholders, therefore there's nothing to test.");
|
||||
String textToParse = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
|
||||
if (!textToParse.contains("%")) {
|
||||
sendMessage(sender, "&cThe provided input (" + textToParse + ") does not contain any placeholders, therefore there's nothing to test.");
|
||||
return;
|
||||
}
|
||||
String message = EnumChatFormat.color("&6Replacing placeholder &e%placeholder% &6for player &e" + target.getName()).replace("%placeholder%", replaced);
|
||||
sendRawMessage(sender, message);
|
||||
// Do it this way to avoid sending the "§" symbol to the console to try to color the text (does not work on Velocity)
|
||||
sendMessage(sender, new StructuredComponent("", Arrays.asList(
|
||||
new StructuredComponent("Replacing placeholder ", TextColor.legacy(EnumChatFormat.GOLD)),
|
||||
new StructuredComponent(textToParse, TextColor.legacy(EnumChatFormat.YELLOW)),
|
||||
new StructuredComponent(" for player ", TextColor.legacy(EnumChatFormat.GOLD)),
|
||||
new StructuredComponent(target.getName(), TextColor.legacy(EnumChatFormat.YELLOW))
|
||||
)));
|
||||
try {
|
||||
replaced = new Property(null, null, target, replaced, null).get();
|
||||
String replaced = new Property(null, null, target, textToParse, null).get();
|
||||
TabComponent colored = TabComponent.fromColoredText("&3Colored output: &e\"&r" + replaced + "&e\"");
|
||||
if (sender != null) {
|
||||
sender.sendMessage(colored);
|
||||
} else {
|
||||
TAB.getInstance().getPlatform().logInfo(colored);
|
||||
}
|
||||
sendMessage(sender, new StructuredComponent("", Arrays.asList(
|
||||
new StructuredComponent("Raw colors: ", TextColor.legacy(EnumChatFormat.DARK_AQUA)),
|
||||
new StructuredComponent("\"", TextColor.legacy(EnumChatFormat.YELLOW)),
|
||||
new StructuredComponent(replaced.replace('§', '&'), TextColor.legacy(EnumChatFormat.WHITE)),
|
||||
new StructuredComponent("\"", TextColor.legacy(EnumChatFormat.YELLOW))
|
||||
)));
|
||||
sendMessage(sender, "&3Output length: &e" + replaced.length() + " &3characters");
|
||||
} catch (Exception e) {
|
||||
sendMessage(sender, "&cThe placeholder threw an exception when parsing. Check console for more info.");
|
||||
TAB.getInstance().getErrorManager().parseCommandError(replaced, target, e);
|
||||
return;
|
||||
TAB.getInstance().getErrorManager().parseCommandError(textToParse, target, e);
|
||||
}
|
||||
TabComponent colored = TabComponent.fromColoredText("&3Colored output: &e\"&r" + replaced + "&e\"");
|
||||
if (sender != null) {
|
||||
sender.sendMessage(colored);
|
||||
} else {
|
||||
TAB.getInstance().getPlatform().logInfo(colored);
|
||||
}
|
||||
sendRawMessage(sender, EnumChatFormat.color("&3Raw colors: &e\"&r") + replaced.replace('§', '&') + EnumChatFormat.color("&e\""));
|
||||
sendMessage(sender, "&3Output length: &e" + replaced.length() + " &3characters");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package me.neznamy.tab.shared.command;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.neznamy.tab.shared.chat.SimpleComponent;
|
||||
import me.neznamy.tab.shared.chat.TabComponent;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.TabConstants;
|
||||
import me.neznamy.tab.shared.chat.TabComponent;
|
||||
import me.neznamy.tab.shared.config.MessageFile;
|
||||
import me.neznamy.tab.shared.platform.TabPlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Abstract class representing a subcommand of "/tab" command
|
||||
*/
|
||||
@@ -87,7 +86,7 @@ public abstract class SubCommand {
|
||||
* @param sender
|
||||
* player or console to send the message to
|
||||
* @param message
|
||||
* the message to sent
|
||||
* the message to send
|
||||
*/
|
||||
public void sendMessage(@Nullable TabPlayer sender, @NotNull String message) {
|
||||
if (message.isEmpty()) return;
|
||||
@@ -99,19 +98,19 @@ public abstract class SubCommand {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends message to the command sender without colors translated
|
||||
* Sends the message component to the player.
|
||||
* If player is {@code null}, the message is sent to the console instead.
|
||||
*
|
||||
* @param sender
|
||||
* player or console to send the message to
|
||||
* @param message
|
||||
* the message to sent
|
||||
* the message to send
|
||||
*/
|
||||
public void sendRawMessage(@Nullable TabPlayer sender, @NotNull String message) {
|
||||
if (message.isEmpty()) return;
|
||||
public void sendMessage(@Nullable TabPlayer sender, @NotNull TabComponent message) {
|
||||
if (sender != null) {
|
||||
sender.sendMessage(message, false);
|
||||
sender.sendMessage(message);
|
||||
} else {
|
||||
TAB.getInstance().getPlatform().logInfo(new SimpleComponent(message));
|
||||
TAB.getInstance().getPlatform().logInfo(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.neznamy.tab.shared.hook;
|
||||
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.chat.AdventureComponent;
|
||||
import me.neznamy.tab.shared.chat.TabComponent;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
@@ -14,9 +15,26 @@ public class MiniMessageHook {
|
||||
|
||||
/** Minimessage deserializer with disabled component post-processing */
|
||||
@Nullable
|
||||
private static final MiniMessage mm = ReflectionUtils.classExists("net.kyori.adventure.text.minimessage.MiniMessage") &&
|
||||
ReflectionUtils.classExists("net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer") ?
|
||||
MiniMessage.builder().postProcessor(c->c).build() : null;
|
||||
private static final MiniMessage mm = createMiniMessage();
|
||||
|
||||
@Nullable
|
||||
private static MiniMessage createMiniMessage() {
|
||||
try {
|
||||
if (ReflectionUtils.classExists("net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer")) {
|
||||
return MiniMessage.builder().postProcessor(c->c).build();
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if MiniMessage is available on the server, {@code false} if not.
|
||||
*
|
||||
* @return {@code true} if MiniMessage is available on the server, {@code false} if not
|
||||
*/
|
||||
public static boolean isAvailable() {
|
||||
return mm != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to parse the text into an adventure component using MiniMessage syntax. If MiniMessage is
|
||||
@@ -29,11 +47,14 @@ public class MiniMessageHook {
|
||||
@Nullable
|
||||
public static TabComponent parseText(@NotNull String text) {
|
||||
if (mm == null) return null;
|
||||
if (!text.contains("<")) return null; // User did not even attempt to use MiniMessage
|
||||
if (text.contains("§")) return null;
|
||||
if (text.contains("§")) {
|
||||
TAB.getInstance().getErrorManager().printError("Cannot convert \"" + text + "\" into a MiniMessage component, because it contains legacy colors", null);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new AdventureComponent(mm.deserialize(text));
|
||||
} catch (Throwable ignored) {
|
||||
} catch (Throwable t) {
|
||||
TAB.getInstance().getErrorManager().printError("Failed to convert \"" + text + "\" into a MiniMessage component", t);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import lombok.NonNull;
|
||||
import me.neznamy.tab.shared.TAB;
|
||||
import me.neznamy.tab.shared.TabConstants;
|
||||
import me.neznamy.tab.shared.chat.EnumChatFormat;
|
||||
import me.neznamy.tab.shared.chat.rgb.RGBUtils;
|
||||
import me.neznamy.tab.shared.features.PlaceholderManagerImpl;
|
||||
import me.neznamy.tab.shared.placeholders.animation.AnimationConfiguration.AnimationDefinition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -57,7 +56,6 @@ public class Animation {
|
||||
int refresh = interval;
|
||||
List<String> nestedPlaceholders = new ArrayList<>();
|
||||
for (int i=0; i<messages.length; i++) {
|
||||
messages[i] = RGBUtils.getInstance().applyCleanGradients(messages[i]);
|
||||
messages[i] = EnumChatFormat.color(messages[i]);
|
||||
nestedPlaceholders.addAll(PlaceholderManagerImpl.detectPlaceholders(messages[i]));
|
||||
}
|
||||
|
||||
+52
-4
@@ -1,14 +1,33 @@
|
||||
package me.neznamy.tab.shared.util.cache;
|
||||
|
||||
import me.neznamy.tab.shared.chat.EnumChatFormat;
|
||||
import me.neznamy.tab.shared.chat.SimpleComponent;
|
||||
import me.neznamy.tab.shared.chat.TabComponent;
|
||||
import me.neznamy.tab.shared.chat.TextColor;
|
||||
import me.neznamy.tab.shared.chat.rgb.RGBUtils;
|
||||
import me.neznamy.tab.shared.hook.MiniMessageHook;
|
||||
import me.neznamy.tab.shared.util.function.TriFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Cache for String -> TabComponent conversion.
|
||||
* Cache for String → TabComponent conversion.
|
||||
*/
|
||||
public class StringToComponentCache extends Cache<String, TabComponent> {
|
||||
|
||||
/** Formatter to use Kyori's <gradient:#RRGGBB:#RRGGBB>Text</gradient> */
|
||||
private static final TriFunction<TextColor, String, TextColor, String> kyoriGradientFormatter =
|
||||
(start, text, end) -> String.format("<gradient:#%s:#%s>%s</gradient>", start.getHexCode(), end.getHexCode(), text);
|
||||
|
||||
/** Formatter to convert RGB code to use Kyori's <color:#RRGGBB>*/
|
||||
private static final Function<TextColor, String> kyoriRGBFormatter = color -> String.format("<color:#%s>", color.getHexCode());
|
||||
|
||||
private static final Pattern tabToKyori = Pattern.compile("(?<!:)(#([0-9A-Fa-f]{6}))(?![:>])");
|
||||
|
||||
/**
|
||||
* Constructs new instance with given parameters.
|
||||
*
|
||||
@@ -19,11 +38,40 @@ public class StringToComponentCache extends Cache<String, TabComponent> {
|
||||
*/
|
||||
public StringToComponentCache(String name, int cacheSize) {
|
||||
super(name, cacheSize, text -> {
|
||||
TabComponent component = MiniMessageHook.parseText(text);
|
||||
if (component != null) return component;
|
||||
return text.contains("#") || text.contains("&x") || text.contains("§x") || text.contains("<") ?
|
||||
if (MiniMessageHook.isAvailable() && text.indexOf('<') != -1) { // User may have wanted to use MiniMessage
|
||||
|
||||
// Reformat gradients and RGB to kyori format
|
||||
String mmFormatted = RGBUtils.getInstance().applyFormats(text, kyoriGradientFormatter, kyoriRGBFormatter);
|
||||
|
||||
// Convert legacy codes into kyori format
|
||||
for (EnumChatFormat format : EnumChatFormat.VALUES) {
|
||||
if (mmFormatted.contains(format.getFormat())) {
|
||||
String colorName = format == EnumChatFormat.UNDERLINE ? "underlined" : format.name().toLowerCase(Locale.US);
|
||||
mmFormatted = mmFormatted.replace(format.getFormat(), "<" + colorName + ">");
|
||||
}
|
||||
}
|
||||
|
||||
// Convert TAB's #RRGGBB to Kyori <color:#RRGGBB>
|
||||
mmFormatted = tabToKyori(mmFormatted);
|
||||
|
||||
TabComponent component = MiniMessageHook.parseText(mmFormatted);
|
||||
if (component != null) return component;
|
||||
}
|
||||
return text.contains("#") || text.contains("§x") || text.contains("<") ?
|
||||
TabComponent.fromColoredText(text) : //contains RGB colors or font
|
||||
new SimpleComponent(text); //no RGB
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String tabToKyori(@NotNull String text) {
|
||||
Matcher matcher = tabToKyori.matcher(text);
|
||||
StringBuffer result = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
// Replace standalone #RRGGBB with <color:#RRGGBB>
|
||||
matcher.appendReplacement(result, "<color:" + matcher.group(1) + ">");
|
||||
}
|
||||
matcher.appendTail(result);
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package me.neznamy.tab.shared.util;
|
||||
package me.neznamy.tab.shared.util.function;
|
||||
|
||||
/**
|
||||
* An interface for BiConsumer which can throw an exception.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package me.neznamy.tab.shared.util;
|
||||
package me.neznamy.tab.shared.util.function;
|
||||
|
||||
/**
|
||||
* An interface for BiFunction which can throw an exception.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package me.neznamy.tab.shared.util;
|
||||
package me.neznamy.tab.shared.util.function;
|
||||
|
||||
/**
|
||||
* An interface for Function which can throw an exception.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package me.neznamy.tab.shared.util;
|
||||
package me.neznamy.tab.shared.util.function;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package me.neznamy.tab.shared.util;
|
||||
package me.neznamy.tab.shared.util.function;
|
||||
|
||||
/**
|
||||
* Represents a function that accepts an int-valued argument and produces a
|
||||
@@ -0,0 +1,29 @@
|
||||
package me.neznamy.tab.shared.util.function;
|
||||
|
||||
/**
|
||||
* An interface for a function with 3 input arguments.
|
||||
* @param <A>
|
||||
* First function argument
|
||||
* @param <B>
|
||||
* Second function argument
|
||||
* @param <C>
|
||||
* Third function argument
|
||||
* @param <D>
|
||||
* Function return type
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface TriFunction<A, B, C, D> {
|
||||
|
||||
/**
|
||||
* Runs the function and returns the result
|
||||
*
|
||||
* @param a
|
||||
* First argument
|
||||
* @param b
|
||||
* Second argument
|
||||
* @param c
|
||||
* Third argument
|
||||
* @return Output from function
|
||||
*/
|
||||
D apply(A a, B b, C c);
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package me.neznamy.tab.shared.util;
|
||||
package me.neznamy.tab.shared.util.function;
|
||||
|
||||
/**
|
||||
* An interface for BiFunction which can throw an exception.
|
||||
* An interface for TriFunction which can throw an exception.
|
||||
* @param <A>
|
||||
* First function argument
|
||||
* @param <B>
|
||||
@@ -1,10 +1,10 @@
|
||||
package me.neznamy.tab.platforms.sponge8;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import me.neznamy.tab.shared.util.BiFunctionWithException;
|
||||
import me.neznamy.tab.shared.util.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.BiFunctionWithException;
|
||||
import me.neznamy.tab.shared.util.function.FunctionWithException;
|
||||
import me.neznamy.tab.shared.util.ReflectionUtils;
|
||||
import me.neznamy.tab.shared.util.ToIntFunction;
|
||||
import me.neznamy.tab.shared.util.function.ToIntFunction;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
|
||||
Reference in new issue
Block a user