From 22f42df1dae0d1e58c3655391a90f8e9dec719e4 Mon Sep 17 00:00:00 2001 From: Shiewk Date: Sun, 4 Aug 2024 14:47:29 +0200 Subject: [PATCH 1/5] Fixed a bug where unknown players would crash the SMod menu --- .../de/shiewk/smoderation/inventory/SModMenu.java | 12 ++++++++++-- .../java/de/shiewk/smoderation/util/PlayerUtil.java | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/shiewk/smoderation/inventory/SModMenu.java b/src/main/java/de/shiewk/smoderation/inventory/SModMenu.java index c2bb440..d5049aa 100644 --- a/src/main/java/de/shiewk/smoderation/inventory/SModMenu.java +++ b/src/main/java/de/shiewk/smoderation/inventory/SModMenu.java @@ -102,7 +102,11 @@ public class SModMenu extends PageableCustomInventory { } private void reload(){ - this.punishments = container.copy().stream().filter(getFilter().filter).filter(p -> getType() == null || p.type == getType()).filter(p -> p.matchesSearchQuery(searchQuery)).sorted(getSort().comparator).toList(); + this.punishments = container.copy().stream() + .filter(getFilter().filter) + .filter(p -> getType() == null || p.type == getType()) + .filter(p -> p.matchesSearchQuery(searchQuery)) + .sorted(getSort().comparator).toList(); } public void promptSearchQuery(){ @@ -269,7 +273,11 @@ public class SModMenu extends PageableCustomInventory { ItemStack stack = new ItemStack(Material.PLAYER_HEAD); stack.editMeta(meta -> { if (meta instanceof SkullMeta skullMeta){ - skullMeta.setOwningPlayer(Bukkit.getOfflinePlayer(punishment.to)); + try { + skullMeta.setOwningPlayer(Bukkit.getOfflinePlayer(punishment.to)); + } catch (NullPointerException e) { + LOGGER.warn("Player {} has a punishment but was never on this server!", punishment.to); + }; } meta.displayName(applyFormatting(text(punishment.type.name).color(NamedTextColor.RED).decorate(TextDecoration.BOLD))); ArrayList lore = new ArrayList<>(); diff --git a/src/main/java/de/shiewk/smoderation/util/PlayerUtil.java b/src/main/java/de/shiewk/smoderation/util/PlayerUtil.java index afc6fc5..2d0f157 100644 --- a/src/main/java/de/shiewk/smoderation/util/PlayerUtil.java +++ b/src/main/java/de/shiewk/smoderation/util/PlayerUtil.java @@ -25,7 +25,7 @@ public abstract class PlayerUtil { return "CONSOLE"; } OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); - return player.getName() == null ? uuid.toString() : player.getName(); + return player.getName() == null ? "Unknown Player" + uuid : player.getName(); } public static @Nullable UUID offlinePlayerUUIDByName(String name){ From a7c487decda41013d1bad4534d3c8977007ee94e Mon Sep 17 00:00:00 2001 From: Shiewk Date: Sun, 4 Aug 2024 14:48:51 +0200 Subject: [PATCH 2/5] Update to version 1.3.1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 52a421b..11ffe3f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -pluginVersion = 1.3.0 \ No newline at end of file +pluginVersion = 1.3.1 \ No newline at end of file From 8de4382ec490b98f9fbbf340752fb31f9614670d Mon Sep 17 00:00:00 2001 From: Shiewk Date: Wed, 21 Aug 2024 18:32:01 +0200 Subject: [PATCH 3/5] SocialSpy command and permissions --- docs/commands.md | 31 +++--- docs/permissions.md | 1 + .../de/shiewk/smoderation/SModeration.java | 5 + .../smoderation/command/SocialSpyCommand.java | 32 +++++++ .../smoderation/config/SModerationConfig.java | 30 ++++++ .../listener/SocialSpyListener.java | 94 +++++++++++++++++++ src/main/resources/plugin.yml | 17 +++- 7 files changed, 194 insertions(+), 16 deletions(-) create mode 100644 src/main/java/de/shiewk/smoderation/command/SocialSpyCommand.java create mode 100644 src/main/java/de/shiewk/smoderation/config/SModerationConfig.java create mode 100644 src/main/java/de/shiewk/smoderation/listener/SocialSpyListener.java diff --git a/docs/commands.md b/docs/commands.md index 7685173..b7c886a 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -1,17 +1,18 @@ # SModeration commands -| Command | Description | Permission | -|----------------------------------------|------------------------------------------------------------------------------|---------------------| -| /smod | Opens the SMod menu. | smod.menu | -| /mute \ \ \ | Mutes a player so that they can't type in chat for the specified duration. | smod.mute | -| /ban \ \ \ | Bans a player so that they can't join the server for the specified duration. | smod.ban | -| /kick \ \ | Kicks a player from the server. | smod.kick | -| /modlogs | Lists a player's active punishments in chat. | smod.logs | -| /unmute | Clears a player's mute status. | smod.unmute | -| /unban | Clears a player's ban status. | smod.unban | -| /invsee \ inventory | Views another player's inventory. | smod.invsee | -| /invsee \ equipment | Views another player's equipment (armor and offhand). | smod.invsee | -| /enderchestsee | Views another player's ender chest. | smod.enderchestsee | -| /vanish | Toggles vanish mode so that other players can't see you're online. | smod.vanish | -| /vanish toggle \ | Toggles vanish mode for another player. | smod.vanish | -| /vanish list | Lists all vanished players. | smod.vanish.see | +| Command | Description | Permission | +|----------------------------------------|------------------------------------------------------------------------------|--------------------| +| /smod | Opens the SMod menu. | smod.menu | +| /mute \ \ \ | Mutes a player so that they can't type in chat for the specified duration. | smod.mute | +| /ban \ \ \ | Bans a player so that they can't join the server for the specified duration. | smod.ban | +| /kick \ \ | Kicks a player from the server. | smod.kick | +| /modlogs | Lists a player's active punishments in chat. | smod.logs | +| /unmute | Clears a player's mute status. | smod.unmute | +| /unban | Clears a player's ban status. | smod.unban | +| /invsee \ inventory | Views another player's inventory. | smod.invsee | +| /invsee \ equipment | Views another player's equipment (armor and offhand). | smod.invsee | +| /enderchestsee | Views another player's ender chest. | smod.enderchestsee | +| /vanish | Toggles vanish mode so that other players can't see you're online. | smod.vanish | +| /vanish toggle \ | Toggles vanish mode for another player. | smod.vanish | +| /vanish list | Lists all vanished players. | smod.vanish.see | +| /socialspy | Enables SocialSpy mode where you can see other player's private messages. | smod.socialspy | \ No newline at end of file diff --git a/docs/permissions.md b/docs/permissions.md index 0572df5..3c05088 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -19,5 +19,6 @@ | smod.enderchestsee.modify | Allows the player to view and modify other players ender chests. | | smod.vanish | Allows the player to enter and leave vanish mode. | | smod.vanish.see | Allows the player to see vanished players | +| smod.socialspy | Allows the player to enable SocialSpy | All of these permissions are granted by default if the player is a server operator. diff --git a/src/main/java/de/shiewk/smoderation/SModeration.java b/src/main/java/de/shiewk/smoderation/SModeration.java index 6bbdb7a..b2c7c07 100644 --- a/src/main/java/de/shiewk/smoderation/SModeration.java +++ b/src/main/java/de/shiewk/smoderation/SModeration.java @@ -1,6 +1,7 @@ package de.shiewk.smoderation; import de.shiewk.smoderation.command.*; +import de.shiewk.smoderation.config.SModerationConfig; import de.shiewk.smoderation.input.ChatInputListener; import de.shiewk.smoderation.listener.*; import de.shiewk.smoderation.storage.PunishmentContainer; @@ -26,6 +27,7 @@ public final class SModeration extends JavaPlugin { public static final PunishmentContainer container = new PunishmentContainer(); public static ComponentLogger LOGGER = null; public static SModeration PLUGIN = null; + public static SModerationConfig CONFIG = null; public static File SAVE_FILE = null; public static final TextColor PRIMARY_COLOR = TextColor.color(212, 0, 255); @@ -38,6 +40,7 @@ public final class SModeration extends JavaPlugin { public void onLoad() { LOGGER = getComponentLogger(); PLUGIN = this; + CONFIG = new SModerationConfig(this.getConfig(), this); SAVE_FILE = new File(this.getDataFolder().getAbsolutePath() + "/container.gz"); } @@ -49,6 +52,7 @@ public final class SModeration extends JavaPlugin { getPluginManager().registerEvents(new EnderchestSeeListener(), this); getPluginManager().registerEvents(new VanishListener(), this); getPluginManager().registerEvents(new ChatInputListener(), this); + getPluginManager().registerEvents(new SocialSpyListener(), this); registerCommand("mute", new MuteCommand()); registerCommand("ban", new BanCommand()); @@ -60,6 +64,7 @@ public final class SModeration extends JavaPlugin { registerCommand("invsee", new InvseeCommand()); registerCommand("enderchestsee", new EnderchestSeeCommand()); registerCommand("vanish", new VanishCommand()); + registerCommand("socialspy", new SocialSpyCommand()); container.load(SAVE_FILE); } diff --git a/src/main/java/de/shiewk/smoderation/command/SocialSpyCommand.java b/src/main/java/de/shiewk/smoderation/command/SocialSpyCommand.java new file mode 100644 index 0000000..bd1a677 --- /dev/null +++ b/src/main/java/de/shiewk/smoderation/command/SocialSpyCommand.java @@ -0,0 +1,32 @@ +package de.shiewk.smoderation.command; + +import de.shiewk.smoderation.listener.SocialSpyListener; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +import static de.shiewk.smoderation.SModeration.CHAT_PREFIX; +import static net.kyori.adventure.text.Component.text; + +public class SocialSpyCommand implements TabExecutor { + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + final boolean enabled = SocialSpyListener.toggle(sender); + sender.sendMessage(CHAT_PREFIX.append(text("SocialSpy ").append( + enabled ? + text("enabled").color(NamedTextColor.GREEN) : + text("disabled").color(NamedTextColor.RED) + ).append(text(".")))); + return true; + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + return List.of(); + } +} diff --git a/src/main/java/de/shiewk/smoderation/config/SModerationConfig.java b/src/main/java/de/shiewk/smoderation/config/SModerationConfig.java new file mode 100644 index 0000000..3de402b --- /dev/null +++ b/src/main/java/de/shiewk/smoderation/config/SModerationConfig.java @@ -0,0 +1,30 @@ +package de.shiewk.smoderation.config; + +import de.shiewk.smoderation.SModeration; +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.List; + +public class SModerationConfig { + + private final FileConfiguration config; + private final SModeration plugin; + + public SModerationConfig(FileConfiguration config, SModeration plugin) { + this.config = config; + this.plugin = plugin; + } + + public List getSocialSpyCommands(List default_){ + final String path = "socialspy-commands"; + if (!config.contains(path)){ + config.set(path, default_); + plugin.saveConfig(); + } + return config.getStringList(path); + } + + public FileConfiguration getConfig() { + return config; + } +} diff --git a/src/main/java/de/shiewk/smoderation/listener/SocialSpyListener.java b/src/main/java/de/shiewk/smoderation/listener/SocialSpyListener.java new file mode 100644 index 0000000..ad8329e --- /dev/null +++ b/src/main/java/de/shiewk/smoderation/listener/SocialSpyListener.java @@ -0,0 +1,94 @@ +package de.shiewk.smoderation.listener; + +import de.shiewk.smoderation.SModeration; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.bukkit.NamespacedKey; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import java.util.List; + +import static de.shiewk.smoderation.SModeration.PRIMARY_COLOR; +import static de.shiewk.smoderation.SModeration.SECONDARY_COLOR; +import static net.kyori.adventure.text.Component.text; + +public class SocialSpyListener implements Listener { + + private static final List defaultCommands = List.of( + "w", + "tell", + "msg", + "teammsg", + "tm", + "minecraft:w", + "minecraft:tell", + "minecraft:msg", + "minecraft:teammsg", + "minecraft:tm" + ); + + private static final NamespacedKey SAVE_KEY = new NamespacedKey("smoderation", "socialspy"); + private static final ObjectArrayList targets = new ObjectArrayList<>(); + + public static boolean toggle(CommandSender sender) { + boolean enabledNow = isEnabled(sender); + if (enabledNow){ + targets.remove(sender); + if (sender instanceof Player player){ + player.getPersistentDataContainer().set(SAVE_KEY, PersistentDataType.BOOLEAN, false); + } + return false; + } else { + targets.add(sender); + if (sender instanceof Player player){ + player.getPersistentDataContainer().set(SAVE_KEY, PersistentDataType.BOOLEAN, true); + } + return true; + } + } + + @EventHandler public void onPlayerJoin(PlayerJoinEvent event){ + final PersistentDataContainer pdc = event.getPlayer().getPersistentDataContainer(); + if (Boolean.TRUE.equals(pdc.get(SAVE_KEY, PersistentDataType.BOOLEAN))){ + targets.add(event.getPlayer()); + } + } + + @EventHandler public void onPlayerQuit(PlayerQuitEvent event){ + targets.remove(event.getPlayer()); + } + + public static boolean isEnabled(CommandSender sender){ + return targets.contains(sender); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) + public void onPlayerSendCommand(PlayerCommandPreprocessEvent event){ + List ssCommands = SModeration.CONFIG.getSocialSpyCommands(defaultCommands); + final String message = event.getMessage(); + if (ssCommands.stream().anyMatch(str -> + message.startsWith("/"+str+" ") + || message.startsWith(str+" ") + )){ + SocialSpyListener.command(event.getPlayer(), message); + } + } + + public static void command(Player player, String command){ + for (CommandSender target : targets) { + target.sendMessage(text("[SocialSpy] ") + .append(player.displayName().colorIfAbsent(SECONDARY_COLOR)) + .append(text(": " + command).color(SECONDARY_COLOR)) + .color(PRIMARY_COLOR)); + } + } + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index becbadc..65651c6 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -75,8 +75,20 @@ commands: usage: "§cUsage: /vanish list or /vanish toggle " aliases: - smvanish + - smodvanish + - v + - smv permission: smod.vanish description: Toggles vanish mode which prevents other players from seeing you're online + socialspy: + usage: "§cUsage: /socialspy" + description: Enables socialspy mode (you can see private messages of other players) + permission: smod.socialspy + aliases: + - smodsocialspy + - smsocialspy + - smss + - ss permissions: smod.mute: default: op @@ -137,4 +149,7 @@ permissions: description: Allows the player to use /vanish smod.vanish.see: default: op - description: Allows the player to see vanished players \ No newline at end of file + description: Allows the player to see vanished players + smod.socialspy: + default: op + description: Allows the player to enable SocialSpy \ No newline at end of file From 8c00347ef2b0205ed7df7755c0fc1d5ba17cfdd3 Mon Sep 17 00:00:00 2001 From: Shiewk Date: Wed, 21 Aug 2024 18:40:06 +0200 Subject: [PATCH 4/5] Hide death messages from vanished players --- .../smoderation/listener/VanishListener.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/de/shiewk/smoderation/listener/VanishListener.java b/src/main/java/de/shiewk/smoderation/listener/VanishListener.java index a1bf84e..fa7a596 100644 --- a/src/main/java/de/shiewk/smoderation/listener/VanishListener.java +++ b/src/main/java/de/shiewk/smoderation/listener/VanishListener.java @@ -2,14 +2,19 @@ package de.shiewk.smoderation.listener; import de.shiewk.smoderation.SModeration; import de.shiewk.smoderation.command.VanishCommand; +import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import static de.shiewk.smoderation.SModeration.SECONDARY_COLOR; +import static net.kyori.adventure.text.Component.text; + public class VanishListener implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event){ @@ -37,4 +42,17 @@ public class VanishListener implements Listener { }); } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerDeath(PlayerDeathEvent event){ + final Component message = event.deathMessage(); + if (VanishCommand.isVanished(event.getPlayer()) && message != null){ + event.deathMessage(null); + for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { + if (onlinePlayer.hasPermission("smod.vanish.see")){ + onlinePlayer.sendMessage(text("[VANISH] ").color(SECONDARY_COLOR).append(message)); + } + } + } + } + } From faa2eb0a43e1588944104c4a882101698daea880 Mon Sep 17 00:00:00 2001 From: Shiewk Date: Wed, 21 Aug 2024 18:40:56 +0200 Subject: [PATCH 5/5] 1.4.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 11ffe3f..d4d2098 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -pluginVersion = 1.3.1 \ No newline at end of file +pluginVersion = 1.4.0 \ No newline at end of file