From e74361a7b7c17389f0e53c97bee2b7807be22c3c Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Sat, 22 Mar 2025 18:19:25 +0100 Subject: [PATCH] Add "local" chat channels with proximity-based messaging Introduced a "local" channel type to restrict chat visibility based on player proximity, configurable via `LOCAL_DISTANCE`. Added channel spy functionality to monitor "local" messages. Updated constructors and configuration to support this new feature. --- .../java/com/alttd/chat/config/Config.java | 8 ++++- .../alttd/chat/objects/channels/Channel.java | 8 ++++- .../chat/objects/channels/CustomChannel.java | 4 +-- .../chat/objects/channels/DefaultChannel.java | 2 +- .../com/alttd/chat/handler/ChatHandler.java | 33 ++++++++++++++++--- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/com/alttd/chat/config/Config.java b/api/src/main/java/com/alttd/chat/config/Config.java index a968aa4..55a254b 100755 --- a/api/src/main/java/com/alttd/chat/config/Config.java +++ b/api/src/main/java/com/alttd/chat/config/Config.java @@ -368,6 +368,8 @@ public final class Config { public static String CUSTOM_CHANNEL_TOGGLED = "Toggled ."; public static Component TOGGLED_ON = null; public static Component TOGGLED_OFF = null; + public static double LOCAL_DISTANCE; + public static String CHANNEL_SPY = "SPY: () "; private static void chatChannels() { ConfigurationNode node = getNode("chat-channels"); if (node.empty()) { @@ -383,12 +385,16 @@ public final class Config { new CustomChannel(channelName, getString(key + "format", ""), getList(key + "servers", Collections.EMPTY_LIST), - getBoolean(key + "proxy", false)); + getBoolean(key + "proxy", false), + getBoolean(key + "local", false) + ); } CUSTOM_CHANNEL_TOGGLED = getString("chat-channels-messages.channel-toggled", CUSTOM_CHANNEL_TOGGLED); TOGGLED_ON = Utility.parseMiniMessage(getString("chat-channels-messages.channel-on", "on")); TOGGLED_OFF = Utility.parseMiniMessage(getString("chat-channels-messages.channel-off", "off")); + LOCAL_DISTANCE = getDouble("chat-channels-messages.local-distance", 200.0); + CHANNEL_SPY = getString("chat-channels-messages.spy", CHANNEL_SPY); } public static String SERVERMUTEPERMISSION = "chat.command.mute-server"; diff --git a/api/src/main/java/com/alttd/chat/objects/channels/Channel.java b/api/src/main/java/com/alttd/chat/objects/channels/Channel.java index c26ea0f..ab0e636 100644 --- a/api/src/main/java/com/alttd/chat/objects/channels/Channel.java +++ b/api/src/main/java/com/alttd/chat/objects/channels/Channel.java @@ -10,12 +10,14 @@ public class Channel { protected String channelName; protected String format; protected boolean proxy; + protected boolean local; - public Channel(String channelName, String format, boolean proxy) { + public Channel(String channelName, String format, boolean proxy, boolean local) { this.permission = "chat.channel." + channelName.toLowerCase(); this.channelName = channelName; this.format = format; this.proxy = proxy; + this.local = local; channels.put(channelName.toLowerCase(), this); } @@ -39,6 +41,10 @@ public class Channel { return proxy; } + public boolean isLocal() { + return local; + } + public static Channel getChatChannel(String channelName) { return channels.get(channelName.toLowerCase()); } diff --git a/api/src/main/java/com/alttd/chat/objects/channels/CustomChannel.java b/api/src/main/java/com/alttd/chat/objects/channels/CustomChannel.java index b4e6053..192f24f 100644 --- a/api/src/main/java/com/alttd/chat/objects/channels/CustomChannel.java +++ b/api/src/main/java/com/alttd/chat/objects/channels/CustomChannel.java @@ -5,8 +5,8 @@ import java.util.*; public class CustomChannel extends Channel { private final List servers; - public CustomChannel(String channelName, String format, List servers, boolean proxy) { - super(channelName, format, proxy); + public CustomChannel(String channelName, String format, List servers, boolean proxy, boolean local) { + super(channelName, format, proxy, local); this.permission = "chat.channel." + channelName.toLowerCase(); this.channelName = channelName; this.format = format; diff --git a/api/src/main/java/com/alttd/chat/objects/channels/DefaultChannel.java b/api/src/main/java/com/alttd/chat/objects/channels/DefaultChannel.java index 6a23c6c..d71639b 100644 --- a/api/src/main/java/com/alttd/chat/objects/channels/DefaultChannel.java +++ b/api/src/main/java/com/alttd/chat/objects/channels/DefaultChannel.java @@ -2,6 +2,6 @@ package com.alttd.chat.objects.channels; public abstract class DefaultChannel extends Channel{ public DefaultChannel(String channelName, String format, boolean proxy) { - super(channelName, format, proxy); + super(channelName, format, proxy, false); } } diff --git a/galaxy/src/main/java/com/alttd/chat/handler/ChatHandler.java b/galaxy/src/main/java/com/alttd/chat/handler/ChatHandler.java index a5863c2..e54242f 100755 --- a/galaxy/src/main/java/com/alttd/chat/handler/ChatHandler.java +++ b/galaxy/src/main/java/com/alttd/chat/handler/ChatHandler.java @@ -22,7 +22,9 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -188,9 +190,9 @@ public class ChatHandler { component = modifiableString.component(); if (channel.isProxy()) { - sendChatChannelMessage(player, channel.getChannelName(), "chatchannel", component); + sendChatChannelMessage(player, channel.getChannelName(), "chatchannel", component, message); } else { - sendChatChannelMessage(channel, player.getUniqueId(), component); + sendChatChannelMessage(channel, player.getUniqueId(), component, message); } } @@ -243,7 +245,7 @@ public class ChatHandler { // } } - private void sendChatChannelMessage(CustomChannel chatChannel, UUID uuid, Component component) { + private void sendChatChannelMessage(CustomChannel chatChannel, UUID uuid, Component component, String message) { Player player = Bukkit.getPlayer(uuid); if (player == null) { ALogger.warn("Failed to send chat message from non existent player"); @@ -264,7 +266,28 @@ public class ChatHandler { stream = stream.filter(receiver -> !ChatUserManager.getChatUser(receiver.getUniqueId()).getIgnoredPlayers().contains(uuid) || receiver.hasPermission("chat.ignorebypass")); } - stream.forEach(p -> p.sendMessage(component)); + if (chatChannel.isLocal()) { + Location location = player.getLocation(); + stream = stream.filter(receiver -> { + Player receiverPlayer = Bukkit.getPlayer(receiver.getUniqueId()); + if (receiverPlayer == null) + return false; + if (!location.getWorld().getUID().equals(receiverPlayer.getLocation().getWorld().getUID())) + return false; + return !(receiverPlayer.getLocation().distance(location) > Config.LOCAL_DISTANCE); + }); + } + List recipientPlayers = stream.toList(); + recipientPlayers.forEach(p -> p.sendMessage(component)); + + List recipientUUIDs = recipientPlayers.stream().map(Entity::getUniqueId).toList(); + Bukkit.getServer().getOnlinePlayers().stream() + .filter(onlinePlayer -> onlinePlayer.hasPermission(Config.SPYPERMISSION)) + .filter(onlinePlayer -> !recipientUUIDs.contains(onlinePlayer.getUniqueId())) + .forEach(onlinePlayer -> onlinePlayer.sendRichMessage(Config.CHANNEL_SPY, + Placeholder.component("sender", player.name()), + Placeholder.parsed("channel", chatChannel.getChannelName()), + Placeholder.parsed("message", message))); } private void sendPluginMessage(Player player, String channel, Component component) { @@ -284,7 +307,7 @@ public class ChatHandler { player.sendPluginMessage(plugin, Config.MESSAGECHANNEL, out.toByteArray()); } - public void sendChatChannelMessage(Player player, String chatChannelName, String channel, Component component) { + public void sendChatChannelMessage(Player player, String chatChannelName, String channel, Component component, String ignored) { ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF(channel); out.writeUTF(chatChannelName);