feat: add server console logging for local chat and optimize ChatHandler.java

This commit is contained in:
2026-08-11 19:14:19 +02:00
parent c20ee0bc49
commit e70fe89d19
2 changed files with 85 additions and 11 deletions
+19 -11
View File
@@ -11,17 +11,16 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ChatHandler { public class ChatHandler {
public static void register() { public static void register() {
final String prefix = "!"; final String prefix = "!";
final float LOCAL_CHAT_RADIUS = 100; final float LOCAL_CHAT_RADIUS = 100;
ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> { ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> {
String text = message.signedContent(); String text = message.signedContent();
ServerLevel serverLevel = sender.level(); ServerLevel serverLevel = sender.level();
MinecraftServer server = serverLevel.getServer(); MinecraftServer server = serverLevel.getServer();
List<ServerPlayer> players = server.getPlayerList().getPlayers(); List<ServerPlayer> players = server.getPlayerList().getPlayers();
@@ -55,36 +54,45 @@ public class ChatHandler {
player.sendSystemMessage(globalMessage); player.sendSystemMessage(globalMessage);
} }
// Логування: глобальний чат чують всі онлайн-гравці
ChatLogger.logGlobal(sender, actualMessage, players);
} else { } else {
// ЛОКАЛЬНИЙ ЧАТ // ЛОКАЛЬНИЙ ЧАТ
int heardCount = 0; List<ServerPlayer> hearers = new ArrayList<>();
for (ServerPlayer player : players) { for (ServerPlayer player : players) {
if (player.level() == serverLevel && player.distanceTo(sender) <= LOCAL_CHAT_RADIUS) { if (player.level() == serverLevel && player.distanceTo(sender) <= LOCAL_CHAT_RADIUS) {
if (player != sender) { if (player != sender) {
heardCount++; hearers.add(player);
} }
} }
} }
if (heardCount > 0) { if (!hearers.isEmpty()) {
Component localMessage = Component.empty() Component localMessage = Component.empty()
.append(formattedName) .append(formattedName)
.append(Component.literal(": " + text).withStyle(ChatFormatting.GRAY)); .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 { } else {
sender.sendSystemMessage( sender.sendSystemMessage(
Component.literal("Вас ніхто не почув, додайте на початок повідомлення \"!\" аби написати в глобальний чат") Component.literal("Вас ніхто не почув, додайте на початок повідомлення \"!\" аби написати в глобальний чат")
.withStyle(ChatFormatting.ITALIC, ChatFormatting.YELLOW) .withStyle(ChatFormatting.ITALIC, ChatFormatting.YELLOW)
); );
// Логування: ніхто не почув
ChatLogger.logUnheard(sender, text);
} }
} }
return false; return false;
}); });
} }
@@ -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<ServerPlayer> 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<ServerPlayer> 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()
);
}
}