mirror of
https://github.com/CPTProgrammer/ChatPlus.git
synced 2026-02-04 04:02:00 +08:00
93 lines
2.9 KiB
Java
93 lines
2.9 KiB
Java
package cn.revaria.chatplus.util;
|
|
|
|
#if MC_VER <= MC_1_20
|
|
import net.minecraft.text.LiteralTextContent;
|
|
#else
|
|
import net.minecraft.text.PlainTextContent.Literal;
|
|
#endif
|
|
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.server.network.ServerPlayerEntity;
|
|
import net.minecraft.text.MutableText;
|
|
import net.minecraft.text.Text;
|
|
|
|
import java.util.ArrayDeque;
|
|
import java.util.Deque;
|
|
import java.util.List;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
public class TextStyleFormatter {
|
|
public static int MAIN_HAND = -1; // Must be smaller than or equal to 0
|
|
|
|
/**
|
|
* Processes text styling with two key functions:
|
|
* <p>
|
|
* 1. Replaces {@code &} with {@code §}, using {@code &&} to escape literal {@code &}<br>
|
|
* 2. Substitutes {@code [item]} with main-hand item hover text and {@code [item=N]} with Nth slot's hover text
|
|
* </p>
|
|
* Recursively processes nested text components.
|
|
*
|
|
* @param sourceText Original text to process (supports nested text components)
|
|
* @param sourcePlayer Player used for item stack references
|
|
* @return Processed text with styling and item hover elements
|
|
*/
|
|
public static MutableText applyStyle(Text sourceText, ServerPlayerEntity sourcePlayer) {
|
|
MutableText sourceMutableText = sourceText.copy();
|
|
|
|
MutableText finalText = Text.empty().setStyle(sourceMutableText.getStyle());
|
|
|
|
if (sourceText.getContent() instanceof #if MC_VER <= MC_1_20 LiteralTextContent #else Literal #endif plainTextContent) {
|
|
String changedMessage = plainTextContent.string()
|
|
.replace('&', '§')
|
|
.replace("§§", "&");
|
|
String regex = "\\[item(?:=([1-9]))?\\]";
|
|
String[] messages = changedMessage.split(regex, -1);
|
|
Deque<Integer> itemDeque = new ArrayDeque<>();
|
|
|
|
Matcher matcher = Pattern.compile(regex).matcher(changedMessage);
|
|
while (matcher.find()) {
|
|
String digit = matcher.group(1);
|
|
if (digit == null) {
|
|
itemDeque.addLast(MAIN_HAND);
|
|
} else {
|
|
itemDeque.addLast(Integer.parseInt(digit));
|
|
}
|
|
}
|
|
|
|
for (String message : messages) {
|
|
finalText.append(Text.literal(message));
|
|
if (!itemDeque.isEmpty()) {
|
|
ItemStack itemStack;
|
|
if (itemDeque.getFirst() == MAIN_HAND) {
|
|
itemStack = sourcePlayer.getMainHandStack();
|
|
} else {
|
|
itemStack = sourcePlayer.getInventory().getStack(itemDeque.getFirst() - 1);
|
|
}
|
|
finalText.append(itemStack.toHoverableText());
|
|
itemDeque.removeFirst();
|
|
}
|
|
}
|
|
}
|
|
|
|
List<Text> sourceTexts = sourceMutableText.getSiblings();
|
|
for (Text text : sourceTexts) {
|
|
finalText.append(applyStyle(text, sourcePlayer));
|
|
}
|
|
|
|
return finalText;
|
|
}
|
|
|
|
/**
|
|
* Simple style application that only replaces color codes.
|
|
* Used for anvil renaming where [item] tags are not appropriate.
|
|
*
|
|
* @param text The text to format
|
|
* @return Formatted text with § color codes
|
|
*/
|
|
public static String applySimpleStyle(String text) {
|
|
if (text == null) return null;
|
|
return text.replace('&', '§').replace("§§", "&");
|
|
}
|
|
}
|