From f80a85fa79d32a2346bd7192470add8ae92fb273 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Sat, 15 Apr 2023 20:55:58 +0300 Subject: [PATCH 1/5] Cross Server - Local to Local and Local to Remote work --- .../helpch/chatchat/api/channel/Channel.java | 7 + .../api/channel/ChannelTypeRegistry.java | 3 +- .../chatchat/channel/AbstractChannel.java | 11 +- .../helpch/chatchat/channel/ChatChannel.java | 5 +- .../chatchat/command/FormatTestCommand.java | 4 +- .../helpch/chatchat/command/MainCommand.java | 2 +- .../command/SwitchChannelCommand.java | 5 +- .../chatchat/config/DefaultConfigObjects.java | 4 +- .../chatchat/config/mapper/ChannelMapper.java | 5 +- .../hooks/towny/AbstractTownyChannel.java | 5 +- .../hooks/towny/TownyNationChannel.java | 5 +- .../hooks/towny/TownyTownChannel.java | 5 +- .../chatchat/listener/ChatListener.java | 9 +- .../placeholder/MiniPlaceholderImpl.java | 8 +- .../LocalToLocalMessageProcessor.java | 171 +++++++++++++ .../LocalToRemoteMessageProcessor.java | 36 +++ .../chatchat/processor/MessageProcessor.java | 117 +++++++++ .../at/helpch/chatchat/util/FormatUtils.java | 8 +- .../at/helpch/chatchat/util/ItemUtils.java | 8 +- .../chatchat/util/MessageProcessor.java | 231 ------------------ .../at/helpch/chatchat/util/MessageUtils.java | 13 +- .../at/helpch/chatchat/util/PapiTagUtils.java | 4 +- 22 files changed, 395 insertions(+), 271 deletions(-) create mode 100644 plugin/src/main/java/at/helpch/chatchat/processor/LocalToLocalMessageProcessor.java create mode 100644 plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java create mode 100644 plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java delete mode 100644 plugin/src/main/java/at/helpch/chatchat/util/MessageProcessor.java diff --git a/api/src/main/java/at/helpch/chatchat/api/channel/Channel.java b/api/src/main/java/at/helpch/chatchat/api/channel/Channel.java index d55428cf..9cf77cec 100644 --- a/api/src/main/java/at/helpch/chatchat/api/channel/Channel.java +++ b/api/src/main/java/at/helpch/chatchat/api/channel/Channel.java @@ -57,6 +57,13 @@ public interface Channel { */ int radius(); + /** + * Check if this channel is cross server. + * + * @return True if this channel is cross server, false otherwise. + */ + boolean crossServer(); + /** * Get a set of {@link ChatUser}s that can see this channel. * diff --git a/api/src/main/java/at/helpch/chatchat/api/channel/ChannelTypeRegistry.java b/api/src/main/java/at/helpch/chatchat/api/channel/ChannelTypeRegistry.java index c9402949..ded195ea 100644 --- a/api/src/main/java/at/helpch/chatchat/api/channel/ChannelTypeRegistry.java +++ b/api/src/main/java/at/helpch/chatchat/api/channel/ChannelTypeRegistry.java @@ -22,7 +22,8 @@ interface Builder { @NotNull final List toggleCommands, @NotNull final String channelPrefix, @NotNull final FormatsHolder formats, - final int radius); + final int radius, + final boolean crossServer); } /** diff --git a/plugin/src/main/java/at/helpch/chatchat/channel/AbstractChannel.java b/plugin/src/main/java/at/helpch/chatchat/channel/AbstractChannel.java index 1c68829a..c8038f71 100644 --- a/plugin/src/main/java/at/helpch/chatchat/channel/AbstractChannel.java +++ b/plugin/src/main/java/at/helpch/chatchat/channel/AbstractChannel.java @@ -22,13 +22,16 @@ public abstract class AbstractChannel implements Channel { private final int radius; + private final boolean crossServer; + protected AbstractChannel( @NotNull final String name, @NotNull final String messagePrefix, @NotNull final List toggleCommands, @NotNull final String channelPrefix, @NotNull final FormatsHolder formats, - final int radius + final int radius, + final boolean crossServer ) { this.name = name; this.messagePrefix = messagePrefix; @@ -36,6 +39,7 @@ protected AbstractChannel( this.channelPrefix = channelPrefix; this.formats = formats; this.radius = radius; + this.crossServer = crossServer; } @Override @@ -68,6 +72,11 @@ public int radius() { return radius; } + @Override + public boolean crossServer() { + return crossServer; + } + @Override public boolean isUsableBy(@NotNull final ChatUser user) { if (ChatChannel.defaultChannel().equals(this)) { diff --git a/plugin/src/main/java/at/helpch/chatchat/channel/ChatChannel.java b/plugin/src/main/java/at/helpch/chatchat/channel/ChatChannel.java index d0b63727..9394c334 100644 --- a/plugin/src/main/java/at/helpch/chatchat/channel/ChatChannel.java +++ b/plugin/src/main/java/at/helpch/chatchat/channel/ChatChannel.java @@ -27,9 +27,10 @@ public ChatChannel( @NotNull final List toggleCommands, @NotNull final String channelPrefix, @NotNull final FormatsHolder formats, - final int radius + final int radius, + final boolean crossServer ) { - super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius); + super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius, crossServer); } public static @NotNull Channel defaultChannel() { diff --git a/plugin/src/main/java/at/helpch/chatchat/command/FormatTestCommand.java b/plugin/src/main/java/at/helpch/chatchat/command/FormatTestCommand.java index e73e5ab5..0b44076c 100644 --- a/plugin/src/main/java/at/helpch/chatchat/command/FormatTestCommand.java +++ b/plugin/src/main/java/at/helpch/chatchat/command/FormatTestCommand.java @@ -5,7 +5,7 @@ import at.helpch.chatchat.api.user.ChatUser; import at.helpch.chatchat.user.ConsoleUser; import at.helpch.chatchat.util.FormatUtils; -import at.helpch.chatchat.util.MessageProcessor; +import at.helpch.chatchat.processor.LocalToLocalMessageProcessor; import dev.triumphteam.cmd.bukkit.annotation.Permission; import dev.triumphteam.cmd.core.annotation.Join; import dev.triumphteam.cmd.core.annotation.SubCommand; @@ -38,7 +38,7 @@ public void testFormat( format, sender.player(), sender.player(), - MessageProcessor.processMessage(plugin, sender, ConsoleUser.INSTANCE, message), + LocalToLocalMessageProcessor.processMessage(plugin, sender, ConsoleUser.INSTANCE, message), plugin.miniPlaceholdersManager().compileTags(false, sender, sender) ) ); diff --git a/plugin/src/main/java/at/helpch/chatchat/command/MainCommand.java b/plugin/src/main/java/at/helpch/chatchat/command/MainCommand.java index 8c65b1ea..102db3f3 100644 --- a/plugin/src/main/java/at/helpch/chatchat/command/MainCommand.java +++ b/plugin/src/main/java/at/helpch/chatchat/command/MainCommand.java @@ -10,7 +10,7 @@ public final class MainCommand extends ChatChatCommand { private static final JavaPlugin PLUGIN = JavaPlugin.getProvidingPlugin(ChatChatPlugin.class); - private static final Component TEXT = MessageUtils.parseToMiniMessage( + private static final Component TEXT = MessageUtils.parseFromMiniMessage( "A Chat Plugin by <#3dbbe4>Help<#f3af4b>Chat
Version: " + PLUGIN.getDescription().getVersion()); @Default diff --git a/plugin/src/main/java/at/helpch/chatchat/command/SwitchChannelCommand.java b/plugin/src/main/java/at/helpch/chatchat/command/SwitchChannelCommand.java index 9d0b038c..eafea800 100644 --- a/plugin/src/main/java/at/helpch/chatchat/command/SwitchChannelCommand.java +++ b/plugin/src/main/java/at/helpch/chatchat/command/SwitchChannelCommand.java @@ -3,7 +3,8 @@ import at.helpch.chatchat.ChatChatPlugin; import at.helpch.chatchat.api.user.ChatUser; import at.helpch.chatchat.hooks.towny.AbstractTownyChannel; -import at.helpch.chatchat.util.MessageProcessor; +import at.helpch.chatchat.processor.LocalToLocalMessageProcessor; +import at.helpch.chatchat.processor.MessageProcessor; import com.palmergames.bukkit.towny.TownyUniverse; import com.palmergames.bukkit.towny.object.Resident; import dev.triumphteam.cmd.core.BaseCommand; @@ -57,6 +58,6 @@ public void switchChannel(final ChatUser user, @Join @Optional @NotNull final St return; } - MessageProcessor.process(plugin, user, channel, message, false); + MessageProcessor.processEvent(plugin, user, channel, message, false); } } diff --git a/plugin/src/main/java/at/helpch/chatchat/config/DefaultConfigObjects.java b/plugin/src/main/java/at/helpch/chatchat/config/DefaultConfigObjects.java index 828c68d7..3dcc4b3f 100644 --- a/plugin/src/main/java/at/helpch/chatchat/config/DefaultConfigObjects.java +++ b/plugin/src/main/java/at/helpch/chatchat/config/DefaultConfigObjects.java @@ -21,12 +21,12 @@ public final class DefaultConfigObjects { public static @NotNull Channel createDefaultChannel() { return new ChatChannel("default", "", - List.of("global"), "[Global]", new FormatsHolderImpl(), -1); + List.of("global"), "[Global]", new FormatsHolderImpl(), -1, false); } public static @NotNull Channel createStaffChannel() { return new ChatChannel("staff", "@", - List.of("staffchat"), "[Staff]", new FormatsHolderImpl(), -1); + List.of("staffchat"), "[Staff]", new FormatsHolderImpl(), -1, false); } public static @NotNull SimpleFormat createDefaultConsoleFormat() { diff --git a/plugin/src/main/java/at/helpch/chatchat/config/mapper/ChannelMapper.java b/plugin/src/main/java/at/helpch/chatchat/config/mapper/ChannelMapper.java index edb6b557..553fe9e0 100644 --- a/plugin/src/main/java/at/helpch/chatchat/config/mapper/ChannelMapper.java +++ b/plugin/src/main/java/at/helpch/chatchat/config/mapper/ChannelMapper.java @@ -21,6 +21,7 @@ public final class ChannelMapper implements TypeSerializer { private static final String CHANNEL_PREFIX = "channel-prefix"; private static final String FORMATS = "formats"; private static final String RADIUS = "radius"; + private static final String CROSS_SERVER = "cross-server"; private static final String TYPE = "type"; private static final TypeToken> FORMATS_MAP_TYPE = new TypeToken<>() {}; @@ -55,6 +56,7 @@ public Channel deserialize(Type type, ConfigurationNode node) throws Serializati final var formatsMap = node.node(FORMATS).get(FORMATS_MAP_TYPE, Map.of()); final var formats = new FormatsHolderImpl(formatsMap); final var radius = node.node(RADIUS).getInt(-1); + final var crossServer = node.node(CROSS_SERVER).getBoolean(false); final var channelType = node.node(TYPE).getString("default").toLowerCase(); @@ -63,7 +65,7 @@ public Channel deserialize(Type type, ConfigurationNode node) throws Serializati throw new SerializationException("Channel " + key + " has unknown channel type " + channelType + ", " + "ignoring."); } - return builder.build(key, messagePrefix, commandName, channelPrefix, formats, radius); + return builder.build(key, messagePrefix, commandName, channelPrefix, formats, radius, crossServer); } @Override @@ -78,5 +80,6 @@ public void serialize(Type type, @Nullable Channel channel, ConfigurationNode ta target.node(CHANNEL_PREFIX).set(channel.channelPrefix()); target.node(FORMATS).set(channel.formats().formats()); target.node(RADIUS).set(channel.radius()); + target.node(CROSS_SERVER).set(channel.crossServer()); } } diff --git a/plugin/src/main/java/at/helpch/chatchat/hooks/towny/AbstractTownyChannel.java b/plugin/src/main/java/at/helpch/chatchat/hooks/towny/AbstractTownyChannel.java index 7a0613ea..a064d0ee 100644 --- a/plugin/src/main/java/at/helpch/chatchat/hooks/towny/AbstractTownyChannel.java +++ b/plugin/src/main/java/at/helpch/chatchat/hooks/towny/AbstractTownyChannel.java @@ -26,8 +26,9 @@ protected AbstractTownyChannel(@NotNull final String name, @NotNull final List toggleCommands, @NotNull final String channelPrefix, @NotNull final FormatsHolder formats, - final int radius) { - super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius); + final int radius, + final boolean crossServer) { + super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius, crossServer); if (Bukkit.getPluginManager().getPlugin("Towny") == null) { throw new RuntimeException("Attempting to use a Towny channel but Towny is not installed."); }} diff --git a/plugin/src/main/java/at/helpch/chatchat/hooks/towny/TownyNationChannel.java b/plugin/src/main/java/at/helpch/chatchat/hooks/towny/TownyNationChannel.java index d250400c..015823e0 100644 --- a/plugin/src/main/java/at/helpch/chatchat/hooks/towny/TownyNationChannel.java +++ b/plugin/src/main/java/at/helpch/chatchat/hooks/towny/TownyNationChannel.java @@ -15,8 +15,9 @@ public TownyNationChannel(@NotNull final String name, @NotNull final List toggleCommands, @NotNull final String channelPrefix, @NotNull final FormatsHolder formats, - final int radius) { - super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius); + final int radius, + final boolean crossServer) { + super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius, crossServer); } @Override diff --git a/plugin/src/main/java/at/helpch/chatchat/hooks/towny/TownyTownChannel.java b/plugin/src/main/java/at/helpch/chatchat/hooks/towny/TownyTownChannel.java index a963827e..77c1d996 100644 --- a/plugin/src/main/java/at/helpch/chatchat/hooks/towny/TownyTownChannel.java +++ b/plugin/src/main/java/at/helpch/chatchat/hooks/towny/TownyTownChannel.java @@ -15,8 +15,9 @@ public TownyTownChannel(@NotNull final String name, @NotNull final List toggleCommands, @NotNull final String channelPrefix, @NotNull final FormatsHolder formats, - final int radius) { - super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius); + final int radius, + final boolean crossServer) { + super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius, crossServer); } @Override diff --git a/plugin/src/main/java/at/helpch/chatchat/listener/ChatListener.java b/plugin/src/main/java/at/helpch/chatchat/listener/ChatListener.java index 43a45815..7c2a6550 100644 --- a/plugin/src/main/java/at/helpch/chatchat/listener/ChatListener.java +++ b/plugin/src/main/java/at/helpch/chatchat/listener/ChatListener.java @@ -2,11 +2,12 @@ import at.helpch.chatchat.ChatChatPlugin; import at.helpch.chatchat.api.user.ChatUser; +import at.helpch.chatchat.processor.MessageProcessor; import at.helpch.chatchat.user.ConsoleUser; import at.helpch.chatchat.channel.ChatChannel; import at.helpch.chatchat.util.ChannelUtils; import at.helpch.chatchat.util.FormatUtils; -import at.helpch.chatchat.util.MessageProcessor; +import at.helpch.chatchat.processor.LocalToLocalMessageProcessor; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -68,7 +69,7 @@ public void onChat(final AsyncPlayerChatEvent event) { final var consoleFormat = plugin.configManager().formats().consoleFormat(); event.setMessage(LegacyComponentSerializer.legacySection().serialize( - MessageProcessor.processMessage(plugin, user, ConsoleUser.INSTANCE, message) + LocalToLocalMessageProcessor.processMessage(plugin, user, ConsoleUser.INSTANCE, message) )); try { @@ -89,8 +90,8 @@ public void onChat(final AsyncPlayerChatEvent event) { } // Cancel the event if the message doesn't end up being sent - // This only happens if the message contains illegal characters or if the ChatChatEvent is canceled. - event.setCancelled(!MessageProcessor.process(plugin, user, channel, message, event.isAsynchronous())); + // This happens if rules are not respected or if ChatChatEvent is canceled. + event.setCancelled(!MessageProcessor.processEvent(plugin, user, channel, message, event.isAsynchronous())); } private static String cleanseMessage(@NotNull final String message) { diff --git a/plugin/src/main/java/at/helpch/chatchat/placeholder/MiniPlaceholderImpl.java b/plugin/src/main/java/at/helpch/chatchat/placeholder/MiniPlaceholderImpl.java index c07978ce..4bf528a2 100644 --- a/plugin/src/main/java/at/helpch/chatchat/placeholder/MiniPlaceholderImpl.java +++ b/plugin/src/main/java/at/helpch/chatchat/placeholder/MiniPlaceholderImpl.java @@ -3,7 +3,7 @@ import at.helpch.chatchat.api.placeholder.MiniPlaceholder; import at.helpch.chatchat.api.user.ChatUser; import at.helpch.chatchat.api.user.User; -import at.helpch.chatchat.util.MessageProcessor; +import at.helpch.chatchat.processor.MessageProcessor; import at.helpch.chatchat.util.MessageUtils; import at.helpch.chatchat.util.PapiTagUtils; import net.kyori.adventure.text.minimessage.tag.Tag; @@ -17,7 +17,7 @@ @ConfigSerializable public class MiniPlaceholderImpl implements MiniPlaceholder { - private static final String MINI_PLACEHOLDER_PERMISSION = MessageProcessor.TAG_BASE_PERMISSION + "placeholder."; + private static final String MINI_PLACEHOLDER_PERMISSION = MessageProcessor.Constants.TAG_BASE_PERMISSION + "placeholder."; private final String name; private final boolean requiresRecipient; @@ -71,8 +71,8 @@ public MiniPlaceholderImpl( } return closing - ? Placeholder.component(name, MessageUtils.parseToMiniMessage(message, papiTag)) - : TagResolver.resolver(name, Tag.inserting(MessageUtils.parseToMiniMessage(message, papiTag))); + ? Placeholder.component(name, MessageUtils.parseFromMiniMessage(message, papiTag)) + : TagResolver.resolver(name, Tag.inserting(MessageUtils.parseFromMiniMessage(message, papiTag))); } public @NotNull String name() { diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToLocalMessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToLocalMessageProcessor.java new file mode 100644 index 00000000..a388f38c --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToLocalMessageProcessor.java @@ -0,0 +1,171 @@ +package at.helpch.chatchat.processor; + +import at.helpch.chatchat.ChatChatPlugin; +import at.helpch.chatchat.api.channel.Channel; +import at.helpch.chatchat.api.event.ChatChatEvent; +import at.helpch.chatchat.api.user.ChatUser; +import at.helpch.chatchat.api.user.User; +import at.helpch.chatchat.user.ConsoleUser; +import at.helpch.chatchat.util.FormatUtils; +import at.helpch.chatchat.util.ItemUtils; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; +import org.jetbrains.annotations.NotNull; + +public final class LocalToLocalMessageProcessor { + + private LocalToLocalMessageProcessor() { + throw new AssertionError("Util classes are not to be instantiated!"); + } + + public static boolean processLocalMessageEvent( + @NotNull final ChatChatPlugin plugin, + @NotNull final ChatChatEvent chatEvent, + @NotNull final ChatUser sender, + @NotNull final Channel channel, + final boolean async + ) { + final var oldChannel = sender.channel(); + sender.channel(channel); + + final var parsedMessage = chatEvent.message().compact(); + final var mentions = plugin.configManager().settings().mentions(); + + var messageForSender = parsedMessage; + var senderIsTarget = false; + + for (final var target : chatEvent.recipients()) { + if (target.uuid() == sender.uuid()) { + senderIsTarget = true; + continue; + } + + // Console Users have their own format we set in ChatListener.java + if (target instanceof ConsoleUser) continue; + + // Process mentions and get the result. + final var mentionResult = plugin.mentionsManager().processMentions( + async, + sender, + target, + chatEvent.channel(), + parsedMessage, + true + ); + + if (target instanceof ChatUser) { + final var chatTarget = (ChatUser) target; + + final var component = FormatUtils.parseFormat( + chatEvent.format(), + sender.player(), + chatTarget.player(), + mentionResult.message(), + plugin.miniPlaceholdersManager().compileTags(false, sender, target) + ); + + target.sendMessage(component); + if (mentionResult.playSound()) { + target.playSound(mentions.sound()); + } + if (sender.canSee(chatTarget)) { + messageForSender = plugin.mentionsManager().processMentions( + async, + sender, + chatTarget, + chatEvent.channel(), + messageForSender, + false + ).message(); + } + continue; + } + + final var component = FormatUtils.parseFormat( + chatEvent.format(), + sender.player(), + mentionResult.message(), + plugin.miniPlaceholdersManager().compileTags(false, sender, target) + ); + + target.sendMessage(component); + if (mentionResult.playSound()) { + target.playSound(mentions.sound()); + } + } + + if (!senderIsTarget) { + sender.channel(oldChannel); + return true; + } + + final var mentionResult = plugin.mentionsManager().processMentions( + async, + sender, + sender, + chatEvent.channel(), + parsedMessage, + true + ); + + final var component = FormatUtils.parseFormat( + chatEvent.format(), + sender.player(), + sender.player(), + mentionResult.message(), + plugin.miniPlaceholdersManager().compileTags(false, sender, sender) + ); + + sender.sendMessage(component); + if (mentionResult.playSound()) { + sender.playSound(mentions.sound()); + } + + sender.channel(oldChannel); + return true; + } + + public static @NotNull Component processMessage( + @NotNull final ChatChatPlugin plugin, + @NotNull final ChatUser sender, + @NotNull final User recipient, + @NotNull final String message + ) { + final var resolver = TagResolver.builder(); + + for (final var entry : MessageProcessor.Constants.PERMISSION_TAGS.entrySet()) { + if (!sender.hasPermission(MessageProcessor.Constants.TAG_BASE_PERMISSION + entry.getKey())) { + continue; + } + + resolver.resolver(entry.getValue()); + } + + for (final var tag : TextDecoration.values()) { + if (!sender.hasPermission(MessageProcessor.Constants.TAG_BASE_PERMISSION + tag.toString())) { + continue; + } + + resolver.resolver(StandardTags.decorations(tag)); + } + + if (sender.hasPermission(MessageProcessor.Constants.ITEM_TAG_PERMISSION)) { + resolver.resolver( + ItemUtils.createItemPlaceholder( + plugin.configManager().settings().itemFormat(), + plugin.configManager().settings().itemFormatInfo(), + sender.player().getInventory().getItemInMainHand() + ) + ); + } + + resolver.resolvers(plugin.miniPlaceholdersManager().compileTags(true, sender, recipient)); + + return !sender.hasPermission(MessageProcessor.Constants.URL_PERMISSION) + ? MessageProcessor.Constants.USER_MESSAGE_MINI_MESSAGE.deserialize(message, resolver.build()) + : MessageProcessor.Constants.USER_MESSAGE_MINI_MESSAGE.deserialize(message, resolver.build()).replaceText(MessageProcessor.Constants.URL_REPLACER_CONFIG); + } + +} diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java new file mode 100644 index 00000000..920fa593 --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java @@ -0,0 +1,36 @@ +package at.helpch.chatchat.processor; + +import at.helpch.chatchat.ChatChatPlugin; +import at.helpch.chatchat.api.channel.Channel; +import at.helpch.chatchat.api.event.ChatChatEvent; +import at.helpch.chatchat.api.user.ChatUser; +import at.helpch.chatchat.user.ConsoleUser; +import at.helpch.chatchat.util.FormatUtils; +import at.helpch.chatchat.util.MessageUtils; +import org.jetbrains.annotations.NotNull; + +public final class LocalToRemoteMessageProcessor { + + private LocalToRemoteMessageProcessor() { + throw new AssertionError("Util classes are not to be instantiated!"); + } + + public static boolean processLocalMessageEvent( + @NotNull final ChatChatPlugin plugin, + @NotNull final ChatChatEvent chatEvent, + @NotNull final ChatUser sender, + @NotNull final Channel channel + ) { + final var parsedMessage = chatEvent.message().compact(); + + final var component = FormatUtils.parseFormat( + chatEvent.format(), + sender.player(), + parsedMessage, + plugin.miniPlaceholdersManager().compileTags(false, sender, ConsoleUser.INSTANCE) + ); + + // TODO: Pass the message to the RemoteMessageSender + return RemoteMessageSender.send(plugin, channel.name(), MessageUtils.parseToMiniMessage(component)); + } +} diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java new file mode 100644 index 00000000..5402ac0e --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java @@ -0,0 +1,117 @@ +package at.helpch.chatchat.processor; + +import at.helpch.chatchat.ChatChatPlugin; +import at.helpch.chatchat.api.channel.Channel; +import at.helpch.chatchat.api.event.ChatChatEvent; +import at.helpch.chatchat.api.user.ChatUser; +import at.helpch.chatchat.user.ConsoleUser; +import at.helpch.chatchat.util.FormatUtils; +import net.kyori.adventure.text.TextReplacementConfig; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; +import java.util.regex.Pattern; + +public final class MessageProcessor { + + private MessageProcessor() { + throw new AssertionError("Util classes are not to be instantiated!"); + } + + public static boolean processEvent( + @NotNull final ChatChatPlugin plugin, + @NotNull final ChatUser sender, + @NotNull final Channel channel, + @NotNull final String message, + final boolean async + ) { + if (!validateRules(plugin, sender, message)) { + return false; + } + + final var chatEvent = new ChatChatEvent( + async, + sender, + FormatUtils.findFormat(sender.player(), channel, plugin.configManager().formats()), + LocalToLocalMessageProcessor.processMessage(plugin, sender, ConsoleUser.INSTANCE, message), + channel, + channel.targets(sender) + ); + + plugin.getServer().getPluginManager().callEvent(chatEvent); + + if (chatEvent.isCancelled()) { + return false; + } + + final boolean localResult = LocalToLocalMessageProcessor.processLocalMessageEvent(plugin, chatEvent, sender, channel, async); + + if (!localResult) { + return false; + } + + if (!channel.crossServer()) { + return true; + } + + LocalToRemoteMessageProcessor.processLocalMessageEvent(plugin, chatEvent, sender, channel); + return true; + } + + private static boolean validateRules( + @NotNull final ChatChatPlugin plugin, + @NotNull final ChatUser sender, + @NotNull final String message + ) { + final var rulesResult = plugin.ruleManager().isAllowedPublicChat(sender, message); + if (rulesResult.isPresent()) { + sender.sendMessage(rulesResult.get()); + return false; + } + + return true; + } + + public static final class Constants { + public static final MiniMessage USER_MESSAGE_MINI_MESSAGE = MiniMessage.builder().tags(TagResolver.empty()).build(); + public static final Pattern DEFAULT_URL_PATTERN = Pattern.compile("(?:(https?)://)?([-\\w_.]+\\.\\w{2,})(/\\S*)?"); + public static final Pattern URL_SCHEME_PATTERN = Pattern.compile("^[a-z][a-z\\d+\\-.]*:"); + + public static final TextReplacementConfig URL_REPLACER_CONFIG = TextReplacementConfig.builder() + .match(DEFAULT_URL_PATTERN) + .replacement(builder -> { + String clickUrl = builder.content(); + if (!URL_SCHEME_PATTERN.matcher(clickUrl).find()) { + clickUrl = "https://" + clickUrl; + } + return builder.clickEvent(ClickEvent.openUrl(clickUrl)); + }) + .build(); + + public static final String URL_PERMISSION = "chatchat.url"; + public static final String TAG_BASE_PERMISSION = "chatchat.tag."; + public static final String ITEM_TAG_PERMISSION = TAG_BASE_PERMISSION + "item"; + + public static final Map PERMISSION_TAGS = Map.ofEntries( + Map.entry("click", StandardTags.clickEvent()), + Map.entry("color", StandardTags.color()), + Map.entry("font", StandardTags.font()), + Map.entry("gradient", StandardTags.gradient()), + Map.entry("hover", StandardTags.hoverEvent()), + Map.entry("insertion", StandardTags.insertion()), + Map.entry("keybind", StandardTags.keybind()), + Map.entry("newline", StandardTags.newline()), + Map.entry("rainbow", StandardTags.rainbow()), + Map.entry("reset", StandardTags.reset()), + Map.entry("translatable", StandardTags.translatable()) + ); + + private Constants() { + throw new AssertionError("Util classes are not to be instantiated!"); + } + } +} diff --git a/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java b/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java index 5d568ad0..fb727c95 100644 --- a/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java +++ b/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java @@ -56,7 +56,7 @@ private FormatUtils() { public static @NotNull Component parseConsoleFormat( @NotNull final Format format, @NotNull final Player player) { - return MessageUtils.parseToMiniMessage( + return MessageUtils.parseFromMiniMessage( PlaceholderAPI.setPlaceholders( player, format.parts() @@ -80,7 +80,7 @@ private FormatUtils() { @NotNull final Player player, @NotNull final ComponentLike message, @NotNull final TagResolver miniPlaceholders) { - return MessageUtils.parseToMiniMessage( + return MessageUtils.parseFromMiniMessage( PlaceholderAPI.setPlaceholders( player, format.parts() @@ -105,7 +105,7 @@ private FormatUtils() { @NotNull final Format format, @NotNull final ComponentLike message, @NotNull final TagResolver miniPlaceholders) { - return MessageUtils.parseToMiniMessage( + return MessageUtils.parseFromMiniMessage( PlaceholderAPI.setPlaceholders( null, format.parts() @@ -134,7 +134,7 @@ private FormatUtils() { @NotNull final Player recipient, @NotNull final ComponentLike message, @NotNull final TagResolver miniPlaceholders) { - return MessageUtils.parseToMiniMessage( + return MessageUtils.parseFromMiniMessage( PlaceholderAPI.setRelationalPlaceholders( player, recipient, diff --git a/plugin/src/main/java/at/helpch/chatchat/util/ItemUtils.java b/plugin/src/main/java/at/helpch/chatchat/util/ItemUtils.java index 188aaaab..63526a10 100644 --- a/plugin/src/main/java/at/helpch/chatchat/util/ItemUtils.java +++ b/plugin/src/main/java/at/helpch/chatchat/util/ItemUtils.java @@ -40,13 +40,13 @@ private ItemUtils() { final var amountPlaceholder = Placeholder.component("amount", Component.text(item.getAmount())); final var hoverInfoComponent = !itemFormatInfo.isBlank() - ? MessageUtils.parseToMiniMessage(itemFormatInfo, itemPlaceholder, amountPlaceholder) + ? MessageUtils.parseFromMiniMessage(itemFormatInfo, itemPlaceholder, amountPlaceholder) : null; if (item.getType().isAir() || !item.hasItemMeta()) { return Placeholder.component( "item", - MessageUtils.parseToMiniMessage(itemFormat, itemPlaceholder, amountPlaceholder).hoverEvent(hoverInfoComponent) + MessageUtils.parseFromMiniMessage(itemFormat, itemPlaceholder, amountPlaceholder).hoverEvent(hoverInfoComponent) ); } @@ -56,7 +56,7 @@ private ItemUtils() { if (meta == null) { return Placeholder.component( "item", - MessageUtils.parseToMiniMessage(itemFormat, itemPlaceholder, amountPlaceholder).hoverEvent(hoverInfoComponent) + MessageUtils.parseFromMiniMessage(itemFormat, itemPlaceholder, amountPlaceholder).hoverEvent(hoverInfoComponent) ); } @@ -97,7 +97,7 @@ private ItemUtils() { return Placeholder.component( "item", - MessageUtils.parseToMiniMessage(itemFormat, newItemPlaceholder, amountPlaceholder).hoverEvent( + MessageUtils.parseFromMiniMessage(itemFormat, newItemPlaceholder, amountPlaceholder).hoverEvent( Component.join(JoinConfiguration.newlines(), hoverComponents) ) ); diff --git a/plugin/src/main/java/at/helpch/chatchat/util/MessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/util/MessageProcessor.java deleted file mode 100644 index 3cee7e42..00000000 --- a/plugin/src/main/java/at/helpch/chatchat/util/MessageProcessor.java +++ /dev/null @@ -1,231 +0,0 @@ -package at.helpch.chatchat.util; - -import at.helpch.chatchat.ChatChatPlugin; -import at.helpch.chatchat.api.channel.Channel; -import at.helpch.chatchat.api.event.ChatChatEvent; -import at.helpch.chatchat.api.user.ChatUser; -import at.helpch.chatchat.api.user.User; -import at.helpch.chatchat.user.ConsoleUser; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextReplacementConfig; -import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.text.format.TextDecoration; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; -import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; -import org.jetbrains.annotations.NotNull; - -import java.util.Map; -import java.util.regex.Pattern; - -public final class MessageProcessor { - - private static final MiniMessage USER_MESSAGE_MINI_MESSAGE = MiniMessage.builder().tags(TagResolver.empty()).build(); - private static final Pattern DEFAULT_URL_PATTERN = Pattern.compile("(?:(https?)://)?([-\\w_.]+\\.\\w{2,})(/\\S*)?"); - private static final Pattern URL_SCHEME_PATTERN = Pattern.compile("^[a-z][a-z\\d+\\-.]*:"); - - private static final TextReplacementConfig URL_REPLACER_CONFIG = TextReplacementConfig.builder() - .match(DEFAULT_URL_PATTERN) - .replacement(builder -> { - String clickUrl = builder.content(); - if (!URL_SCHEME_PATTERN.matcher(clickUrl).find()) { - clickUrl = "https://" + clickUrl; - } - return builder.clickEvent(ClickEvent.openUrl(clickUrl)); - }) - .build(); - - private static final String URL_PERMISSION = "chatchat.url"; - public static final String TAG_BASE_PERMISSION = "chatchat.tag."; - private static final String ITEM_TAG_PERMISSION = TAG_BASE_PERMISSION + "item"; - - private static final Map PERMISSION_TAGS = Map.ofEntries( - Map.entry("click", StandardTags.clickEvent()), - Map.entry("color", StandardTags.color()), - Map.entry("font", StandardTags.font()), - Map.entry("gradient", StandardTags.gradient()), - Map.entry("hover", StandardTags.hoverEvent()), - Map.entry("insertion", StandardTags.insertion()), - Map.entry("keybind", StandardTags.keybind()), - Map.entry("newline", StandardTags.newline()), - Map.entry("rainbow", StandardTags.rainbow()), - Map.entry("reset", StandardTags.reset()), - Map.entry("translatable", StandardTags.translatable()) - ); - - private MessageProcessor() { - throw new AssertionError("Util classes are not to be instantiated!"); - } - - public static boolean process( - @NotNull final ChatChatPlugin plugin, - @NotNull final ChatUser user, - @NotNull final Channel channel, - @NotNull final String message, - final boolean async - ) { - final var rulesResult = plugin.ruleManager().isAllowedPublicChat(user, message); - if (rulesResult.isPresent()) { - user.sendMessage(rulesResult.get()); - return false; - } - - final var chatEvent = new ChatChatEvent( - async, - user, - FormatUtils.findFormat(user.player(), channel, plugin.configManager().formats()), - // TODO: 9/2/22 Process message for each recipient to add rel support inside the message itself. - // Possibly even pass the minimessage string here instead of the processed component. - MessageProcessor.processMessage(plugin, user, ConsoleUser.INSTANCE, message), - channel, - channel.targets(user) - ); - - plugin.getServer().getPluginManager().callEvent(chatEvent); - - if (chatEvent.isCancelled()) { - return false; - } - - final var oldChannel = user.channel(); - user.channel(channel); - - final var parsedMessage = chatEvent.message().compact(); - final var mentions = plugin.configManager().settings().mentions(); - - var userMessage = parsedMessage; - var userIsTarget = false; - - for (final var target : chatEvent.recipients()) { - if (target.uuid() == user.uuid()) { - userIsTarget = true; - continue; - } - - // Console Users have their own format we set in ChatListener.java - if (target instanceof ConsoleUser) continue; - - // Process mentions and get the result. - final var mentionResult = plugin.mentionsManager().processMentions( - async, - user, - target, - chatEvent.channel(), - parsedMessage, - true - ); - - if (target instanceof ChatUser) { - final var chatTarget = (ChatUser) target; - - final var component = FormatUtils.parseFormat( - chatEvent.format(), - user.player(), - chatTarget.player(), - mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(false, user, target) - ); - - target.sendMessage(component); - if (mentionResult.playSound()) { - target.playSound(mentions.sound()); - } - if (user.canSee(chatTarget)) { - userMessage = plugin.mentionsManager().processMentions( - async, - user, - chatTarget, - chatEvent.channel(), - userMessage, - false - ).message(); - } - continue; - } - - final var component = FormatUtils.parseFormat( - chatEvent.format(), - user.player(), - mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(false, user, target) - ); - - target.sendMessage(component); - if (mentionResult.playSound()) { - target.playSound(mentions.sound()); - } - } - - if (!userIsTarget) { - user.channel(oldChannel); - return true; - } - - final var mentionResult = plugin.mentionsManager().processMentions( - async, - user, - user, - chatEvent.channel(), - parsedMessage, - true - ); - - final var component = FormatUtils.parseFormat( - chatEvent.format(), - user.player(), - user.player(), - mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(false, user, user) - ); - - user.sendMessage(component); - if (mentionResult.playSound()) { - user.playSound(mentions.sound()); - } - - user.channel(oldChannel); - return true; - } - - public static @NotNull Component processMessage( - @NotNull final ChatChatPlugin plugin, - @NotNull final ChatUser user, - @NotNull final User recipient, - @NotNull final String message - ) { - final var resolver = TagResolver.builder(); - - for (final var entry : PERMISSION_TAGS.entrySet()) { - if (!user.hasPermission(TAG_BASE_PERMISSION + entry.getKey())) { - continue; - } - - resolver.resolver(entry.getValue()); - } - - for (final var tag : TextDecoration.values()) { - if (!user.hasPermission(TAG_BASE_PERMISSION + tag.toString())) { - continue; - } - - resolver.resolver(StandardTags.decorations(tag)); - } - - if (user.hasPermission(ITEM_TAG_PERMISSION)) { - resolver.resolver( - ItemUtils.createItemPlaceholder( - plugin.configManager().settings().itemFormat(), - plugin.configManager().settings().itemFormatInfo(), - user.player().getInventory().getItemInMainHand() - ) - ); - } - - resolver.resolvers(plugin.miniPlaceholdersManager().compileTags(true, user, recipient)); - - return !user.hasPermission(URL_PERMISSION) - ? USER_MESSAGE_MINI_MESSAGE.deserialize(message, resolver.build()) - : USER_MESSAGE_MINI_MESSAGE.deserialize(message, resolver.build()).replaceText(URL_REPLACER_CONFIG); - } - -} diff --git a/plugin/src/main/java/at/helpch/chatchat/util/MessageUtils.java b/plugin/src/main/java/at/helpch/chatchat/util/MessageUtils.java index 396e4b44..4a152a7a 100644 --- a/plugin/src/main/java/at/helpch/chatchat/util/MessageUtils.java +++ b/plugin/src/main/java/at/helpch/chatchat/util/MessageUtils.java @@ -1,6 +1,7 @@ package at.helpch.chatchat.util; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.jetbrains.annotations.NotNull; @@ -14,19 +15,23 @@ private MessageUtils() { throw new AssertionError("Util classes are not to be instantiated!"); } - public static @NotNull Component parseToMiniMessage(@NotNull final String formatPart) { + public static @NotNull String parseToMiniMessage(@NotNull final ComponentLike component) { + return miniMessage.serialize(component.asComponent()); + } + + public static @NotNull Component parseFromMiniMessage(@NotNull final String formatPart) { return miniMessage.deserialize(formatPart); } - public static @NotNull Component parseToMiniMessage(@NotNull final String formatPart, @NotNull final TagResolver tag) { + public static @NotNull Component parseFromMiniMessage(@NotNull final String formatPart, @NotNull final TagResolver tag) { return miniMessage.deserialize(formatPart, tag); } - public static @NotNull Component parseToMiniMessage(@NotNull final String formatPart, @NotNull final TagResolver... tags) { + public static @NotNull Component parseFromMiniMessage(@NotNull final String formatPart, @NotNull final TagResolver... tags) { return miniMessage.deserialize(formatPart, tags); } - public static @NotNull Component parseToMiniMessage(@NotNull final String formatPart, @NotNull final List tags) { + public static @NotNull Component parseFromMiniMessage(@NotNull final String formatPart, @NotNull final List tags) { return miniMessage.deserialize(formatPart, TagResolver.resolver(tags)); } diff --git a/plugin/src/main/java/at/helpch/chatchat/util/PapiTagUtils.java b/plugin/src/main/java/at/helpch/chatchat/util/PapiTagUtils.java index d73b708c..3caf7812 100644 --- a/plugin/src/main/java/at/helpch/chatchat/util/PapiTagUtils.java +++ b/plugin/src/main/java/at/helpch/chatchat/util/PapiTagUtils.java @@ -69,7 +69,7 @@ private PapiTagUtils() { } final var kyorifiedPlaceholder = Kyorifier.kyorify(parsedPlaceholder); - final var componentPlaceholder = MessageUtils.parseToMiniMessage(kyorifiedPlaceholder); + final var componentPlaceholder = MessageUtils.parseFromMiniMessage(kyorifiedPlaceholder); return inserting ? Tag.inserting(componentPlaceholder) : Tag.selfClosingInserting(componentPlaceholder); }); @@ -128,7 +128,7 @@ private PapiTagUtils() { } final var kyorifiedPlaceholder = Kyorifier.kyorify(parsedPlaceholder); - final var componentPlaceholder = MessageUtils.parseToMiniMessage(kyorifiedPlaceholder); + final var componentPlaceholder = MessageUtils.parseFromMiniMessage(kyorifiedPlaceholder); return inserting ? Tag.inserting(componentPlaceholder) : Tag.selfClosingInserting(componentPlaceholder); }); From a6bf05274118dff7a25cc80f8814e28fcd539d10 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Sun, 16 Apr 2023 02:08:24 +0300 Subject: [PATCH 2/5] Added remote message sender + receiver and remote to local message processor --- .../at/helpch/chatchat/ChatChatPlugin.java | 26 ++++++++ .../cs/receiver/BungeeMessageReceiver.java | 62 +++++++++++++++++++ .../cs/receiver/RemoteMessageReceiver.java | 6 ++ .../cs/sender/BungeeMessageSender.java | 54 ++++++++++++++++ .../cs/sender/RemoteMessageSender.java | 5 ++ .../LocalToRemoteMessageProcessor.java | 3 +- .../RemoteToLocalMessageProcessor.java | 43 +++++++++++++ .../at/helpch/chatchat/util/Constants.java | 8 +++ .../at/helpch/chatchat/util/FormatUtils.java | 8 +++ 9 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 plugin/src/main/java/at/helpch/chatchat/cs/receiver/BungeeMessageReceiver.java create mode 100644 plugin/src/main/java/at/helpch/chatchat/cs/receiver/RemoteMessageReceiver.java create mode 100644 plugin/src/main/java/at/helpch/chatchat/cs/sender/BungeeMessageSender.java create mode 100644 plugin/src/main/java/at/helpch/chatchat/cs/sender/RemoteMessageSender.java create mode 100644 plugin/src/main/java/at/helpch/chatchat/processor/RemoteToLocalMessageProcessor.java create mode 100644 plugin/src/main/java/at/helpch/chatchat/util/Constants.java diff --git a/plugin/src/main/java/at/helpch/chatchat/ChatChatPlugin.java b/plugin/src/main/java/at/helpch/chatchat/ChatChatPlugin.java index fc872b4a..2747fb30 100644 --- a/plugin/src/main/java/at/helpch/chatchat/ChatChatPlugin.java +++ b/plugin/src/main/java/at/helpch/chatchat/ChatChatPlugin.java @@ -21,6 +21,10 @@ import at.helpch.chatchat.command.WhisperToggleCommand; import at.helpch.chatchat.api.hook.Hook; import at.helpch.chatchat.config.ConfigManager; +import at.helpch.chatchat.cs.receiver.BungeeMessageReceiver; +import at.helpch.chatchat.cs.receiver.RemoteMessageReceiver; +import at.helpch.chatchat.cs.sender.BungeeMessageSender; +import at.helpch.chatchat.cs.sender.RemoteMessageSender; import at.helpch.chatchat.data.base.Database; import at.helpch.chatchat.data.impl.gson.GsonDatabase; import at.helpch.chatchat.hooks.HookManagerImpl; @@ -52,6 +56,8 @@ import java.util.List; import java.util.stream.Collectors; +import static at.helpch.chatchat.util.Constants.BUNGEE_CROSS_SERVER_CHANNEL; + @BukkitMain public final class ChatChatPlugin extends JavaPlugin { @@ -75,6 +81,9 @@ public final class ChatChatPlugin extends JavaPlugin { private @NotNull final ChatChatAPIImpl api = new ChatChatAPIImpl(this); + private RemoteMessageSender remoteMessageSender; + private RemoteMessageReceiver remoteMessageReceiver; + private static BukkitAudiences audiences; private BukkitCommandManager commandManager; @@ -98,6 +107,12 @@ public void onEnable() { hookManager.init(); configManager.reload(); + // TODO: Make cross server type configurable + remoteMessageSender = new BungeeMessageSender(this); + remoteMessageReceiver = new BungeeMessageReceiver(this); + this.getServer().getMessenger().registerOutgoingPluginChannel(this, BUNGEE_CROSS_SERVER_CHANNEL); + this.getServer().getMessenger().registerIncomingPluginChannel(this, BUNGEE_CROSS_SERVER_CHANNEL, remoteMessageReceiver); + // bStats Metrics metrics = new Metrics(this, 14781); metrics.addCustomChart(new SimpleBarChart("channelTypes", () -> @@ -141,6 +156,9 @@ public void onEnable() { @Override public void onDisable() { + this.getServer().getMessenger().unregisterOutgoingPluginChannel(this); + this.getServer().getMessenger().unregisterIncomingPluginChannel(this); + hookManager().hooks().forEach(Hook::disable); hookManager().vanishHooks().forEach(Hook::disable); getServer().getServicesManager().unregisterAll(this); @@ -203,6 +221,14 @@ public static long cacheDuration() { return api; } + public @NotNull RemoteMessageSender remoteMessageSender() { + return remoteMessageSender; + } + + public @NotNull RemoteMessageReceiver remoteMessageReceiver() { + return remoteMessageReceiver; + } + private void registerArguments() { commandManager.registerArgument(PriorityFormat.class, (sender, argument) -> configManager().formats().formats().get(argument)); diff --git a/plugin/src/main/java/at/helpch/chatchat/cs/receiver/BungeeMessageReceiver.java b/plugin/src/main/java/at/helpch/chatchat/cs/receiver/BungeeMessageReceiver.java new file mode 100644 index 00000000..dcee03e8 --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/cs/receiver/BungeeMessageReceiver.java @@ -0,0 +1,62 @@ +package at.helpch.chatchat.cs.receiver; + +import at.helpch.chatchat.ChatChatPlugin; +import at.helpch.chatchat.processor.RemoteToLocalMessageProcessor; +import at.helpch.chatchat.util.Constants; +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteStreams; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.logging.Level; + +import static at.helpch.chatchat.util.Constants.BUNGEE_CROSS_SERVER_CHANNEL; +import static at.helpch.chatchat.util.Constants.CROSS_SERVER_SUB_CHANNEL; + +public class BungeeMessageReceiver implements RemoteMessageReceiver { + + private final @NotNull ChatChatPlugin plugin; + + public BungeeMessageReceiver(final @NotNull ChatChatPlugin plugin) { + this.plugin = plugin; + } + + @Override + public void onPluginMessageReceived(final @NotNull String channel, @NotNull Player player, final byte[] message) { + if (!channel.equals(BUNGEE_CROSS_SERVER_CHANNEL)) return; + + final ByteArrayDataInput in = ByteStreams.newDataInput(message); + final String subChannel = in.readUTF(); + + if (!subChannel.equals(CROSS_SERVER_SUB_CHANNEL)) return; + + final short length = in.readShort(); + final byte[] messageBytes = new byte[length]; + in.readFully(messageBytes); + + final DataInputStream messageIn = new DataInputStream(new ByteArrayInputStream(messageBytes)); + try { + final String messageType = messageIn.readUTF(); + if (!messageType.equals(Constants.PUBLIC_MESSAGE_TYPE) && !messageType.equals(Constants.PRIVATE_MESSAGE_TYPE)) { + plugin.getLogger().warning("Got cross server message but the message type was invalid: " + messageType); + return; + } + + // TODO: Add private message support + + final String channelName = messageIn.readUTF(); + final String messageContent = messageIn.readUTF(); + + plugin.getLogger().info("Received cross server message. Type: " + messageType + "Channel: " + channelName + ", Message: " + messageContent); + + RemoteToLocalMessageProcessor.processRemoteMessageEvent(plugin, channelName, messageContent); + + } catch (final IOException exception) { + plugin.getLogger().log(Level.WARNING, "Got cross server message but could not read it.", exception); + } + } + +} diff --git a/plugin/src/main/java/at/helpch/chatchat/cs/receiver/RemoteMessageReceiver.java b/plugin/src/main/java/at/helpch/chatchat/cs/receiver/RemoteMessageReceiver.java new file mode 100644 index 00000000..6ecc6838 --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/cs/receiver/RemoteMessageReceiver.java @@ -0,0 +1,6 @@ +package at.helpch.chatchat.cs.receiver; + +import org.bukkit.plugin.messaging.PluginMessageListener; + +public interface RemoteMessageReceiver extends PluginMessageListener { +} diff --git a/plugin/src/main/java/at/helpch/chatchat/cs/sender/BungeeMessageSender.java b/plugin/src/main/java/at/helpch/chatchat/cs/sender/BungeeMessageSender.java new file mode 100644 index 00000000..c36955e9 --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/cs/sender/BungeeMessageSender.java @@ -0,0 +1,54 @@ +package at.helpch.chatchat.cs.sender; + +import at.helpch.chatchat.ChatChatPlugin; +import at.helpch.chatchat.util.Constants; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.NotNull; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.logging.Level; + +import static at.helpch.chatchat.util.Constants.BUNGEE_CROSS_SERVER_CHANNEL; +import static at.helpch.chatchat.util.Constants.CROSS_SERVER_SUB_CHANNEL; + +public class BungeeMessageSender implements RemoteMessageSender { + private final @NotNull ChatChatPlugin plugin; + + public BungeeMessageSender(final @NotNull ChatChatPlugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean send(String channel, String message) { + plugin.getLogger().info("SENDING MESSAGE TO BUNGEE. Channel: " + channel + ", Message: " + message); + + final ByteArrayDataOutput out = ByteStreams.newDataOutput(); + + out.writeUTF("Forward"); + out.writeUTF("ALL"); + out.writeUTF(CROSS_SERVER_SUB_CHANNEL); + + final ByteArrayOutputStream messageBytes = new ByteArrayOutputStream(); + final DataOutputStream messageOut = new DataOutputStream(messageBytes); + + try { + messageOut.writeUTF(Constants.PUBLIC_MESSAGE_TYPE); + messageOut.writeUTF(channel); + messageOut.writeUTF(message); + } catch (final IOException exception){ + plugin.getLogger().log(Level.WARNING, "Could not write cross server message.", exception); + return false; + } + + out.writeShort(messageBytes.toByteArray().length); + out.write(messageBytes.toByteArray()); + + Bukkit.getServer().sendPluginMessage(plugin, BUNGEE_CROSS_SERVER_CHANNEL, out.toByteArray()); + plugin.getLogger().info("SENT MESSAGE TO BUNGEE"); + return true; + } +} diff --git a/plugin/src/main/java/at/helpch/chatchat/cs/sender/RemoteMessageSender.java b/plugin/src/main/java/at/helpch/chatchat/cs/sender/RemoteMessageSender.java new file mode 100644 index 00000000..6b2015b0 --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/cs/sender/RemoteMessageSender.java @@ -0,0 +1,5 @@ +package at.helpch.chatchat.cs.sender; + +public interface RemoteMessageSender { + boolean send(String channel, String message); +} diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java index 920fa593..f5ca1162 100644 --- a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java +++ b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java @@ -30,7 +30,6 @@ public static boolean processLocalMessageEvent( plugin.miniPlaceholdersManager().compileTags(false, sender, ConsoleUser.INSTANCE) ); - // TODO: Pass the message to the RemoteMessageSender - return RemoteMessageSender.send(plugin, channel.name(), MessageUtils.parseToMiniMessage(component)); + return plugin.remoteMessageSender().send(channel.name(), MessageUtils.parseToMiniMessage(component)); } } diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/RemoteToLocalMessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/RemoteToLocalMessageProcessor.java new file mode 100644 index 00000000..259e9d57 --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/processor/RemoteToLocalMessageProcessor.java @@ -0,0 +1,43 @@ +package at.helpch.chatchat.processor; + +import at.helpch.chatchat.ChatChatPlugin; +import at.helpch.chatchat.api.user.ChatUser; +import at.helpch.chatchat.user.ConsoleUser; +import at.helpch.chatchat.util.FormatUtils; +import org.jetbrains.annotations.NotNull; + +public final class RemoteToLocalMessageProcessor { + + private RemoteToLocalMessageProcessor() { + throw new AssertionError("Util classes are not to be instantiated!"); + } + + public static boolean processRemoteMessageEvent( + @NotNull final ChatChatPlugin plugin, + @NotNull final String channelName, + @NotNull final String message + ) { + final var channel = plugin.configManager().channels().channels().get(channelName); + if (channel == null) return false; + if (!channel.crossServer()) return false; + + final var recipients = channel.targets(ConsoleUser.INSTANCE); + + // TODO: Trigger an event. Either a ChatChatEvent or create a new Event. Current issue with using ChatChatEvent + // is that it requires a ChatUser which we don't have. We could maybe change this. We still won't have a User + // so we'll have to just pass the console user. + + for (final var recipient : recipients) { + // TODO: Figure out how to support cross server console + if (recipient instanceof ConsoleUser) continue; + + final var component = recipient instanceof ChatUser + ? FormatUtils.parseRemoteFormat(message, ((ChatUser) recipient).player()) + : FormatUtils.parseRemoteFormat(message); + + recipient.sendMessage(component); + } + + return true; + } +} diff --git a/plugin/src/main/java/at/helpch/chatchat/util/Constants.java b/plugin/src/main/java/at/helpch/chatchat/util/Constants.java new file mode 100644 index 00000000..30737bd9 --- /dev/null +++ b/plugin/src/main/java/at/helpch/chatchat/util/Constants.java @@ -0,0 +1,8 @@ +package at.helpch.chatchat.util; + +public final class Constants { + public static final String CROSS_SERVER_SUB_CHANNEL = "hc:cc"; + public static final String BUNGEE_CROSS_SERVER_CHANNEL = "BungeeCord"; + public static final String PUBLIC_MESSAGE_TYPE = "pub"; + public static final String PRIVATE_MESSAGE_TYPE = "prv"; +} diff --git a/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java b/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java index fb727c95..c3e15344 100644 --- a/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java +++ b/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java @@ -68,6 +68,14 @@ private FormatUtils() { ); } + public static @NotNull Component parseRemoteFormat(@NotNull final String message, @NotNull final Player recipient) { + return MessageUtils.parseFromMiniMessage(message, PapiTagUtils.createRecipientTag(recipient)); + } + + public static @NotNull Component parseRemoteFormat(@NotNull final String message) { + return MessageUtils.parseFromMiniMessage(message); + } + public static @NotNull Component parseFormat( @NotNull final Format format, @NotNull final Player player, From 5de56e83c094deecb2753b69373a642bbbb46da9 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Sun, 16 Apr 2023 18:38:54 +0300 Subject: [PATCH 3/5] Cleaned Up + Switched to GSON serializing for cross server message --- .../chatchat/command/SwitchChannelCommand.java | 3 +-- .../chatchat/cs/receiver/BungeeMessageReceiver.java | 2 -- .../chatchat/cs/sender/BungeeMessageSender.java | 3 --- .../at/helpch/chatchat/listener/ChatListener.java | 2 +- .../processor/LocalToRemoteMessageProcessor.java | 6 +++++- .../helpch/chatchat/processor/MessageProcessor.java | 6 +----- .../processor/RemoteToLocalMessageProcessor.java | 13 ++++--------- .../java/at/helpch/chatchat/util/FormatUtils.java | 8 -------- .../java/at/helpch/chatchat/util/MessageUtils.java | 9 +++++++-- 9 files changed, 19 insertions(+), 33 deletions(-) diff --git a/plugin/src/main/java/at/helpch/chatchat/command/SwitchChannelCommand.java b/plugin/src/main/java/at/helpch/chatchat/command/SwitchChannelCommand.java index eafea800..540d9018 100644 --- a/plugin/src/main/java/at/helpch/chatchat/command/SwitchChannelCommand.java +++ b/plugin/src/main/java/at/helpch/chatchat/command/SwitchChannelCommand.java @@ -3,7 +3,6 @@ import at.helpch.chatchat.ChatChatPlugin; import at.helpch.chatchat.api.user.ChatUser; import at.helpch.chatchat.hooks.towny.AbstractTownyChannel; -import at.helpch.chatchat.processor.LocalToLocalMessageProcessor; import at.helpch.chatchat.processor.MessageProcessor; import com.palmergames.bukkit.towny.TownyUniverse; import com.palmergames.bukkit.towny.object.Resident; @@ -58,6 +57,6 @@ public void switchChannel(final ChatUser user, @Join @Optional @NotNull final St return; } - MessageProcessor.processEvent(plugin, user, channel, message, false); + MessageProcessor.processMessageEvent(plugin, user, channel, message, false); } } diff --git a/plugin/src/main/java/at/helpch/chatchat/cs/receiver/BungeeMessageReceiver.java b/plugin/src/main/java/at/helpch/chatchat/cs/receiver/BungeeMessageReceiver.java index dcee03e8..afe223c3 100644 --- a/plugin/src/main/java/at/helpch/chatchat/cs/receiver/BungeeMessageReceiver.java +++ b/plugin/src/main/java/at/helpch/chatchat/cs/receiver/BungeeMessageReceiver.java @@ -50,8 +50,6 @@ public void onPluginMessageReceived(final @NotNull String channel, @NotNull Play final String channelName = messageIn.readUTF(); final String messageContent = messageIn.readUTF(); - plugin.getLogger().info("Received cross server message. Type: " + messageType + "Channel: " + channelName + ", Message: " + messageContent); - RemoteToLocalMessageProcessor.processRemoteMessageEvent(plugin, channelName, messageContent); } catch (final IOException exception) { diff --git a/plugin/src/main/java/at/helpch/chatchat/cs/sender/BungeeMessageSender.java b/plugin/src/main/java/at/helpch/chatchat/cs/sender/BungeeMessageSender.java index c36955e9..ed5561ff 100644 --- a/plugin/src/main/java/at/helpch/chatchat/cs/sender/BungeeMessageSender.java +++ b/plugin/src/main/java/at/helpch/chatchat/cs/sender/BungeeMessageSender.java @@ -24,8 +24,6 @@ public BungeeMessageSender(final @NotNull ChatChatPlugin plugin) { @Override public boolean send(String channel, String message) { - plugin.getLogger().info("SENDING MESSAGE TO BUNGEE. Channel: " + channel + ", Message: " + message); - final ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF("Forward"); @@ -48,7 +46,6 @@ public boolean send(String channel, String message) { out.write(messageBytes.toByteArray()); Bukkit.getServer().sendPluginMessage(plugin, BUNGEE_CROSS_SERVER_CHANNEL, out.toByteArray()); - plugin.getLogger().info("SENT MESSAGE TO BUNGEE"); return true; } } diff --git a/plugin/src/main/java/at/helpch/chatchat/listener/ChatListener.java b/plugin/src/main/java/at/helpch/chatchat/listener/ChatListener.java index 7c2a6550..02569274 100644 --- a/plugin/src/main/java/at/helpch/chatchat/listener/ChatListener.java +++ b/plugin/src/main/java/at/helpch/chatchat/listener/ChatListener.java @@ -91,7 +91,7 @@ public void onChat(final AsyncPlayerChatEvent event) { // Cancel the event if the message doesn't end up being sent // This happens if rules are not respected or if ChatChatEvent is canceled. - event.setCancelled(!MessageProcessor.processEvent(plugin, user, channel, message, event.isAsynchronous())); + event.setCancelled(!MessageProcessor.processMessageEvent(plugin, user, channel, message, event.isAsynchronous())); } private static String cleanseMessage(@NotNull final String message) { diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java index f5ca1162..c27eb3ba 100644 --- a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java +++ b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java @@ -21,6 +21,10 @@ public static boolean processLocalMessageEvent( @NotNull final ChatUser sender, @NotNull final Channel channel ) { + if (!channel.crossServer()) { + return false; + } + final var parsedMessage = chatEvent.message().compact(); final var component = FormatUtils.parseFormat( @@ -30,6 +34,6 @@ public static boolean processLocalMessageEvent( plugin.miniPlaceholdersManager().compileTags(false, sender, ConsoleUser.INSTANCE) ); - return plugin.remoteMessageSender().send(channel.name(), MessageUtils.parseToMiniMessage(component)); + return plugin.remoteMessageSender().send(channel.name(), MessageUtils.parseToGson(component)); } } diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java index 5402ac0e..6a39cddf 100644 --- a/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java +++ b/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java @@ -22,7 +22,7 @@ private MessageProcessor() { throw new AssertionError("Util classes are not to be instantiated!"); } - public static boolean processEvent( + public static boolean processMessageEvent( @NotNull final ChatChatPlugin plugin, @NotNull final ChatUser sender, @NotNull final Channel channel, @@ -54,10 +54,6 @@ public static boolean processEvent( return false; } - if (!channel.crossServer()) { - return true; - } - LocalToRemoteMessageProcessor.processLocalMessageEvent(plugin, chatEvent, sender, channel); return true; } diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/RemoteToLocalMessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/RemoteToLocalMessageProcessor.java index 259e9d57..02b10c96 100644 --- a/plugin/src/main/java/at/helpch/chatchat/processor/RemoteToLocalMessageProcessor.java +++ b/plugin/src/main/java/at/helpch/chatchat/processor/RemoteToLocalMessageProcessor.java @@ -1,9 +1,8 @@ package at.helpch.chatchat.processor; import at.helpch.chatchat.ChatChatPlugin; -import at.helpch.chatchat.api.user.ChatUser; import at.helpch.chatchat.user.ConsoleUser; -import at.helpch.chatchat.util.FormatUtils; +import at.helpch.chatchat.util.MessageUtils; import org.jetbrains.annotations.NotNull; public final class RemoteToLocalMessageProcessor { @@ -23,18 +22,14 @@ public static boolean processRemoteMessageEvent( final var recipients = channel.targets(ConsoleUser.INSTANCE); - // TODO: Trigger an event. Either a ChatChatEvent or create a new Event. Current issue with using ChatChatEvent - // is that it requires a ChatUser which we don't have. We could maybe change this. We still won't have a User - // so we'll have to just pass the console user. + // TODO: Trigger an event? + + final var component = MessageUtils.parseFromGson(message); for (final var recipient : recipients) { // TODO: Figure out how to support cross server console if (recipient instanceof ConsoleUser) continue; - final var component = recipient instanceof ChatUser - ? FormatUtils.parseRemoteFormat(message, ((ChatUser) recipient).player()) - : FormatUtils.parseRemoteFormat(message); - recipient.sendMessage(component); } diff --git a/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java b/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java index c3e15344..fb727c95 100644 --- a/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java +++ b/plugin/src/main/java/at/helpch/chatchat/util/FormatUtils.java @@ -68,14 +68,6 @@ private FormatUtils() { ); } - public static @NotNull Component parseRemoteFormat(@NotNull final String message, @NotNull final Player recipient) { - return MessageUtils.parseFromMiniMessage(message, PapiTagUtils.createRecipientTag(recipient)); - } - - public static @NotNull Component parseRemoteFormat(@NotNull final String message) { - return MessageUtils.parseFromMiniMessage(message); - } - public static @NotNull Component parseFormat( @NotNull final Format format, @NotNull final Player player, diff --git a/plugin/src/main/java/at/helpch/chatchat/util/MessageUtils.java b/plugin/src/main/java/at/helpch/chatchat/util/MessageUtils.java index 4a152a7a..a7310fcf 100644 --- a/plugin/src/main/java/at/helpch/chatchat/util/MessageUtils.java +++ b/plugin/src/main/java/at/helpch/chatchat/util/MessageUtils.java @@ -4,6 +4,7 @@ import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -15,8 +16,12 @@ private MessageUtils() { throw new AssertionError("Util classes are not to be instantiated!"); } - public static @NotNull String parseToMiniMessage(@NotNull final ComponentLike component) { - return miniMessage.serialize(component.asComponent()); + public static @NotNull Component parseFromGson(@NotNull final String formatPart) { + return GsonComponentSerializer.gson().deserialize(formatPart); + } + + public static @NotNull String parseToGson(@NotNull final ComponentLike component) { + return GsonComponentSerializer.gson().serialize(component.asComponent()); } public static @NotNull Component parseFromMiniMessage(@NotNull final String formatPart) { From 0d48053a85e5140e3f89e0af4d40039003b055f7 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Sat, 22 Apr 2023 12:40:16 +0300 Subject: [PATCH 4/5] Upgraded adventure libs --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 31f13090..9142847a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,8 +3,8 @@ spigot = "1.19.3-R0.1-SNAPSHOT" # Adventure -minimessage = "4.11.0" -adventure-platform = "4.2.0" +minimessage = "4.13.1" +adventure-platform = "4.3.0" # Other configurate = "4.1.2" From cc4e0df01769e1fdf43f545787b1c5ad92c58575 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:38:07 +0300 Subject: [PATCH 5/5] fixed conflicts with main branch --- .../placeholder/MiniPlaceholderImpl.java | 4 +- .../LocalToLocalMessageProcessor.java | 9 +- .../LocalToRemoteMessageProcessor.java | 3 +- .../chatchat/processor/MessageProcessor.java | 20 +- .../chatchat/util/MessageProcessor.java | 247 ------------------ 5 files changed, 28 insertions(+), 255 deletions(-) delete mode 100644 plugin/src/main/java/at/helpch/chatchat/util/MessageProcessor.java diff --git a/plugin/src/main/java/at/helpch/chatchat/placeholder/MiniPlaceholderImpl.java b/plugin/src/main/java/at/helpch/chatchat/placeholder/MiniPlaceholderImpl.java index 26c033fd..c0c0aeaa 100644 --- a/plugin/src/main/java/at/helpch/chatchat/placeholder/MiniPlaceholderImpl.java +++ b/plugin/src/main/java/at/helpch/chatchat/placeholder/MiniPlaceholderImpl.java @@ -69,8 +69,8 @@ public MiniPlaceholderImpl( if (!shouldParsePlaceholderAPIPlaceholders) { return shouldAutoCloseTags - ? Placeholder.component(tagName, MessageUtils.parseToMiniMessage(message)) - : TagResolver.resolver(tagName, Tag.inserting(MessageUtils.parseToMiniMessage(message))); + ? Placeholder.component(tagName, MessageUtils.parseFromMiniMessage(message)) + : TagResolver.resolver(tagName, Tag.inserting(MessageUtils.parseFromMiniMessage(message))); } if (isRelationalTag && recipient.isEmpty()) { diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToLocalMessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToLocalMessageProcessor.java index a388f38c..1e61752e 100644 --- a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToLocalMessageProcessor.java +++ b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToLocalMessageProcessor.java @@ -5,6 +5,7 @@ import at.helpch.chatchat.api.event.ChatChatEvent; import at.helpch.chatchat.api.user.ChatUser; import at.helpch.chatchat.api.user.User; +import at.helpch.chatchat.placeholder.MiniPlaceholderContext; import at.helpch.chatchat.user.ConsoleUser; import at.helpch.chatchat.util.FormatUtils; import at.helpch.chatchat.util.ItemUtils; @@ -63,7 +64,7 @@ public static boolean processLocalMessageEvent( sender.player(), chatTarget.player(), mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(false, sender, target) + plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(false).sender(sender).recipient(target).build()) ); target.sendMessage(component); @@ -87,7 +88,7 @@ public static boolean processLocalMessageEvent( chatEvent.format(), sender.player(), mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(false, sender, target) + plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(false).sender(sender).recipient(target).build()) ); target.sendMessage(component); @@ -115,7 +116,7 @@ public static boolean processLocalMessageEvent( sender.player(), sender.player(), mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(false, sender, sender) + plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(false).sender(sender).recipient(sender).build()) ); sender.sendMessage(component); @@ -161,7 +162,7 @@ public static boolean processLocalMessageEvent( ); } - resolver.resolvers(plugin.miniPlaceholdersManager().compileTags(true, sender, recipient)); + resolver.resolvers(plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(true).sender(sender).recipient(recipient).build())); return !sender.hasPermission(MessageProcessor.Constants.URL_PERMISSION) ? MessageProcessor.Constants.USER_MESSAGE_MINI_MESSAGE.deserialize(message, resolver.build()) diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java index c27eb3ba..45b0111f 100644 --- a/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java +++ b/plugin/src/main/java/at/helpch/chatchat/processor/LocalToRemoteMessageProcessor.java @@ -4,6 +4,7 @@ import at.helpch.chatchat.api.channel.Channel; import at.helpch.chatchat.api.event.ChatChatEvent; import at.helpch.chatchat.api.user.ChatUser; +import at.helpch.chatchat.placeholder.MiniPlaceholderContext; import at.helpch.chatchat.user.ConsoleUser; import at.helpch.chatchat.util.FormatUtils; import at.helpch.chatchat.util.MessageUtils; @@ -31,7 +32,7 @@ public static boolean processLocalMessageEvent( chatEvent.format(), sender.player(), parsedMessage, - plugin.miniPlaceholdersManager().compileTags(false, sender, ConsoleUser.INSTANCE) + plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(false).sender(sender).build()) ); return plugin.remoteMessageSender().send(channel.name(), MessageUtils.parseToGson(component)); diff --git a/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java index 6a39cddf..660460d8 100644 --- a/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java +++ b/plugin/src/main/java/at/helpch/chatchat/processor/MessageProcessor.java @@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Map; +import java.util.Objects; import java.util.regex.Pattern; public final class MessageProcessor { @@ -29,6 +30,16 @@ public static boolean processMessageEvent( @NotNull final String message, final boolean async ) { + final var isMuted = plugin.hookManager() + .muteHooks() + .stream() + .filter(Objects::nonNull) + .anyMatch(hook -> hook.isMuted(sender)); + + if (isMuted) { + return false; + } + if (!validateRules(plugin, sender, message)) { return false; } @@ -36,7 +47,14 @@ public static boolean processMessageEvent( final var chatEvent = new ChatChatEvent( async, sender, - FormatUtils.findFormat(sender.player(), channel, plugin.configManager().formats()), + FormatUtils.findFormat( + sender.player(), + channel, + plugin.configManager().formats(), + plugin.configManager().extensions().addons().deluxeChatInversePriorities() + ), + // TODO: 9/2/22 Process message for each recipient to add rel support inside the message itself. + // Possibly even pass the minimessage string here instead of the processed component. LocalToLocalMessageProcessor.processMessage(plugin, sender, ConsoleUser.INSTANCE, message), channel, channel.targets(sender) diff --git a/plugin/src/main/java/at/helpch/chatchat/util/MessageProcessor.java b/plugin/src/main/java/at/helpch/chatchat/util/MessageProcessor.java deleted file mode 100644 index 3aec1eeb..00000000 --- a/plugin/src/main/java/at/helpch/chatchat/util/MessageProcessor.java +++ /dev/null @@ -1,247 +0,0 @@ -package at.helpch.chatchat.util; - -import at.helpch.chatchat.ChatChatPlugin; -import at.helpch.chatchat.api.channel.Channel; -import at.helpch.chatchat.api.event.ChatChatEvent; -import at.helpch.chatchat.api.user.ChatUser; -import at.helpch.chatchat.api.user.User; -import at.helpch.chatchat.placeholder.MiniPlaceholderContext; -import at.helpch.chatchat.user.ConsoleUser; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextReplacementConfig; -import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.text.format.TextDecoration; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; -import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; -import org.jetbrains.annotations.NotNull; - -import java.util.Map; -import java.util.Objects; -import java.util.regex.Pattern; - -public final class MessageProcessor { - - private static final MiniMessage USER_MESSAGE_MINI_MESSAGE = MiniMessage.builder().tags(TagResolver.empty()).build(); - private static final Pattern DEFAULT_URL_PATTERN = Pattern.compile("(?:(https?)://)?([-\\w_.]+\\.\\w{2,})(/\\S*)?"); - private static final Pattern URL_SCHEME_PATTERN = Pattern.compile("^[a-z][a-z\\d+\\-.]*:"); - - private static final TextReplacementConfig URL_REPLACER_CONFIG = TextReplacementConfig.builder() - .match(DEFAULT_URL_PATTERN) - .replacement(builder -> { - String clickUrl = builder.content(); - if (!URL_SCHEME_PATTERN.matcher(clickUrl).find()) { - clickUrl = "https://" + clickUrl; - } - return builder.clickEvent(ClickEvent.openUrl(clickUrl)); - }) - .build(); - - private static final String URL_PERMISSION = "chatchat.url"; - public static final String TAG_BASE_PERMISSION = "chatchat.tag."; - private static final String ITEM_TAG_PERMISSION = TAG_BASE_PERMISSION + "item"; - - private static final Map PERMISSION_TAGS = Map.ofEntries( - Map.entry("click", StandardTags.clickEvent()), - Map.entry("color", StandardTags.color()), - Map.entry("font", StandardTags.font()), - Map.entry("gradient", StandardTags.gradient()), - Map.entry("hover", StandardTags.hoverEvent()), - Map.entry("insertion", StandardTags.insertion()), - Map.entry("keybind", StandardTags.keybind()), - Map.entry("newline", StandardTags.newline()), - Map.entry("rainbow", StandardTags.rainbow()), - Map.entry("reset", StandardTags.reset()), - Map.entry("translatable", StandardTags.translatable()) - ); - - private MessageProcessor() { - throw new AssertionError("Util classes are not to be instantiated!"); - } - - public static boolean process( - @NotNull final ChatChatPlugin plugin, - @NotNull final ChatUser user, - @NotNull final Channel channel, - @NotNull final String message, - final boolean async - ) { - final var isMuted = plugin.hookManager() - .muteHooks() - .stream() - .filter(Objects::nonNull) - .anyMatch(hook -> hook.isMuted(user)); - - if (isMuted) { - return false; - } - - final var rulesResult = plugin.ruleManager().isAllowedPublicChat(user, message); - if (rulesResult.isPresent()) { - user.sendMessage(rulesResult.get()); - return false; - } - - final var chatEvent = new ChatChatEvent( - async, - user, - FormatUtils.findFormat( - user.player(), - channel, - plugin.configManager().formats(), - plugin.configManager().extensions().addons().deluxeChatInversePriorities()), - // TODO: 9/2/22 Process message for each recipient to add rel support inside the message itself. - // Possibly even pass the minimessage string here instead of the processed component. - MessageProcessor.processMessage(plugin, user, ConsoleUser.INSTANCE, message), - channel, - channel.targets(user) - ); - - plugin.getServer().getPluginManager().callEvent(chatEvent); - - if (chatEvent.isCancelled()) { - return false; - } - - final var oldChannel = user.channel(); - user.channel(channel); - - final var parsedMessage = chatEvent.message().compact(); - final var mentions = plugin.configManager().settings().mentions(); - - var userMessage = parsedMessage; - var userIsTarget = false; - - for (final var target : chatEvent.recipients()) { - if (target.uuid() == user.uuid()) { - userIsTarget = true; - continue; - } - - // Console Users have their own format we set in ChatListener.java - if (target instanceof ConsoleUser) continue; - - // Process mentions and get the result. - final var mentionResult = plugin.mentionsManager().processMentions( - async, - user, - target, - chatEvent.channel(), - parsedMessage, - true - ); - - if (target instanceof ChatUser) { - final var chatTarget = (ChatUser) target; - - final var component = FormatUtils.parseFormat( - chatEvent.format(), - user.player(), - chatTarget.player(), - mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(false).sender(user).recipient(target).build()) - ); - - target.sendMessage(component); - if (mentionResult.playSound()) { - target.playSound(mentions.sound()); - } - if (user.canSee(chatTarget)) { - userMessage = plugin.mentionsManager().processMentions( - async, - user, - chatTarget, - chatEvent.channel(), - userMessage, - false - ).message(); - } - continue; - } - - final var component = FormatUtils.parseFormat( - chatEvent.format(), - user.player(), - mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(false).sender(user).recipient(target).build()) - ); - - target.sendMessage(component); - if (mentionResult.playSound()) { - target.playSound(mentions.sound()); - } - } - - if (!userIsTarget) { - user.channel(oldChannel); - return true; - } - - final var mentionResult = plugin.mentionsManager().processMentions( - async, - user, - user, - chatEvent.channel(), - parsedMessage, - true - ); - - final var component = FormatUtils.parseFormat( - chatEvent.format(), - user.player(), - user.player(), - mentionResult.message(), - plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(false).sender(user).recipient(user).build()) - ); - - user.sendMessage(component); - if (mentionResult.playSound()) { - user.playSound(mentions.sound()); - } - - user.channel(oldChannel); - return true; - } - - public static @NotNull Component processMessage( - @NotNull final ChatChatPlugin plugin, - @NotNull final ChatUser user, - @NotNull final User recipient, - @NotNull final String message - ) { - final var resolver = TagResolver.builder(); - - for (final var entry : PERMISSION_TAGS.entrySet()) { - if (!user.hasPermission(TAG_BASE_PERMISSION + entry.getKey())) { - continue; - } - - resolver.resolver(entry.getValue()); - } - - for (final var tag : TextDecoration.values()) { - if (!user.hasPermission(TAG_BASE_PERMISSION + tag.toString())) { - continue; - } - - resolver.resolver(StandardTags.decorations(tag)); - } - - if (user.hasPermission(ITEM_TAG_PERMISSION)) { - resolver.resolver( - ItemUtils.createItemPlaceholder( - plugin.configManager().settings().itemFormat(), - plugin.configManager().settings().itemFormatInfo(), - user.player().getInventory().getItemInMainHand() - ) - ); - } - - resolver.resolvers(plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(true).sender(user).recipient(recipient).build())); - - return !user.hasPermission(URL_PERMISSION) - ? USER_MESSAGE_MINI_MESSAGE.deserialize(message, resolver.build()) - : USER_MESSAGE_MINI_MESSAGE.deserialize(message, resolver.build()).replaceText(URL_REPLACER_CONFIG); - } - -}