From b9fae1cb355b01468a49a1fe09623080f2f22c50 Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Thu, 5 Aug 2021 11:40:42 +0200 Subject: [PATCH] Created configurable chat channels --- .../java/com/alttd/chat/config/Config.java | 23 +++++-- .../java/com/alttd/chat/objects/Channel.java | 49 +++++++++++++++ .../main/java/com/alttd/chat/ChatPlugin.java | 6 +- .../com/alttd/chat/commands/ChatChannel.java | 27 +++++++-- .../com/alttd/chat/handler/ChatHandler.java | 60 ++++++++++++------- .../alttd/chat/listeners/PluginMessage.java | 50 ++++++++++++---- galaxy/src/main/resources/plugin.yml | 4 +- .../chat/listeners/PluginMessageListener.java | 26 ++++++++ 8 files changed, 196 insertions(+), 49 deletions(-) create mode 100644 api/src/main/java/com/alttd/chat/objects/Channel.java 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 3c03a83..66d9a08 100755 --- a/api/src/main/java/com/alttd/chat/config/Config.java +++ b/api/src/main/java/com/alttd/chat/config/Config.java @@ -1,5 +1,6 @@ package com.alttd.chat.config; +import com.alttd.chat.objects.Channel; import com.google.common.base.Throwables; import com.google.common.collect.Lists; import com.google.common.reflect.TypeToken; @@ -14,9 +15,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.regex.Pattern; public final class Config { @@ -238,9 +237,23 @@ public final class Config { } - public static List CHATCHANNEL_CHANNELS = List.of("ac"); private static void chatChannels() { - CHATCHANNEL_CHANNELS = getList("chat-channels", CHATCHANNEL_CHANNELS); + ConfigurationNode node = getNode("chat-channels"); + if (node.isEmpty()) { + getString("chat-channels.ac.format", " >to : "); + getList("chat-channels.ac.servers", List.of("lobby")); + getBoolean("chat-channels.ac.proxy", false); + node = getNode("chat-channels"); + } + + for (ConfigurationNode configurationNode : node.getChildrenMap().values()) { + String channelName = Objects.requireNonNull(configurationNode.getKey()).toString(); + String key = "chat-channels." + channelName + "."; + new Channel(channelName, + getString(key + "format", ""), + getList(key + "servers", Collections.EMPTY_LIST), + getBoolean(key + "proxy", false)); + } } public static String SERVERMUTEPERMISSION = "command.mute-server"; diff --git a/api/src/main/java/com/alttd/chat/objects/Channel.java b/api/src/main/java/com/alttd/chat/objects/Channel.java new file mode 100644 index 0000000..9a1ff9b --- /dev/null +++ b/api/src/main/java/com/alttd/chat/objects/Channel.java @@ -0,0 +1,49 @@ +package com.alttd.chat.objects; + +import java.util.*; + +public class Channel { + public static HashMap channels = new HashMap<>(); + private String permission; + private String channelName; + private String format; + private List servers; + private boolean proxy; + + public Channel(String channelName, String format, List servers, boolean proxy) { + this.permission = "chat.channel." + channelName.toLowerCase(); + this.channelName = channelName; + this.format = format; + this.servers = servers; + this.proxy = proxy; + channels.put(channelName.toLowerCase(), this); + } + + public static Collection getChannels() { + return channels.values(); + } + + public String getPermission() { + return permission; + } + + public String getChannelName() { + return channelName; + } + + public String getFormat() { + return format; + } + + public List getServers() { + return servers; + } + + public boolean isProxy() { + return proxy; + } + + public static Channel getChatChannel(String channelName) { + return channels.get(channelName.toLowerCase()); + } +} diff --git a/galaxy/src/main/java/com/alttd/chat/ChatPlugin.java b/galaxy/src/main/java/com/alttd/chat/ChatPlugin.java index 1f2b797..1a78803 100755 --- a/galaxy/src/main/java/com/alttd/chat/ChatPlugin.java +++ b/galaxy/src/main/java/com/alttd/chat/ChatPlugin.java @@ -8,6 +8,7 @@ import com.alttd.chat.handler.ChatHandler; import com.alttd.chat.listeners.ChatListener; import com.alttd.chat.listeners.PlayerListener; import com.alttd.chat.listeners.PluginMessage; +import com.alttd.chat.objects.Channel; import com.alttd.chat.util.ALogger; import org.bukkit.Bukkit; import org.bukkit.command.CommandExecutor; @@ -15,7 +16,6 @@ import org.bukkit.command.PluginCommand; import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; -import java.util.Collections; import java.util.List; public class ChatPlugin extends JavaPlugin { @@ -47,7 +47,9 @@ public class ChatPlugin extends JavaPlugin { registerCommand("unignore", new Unignore()); registerCommand("muteserver", new MuteServer()); registerCommand("spy", new Spy()); - registerCommand("chatchannel", new ChatChannel(), Config.CHATCHANNEL_CHANNELS); + for (Channel channel : Channel.getChannels()) { + this.getServer().getCommandMap().register(channel.getChannelName().toLowerCase(), new ChatChannel(channel)); + } messageChannel = Config.MESSAGECHANNEL; getServer().getMessenger().registerOutgoingPluginChannel(this, messageChannel); diff --git a/galaxy/src/main/java/com/alttd/chat/commands/ChatChannel.java b/galaxy/src/main/java/com/alttd/chat/commands/ChatChannel.java index 2596ede..9a9c458 100644 --- a/galaxy/src/main/java/com/alttd/chat/commands/ChatChannel.java +++ b/galaxy/src/main/java/com/alttd/chat/commands/ChatChannel.java @@ -1,17 +1,32 @@ package com.alttd.chat.commands; import com.alttd.chat.ChatPlugin; -import net.kyori.adventure.text.minimessage.MiniMessage; +import com.alttd.chat.objects.Channel; import org.apache.commons.lang.StringUtils; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.command.defaults.BukkitCommand; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; + +public class ChatChannel extends BukkitCommand { + + Channel channel; + String command; + + public ChatChannel(Channel channel) { + super(channel.getChannelName().toLowerCase()); + this.channel = channel; + this.command = channel.getChannelName().toLowerCase(); + this.description = "Chat channel named " + channel.getChannelName() + "."; + this.usageMessage = "/" + command + " "; + this.setAliases(Collections.emptyList()); + } -public class ChatChannel implements CommandExecutor { @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public boolean execute(@NotNull CommandSender sender, @NotNull String command, @NotNull String[] args) { if(!(sender instanceof Player player)) { // must be a player return true; } @@ -22,7 +37,7 @@ public class ChatChannel implements CommandExecutor { new BukkitRunnable() { @Override public void run() { - ChatPlugin.getInstance().getChatHandler().chatChannel(player, label, message); + ChatPlugin.getInstance().getChatHandler().chatChannel(player, channel, message); } }.runTaskAsynchronously(ChatPlugin.getInstance()); 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 642afe1..734cf72 100755 --- a/galaxy/src/main/java/com/alttd/chat/handler/ChatHandler.java +++ b/galaxy/src/main/java/com/alttd/chat/handler/ChatHandler.java @@ -1,9 +1,11 @@ package com.alttd.chat.handler; import com.alttd.chat.ChatPlugin; +import com.alttd.chat.commands.ChatChannel; import com.alttd.chat.config.Config; import com.alttd.chat.managers.ChatUserManager; import com.alttd.chat.managers.RegexManager; +import com.alttd.chat.objects.Channel; import com.alttd.chat.objects.ChatUser; import com.alttd.chat.util.GalaxyUtility; import com.alttd.chat.util.Utility; @@ -117,13 +119,13 @@ public class ChatHandler { sendPluginMessage(player, "globalchat", component); } - public void chatChannel(Player player, String label, String message) { - if (!player.hasPermission("chat.channel." + label)) { + public void chatChannel(Player player, Channel channel, String message) { + if (!player.hasPermission(channel.getPermission())) { player.sendMessage(MiniMessage.get().parse("You don't have permission to use this channel.")); return; } - if (isMuted(player, message, "[" + StringUtils.capitalize(label) + " Muted] ")) return; + if (isMuted(player, message, "[" + channel.getChannelName() + " Muted] ")) return; ChatUser user = ChatUserManager.getChatUser(player.getUniqueId()); Component senderName = user.getDisplayName(); @@ -144,28 +146,24 @@ public class ChatHandler { Template.of("sender", senderName), Template.of("message", updatedMessage), Template.of("server", Bukkit.getServerName()), + Template.of("channel", channel.getChannelName()), Template.of("[i]", itemComponent(player.getInventory().getItemInMainHand())))); - Component component = miniMessage.parse(Config.GCFORMAT, templates); - sendChatChannelMessage(player, label, "chatchannel", component); + Component component = miniMessage.parse(channel.getFormat(), templates); + + if (channel.isProxy()) { + sendChatChannelMessage(player, channel.getChannelName(), "chatchannel", component); + } else { + sendChatChannelMessage(channel, component); + } } - private boolean isMuted(Player player, String message, String prefix) { - if (Database.get().isPlayerMuted(player.getUniqueId(), null) || (ChatPlugin.getInstance().serverMuted() && !player.hasPermission("chat.bypass-server-muted"))) { - MiniMessage miniMessage = MiniMessage.get(); - Component blockedNotification = miniMessage.parse("" + prefix - + Utility.getDisplayName(player.getUniqueId(), player.getName()) - + " tried to say: " - + message + ""); + private void sendChatChannelMessage(Channel chatChannel, Component component) { + if (!chatChannel.getServers().contains(Bukkit.getServerName())) return; - Bukkit.getOnlinePlayers().forEach(a ->{ - if (a.hasPermission("chat.alert-blocked")) { - a.sendMessage(blockedNotification);//TODO make configurable (along with all the messages) - } - }); - return true; - } - return false; + Bukkit.getServer().getOnlinePlayers().stream() + .filter(p -> p.hasPermission(chatChannel.getPermission())) + .forEach(p -> p.sendMessage(component)); } private void sendPluginMessage(Player player, String channel, Component component) { @@ -185,15 +183,33 @@ public class ChatHandler { player.sendPluginMessage(plugin, Config.MESSAGECHANNEL, out.toByteArray()); } - public void sendChatChannelMessage(Player player, String label, String channel, Component component) { + public void sendChatChannelMessage(Player player, String chatChannelName, String channel, Component component) { ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF(channel); - out.writeUTF(label); + out.writeUTF(chatChannelName); out.writeUTF(GsonComponentSerializer.gson().serialize(component)); player.sendPluginMessage(plugin, Config.MESSAGECHANNEL, out.toByteArray()); } // Start - move these to util + private boolean isMuted(Player player, String message, String prefix) { + if (Database.get().isPlayerMuted(player.getUniqueId(), null) || (ChatPlugin.getInstance().serverMuted() && !player.hasPermission("chat.bypass-server-muted"))) { + MiniMessage miniMessage = MiniMessage.get(); + Component blockedNotification = miniMessage.parse("" + prefix + + Utility.getDisplayName(player.getUniqueId(), player.getName()) + + " tried to say: " + + message + ""); + + Bukkit.getOnlinePlayers().forEach(a ->{ + if (a.hasPermission("chat.alert-blocked")) { + a.sendMessage(blockedNotification);//TODO make configurable (along with all the messages) + } + }); + return true; + } + return false; + } + public static Component itemComponent(ItemStack item) { Component component = Component.text("[i]", NamedTextColor.AQUA); if(item.getType().equals(Material.AIR)) diff --git a/galaxy/src/main/java/com/alttd/chat/listeners/PluginMessage.java b/galaxy/src/main/java/com/alttd/chat/listeners/PluginMessage.java index 3aaa742..9794242 100755 --- a/galaxy/src/main/java/com/alttd/chat/listeners/PluginMessage.java +++ b/galaxy/src/main/java/com/alttd/chat/listeners/PluginMessage.java @@ -4,6 +4,7 @@ import com.alttd.chat.ChatPlugin; import com.alttd.chat.config.Config; import com.alttd.chat.database.Queries; import com.alttd.chat.managers.ChatUserManager; +import com.alttd.chat.objects.Channel; import com.alttd.chat.objects.ChatUser; import com.alttd.chat.util.ALogger; import com.alttd.chat.util.Utility; @@ -60,31 +61,58 @@ public class PluginMessage implements PluginMessageListener { if(!chatUser.getIgnoredPlayers().contains(targetUUID)) { chatUser.addIgnoredPlayers(targetUUID); } + break; } case "unignore": { ChatUser chatUser = ChatUserManager.getChatUser(UUID.fromString(in.readUTF())); chatUser.removeIgnoredPlayers(UUID.fromString(in.readUTF())); + break; } case "chatchannel": { if (ChatPlugin.getInstance().serverMuted()) break; - String chatChannel = in.readUTF(); - Component component = GsonComponentSerializer.gson().deserialize(in.readUTF()); - - new BukkitRunnable() { - @Override - public void run() { - Bukkit.getOnlinePlayers().stream() - .filter(p -> p.hasPermission("chat.channel." + chatChannel)) - .forEach(p -> p.sendMessage(component)); - } - }.runTaskAsynchronously(ChatPlugin.getInstance()); + chatChannel(in); } default: break; } } + private void chatChannel(ByteArrayDataInput in) { + Channel chatChannel = null; + Component component = null; + try { + chatChannel = Channel.getChatChannel(in.readUTF()); + component = GsonComponentSerializer.gson().deserialize(in.readUTF()); + } catch (Exception e) { //Idk the exception for reading too far into in.readUTF() + e.printStackTrace(); + } + + if (chatChannel == null) { + ALogger.warn("Received ChatChannel message for non existent channel."); + return; + } + if (!chatChannel.getServers().contains(Bukkit.getServerName())) { + ALogger.warn("Received ChatChannel message for the wrong server."); + return; + } + if (component == null) { + ALogger.warn("Didn't receive a valid message for ChatChannel " + chatChannel.getChannelName() + "."); + } + + final Channel finalChatChannel = chatChannel; + final Component finalComponent = component; + + new BukkitRunnable() { + @Override + public void run() { + Bukkit.getOnlinePlayers().stream() + .filter(p -> p.hasPermission(finalChatChannel.getPermission())) + .forEach(p -> p.sendMessage(finalComponent)); + } + }.runTaskAsynchronously(ChatPlugin.getInstance()); + } + } /* // todo implement AdvancedChatFilter for this like this // send pluginmessage to backend server and return a shatteredcomponent to be reparsed by proxy diff --git a/galaxy/src/main/resources/plugin.yml b/galaxy/src/main/resources/plugin.yml index 323dc9d..f71b05a 100755 --- a/galaxy/src/main/resources/plugin.yml +++ b/galaxy/src/main/resources/plugin.yml @@ -26,6 +26,4 @@ commands: muteserver: permission: command.mute-server spy: - permission: command.togglespy - chatchannel: - permission: chat.channel.chatchannel \ No newline at end of file + permission: command.togglespy \ No newline at end of file diff --git a/velocity/src/main/java/com/alttd/chat/listeners/PluginMessageListener.java b/velocity/src/main/java/com/alttd/chat/listeners/PluginMessageListener.java index e98cf20..014d416 100755 --- a/velocity/src/main/java/com/alttd/chat/listeners/PluginMessageListener.java +++ b/velocity/src/main/java/com/alttd/chat/listeners/PluginMessageListener.java @@ -1,14 +1,21 @@ package com.alttd.chat.listeners; import com.alttd.chat.VelocityChat; +import com.alttd.chat.objects.Channel; +import com.alttd.chat.util.ALogger; import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.messages.ChannelIdentifier; +import com.velocitypowered.api.proxy.server.RegisteredServer; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import java.util.Optional; import java.util.UUID; public class PluginMessageListener { @@ -43,8 +50,27 @@ public class PluginMessageListener { case "privatemessage": // TODO redirect this to the server that player is on VelocityChat.getPlugin().getChatHandler().privateMessage(in.readUTF(), in.readUTF(), in.readUTF()); break; + case "chatchannel": { + String channelName = in.readUTF(); + Channel chatChannel = Channel.getChatChannel(channelName); + + if (chatChannel == null) { + ALogger.warn("Received non existent channel" + channelName +"."); + break; + } + + ProxyServer proxy = VelocityChat.getPlugin().getProxy(); + chatChannel.getServers().forEach(server -> proxy.getServer(server).ifPresent(registeredServer -> + registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData()))); + break; + } default: VelocityChat.getPlugin().getLogger().info("server " + event.getSource()); + ProxyServer proxy = VelocityChat.getPlugin().getProxy(); + + for (RegisteredServer registeredServer : proxy.getAllServers()) { + registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData()); + } break; } }