From 020275f3785c46e0a3d29b1f9e318d08d73fc94e Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sun, 23 Jun 2024 12:41:24 -0300 Subject: [PATCH 01/14] style: match file structure with Extras --- .gitignore | 2 ++ README.md | 6 +++--- suppressions.xml | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index f845591..d3ee570 100755 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ target/ .classpath .project *.iml +.theia/ +run/ \ No newline at end of file diff --git a/README.md b/README.md index 57d3662..bb7b021 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ The plugin is created for the Kaboom server. ## Commands -| Command | Alias | Permission | Description | -| ------- | ----- | ---------- | ----------- | -|/commandspy | /c, /cs, /cspy | commandspy.command | Allows you to spy on players' commands| +| Command | Alias | Permission | Description | +|-------------|----------------|--------------------|----------------------------------------| +| /commandspy | /c, /cs, /cspy | commandspy.command | Allows you to spy on players' commands | ## Compiling diff --git a/suppressions.xml b/suppressions.xml index 8990963..30ced2c 100644 --- a/suppressions.xml +++ b/suppressions.xml @@ -5,4 +5,6 @@ - + + + \ No newline at end of file From d5c402cfc7cc9242f647b99416be938956964383 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sun, 23 Jun 2024 12:51:26 -0300 Subject: [PATCH 02/14] chore: bump used actions, checkstyle & paper --- .github/workflows/main.yml | 9 +++++---- pom.xml | 4 ++-- src/main/resources/plugin.yml | 5 ++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d5644a3..3af4259 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,14 +11,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: 17 - name: Cache maven packages to speed up build - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -27,7 +27,8 @@ jobs: - name: Build with Maven run: mvn -B package --file pom.xml - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: CommandSpy path: target/CommandSpy.jar + compression-level: 0 diff --git a/pom.xml b/pom.xml index 8c686a8..15ddd18 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ io.papermc.paper paper-api - 1.18.2-R0.1-SNAPSHOT + 1.19.4-R0.1-SNAPSHOT provided @@ -33,7 +33,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.2 + 3.4.0 checkstyle diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f95cb20..af086de 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,13 +1,12 @@ name: CommandSpy main: pw.kaboom.commandspy.Main description: Plugin that allows you to spy on players' commands. -api-version: 1.13 +api-version: '1.19' version: master folia-supported: true commands: commandspy: - aliases: [c,cs,cspy] + aliases: [ c, cs, cspy ] description: Allows you to spy on players' commands - usage: /commandspy permission: commandspy.command From 130f06fe5ac02c71cb14730b2fc14f3cf1c314c4 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sun, 23 Jun 2024 12:54:02 -0300 Subject: [PATCH 03/14] fix: use MONITOR priority for the command event This hides commands from players that are being controlled with iControlU. --- src/main/java/pw/kaboom/commandspy/Main.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/pw/kaboom/commandspy/Main.java b/src/main/java/pw/kaboom/commandspy/Main.java index 7aab4d7..8e7e48c 100644 --- a/src/main/java/pw/kaboom/commandspy/Main.java +++ b/src/main/java/pw/kaboom/commandspy/Main.java @@ -1,6 +1,5 @@ package pw.kaboom.commandspy; -import java.util.Set; import java.util.UUID; import org.bukkit.Bukkit; @@ -11,10 +10,10 @@ import org.bukkit.command.ConsoleCommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -71,12 +70,8 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener return true; } - @EventHandler + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) { - if (event.isCancelled()) { - return; - } - final Player player = event.getPlayer(); final NamedTextColor color = getTextColor(player); final Component message = Component.text(player.getName(), color) From 1ca2ffc91aea7c593f32d771ba754cfb0fbbfc43 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sun, 23 Jun 2024 13:07:12 -0300 Subject: [PATCH 04/14] perf: opt-out of paper plugin remapping Since we don't use NMS, this is harmless. Saves about 100ms of startup time on first boot on my machine --- pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pom.xml b/pom.xml index 15ddd18..6dfe236 100644 --- a/pom.xml +++ b/pom.xml @@ -30,6 +30,18 @@ ${project.artifactId} + + org.apache.maven.plugins + maven-jar-plugin + 3.4.2 + + + + mojang + + + + org.apache.maven.plugins maven-checkstyle-plugin From 3de6d8d6c96d69ee03c54c25e7f5d0dca8b56340 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sun, 23 Jun 2024 13:18:37 -0300 Subject: [PATCH 05/14] style: misc style fixes Finalizes everything, adds @NotNull to onCommand parameters, and uses pattern matching for the onCommand instanceof Player check. --- src/main/java/pw/kaboom/commandspy/Main.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/pw/kaboom/commandspy/Main.java b/src/main/java/pw/kaboom/commandspy/Main.java index 8e7e48c..10692b4 100644 --- a/src/main/java/pw/kaboom/commandspy/Main.java +++ b/src/main/java/pw/kaboom/commandspy/Main.java @@ -6,7 +6,6 @@ import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -17,6 +16,7 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.plugin.java.JavaPlugin; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; +import org.jetbrains.annotations.NotNull; public final class Main extends JavaPlugin implements CommandExecutor, Listener { private FileConfiguration config; @@ -44,19 +44,18 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener if (config.contains(player.getUniqueId().toString())) { return NamedTextColor.YELLOW; } + return NamedTextColor.AQUA; } @Override - public boolean onCommand(final CommandSender sender, final Command cmd, final String label, - final String[] args) { - if (sender instanceof ConsoleCommandSender) { + public boolean onCommand(final @NotNull CommandSender sender, final @NotNull Command cmd, + final @NotNull String label, final String[] args) { + if (!(sender instanceof final Player player)) { sender.sendMessage(Component.text("Command has to be run by a player")); return true; } - final Player player = (Player) sender; - if (args.length >= 1 && "on".equalsIgnoreCase(args[0])) { enableCommandSpy(player); return true; @@ -78,31 +77,32 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener .append(Component.text(": ")) .append(Component.text(event.getMessage())); - for (String uuidString : config.getKeys(false)) { + for (final String uuidString : config.getKeys(false)) { final UUID uuid = UUID.fromString(uuidString); final Player recipient = Bukkit.getPlayer(uuid); if (recipient == null) { continue; } + recipient.sendMessage(message); } } - @EventHandler + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) void onSignChange(final SignChangeEvent event) { final Player player = event.getPlayer(); final NamedTextColor color = getTextColor(player); Component message = Component.text(player.getName(), color) .append(Component.text(" created a sign with contents:")); - for (Component line : event.lines()) { + for (final Component line : event.lines()) { message = message .append(Component.text("\n ")) .append(line); } - for (String uuidString : config.getKeys(false)) { + for (final String uuidString : config.getKeys(false)) { final UUID uuid = UUID.fromString(uuidString); final Player recipient = Bukkit.getPlayer(uuid); From 7635411849bcb686516e413a9c995ad49636b32a Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sun, 23 Jun 2024 16:22:21 -0300 Subject: [PATCH 06/14] perf: rewrite config logic; use binary format This was done so spamming CommandSpy commands wouldn't lag the server as much, and having a bunch of players turn on CommandSpy wouldn't fill up the server storage. --- .../pw/kaboom/commandspy/CommandSpyState.java | 126 ++++++++++++++++++ src/main/java/pw/kaboom/commandspy/Main.java | 48 +++---- 2 files changed, 145 insertions(+), 29 deletions(-) create mode 100644 src/main/java/pw/kaboom/commandspy/CommandSpyState.java diff --git a/src/main/java/pw/kaboom/commandspy/CommandSpyState.java b/src/main/java/pw/kaboom/commandspy/CommandSpyState.java new file mode 100644 index 0000000..97e8542 --- /dev/null +++ b/src/main/java/pw/kaboom/commandspy/CommandSpyState.java @@ -0,0 +1,126 @@ +package pw.kaboom.commandspy; + +import com.google.common.io.Files; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; + +import java.io.*; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.StampedLock; +import java.util.stream.Collectors; + +public final class CommandSpyState { + private static final Logger LOGGER = JavaPlugin.getPlugin(Main.class).getSLF4JLogger(); + + private final ObjectOpenHashSet users = new ObjectOpenHashSet<>(); + private final StampedLock usersLock = new StampedLock(); + private final AtomicBoolean dirty = new AtomicBoolean(); + private final File file; + + public CommandSpyState(final @NotNull File file) { + this.file = file; + + try { + this.load(); + } catch (final FileNotFoundException exception) { + try { + this.save(); // Create file if it doesn't exist + } catch (IOException ignored) {} + } catch (final IOException exception) { + LOGGER.error("Failed to load state file:", exception); + } + } + + private void load() throws IOException { + final InputStream reader = new BufferedInputStream(new FileInputStream(this.file)); + + int read; + final ByteBuffer buffer = ByteBuffer.wrap(new byte[16]); + + // Loop until we read less than 16 bytes + while ((read = reader.readNBytes(buffer.array(), 0, 16)) == 16) { + this.users.add(new UUID(buffer.getLong(0), buffer.getLong(8))); + } + + reader.close(); + if (read != 0) { + throw new IOException("Found " + read + " bytes extra whilst reading file"); + } + } + + private void save() throws IOException { + Files.createParentDirs(this.file); + final OutputStream writer = new BufferedOutputStream(new FileOutputStream(this.file)); + final ByteBuffer buffer = ByteBuffer.wrap(new byte[16]); + + final long stamp = this.usersLock.readLock(); + for (final UUID uuid: this.users) { + buffer.putLong(0, uuid.getMostSignificantBits()); + buffer.putLong(8, uuid.getLeastSignificantBits()); + writer.write(buffer.array()); + } + this.usersLock.unlockRead(stamp); + + writer.flush(); + writer.close(); + } + + public void trySave() { + // If the state is not dirty, then we don't need to do anything. + if (!this.dirty.compareAndExchange(true, false)) { + return; + } + + try { + this.save(); + } catch (final IOException exception) { + LOGGER.error("Failed to save state file:", exception); + } + } + + public boolean getCommandSpyState(final @NotNull UUID playerUUID) { + final long stamp = this.usersLock.readLock(); + final boolean result = this.users.contains(playerUUID); + this.usersLock.unlockRead(stamp); + + return result; + } + + public void setCommandSpyState(final @NotNull UUID playerUUID, final boolean state) { + final long stamp = this.usersLock.writeLock(); + + final boolean dirty; + if (state) { + dirty = this.users.add(playerUUID); + } else { + dirty = this.users.remove(playerUUID); + } + + this.usersLock.unlockWrite(stamp); + if (dirty) { + this.dirty.set(true); + } + } + + public void broadcastSpyMessage(final @NotNull Component message) { + // Raw access here, so we can get more performance by not locking/unlocking over and over + final long stamp = this.usersLock.readLock(); + final Collection players = Bukkit.getOnlinePlayers() + .stream() + .filter(p -> this.users.contains(p.getUniqueId())) + .collect(Collectors.toUnmodifiableSet()); + this.usersLock.unlockRead(stamp); + + for (final Player recipient : players) { + recipient.sendMessage(message); + } + } +} diff --git a/src/main/java/pw/kaboom/commandspy/Main.java b/src/main/java/pw/kaboom/commandspy/Main.java index 10692b4..9679dc5 100644 --- a/src/main/java/pw/kaboom/commandspy/Main.java +++ b/src/main/java/pw/kaboom/commandspy/Main.java @@ -1,12 +1,11 @@ package pw.kaboom.commandspy; -import java.util.UUID; +import java.io.File; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -19,29 +18,36 @@ import net.kyori.adventure.text.format.NamedTextColor; import org.jetbrains.annotations.NotNull; public final class Main extends JavaPlugin implements CommandExecutor, Listener { - private FileConfiguration config; + private CommandSpyState config; @Override public void onEnable() { - config = getConfig(); + this.config = new CommandSpyState(new File(this.getDataFolder(), "state.bin")); + this.getCommand("commandspy").setExecutor(this); this.getServer().getPluginManager().registerEvents(this, this); + + // Save the config every 30 seconds + Bukkit.getScheduler().runTaskTimerAsynchronously(this, this.config::trySave, 600L, 600L); + } + + @Override + public void onDisable() { + this.config.trySave(); } private void enableCommandSpy(final Player player) { - config.set(player.getUniqueId().toString(), true); - saveConfig(); + this.config.setCommandSpyState(player.getUniqueId(), true); player.sendMessage(Component.text("Successfully enabled CommandSpy")); } private void disableCommandSpy(final Player player) { - config.set(player.getUniqueId().toString(), null); - saveConfig(); + this.config.setCommandSpyState(player.getUniqueId(), false); player.sendMessage(Component.text("Successfully disabled CommandSpy")); } private NamedTextColor getTextColor(final Player player) { - if (config.contains(player.getUniqueId().toString())) { + if (this.config.getCommandSpyState(player.getUniqueId())) { return NamedTextColor.YELLOW; } @@ -61,7 +67,7 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener return true; } if ((args.length >= 1 && "off".equalsIgnoreCase(args[0])) - || config.contains(player.getUniqueId().toString())) { + || this.config.getCommandSpyState(player.getUniqueId())) { disableCommandSpy(player); return true; } @@ -73,20 +79,12 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) { final Player player = event.getPlayer(); final NamedTextColor color = getTextColor(player); + final Component message = Component.text(player.getName(), color) .append(Component.text(": ")) .append(Component.text(event.getMessage())); - for (final String uuidString : config.getKeys(false)) { - final UUID uuid = UUID.fromString(uuidString); - final Player recipient = Bukkit.getPlayer(uuid); - - if (recipient == null) { - continue; - } - - recipient.sendMessage(message); - } + this.config.broadcastSpyMessage(message); } @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) @@ -102,14 +100,6 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener .append(line); } - for (final String uuidString : config.getKeys(false)) { - final UUID uuid = UUID.fromString(uuidString); - final Player recipient = Bukkit.getPlayer(uuid); - - if (recipient == null) { - continue; - } - recipient.sendMessage(message); - } + this.config.broadcastSpyMessage(message); } } From c6351f3f5447f61a71f2e14fce16e60770e688a1 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sun, 23 Jun 2024 18:42:10 -0300 Subject: [PATCH 07/14] feat: allow players to disable/enable cspy for others --- src/main/java/pw/kaboom/commandspy/Main.java | 124 +++++++++++++++---- src/main/resources/plugin.yml | 1 + 2 files changed, 101 insertions(+), 24 deletions(-) diff --git a/src/main/java/pw/kaboom/commandspy/Main.java b/src/main/java/pw/kaboom/commandspy/Main.java index 9679dc5..62da442 100644 --- a/src/main/java/pw/kaboom/commandspy/Main.java +++ b/src/main/java/pw/kaboom/commandspy/Main.java @@ -1,6 +1,7 @@ package pw.kaboom.commandspy; import java.io.File; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -27,7 +28,7 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener this.getCommand("commandspy").setExecutor(this); this.getServer().getPluginManager().registerEvents(this, this); - // Save the config every 30 seconds + // Save the state every 30 seconds Bukkit.getScheduler().runTaskTimerAsynchronously(this, this.config::trySave, 600L, 600L); } @@ -36,14 +37,26 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener this.config.trySave(); } - private void enableCommandSpy(final Player player) { - this.config.setCommandSpyState(player.getUniqueId(), true); - player.sendMessage(Component.text("Successfully enabled CommandSpy")); - } + private void updateCommandSpyState(final @NotNull Player target, + final @NotNull CommandSender source, final boolean state) { + this.config.setCommandSpyState(target.getUniqueId(), state); - private void disableCommandSpy(final Player player) { - this.config.setCommandSpyState(player.getUniqueId(), false); - player.sendMessage(Component.text("Successfully disabled CommandSpy")); + final Component stateString = Component.text(state ? "enabled" : "disabled"); + + target.sendMessage(Component.empty() + .append(Component.text("Successfully ")) + .append(stateString) + .append(Component.text(" CommandSpy."))); + + if (source != target) { + source.sendMessage(Component.empty() + .append(Component.text("Successfully ")) + .append(stateString) + .append(Component.text(" CommandSpy for ")) + .append(target.name()) + .append(Component.text(".")) + ); + } } private NamedTextColor getTextColor(final Player player) { @@ -57,21 +70,54 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener @Override public boolean onCommand(final @NotNull CommandSender sender, final @NotNull Command cmd, final @NotNull String label, final String[] args) { - if (!(sender instanceof final Player player)) { - sender.sendMessage(Component.text("Command has to be run by a player")); - return true; + + Player target = null; + Boolean state = null; + + switch (args.length) { + case 0 -> {} + case 1, 2 -> { + // Get the last argument as a state. Fail if we have 2 arguments. + state = getState(args[args.length - 1]); + if (state != null && args.length == 1) { + break; + } else if (state == null && args.length == 2) { + return false; + } + + // Get the first argument as a player. Fail if it can't be found. + target = getPlayer(args[0]); + if (target != null) { + break; + } + + sender.sendMessage(Component.empty() + .append(Component.text("Player \"")) + .append(Component.text(args[0])) + .append(Component.text("\" not found")) + ); + return true; + } + default -> { + return false; + } } - if (args.length >= 1 && "on".equalsIgnoreCase(args[0])) { - enableCommandSpy(player); - return true; + if (target == null) { + if (!(sender instanceof final Player player)) { + sender.sendMessage(Component.text("Command has to be run by a player")); + return true; + } + + target = player; } - if ((args.length >= 1 && "off".equalsIgnoreCase(args[0])) - || this.config.getCommandSpyState(player.getUniqueId())) { - disableCommandSpy(player); - return true; + + if (state == null) { + state = !this.config.getCommandSpyState(target.getUniqueId()); } - enableCommandSpy(player); + + this.updateCommandSpyState(target, sender, state); + return true; } @@ -81,8 +127,8 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener final NamedTextColor color = getTextColor(player); final Component message = Component.text(player.getName(), color) - .append(Component.text(": ")) - .append(Component.text(event.getMessage())); + .append(Component.text(": ")) + .append(Component.text(event.getMessage())); this.config.broadcastSpyMessage(message); } @@ -92,14 +138,44 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener final Player player = event.getPlayer(); final NamedTextColor color = getTextColor(player); Component message = Component.text(player.getName(), color) - .append(Component.text(" created a sign with contents:")); + .append(Component.text(" created a sign with contents:")); for (final Component line : event.lines()) { message = message - .append(Component.text("\n ")) - .append(line); + .append(Component.text("\n ")) + .append(line); } this.config.broadcastSpyMessage(message); } + + private static Player getPlayer(final String arg) { + final Player player = Bukkit.getPlayer(arg); + if (player != null) { + return player; + } + + final UUID uuid; + try { + uuid = UUID.fromString(arg); + } catch (final IllegalArgumentException ignored) { + return null; + } + + return Bukkit.getPlayer(uuid); + } + + private static Boolean getState(final String arg) { + switch (arg) { + case "on", "enable" -> { + return true; + } + case "off", "disable" -> { + return false; + } + default -> { + return null; + } + } + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index af086de..6a93917 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -10,3 +10,4 @@ commands: aliases: [ c, cs, cspy ] description: Allows you to spy on players' commands permission: commandspy.command + usage: 'Usage: / [player] [on|enable|off|disable]' From 74db21dea145ec7b2011b1b4f01cc91ecd1832d4 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sun, 23 Jun 2024 22:18:51 -0300 Subject: [PATCH 08/14] fix: use correct usage; color usage in red --- src/main/java/pw/kaboom/commandspy/Main.java | 10 ++++++++-- src/main/resources/plugin.yml | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/pw/kaboom/commandspy/Main.java b/src/main/java/pw/kaboom/commandspy/Main.java index 62da442..01f7536 100644 --- a/src/main/java/pw/kaboom/commandspy/Main.java +++ b/src/main/java/pw/kaboom/commandspy/Main.java @@ -82,7 +82,10 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener if (state != null && args.length == 1) { break; } else if (state == null && args.length == 2) { - return false; + sender.sendMessage(Component.text("Usage: ", NamedTextColor.RED) + .append(Component.text(cmd.getUsage().replace("", label))) + ); + return true; } // Get the first argument as a player. Fail if it can't be found. @@ -99,7 +102,10 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener return true; } default -> { - return false; + sender.sendMessage(Component.text("Usage: ", NamedTextColor.RED) + .append(Component.text(cmd.getUsage().replace("", label))) + ); + return true; } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6a93917..7a39943 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -10,4 +10,4 @@ commands: aliases: [ c, cs, cspy ] description: Allows you to spy on players' commands permission: commandspy.command - usage: 'Usage: / [player] [on|enable|off|disable]' + usage: '/ [player] [on|enable|off|disable]' From dbf9796791c1e21e92f1e2626ac1fa96215fe4d8 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:48:00 -0300 Subject: [PATCH 09/14] feat: run build action on every branch --- .github/workflows/main.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3af4259..45948ae 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,10 +1,5 @@ name: Maven CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] +on: [push, pull_request] jobs: build: From 876ec6ae447b80d37f7f52c28f535c261a4678a3 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:45:57 -0300 Subject: [PATCH 10/14] chore: bump paper to 1.20.4; fix warnings We should probably keep kaboom plugins' API version synced with the main server --- pom.xml | 2 +- src/main/java/pw/kaboom/commandspy/Main.java | 1 + src/main/resources/plugin.yml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6dfe236..494839c 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ io.papermc.paper paper-api - 1.19.4-R0.1-SNAPSHOT + 1.20.4-R0.1-SNAPSHOT provided diff --git a/src/main/java/pw/kaboom/commandspy/Main.java b/src/main/java/pw/kaboom/commandspy/Main.java index 01f7536..111587f 100644 --- a/src/main/java/pw/kaboom/commandspy/Main.java +++ b/src/main/java/pw/kaboom/commandspy/Main.java @@ -25,6 +25,7 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener public void onEnable() { this.config = new CommandSpyState(new File(this.getDataFolder(), "state.bin")); + //noinspection DataFlowIssue this.getCommand("commandspy").setExecutor(this); this.getServer().getPluginManager().registerEvents(this, this); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7a39943..9ba5483 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: CommandSpy main: pw.kaboom.commandspy.Main description: Plugin that allows you to spy on players' commands. -api-version: '1.19' +api-version: '1.20' version: master folia-supported: true From 91787dec900e3e89d58cdf60d0d18a2280a3a105 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Tue, 25 Jun 2024 22:31:31 -0300 Subject: [PATCH 11/14] fix: consistency, maven warning --- pom.xml | 3 +-- .../pw/kaboom/commandspy/CommandSpyState.java | 7 ++++--- src/main/java/pw/kaboom/commandspy/Main.java | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 494839c..090e76e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,8 +5,7 @@ master - 17 - 17 + 17 true UTF-8 diff --git a/src/main/java/pw/kaboom/commandspy/CommandSpyState.java b/src/main/java/pw/kaboom/commandspy/CommandSpyState.java index 97e8542..676ba89 100644 --- a/src/main/java/pw/kaboom/commandspy/CommandSpyState.java +++ b/src/main/java/pw/kaboom/commandspy/CommandSpyState.java @@ -33,7 +33,8 @@ public final class CommandSpyState { } catch (final FileNotFoundException exception) { try { this.save(); // Create file if it doesn't exist - } catch (IOException ignored) {} + } catch (IOException ignored) { + } } catch (final IOException exception) { LOGGER.error("Failed to load state file:", exception); } @@ -47,7 +48,7 @@ public final class CommandSpyState { // Loop until we read less than 16 bytes while ((read = reader.readNBytes(buffer.array(), 0, 16)) == 16) { - this.users.add(new UUID(buffer.getLong(0), buffer.getLong(8))); + this.users.add(new UUID(buffer.getLong(0), buffer.getLong(8))); } reader.close(); @@ -62,7 +63,7 @@ public final class CommandSpyState { final ByteBuffer buffer = ByteBuffer.wrap(new byte[16]); final long stamp = this.usersLock.readLock(); - for (final UUID uuid: this.users) { + for (final UUID uuid : this.users) { buffer.putLong(0, uuid.getMostSignificantBits()); buffer.putLong(8, uuid.getLeastSignificantBits()); writer.write(buffer.array()); diff --git a/src/main/java/pw/kaboom/commandspy/Main.java b/src/main/java/pw/kaboom/commandspy/Main.java index 111587f..a5d4f40 100644 --- a/src/main/java/pw/kaboom/commandspy/Main.java +++ b/src/main/java/pw/kaboom/commandspy/Main.java @@ -1,8 +1,7 @@ package pw.kaboom.commandspy; -import java.io.File; -import java.util.UUID; - +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -14,10 +13,11 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.plugin.java.JavaPlugin; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import org.jetbrains.annotations.NotNull; +import java.io.File; +import java.util.UUID; + public final class Main extends JavaPlugin implements CommandExecutor, Listener { private CommandSpyState config; @@ -47,7 +47,7 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener target.sendMessage(Component.empty() .append(Component.text("Successfully ")) .append(stateString) - .append(Component.text(" CommandSpy."))); + .append(Component.text(" CommandSpy"))); if (source != target) { source.sendMessage(Component.empty() @@ -55,7 +55,6 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener .append(stateString) .append(Component.text(" CommandSpy for ")) .append(target.name()) - .append(Component.text(".")) ); } } @@ -76,7 +75,8 @@ public final class Main extends JavaPlugin implements CommandExecutor, Listener Boolean state = null; switch (args.length) { - case 0 -> {} + case 0 -> { + } case 1, 2 -> { // Get the last argument as a state. Fail if we have 2 arguments. state = getState(args[args.length - 1]); From d4ca1c84ad5dc65003d9532128dbd633ff4ae210 Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Tue, 25 Jun 2024 22:34:09 -0300 Subject: [PATCH 12/14] fix: maven skill issue --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 090e76e..7e7e78e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,6 +5,8 @@ master + 17 + 17 17 true UTF-8 From 2a5a9da5672afb060bbdee6f4d9db6d633fde98c Mon Sep 17 00:00:00 2001 From: amy <144570677+amyavi@users.noreply.github.com> Date: Fri, 27 Sep 2024 21:08:11 -0300 Subject: [PATCH 13/14] chore: bump checkstyle version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7e7e78e..66bc096 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.4.0 + 3.5.0 checkstyle From 94c09b61f83ae4ac42578c7ff97d1dc7a980412d Mon Sep 17 00:00:00 2001 From: amyavi <144570677+amyavi@users.noreply.github.com> Date: Sat, 21 Dec 2024 15:41:34 -0300 Subject: [PATCH 14/14] chore: bump checkstyle version --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 66bc096..61c531f 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,6 @@ 17 17 - 17 true UTF-8 @@ -46,7 +45,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.5.0 + 3.6.0 checkstyle