fix: give chat mentions default highlight color and support @tags
This commit is contained in:
@@ -17,6 +17,7 @@ import org.examp.john.stealth.StealthStorage;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class ChatHandler {
|
public class ChatHandler {
|
||||||
public static void register() {
|
public static void register() {
|
||||||
@@ -149,10 +150,11 @@ public class ChatHandler {
|
|||||||
while (!remaining.isEmpty()) {
|
while (!remaining.isEmpty()) {
|
||||||
int earliestIndex = remaining.length();
|
int earliestIndex = remaining.length();
|
||||||
ServerPlayer mentioned = null;
|
ServerPlayer mentioned = null;
|
||||||
|
String lower = remaining.toLowerCase(Locale.ROOT);
|
||||||
|
|
||||||
for (ServerPlayer player : sorted) {
|
for (ServerPlayer player : sorted) {
|
||||||
String name = player.getName().getString();
|
String nameLower = player.getName().getString().toLowerCase(Locale.ROOT);
|
||||||
int index = remaining.toLowerCase().indexOf(name.toLowerCase());
|
int index = indexOfBoundary(lower, nameLower);
|
||||||
if (index >= 0 && index < earliestIndex) {
|
if (index >= 0 && index < earliestIndex) {
|
||||||
earliestIndex = index;
|
earliestIndex = index;
|
||||||
mentioned = player;
|
mentioned = player;
|
||||||
@@ -164,11 +166,13 @@ public class ChatHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (earliestIndex > 0) {
|
boolean withAt = earliestIndex > 0 && remaining.charAt(earliestIndex - 1) == '@';
|
||||||
result.append(Component.literal(remaining.substring(0, earliestIndex)));
|
int prefixEnd = withAt ? earliestIndex - 1 : earliestIndex;
|
||||||
|
if (prefixEnd > 0) {
|
||||||
|
result.append(Component.literal(remaining.substring(0, prefixEnd)));
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append(createMentionComponent(mentioned));
|
result.append(createMentionComponent(mentioned, withAt));
|
||||||
|
|
||||||
remaining = remaining.substring(earliestIndex + mentioned.getName().getString().length());
|
remaining = remaining.substring(earliestIndex + mentioned.getName().getString().length());
|
||||||
}
|
}
|
||||||
@@ -176,13 +180,32 @@ public class ChatHandler {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Component createMentionComponent(ServerPlayer player) {
|
private static int indexOfBoundary(String lowerHaystack, String lowerNeedle) {
|
||||||
String prefix = getLuckPermsPrefix(player);
|
int index = lowerHaystack.indexOf(lowerNeedle);
|
||||||
String formattedPrefix = prefix.replace("&", "\u00a7");
|
while (index >= 0) {
|
||||||
String name = player.getName().getString();
|
boolean okBefore = index == 0 || !isNameChar(lowerHaystack.charAt(index - 1));
|
||||||
|
boolean okAfter = index + lowerNeedle.length() == lowerHaystack.length()
|
||||||
|
|| !isNameChar(lowerHaystack.charAt(index + lowerNeedle.length()));
|
||||||
|
if (okBefore && okAfter) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
index = lowerHaystack.indexOf(lowerNeedle, index + 1);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return Component.literal(formattedPrefix + name)
|
private static boolean isNameChar(char c) {
|
||||||
|
return Character.isLetterOrDigit(c) || c == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Component createMentionComponent(ServerPlayer player, boolean withAt) {
|
||||||
|
String name = player.getName().getString();
|
||||||
|
String prefix = formatLegacyPrefix(getLuckPermsPrefix(player));
|
||||||
|
String text = (withAt ? "@" : "") + prefix + name;
|
||||||
|
|
||||||
|
return Component.literal(text)
|
||||||
.withStyle(Style.EMPTY
|
.withStyle(Style.EMPTY
|
||||||
|
.withColor(ChatFormatting.AQUA)
|
||||||
.withClickEvent(new ClickEvent.SuggestCommand("/msg " + name + " "))
|
.withClickEvent(new ClickEvent.SuggestCommand("/msg " + name + " "))
|
||||||
.withHoverEvent(new HoverEvent.ShowText(
|
.withHoverEvent(new HoverEvent.ShowText(
|
||||||
Component.literal("Натисніть щоб написати " + name)
|
Component.literal("Натисніть щоб написати " + name)
|
||||||
@@ -190,6 +213,40 @@ public class ChatHandler {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String formatLegacyPrefix(String raw) {
|
||||||
|
if (raw == null || raw.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String s = raw.replace('&', '§');
|
||||||
|
StringBuilder out = new StringBuilder(s.length() + 14);
|
||||||
|
int i = 0;
|
||||||
|
while (i < s.length()) {
|
||||||
|
if (s.charAt(i) == '§' && i + 8 <= s.length() && s.charAt(i + 1) == '#'
|
||||||
|
&& isSixHex(s, i + 2)) {
|
||||||
|
out.append("§x");
|
||||||
|
for (int j = 2; j < 8; j++) {
|
||||||
|
out.append('§').append(s.charAt(i + j));
|
||||||
|
}
|
||||||
|
i += 8;
|
||||||
|
} else {
|
||||||
|
out.append(s.charAt(i));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSixHex(String s, int start) {
|
||||||
|
for (int i = start; i < start + 6; i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
boolean hex = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
|
||||||
|
if (!hex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static String getLuckPermsPrefix(ServerPlayer player) {
|
private static String getLuckPermsPrefix(ServerPlayer player) {
|
||||||
try {
|
try {
|
||||||
LuckPerms luckPerms = LuckPermsProvider.get();
|
LuckPerms luckPerms = LuckPermsProvider.get();
|
||||||
@@ -206,21 +263,10 @@ public class ChatHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static MutableComponent buildFormattedName(ServerPlayer player) {
|
private static MutableComponent buildFormattedName(ServerPlayer player) {
|
||||||
String prefix = "";
|
String prefix = formatLegacyPrefix(getLuckPermsPrefix(player));
|
||||||
try {
|
|
||||||
LuckPerms luckPerms = LuckPermsProvider.get();
|
|
||||||
User user = luckPerms.getUserManager().getUser(player.getUUID());
|
|
||||||
if (user != null) {
|
|
||||||
String metaPrefix = user.getCachedData().getMetaData().getPrefix();
|
|
||||||
if (metaPrefix != null) {
|
|
||||||
prefix = metaPrefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return Component.empty()
|
return Component.empty()
|
||||||
.append(Component.literal(prefix.replace("&", "§")))
|
.append(Component.literal(prefix))
|
||||||
.append(player.getDisplayName());
|
.append(player.getDisplayName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user