From 35b829c3db6b3bb43e132c8ff9a7ad52c7ced9b9 Mon Sep 17 00:00:00 2001 From: APairOfMoons <84629346+APairOfMoons@users.noreply.github.com> Date: Mon, 6 Jul 2026 01:06:30 +0800 Subject: [PATCH] Feat & Rebuild: Add @PlayerName Reminder in chat. --- .../java/cn/revaria/chatplus/ChatPlus.java | 10 +++ .../format/formats/ChatInsertFormat.java | 9 +++ .../ChatInsertItemFormat.java | 11 +++- .../ChatInsertReminderFormat.java | 53 +++++++++++++++ .../chatplus/util/TextStyleFormatter.java | 66 +++++++++++++++---- 5 files changed, 135 insertions(+), 14 deletions(-) create mode 100644 src/main/java/cn/revaria/chatplus/format/formats/ChatInsertFormat.java rename src/main/java/cn/revaria/chatplus/format/formats/{ => insertformats}/ChatInsertItemFormat.java (66%) create mode 100644 src/main/java/cn/revaria/chatplus/format/formats/insertformats/ChatInsertReminderFormat.java diff --git a/src/main/java/cn/revaria/chatplus/ChatPlus.java b/src/main/java/cn/revaria/chatplus/ChatPlus.java index e18f3f2..bad1b5e 100644 --- a/src/main/java/cn/revaria/chatplus/ChatPlus.java +++ b/src/main/java/cn/revaria/chatplus/ChatPlus.java @@ -1,6 +1,8 @@ package cn.revaria.chatplus; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.minecraft.server.MinecraftServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,12 +14,20 @@ public class ChatPlus implements ModInitializer { // That way, it's clear which mod wrote info, warnings, and errors. public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + private static MinecraftServer server; + + public static MinecraftServer getServer() { + return server; + } + @Override public void onInitialize() { // This code runs as soon as Minecraft is in a mod-load-ready state. // However, some things (like resources) may still be uninitialized. // Proceed with mild caution. + ServerLifecycleEvents.SERVER_STARTING.register(server -> ChatPlus.server = server); + LOGGER.info("Chat Plus loaded"); } } diff --git a/src/main/java/cn/revaria/chatplus/format/formats/ChatInsertFormat.java b/src/main/java/cn/revaria/chatplus/format/formats/ChatInsertFormat.java new file mode 100644 index 0000000..877dd39 --- /dev/null +++ b/src/main/java/cn/revaria/chatplus/format/formats/ChatInsertFormat.java @@ -0,0 +1,9 @@ +package cn.revaria.chatplus.format.formats; + +import cn.revaria.chatplus.format.ChatFormat; +import net.minecraft.network.chat.MutableComponent; + +public interface ChatInsertFormat extends ChatFormat { + MutableComponent getInsertComponent(); + ChatInsertFormat copy(); +} diff --git a/src/main/java/cn/revaria/chatplus/format/formats/ChatInsertItemFormat.java b/src/main/java/cn/revaria/chatplus/format/formats/insertformats/ChatInsertItemFormat.java similarity index 66% rename from src/main/java/cn/revaria/chatplus/format/formats/ChatInsertItemFormat.java rename to src/main/java/cn/revaria/chatplus/format/formats/insertformats/ChatInsertItemFormat.java index 86c2323..26720eb 100644 --- a/src/main/java/cn/revaria/chatplus/format/formats/ChatInsertItemFormat.java +++ b/src/main/java/cn/revaria/chatplus/format/formats/insertformats/ChatInsertItemFormat.java @@ -1,10 +1,11 @@ -package cn.revaria.chatplus.format.formats; +package cn.revaria.chatplus.format.formats.insertformats; -import cn.revaria.chatplus.format.ChatFormat; import cn.revaria.chatplus.format.ChatFormatType; +import cn.revaria.chatplus.format.formats.ChatInsertFormat; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.item.ItemStack; -public class ChatInsertItemFormat implements ChatFormat { +public class ChatInsertItemFormat implements ChatInsertFormat { private final ItemStack item; @@ -21,6 +22,10 @@ public class ChatInsertItemFormat implements ChatFormat { return item; } + @Override + public MutableComponent getInsertComponent() { + return item.getDisplayName().copy(); + } @Override public int startingIndex() { return startingIndex; diff --git a/src/main/java/cn/revaria/chatplus/format/formats/insertformats/ChatInsertReminderFormat.java b/src/main/java/cn/revaria/chatplus/format/formats/insertformats/ChatInsertReminderFormat.java new file mode 100644 index 0000000..a7aaa31 --- /dev/null +++ b/src/main/java/cn/revaria/chatplus/format/formats/insertformats/ChatInsertReminderFormat.java @@ -0,0 +1,53 @@ +package cn.revaria.chatplus.format.formats.insertformats; + +import cn.revaria.chatplus.format.ChatFormatType; +import cn.revaria.chatplus.format.formats.ChatInsertFormat; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.TextColor; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; + +public class ChatInsertReminderFormat implements ChatInsertFormat { + + private final ServerPlayer aimPlayer; + private boolean soundPlayed = false; + + private final int startingIndex; + private final ChatFormatType formatType = ChatFormatType.INSERT; + + public ChatInsertReminderFormat(int startingIndex, ServerPlayer aim) { + this.startingIndex = startingIndex; + + this.aimPlayer = aim; + } + + public ServerPlayer getAimPlayer() { + return aimPlayer; + } + + @Override + public MutableComponent getInsertComponent() { + if (!soundPlayed) { + soundPlayed = true; + aimPlayer.playSound(SoundEvents.EXPERIENCE_ORB_PICKUP, 3, 1); + } + return Component.literal("@").append(aimPlayer.getDisplayName()) + .withColor(TextColor.GREEN) + .withStyle(ChatFormatting.BOLD); + } + @Override + public int startingIndex() { + return startingIndex; + } + @Override + public ChatFormatType formatType() { + return formatType; + } + @Override + public ChatInsertFormat copy() { + return new ChatInsertReminderFormat(startingIndex, aimPlayer); + } +} diff --git a/src/main/java/cn/revaria/chatplus/util/TextStyleFormatter.java b/src/main/java/cn/revaria/chatplus/util/TextStyleFormatter.java index 5cce8e0..1c75dd7 100644 --- a/src/main/java/cn/revaria/chatplus/util/TextStyleFormatter.java +++ b/src/main/java/cn/revaria/chatplus/util/TextStyleFormatter.java @@ -2,17 +2,20 @@ package cn.revaria.chatplus.util; #if MC_VER <= MC_1_20 import net.minecraft.network.chat.contents.LiteralContents; -#else +#endif + +import cn.revaria.chatplus.ChatPlus; +import cn.revaria.chatplus.format.formats.ChatInsertFormat; +import cn.revaria.chatplus.format.formats.insertformats.ChatInsertReminderFormat; import cn.revaria.chatplus.format.ChatFormat; import cn.revaria.chatplus.format.ChatFormatType; import cn.revaria.chatplus.format.formats.ChatColorFormat; import cn.revaria.chatplus.format.formats.ChatFontFormat; -import cn.revaria.chatplus.format.formats.ChatInsertItemFormat; +import cn.revaria.chatplus.format.formats.insertformats.ChatInsertItemFormat; import cn.revaria.chatplus.format.formats.ChatResetFormat; -#endif - import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import java.util.*; @@ -69,7 +72,7 @@ public class TextStyleFormatter { ArrayList formatsList = formatsTable.get(i); - if (formatsList.getFirst() instanceof ChatInsertItemFormat insertItem) { + if (formatsList.getFirst() instanceof ChatInsertFormat insertFormat) { if (i > 0) { finalText.append(composeChatComponent( @@ -79,7 +82,7 @@ public class TextStyleFormatter { )); } - finalText.append(insertItem.getItem().getDisplayName()); + finalText.append(insertFormat.getInsertComponent()); startIndex = i; continue; @@ -152,6 +155,9 @@ public class TextStyleFormatter { StringBuilder textBuilder = new StringBuilder(); + MinecraftServer server = ChatPlus.getServer(); + String[] playerNames = server.getPlayerList().getPlayerNamesArray(); + String itemRegex = "\\[item(?:=([1-9]))?\\]"; Pattern itemPattern = Pattern.compile(itemRegex); Matcher matcher = itemPattern.matcher(sourceRawText); @@ -268,21 +274,42 @@ public class TextStyleFormatter { } } + if ((character >= '0' && character <= '9') + || (character >= 'a' && character <= 'z') + || (character >= 'A' && character <= 'Z') + || character == '_') { + + String insertName = matchPlayerName(sourceRawText, playerNames, i); + if (insertName != null) { + + if (!formatsTableOutput.containsKey(currentIndex)) { + formatsTableOutput.put(currentIndex, new ArrayList<>()); + } + formatsTableOutput.get(currentIndex).add(new ChatInsertReminderFormat( + currentIndex, + server.getPlayerList().getPlayer(insertName) + )); + + i += insertName.length() - 1; + continue; + } + } + textBuilder.append(character); } formatsTableOutput.forEach((i, formatsList) -> { boolean containsResetFormat = false; - ChatInsertItemFormat containedInsertItemFormat = null; + ChatInsertFormat containedInsertFormat = null; for (ChatFormat format : formatsList) { if (format.formatType() == ChatFormatType.RESET) { containsResetFormat = true; break; } - if (format instanceof ChatInsertItemFormat insertItemFormat && format.formatType() == ChatFormatType.INSERT) { - containedInsertItemFormat = insertItemFormat.copy(); + if (format instanceof ChatInsertFormat insertFormat && format.formatType() == ChatFormatType.INSERT) { + containedInsertFormat = insertFormat.copy(); break; } } @@ -291,12 +318,29 @@ public class TextStyleFormatter { formatsList.clear(); formatsList.add(new ChatResetFormat(i)); } - if (containedInsertItemFormat != null) { + if (containedInsertFormat != null) { formatsList.clear(); - formatsList.add(containedInsertItemFormat); + formatsList.add(containedInsertFormat); } }); return textBuilder.toString(); } + + private static String matchPlayerName(String chatText, String[] playerNames, int startingIndex) { + + String aimName = null; + + for (String name : playerNames) { + + if (chatText.startsWith(name, startingIndex)) { + + if (aimName == null || aimName.length() < name.length()) { + aimName = name; + } + } + } + + return aimName; + } }