From 32c96c0cf5edd969989d98850477e152d63e76a9 Mon Sep 17 00:00:00 2001 From: Ilya Andreev Date: Sun, 7 Jul 2024 16:04:45 +0300 Subject: [PATCH] Add /spy command --- .../main/java/ru/brikster/chatty/Chatty.java | 25 +++++++++++-- .../stage/early/SpyModeStrategy.java | 3 +- .../command/handler/SpyCommandHandler.java | 37 +++++++++++++++++++ .../chatty/config/file/MessagesConfig.java | 2 + .../pm/PrivateMessageCommandHandler.java | 1 + .../chatty/proxy/ProxyServiceImpl.java | 3 ++ .../player/MysqlPlayerDataRepository.java | 29 +++++++++++++++ .../player/PlayerDataRepository.java | 4 ++ .../player/PostgresPlayerDataRepository.java | 29 +++++++++++++++ .../player/SqlitePlayerDataRepository.java | 29 +++++++++++++++ .../mysql/V2__add_spy_mode_column.sql | 2 + .../postgres/V2__add_spy_mode_column.sql | 2 + .../sqlite/V2__add_spy_mode_column.sql | 2 + 13 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 spigot/src/main/java/ru/brikster/chatty/command/handler/SpyCommandHandler.java create mode 100644 spigot/src/main/resources/db/migration/mysql/V2__add_spy_mode_column.sql create mode 100644 spigot/src/main/resources/db/migration/postgres/V2__add_spy_mode_column.sql create mode 100644 spigot/src/main/resources/db/migration/sqlite/V2__add_spy_mode_column.sql diff --git a/spigot/src/main/java/ru/brikster/chatty/Chatty.java b/spigot/src/main/java/ru/brikster/chatty/Chatty.java index 9ef4a00..1df91f1 100644 --- a/spigot/src/main/java/ru/brikster/chatty/Chatty.java +++ b/spigot/src/main/java/ru/brikster/chatty/Chatty.java @@ -5,6 +5,7 @@ import cloud.commandframework.CommandManager.ManagerSettings; import cloud.commandframework.CommandTree.Node; import cloud.commandframework.arguments.CommandArgument; +import cloud.commandframework.arguments.standard.BooleanArgument; import cloud.commandframework.arguments.standard.StringArgument; import cloud.commandframework.bukkit.BukkitCommandManager; import cloud.commandframework.exceptions.ArgumentParseException; @@ -23,6 +24,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; @@ -38,6 +40,7 @@ import ru.brikster.chatty.command.ProxyingCommandHandler; import ru.brikster.chatty.command.ProxyingCommandSuggestionsProvider; import ru.brikster.chatty.command.handler.ClearChatCommandHandler; +import ru.brikster.chatty.command.handler.SpyCommandHandler; import ru.brikster.chatty.config.file.MessagesConfig; import ru.brikster.chatty.config.file.PmConfig; import ru.brikster.chatty.config.file.SettingsConfig; @@ -203,13 +206,16 @@ private void initialize() throws Exception { ClearChatCommandHandler clearChatCommandHandler = injector.getInstance(ClearChatCommandHandler.class); registerProxyingHandler("clearchat", clearChatCommandHandler); + SpyCommandHandler spyCommandHandler = injector.getInstance(SpyCommandHandler.class); + registerProxyingHandler("spy", spyCommandHandler); + if (this.asyncCommandManager == null) { initAsyncCommandManager(); if (pmConfig.isEnable()) { registerPmCommands(commandSuggestionsProvider); } registerIgnoreCommand(commandSuggestionsProvider); - registerClearChatCommand(); + registerMiscCommands(); } ChattyApiImpl.updateInstance(new ChattyApiImpl(injector.getInstance(ChatRegistry.class).getChats())); @@ -265,13 +271,24 @@ private void initAsyncCommandManager() throws Exception { asyncCommandManager.setSetting(ManagerSettings.ALLOW_UNSAFE_REGISTRATION, true); } - private void registerClearChatCommand() { - var command = asyncCommandManager + private void registerMiscCommands() { + var clearChatCommand = asyncCommandManager .commandBuilder("clearchat") .permission("chatty.command.clearchat") .handler(proxyingCommandHandlerMap.get("clearchat")) .build(); - asyncCommandManager.command(command); + asyncCommandManager.command(clearChatCommand); + + var spyCommand = asyncCommandManager + .commandBuilder("spy") + .senderType(Player.class) + .permission("chatty.command.spy") + .argument(BooleanArgument.builder("state") + .withLiberal(true) + .build()) + .handler(proxyingCommandHandlerMap.get("spy")) + .build(); + asyncCommandManager.command(spyCommand); } private void registerIgnoreCommand(CommandSuggestionsProvider pmSuggestionsProvider) { diff --git a/spigot/src/main/java/ru/brikster/chatty/chat/message/transform/stage/early/SpyModeStrategy.java b/spigot/src/main/java/ru/brikster/chatty/chat/message/transform/stage/early/SpyModeStrategy.java index 96bec8a..7ff1cf2 100644 --- a/spigot/src/main/java/ru/brikster/chatty/chat/message/transform/stage/early/SpyModeStrategy.java +++ b/spigot/src/main/java/ru/brikster/chatty/chat/message/transform/stage/early/SpyModeStrategy.java @@ -31,7 +31,8 @@ public final class SpyModeStrategy implements MessageTransformStrategy { if (context.getChat().isEnableSpy()) { for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { if (onlinePlayer.hasPermission("chatty.spy." + context.getChat().getId()) - && !recipients.contains(onlinePlayer)) { + && repository.isEnableSpy(onlinePlayer.getUniqueId()) + && !recipients.contains(onlinePlayer)) { recipients.add(onlinePlayer); spies.add(onlinePlayer); } diff --git a/spigot/src/main/java/ru/brikster/chatty/command/handler/SpyCommandHandler.java b/spigot/src/main/java/ru/brikster/chatty/command/handler/SpyCommandHandler.java new file mode 100644 index 0000000..1a23ccf --- /dev/null +++ b/spigot/src/main/java/ru/brikster/chatty/command/handler/SpyCommandHandler.java @@ -0,0 +1,37 @@ +package ru.brikster.chatty.command.handler; + +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.execution.CommandExecutionHandler; +import lombok.RequiredArgsConstructor; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.checkerframework.checker.nullness.qual.NonNull; +import ru.brikster.chatty.config.file.MessagesConfig; +import ru.brikster.chatty.repository.player.PlayerDataRepository; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +@RequiredArgsConstructor(onConstructor_ = {@Inject}) +public final class SpyCommandHandler implements CommandExecutionHandler { + + private final PlayerDataRepository playerDataRepository; + private final MessagesConfig messagesConfig; + private final BukkitAudiences audiences; + + @Override + public void execute(@NonNull CommandContext commandContext) { + boolean state = commandContext.get("state"); + playerDataRepository.setEnableSpy(((Player) commandContext.getSender()).getUniqueId(), state); + if (state) { + audiences.sender(commandContext.getSender()) + .sendMessage(messagesConfig.getSpyCommandSpyIsNowEnabled()); + } else { + audiences.sender(commandContext.getSender()) + .sendMessage(messagesConfig.getSpyCommandSpyIsNowDisabled()); + } + } + +} diff --git a/spigot/src/main/java/ru/brikster/chatty/config/file/MessagesConfig.java b/spigot/src/main/java/ru/brikster/chatty/config/file/MessagesConfig.java index 43dfc68..9cb2014 100644 --- a/spigot/src/main/java/ru/brikster/chatty/config/file/MessagesConfig.java +++ b/spigot/src/main/java/ru/brikster/chatty/config/file/MessagesConfig.java @@ -54,5 +54,7 @@ public class MessagesConfig extends OkaeriConfig { private Component reloadCommandSuccess = MINI_MESSAGE.deserialize("Plugin successfully reloaded!"); private Component clearchatCommandSuccess = MINI_MESSAGE.deserialize("Chat cleared."); + private Component spyCommandSpyIsNowEnabled = MINI_MESSAGE.deserialize("Spy mode is now enabled."); + private Component spyCommandSpyIsNowDisabled = MINI_MESSAGE.deserialize("Spy mode is now disabled."); } diff --git a/spigot/src/main/java/ru/brikster/chatty/pm/PrivateMessageCommandHandler.java b/spigot/src/main/java/ru/brikster/chatty/pm/PrivateMessageCommandHandler.java index 9938997..64b5489 100644 --- a/spigot/src/main/java/ru/brikster/chatty/pm/PrivateMessageCommandHandler.java +++ b/spigot/src/main/java/ru/brikster/chatty/pm/PrivateMessageCommandHandler.java @@ -62,6 +62,7 @@ public void handleCommand(@NotNull CommandContext<@NotNull CommandSender> comman sender, target, message); audiences.filter(spyCandidate -> spyCandidate.hasPermission("chatty.spy.pm") && !(spyCandidate instanceof ConsoleCommandSender) + && playerDataRepository.isEnableSpy(((Player) spyCandidate).getUniqueId()) && spyCandidate != sender && (!target.isOnline() || spyCandidate != target.asCommandSender())) .sendMessage(spyComponentFormat); diff --git a/spigot/src/main/java/ru/brikster/chatty/proxy/ProxyServiceImpl.java b/spigot/src/main/java/ru/brikster/chatty/proxy/ProxyServiceImpl.java index 9bc25d8..8015e5e 100644 --- a/spigot/src/main/java/ru/brikster/chatty/proxy/ProxyServiceImpl.java +++ b/spigot/src/main/java/ru/brikster/chatty/proxy/ProxyServiceImpl.java @@ -24,6 +24,7 @@ import ru.brikster.chatty.proxy.data.ChatMessage; import ru.brikster.chatty.proxy.data.PrivateMessage; import ru.brikster.chatty.proxy.data.ProxyPlayer; +import ru.brikster.chatty.repository.player.PlayerDataRepository; import javax.inject.Inject; import javax.inject.Singleton; @@ -55,6 +56,7 @@ public ProxyServiceImpl(Config redissonConfig, ChatRegistry chatRegistry, PmConfig pmConfig, ChatStylePlayerGrouper stylePlayerGrouper, + PlayerDataRepository playerDataRepository, Plugin plugin) { RedissonClient redissonClient = Redisson.create(redissonConfig); this.playersCache = redissonClient.getMapCache("chatty_players"); @@ -115,6 +117,7 @@ public ProxyServiceImpl(Config redissonConfig, audiences.filter(spyCandidate -> spyCandidate.hasPermission("chatty.spy.pm") && !(spyCandidate instanceof ConsoleCommandSender) + && playerDataRepository.isEnableSpy(((Player) spyCandidate).getUniqueId()) && !spyCandidate.getName().equalsIgnoreCase(redisMessage.getTargetName())) .sendMessage(spyMessage); } diff --git a/spigot/src/main/java/ru/brikster/chatty/repository/player/MysqlPlayerDataRepository.java b/spigot/src/main/java/ru/brikster/chatty/repository/player/MysqlPlayerDataRepository.java index 1621288..89d4206 100644 --- a/spigot/src/main/java/ru/brikster/chatty/repository/player/MysqlPlayerDataRepository.java +++ b/spigot/src/main/java/ru/brikster/chatty/repository/player/MysqlPlayerDataRepository.java @@ -207,6 +207,35 @@ public boolean isIgnoredPlayer(@NotNull UUID playerUuid, @NotNull UUID uuid) { } } + @Override + public boolean isEnableSpy(@NotNull UUID playerUuid) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement( + "SELECT spy " + + "FROM chatty_users " + + "WHERE uuid = ?")) { + statement.setString(1, playerUuid.toString()); + + ResultSet resultSet = statement.executeQuery(); + return resultSet.getBoolean("spy"); + } catch (SQLException sqlException) { + throw new IllegalStateException("Cannot check player spy mode", sqlException); + } + } + + @Override + public void setEnableSpy(@NotNull UUID playerUuid, boolean spy) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement( + "UPDATE chatty_users SET spy = ? WHERE uuid = ?")) { + statement.setBoolean(1, spy); + statement.setString(2, playerUuid.toString()); + statement.executeUpdate(); + } catch (SQLException sqlException) { + throw new IllegalStateException("Cannot update player spy mode", sqlException); + } + } + @Override public void close() { dataSource.close(); diff --git a/spigot/src/main/java/ru/brikster/chatty/repository/player/PlayerDataRepository.java b/spigot/src/main/java/ru/brikster/chatty/repository/player/PlayerDataRepository.java index c28c5b1..eb59123 100644 --- a/spigot/src/main/java/ru/brikster/chatty/repository/player/PlayerDataRepository.java +++ b/spigot/src/main/java/ru/brikster/chatty/repository/player/PlayerDataRepository.java @@ -28,4 +28,8 @@ public interface PlayerDataRepository extends Closeable { boolean isIgnoredPlayer(@NotNull UUID playerUuid, @NotNull UUID uuid); + boolean isEnableSpy(@NotNull UUID playerUuid); + + void setEnableSpy(@NotNull UUID playerUuid, boolean spy); + } diff --git a/spigot/src/main/java/ru/brikster/chatty/repository/player/PostgresPlayerDataRepository.java b/spigot/src/main/java/ru/brikster/chatty/repository/player/PostgresPlayerDataRepository.java index d2c6101..180c45a 100644 --- a/spigot/src/main/java/ru/brikster/chatty/repository/player/PostgresPlayerDataRepository.java +++ b/spigot/src/main/java/ru/brikster/chatty/repository/player/PostgresPlayerDataRepository.java @@ -208,6 +208,35 @@ public boolean isIgnoredPlayer(@NotNull UUID playerUuid, @NotNull UUID uuid) { } } + @Override + public boolean isEnableSpy(@NotNull UUID playerUuid) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement( + "SELECT spy " + + "FROM chatty_users " + + "WHERE uuid = ?")) { + statement.setString(1, playerUuid.toString()); + + ResultSet resultSet = statement.executeQuery(); + return resultSet.getBoolean("spy"); + } catch (SQLException sqlException) { + throw new IllegalStateException("Cannot check player spy mode", sqlException); + } + } + + @Override + public void setEnableSpy(@NotNull UUID playerUuid, boolean spy) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement( + "UPDATE chatty_users SET spy = ? WHERE uuid = ?")) { + statement.setBoolean(1, spy); + statement.setString(2, playerUuid.toString()); + statement.executeUpdate(); + } catch (SQLException sqlException) { + throw new IllegalStateException("Cannot update player spy mode", sqlException); + } + } + @Override public void close() { dataSource.close(); diff --git a/spigot/src/main/java/ru/brikster/chatty/repository/player/SqlitePlayerDataRepository.java b/spigot/src/main/java/ru/brikster/chatty/repository/player/SqlitePlayerDataRepository.java index 5ee2988..c9c1e06 100644 --- a/spigot/src/main/java/ru/brikster/chatty/repository/player/SqlitePlayerDataRepository.java +++ b/spigot/src/main/java/ru/brikster/chatty/repository/player/SqlitePlayerDataRepository.java @@ -211,6 +211,35 @@ public boolean isIgnoredPlayer(@NotNull UUID playerUuid, @NotNull UUID uuid) { } } + @Override + public boolean isEnableSpy(@NotNull UUID playerUuid) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement( + "SELECT spy " + + "FROM users " + + "WHERE uuid = ?")) { + statement.setBytes(1, SqliteUtil.fromUUID(playerUuid)); + + ResultSet resultSet = statement.executeQuery(); + return resultSet.getBoolean("spy"); + } catch (SQLException sqlException) { + throw new IllegalStateException("Cannot check player spy mode", sqlException); + } + } + + @Override + public void setEnableSpy(@NotNull UUID playerUuid, boolean spy) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement( + "UPDATE users SET spy = ? WHERE uuid = ?")) { + statement.setBoolean(1, spy); + statement.setBytes(2, SqliteUtil.fromUUID(playerUuid)); + statement.executeUpdate(); + } catch (SQLException sqlException) { + throw new IllegalStateException("Cannot update player spy mode", sqlException); + } + } + @Override public void close() { dataSource.close(); diff --git a/spigot/src/main/resources/db/migration/mysql/V2__add_spy_mode_column.sql b/spigot/src/main/resources/db/migration/mysql/V2__add_spy_mode_column.sql new file mode 100644 index 0000000..c9ef55e --- /dev/null +++ b/spigot/src/main/resources/db/migration/mysql/V2__add_spy_mode_column.sql @@ -0,0 +1,2 @@ +ALTER TABLE chatty_users + ADD COLUMN spy BOOLEAN NOT NULL DEFAULT TRUE; \ No newline at end of file diff --git a/spigot/src/main/resources/db/migration/postgres/V2__add_spy_mode_column.sql b/spigot/src/main/resources/db/migration/postgres/V2__add_spy_mode_column.sql new file mode 100644 index 0000000..c9ef55e --- /dev/null +++ b/spigot/src/main/resources/db/migration/postgres/V2__add_spy_mode_column.sql @@ -0,0 +1,2 @@ +ALTER TABLE chatty_users + ADD COLUMN spy BOOLEAN NOT NULL DEFAULT TRUE; \ No newline at end of file diff --git a/spigot/src/main/resources/db/migration/sqlite/V2__add_spy_mode_column.sql b/spigot/src/main/resources/db/migration/sqlite/V2__add_spy_mode_column.sql new file mode 100644 index 0000000..298e0db --- /dev/null +++ b/spigot/src/main/resources/db/migration/sqlite/V2__add_spy_mode_column.sql @@ -0,0 +1,2 @@ +ALTER TABLE users + ADD COLUMN spy BOOLEAN NOT NULL DEFAULT TRUE; \ No newline at end of file