From 7fa26f9a64a34d0723cbaefa1fad18e7b8d01467 Mon Sep 17 00:00:00 2001 From: Taah Date: Tue, 2 Aug 2022 17:03:04 -0700 Subject: [PATCH] add admin chat redis support --- server/src/main/java/dev/plex/Plex.java | 4 ++ .../dev/plex/command/impl/AdminChatCMD.java | 38 ++++------ .../dev/plex/listener/impl/ChatListener.java | 11 ++- .../plex/listener/impl/CommandListener.java | 1 - .../main/java/dev/plex/player/PlexPlayer.java | 1 + .../java/dev/plex/storage/SQLConnection.java | 8 ++- .../main/java/dev/plex/util/PlexUtils.java | 40 ++++++++++- .../java/dev/plex/util/redis/MessageUtil.java | 72 +++++++++++++++++++ server/src/main/resources/messages.yml | 2 + 9 files changed, 149 insertions(+), 28 deletions(-) create mode 100644 server/src/main/java/dev/plex/util/redis/MessageUtil.java diff --git a/server/src/main/java/dev/plex/Plex.java b/server/src/main/java/dev/plex/Plex.java index 2828211..3c97665 100644 --- a/server/src/main/java/dev/plex/Plex.java +++ b/server/src/main/java/dev/plex/Plex.java @@ -26,6 +26,7 @@ import dev.plex.util.BungeeUtil; import dev.plex.util.PlexLog; import dev.plex.util.PlexUtils; import dev.plex.util.UpdateChecker; +import dev.plex.util.redis.MessageUtil; import dev.plex.world.CustomWorld; import java.io.File; import lombok.Getter; @@ -36,6 +37,7 @@ import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; +import redis.clients.jedis.Jedis; @Getter @Setter @@ -159,6 +161,8 @@ public class Plex extends JavaPlugin { redisConnection.getJedis(); PlexLog.log("Connected to Redis!"); + MessageUtil.subscribe(); + } else { diff --git a/server/src/main/java/dev/plex/command/impl/AdminChatCMD.java b/server/src/main/java/dev/plex/command/impl/AdminChatCMD.java index 3d03fa1..03dbac8 100644 --- a/server/src/main/java/dev/plex/command/impl/AdminChatCMD.java +++ b/server/src/main/java/dev/plex/command/impl/AdminChatCMD.java @@ -1,5 +1,6 @@ package dev.plex.command.impl; +import dev.plex.cache.DataUtils; import dev.plex.command.PlexCommand; import dev.plex.command.annotation.CommandParameters; import dev.plex.command.annotation.CommandPermissions; @@ -7,7 +8,10 @@ import dev.plex.command.source.RequiredCommandSource; import dev.plex.player.PlexPlayer; import dev.plex.rank.enums.Rank; import dev.plex.util.PlexUtils; +import dev.plex.util.minimessage.SafeMiniMessage; +import dev.plex.util.redis.MessageUtil; import net.kyori.adventure.text.Component; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; @@ -15,6 +19,8 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.UUID; + @CommandPermissions(level = Rank.ADMIN, permission = "plex.adminchat", source = RequiredCommandSource.ANY) @CommandParameters(name = "adminchat", description = "Talk privately with other admins", usage = "/ ", aliases = "o,ac,sc,staffchat") public class AdminChatCMD extends PlexCommand @@ -24,33 +30,17 @@ public class AdminChatCMD extends PlexCommand { if (args.length == 0) { + if (playerSender != null) { + PlexPlayer player = DataUtils.getPlayer(playerSender.getUniqueId()); + player.setStaffChat(!player.isStaffChat()); + return messageComponent("adminChatToggled", BooleanUtils.toStringOnOff(player.isStaffChat())); + } return usage(); } - adminChat(sender, StringUtils.join(args, " ")); + String message = StringUtils.join(args, " "); + plugin.getServer().getConsoleSender().sendMessage(messageComponent("adminChatFormat", sender.getName(), message)); + MessageUtil.sendStaffChat(sender, SafeMiniMessage.mmDeserialize(message), PlexUtils.adminChat(sender.getName(), message).toArray(UUID[]::new)); return null; } - - private void adminChat(CommandSender sender, String message) - { - for (Player player : Bukkit.getOnlinePlayers()) - { - if (plugin.getSystem().equalsIgnoreCase("ranks")) - { - PlexPlayer plexPlayer = plugin.getPlayerCache().getPlexPlayerMap().get(player.getUniqueId()); - if (plexPlayer.getRankFromString().isAtLeast(Rank.ADMIN) && plexPlayer.isAdminActive()) - { - player.sendMessage(PlexUtils.messageComponent("adminChatFormat", sender.getName(), message)); - } - } - else if (plugin.getSystem().equalsIgnoreCase("permissions")) - { - if (player.hasPermission("plex.adminchat")) - { - player.sendMessage(PlexUtils.messageComponent("adminChatFormat", sender.getName(), message)); - } - } - } - plugin.getServer().getConsoleSender().sendMessage(PlexUtils.messageComponent("adminChatFormat", sender.getName(), message)); - } } diff --git a/server/src/main/java/dev/plex/listener/impl/ChatListener.java b/server/src/main/java/dev/plex/listener/impl/ChatListener.java index 15d2ef7..3e4272c 100644 --- a/server/src/main/java/dev/plex/listener/impl/ChatListener.java +++ b/server/src/main/java/dev/plex/listener/impl/ChatListener.java @@ -5,8 +5,11 @@ import dev.plex.listener.annotation.Toggleable; import dev.plex.player.PlexPlayer; import dev.plex.util.PlexUtils; import dev.plex.util.minimessage.SafeMiniMessage; +import dev.plex.util.redis.MessageUtil; import io.papermc.paper.chat.ChatRenderer; import io.papermc.paper.event.player.AsyncChatEvent; + +import java.util.UUID; import java.util.function.Supplier; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; @@ -21,7 +24,7 @@ import org.jetbrains.annotations.NotNull; public class ChatListener extends PlexListener { - private final static TextReplacementConfig URL_REPLACEMENT_CONFIG = TextReplacementConfig + public static final TextReplacementConfig URL_REPLACEMENT_CONFIG = TextReplacementConfig .builder() .match("(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]") .replacement((matchResult, builder) -> Component.empty() @@ -35,6 +38,12 @@ public class ChatListener extends PlexListener public void onChat(AsyncChatEvent event) { PlexPlayer plexPlayer = plugin.getPlayerCache().getPlexPlayerMap().get(event.getPlayer().getUniqueId()); + if (plexPlayer.isStaffChat()) { + MessageUtil.sendStaffChat(event.getPlayer(), event.message(), PlexUtils.adminChat(event.getPlayer().getName(), SafeMiniMessage.mmSerialize(event.message())).toArray(UUID[]::new)); + plugin.getServer().getConsoleSender().sendMessage(PlexUtils.messageComponent("adminChatFormat", event.getPlayer().getName(), SafeMiniMessage.mmSerialize(event.message())).replaceText(URL_REPLACEMENT_CONFIG)); + event.setCancelled(true); + return; + } Component prefix = plugin.getRankManager().getPrefix(plexPlayer); if (prefix != null) diff --git a/server/src/main/java/dev/plex/listener/impl/CommandListener.java b/server/src/main/java/dev/plex/listener/impl/CommandListener.java index b23bef3..0d3e91a 100644 --- a/server/src/main/java/dev/plex/listener/impl/CommandListener.java +++ b/server/src/main/java/dev/plex/listener/impl/CommandListener.java @@ -29,7 +29,6 @@ public class CommandListener extends PlexListener return player.isCommandSpy() && hasCommandSpy(plugin.getPlayerCache().getPlexPlayer(pl.getUniqueId())); }).forEach(pl -> { - System.out.println("Sending to " + pl.getUniqueId()); Player player = event.getPlayer(); String command = event.getMessage(); if (!pl.getUniqueId().equals(player.getUniqueId())) diff --git a/server/src/main/java/dev/plex/player/PlexPlayer.java b/server/src/main/java/dev/plex/player/PlexPlayer.java index 79d0276..880bc67 100644 --- a/server/src/main/java/dev/plex/player/PlexPlayer.java +++ b/server/src/main/java/dev/plex/player/PlexPlayer.java @@ -45,6 +45,7 @@ public class PlexPlayer private String loginMessage; private String prefix; + private boolean staffChat; private boolean vanished; private boolean commandSpy; diff --git a/server/src/main/java/dev/plex/storage/SQLConnection.java b/server/src/main/java/dev/plex/storage/SQLConnection.java index 8745a59..2b282ad 100644 --- a/server/src/main/java/dev/plex/storage/SQLConnection.java +++ b/server/src/main/java/dev/plex/storage/SQLConnection.java @@ -67,7 +67,8 @@ public class SQLConnection implements PlexBase "`login_msg` VARCHAR(2000), " + "`prefix` VARCHAR(2000), " + "`rank` VARCHAR(20), " + - "`adminActive` BOOLEAN," + + "`adminActive` BOOLEAN, " + + "`staffChat` BOOLEAN, " + "`ips` VARCHAR(2000), " + "`coins` BIGINT, " + "`vanished` BOOLEAN, " + @@ -96,6 +97,11 @@ public class SQLConnection implements PlexBase "`permission` VARCHAR(1000) NOT NULL," + "`allowed` BOOLEAN" + ");").execute(); + // Plex 1.2 + + try { + con.prepareStatement("ALTER TABLE `players` ADD COLUMN `staffChat` BOOLEAN DEFAULT false;").execute(); + } catch (SQLException ignored) {} } catch (SQLException throwables) { diff --git a/server/src/main/java/dev/plex/util/PlexUtils.java b/server/src/main/java/dev/plex/util/PlexUtils.java index 9b7cc8a..88b913e 100644 --- a/server/src/main/java/dev/plex/util/PlexUtils.java +++ b/server/src/main/java/dev/plex/util/PlexUtils.java @@ -1,9 +1,14 @@ package dev.plex.util; import com.google.common.base.CharMatcher; +import com.google.common.collect.Lists; import dev.plex.Plex; import dev.plex.PlexBase; +import dev.plex.listener.impl.ChatListener; +import dev.plex.player.PlexPlayer; +import dev.plex.rank.enums.Rank; import dev.plex.storage.StorageType; + import java.sql.Connection; import java.sql.SQLException; import java.time.Month; @@ -11,7 +16,9 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Arrays; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; + import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -21,6 +28,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommandYamlParser; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -180,7 +188,7 @@ public class PlexUtils implements PlexBase { try { - return ((TextComponent)component).content(); + return ((TextComponent) component).content(); } catch (Exception e) { @@ -232,6 +240,36 @@ public class PlexUtils implements PlexBase }); } + public static List adminChat(String senderName, String message, UUID... ignore) + { + List sent = Lists.newArrayList(); + for (Player player : Bukkit.getOnlinePlayers()) + { + if (Arrays.stream(ignore).anyMatch(uuid -> player.getUniqueId().equals(uuid))) + { + continue; + } + if (plugin.getSystem().equalsIgnoreCase("ranks")) + { + PlexPlayer plexPlayer = plugin.getPlayerCache().getPlexPlayerMap().get(player.getUniqueId()); + if (plexPlayer.getRankFromString().isAtLeast(Rank.ADMIN) && plexPlayer.isAdminActive()) + { + player.sendMessage(messageComponent("adminChatFormat", senderName, message).replaceText(ChatListener.URL_REPLACEMENT_CONFIG)); + sent.add(player.getUniqueId()); + } + } + else if (plugin.getSystem().equalsIgnoreCase("permissions")) + { + if (player.hasPermission("plex.adminchat")) + { + player.sendMessage(PlexUtils.messageComponent("adminChatFormat", senderName, message).replaceText(ChatListener.URL_REPLACEMENT_CONFIG)); + sent.add(player.getUniqueId()); + } + } + } + return sent; + } + public static String cleanString(String input) { return CharMatcher.ascii().retainFrom(input); diff --git a/server/src/main/java/dev/plex/util/redis/MessageUtil.java b/server/src/main/java/dev/plex/util/redis/MessageUtil.java new file mode 100644 index 0000000..7e6204b --- /dev/null +++ b/server/src/main/java/dev/plex/util/redis/MessageUtil.java @@ -0,0 +1,72 @@ +package dev.plex.util.redis; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import dev.plex.Plex; +import dev.plex.util.PlexLog; +import dev.plex.util.PlexUtils; +import dev.plex.util.minimessage.SafeMiniMessage; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.json.JSONException; +import org.json.JSONObject; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPubSub; + +import java.util.UUID; + +import static dev.plex.util.PlexUtils.messageComponent; + +public class MessageUtil { + private static final Gson GSON = new Gson(); + private static JedisPubSub SUBSCRIBER; + + public static void subscribe() { + PlexLog.debug("Subscribing"); + SUBSCRIBER = new JedisPubSub() { + @Override + public void onMessage(String channel, String message) { + try { + JSONObject object = new JSONObject(message); + if (channel.equalsIgnoreCase("staffchat")) { + UUID[] ignore = GSON.fromJson(object.getString("ignore"), new TypeToken(){}.getType()); + String sender = object.getString("sender").isEmpty() ? "CONSOLE": object.getString("sender"); + PlexUtils.adminChat(sender, object.getString("message"), ignore); + String[] server = object.getString("server").split(":"); + if (!Bukkit.getServer().getIp().equalsIgnoreCase(server[0]) || Bukkit.getServer().getPort() != Integer.parseInt(server[1])) { + Plex.get().getServer().getConsoleSender().sendMessage(messageComponent("adminChatFormat", sender, object.getString("message"))); + } + } + } catch (JSONException ignored) { + + } + } + + @Override + public void onSubscribe(String channel, int subscribedChannels) + { + PlexLog.debug("Subscribed to {0}", channel); + } + }; +// SUBSCRIBER.subscribe("staffchat", "chat"); + Plex.get().getRedisConnection().runAsync(jedis -> { + jedis.subscribe(SUBSCRIBER, "staffchat", "chat"); + }); + } + + public static void sendStaffChat(CommandSender sender, Component message, UUID... ignore) { + if (!Plex.get().getRedisConnection().isEnabled() || Plex.get().getRedisConnection().getJedis() == null) { + return; + } + + String miniMessage = SafeMiniMessage.mmSerialize(message); + JSONObject object = new JSONObject(); + object.put("sender", sender instanceof Player player ? player.getName() : ""); + object.put("message", miniMessage); + object.put("ignore", GSON.toJson(ignore)); + object.put("server", String.format("%s:%s", Bukkit.getServer().getIp(), Bukkit.getServer().getPort())); + Plex.get().getRedisConnection().getJedis().publish("staffchat", object.toString()); + } +} diff --git a/server/src/main/resources/messages.yml b/server/src/main/resources/messages.yml index bbc1c26..eac56a4 100644 --- a/server/src/main/resources/messages.yml +++ b/server/src/main/resources/messages.yml @@ -124,6 +124,8 @@ disabled: "disabled." # 0 - The admin / staff member # 1 - The message adminChatFormat: '[AdminChat] {0} ยป {1}' +# 0 - Whether it was toggled on or off +adminChatToggled: 'AdminChat was toggled {0}' # 0 - Maximum length, configured in config.yml maximumPrefixLength: "The maximum length for a tag may only be {0}." prefixCleared: "Your prefix has been cleared."