From e70fe89d193ab446a406069339a897246c517a0e Mon Sep 17 00:00:00 2001 From: John Etherfield Date: Tue, 11 Aug 2026 19:14:19 +0200 Subject: [PATCH] feat: add server console logging for local chat and optimize ChatHandler.java --- src/main/java/org/examp/john/ChatHandler.java | 30 +++++---- src/main/java/org/examp/john/ChatLogger.java | 66 +++++++++++++++++++ 2 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 src/main/java/org/examp/john/ChatLogger.java diff --git a/src/main/java/org/examp/john/ChatHandler.java b/src/main/java/org/examp/john/ChatHandler.java index 0ee0f41..6061e12 100644 --- a/src/main/java/org/examp/john/ChatHandler.java +++ b/src/main/java/org/examp/john/ChatHandler.java @@ -11,17 +11,16 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import java.util.ArrayList; import java.util.List; public class ChatHandler { - public static void register() { final String prefix = "!"; final float LOCAL_CHAT_RADIUS = 100; ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> { String text = message.signedContent(); - ServerLevel serverLevel = sender.level(); MinecraftServer server = serverLevel.getServer(); List players = server.getPlayerList().getPlayers(); @@ -55,36 +54,45 @@ public class ChatHandler { player.sendSystemMessage(globalMessage); } + // Логування: глобальний чат чують всі онлайн-гравці + ChatLogger.logGlobal(sender, actualMessage, players); + } else { // ЛОКАЛЬНИЙ ЧАТ - int heardCount = 0; - + List hearers = new ArrayList<>(); for (ServerPlayer player : players) { if (player.level() == serverLevel && player.distanceTo(sender) <= LOCAL_CHAT_RADIUS) { if (player != sender) { - heardCount++; + hearers.add(player); } } } - if (heardCount > 0) { + if (!hearers.isEmpty()) { Component localMessage = Component.empty() .append(formattedName) .append(Component.literal(": " + text).withStyle(ChatFormatting.GRAY)); - for (ServerPlayer player : players) { - if (player.level() == serverLevel && player.distanceTo(sender) <= LOCAL_CHAT_RADIUS) { - player.sendSystemMessage(localMessage); - } + // ОПТИМІЗАЦІЯ: Замість повторної перевірки всіх гравців сервера, + // просто відправляємо повідомлення самому відправнику та вже готовому списку слухачів. + sender.sendSystemMessage(localMessage); + for (ServerPlayer hearer : hearers) { + hearer.sendSystemMessage(localMessage); } + + // Логування: локальний чат, хто почув + координати + ChatLogger.logLocal(sender, text, hearers); + } else { sender.sendSystemMessage( Component.literal("Вас ніхто не почув, додайте на початок повідомлення \"!\" аби написати в глобальний чат") .withStyle(ChatFormatting.ITALIC, ChatFormatting.YELLOW) ); + + // Логування: ніхто не почув + ChatLogger.logUnheard(sender, text); } } - return false; }); } diff --git a/src/main/java/org/examp/john/ChatLogger.java b/src/main/java/org/examp/john/ChatLogger.java new file mode 100644 index 0000000..9fd979c --- /dev/null +++ b/src/main/java/org/examp/john/ChatLogger.java @@ -0,0 +1,66 @@ +package org.examp.john; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Логує повідомлення локального та глобального чату в консоль сервера. + * Формат: хто сказав ➔ що сказав ➔ хто почув (тільки імена) ➔ координати відправника. + */ +public class ChatLogger { + + public static void logGlobal(ServerPlayer sender, String message, List recipients) { + // Для глобального чату ігноруємо список отримувачів і просто пишемо "everyone" + Localchat.magicModLog.info( + "[CHAT][GLOBAL] {} said: \"{}\" | heard by: everyone | pos: {}", + sender.getName().getString(), + message, + formatPos(sender) + ); + } + + public static void logLocal(ServerPlayer sender, String message, List recipients) { + // Для локального чату виводимо лише імена отримувачів, без їхніх координат + String heardBy = recipients.isEmpty() + ? "nobody" + : recipients.stream() + .map(p -> p.getName().getString()) + .collect(Collectors.joining(", ")); + + Localchat.magicModLog.info( + "[CHAT][LOCAL] {} said: \"{}\" | heard by: {} | pos: {}", + sender.getName().getString(), + message, + heardBy, + formatPos(sender) + ); + } + + public static void logUnheard(ServerPlayer sender, String message) { + Localchat.magicModLog.info( + "[CHAT][LOCAL][UNHEARD] {} said: \"{}\" | heard by: nobody | pos: {}", + sender.getName().getString(), + message, + formatPos(sender) + ); + } + + private static String formatPos(ServerPlayer player) { + ServerLevel level = player.level(); + + // У ResourceKey дістаємо Identifier/ResourceLocation через .identifier(), + // після чого через .getPath() беремо чисту назву ("overworld", "the_nether", "the_end") + String rawDimension = level.dimension().identifier().getPath(); + + return String.format( + "%s(%.1f, %.1f, %.1f)", + rawDimension, + player.getX(), + player.getY(), + player.getZ() + ); + } +} \ No newline at end of file