/slowchat Command

Discussion in 'Plugin Development' started by Kajuze, Feb 1, 2023.

Thread Status:
Not open for further replies.
  1. Offline

    Kajuze

    I just started with coding and are still learning. This is the first time I was trying to create a "/slowchat (Secounds)" command. This is a command for a private server and should only be able to be executed by operators. I've started coding this command, however, after executing the command, players without operator privileges can continue to spam chat without waiting the specified number of seconds.

    Code:
    import org.bukkit.Bukkit;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.AsyncPlayerChatEvent;
    import java.util.HashMap;
    
    public class SlowChatCommand implements CommandExecutor, Listener {
    private final HashMap<Player, Long> cooldowns = new HashMap<>();
    private int cooldownTime;
    public SlowChatCommand(int cooldownTime) {
        this.cooldownTime = cooldownTime;
    }
    
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage("[§d§lInvControl§f] §cDieser Befehl kann nur von einem Spieler ausgeführt werden.");
            return true;
        }
        Player player = (Player) sender;
        if (!player.isOp()) {
            player.sendMessage("[§d§lInvControl§f] §cDu hast keine Berechtigung für diesen Befehl.");
            return true;
        }
        if (args.length != 1) {
            player.sendMessage("[§d§lInvControl§f] §cVerwendung: /slowchat [Sekunden]");
            return true;
        }
        try {
            cooldownTime = Integer.parseInt(args[0]) * 1000;
            player.sendMessage("[§d§lInvControl§f] §aDie Chatrate wurde auf " + args[0] + " Sekunden gesetzt.");
        } catch (NumberFormatException e) {
            player.sendMessage("[§d§lInvControl§f] §cBitte gib eine gültige Zahl ein.");
        }
        return true;
    }
    
    public boolean checkCooldown(Player player) {
        Long lastMessage = cooldowns.get(player);
        long currentTime = System.currentTimeMillis();
        if (lastMessage == null || lastMessage + cooldownTime <= currentTime) {
            cooldowns.put(player, currentTime);
            return true;
        } else {
            return false;
        }
    }
    
    @EventHandler
    public void onPlayerChat(AsyncPlayerChatEvent event) {
        Player player = event.getPlayer();
        if (!player.isOp()) {
            if (!checkCooldown(player)) {
                player.sendMessage("[§d§lInvControl§f] §cBitte warte " + cooldownTime / 1000 + " Sekunden, bevor du erneut eine Nachricht sendest.");
                event.setCancelled(true);
            }
        }
    }
    }
    I wasted hours but can't figure out what's wrong with it. Can anybody help me with that one please?
     
  2. Offline

    timtower Administrator Administrator Moderator

    @Kajuze Show your onEnable please.
     
  3. Offline

    Kajuze

    Code:
    package kajuze.de.chatcontrol;
    
    import kajuze.de.chatcontrol.commands.ChatControl.Commands;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public final class ChatControl extends JavaPlugin {
    
        @Override
        public void onEnable() {
            getLogger().info("ChatControl wurde aktiviert!");
            getCommand("slowchat").setExecutor(new SlowChatCommand());
    
        }
    
        @Override
        public void onDisable() {
    
            getLogger().info("ChatControl wurde deaktiviert!");
    
        }
    }
    
     
  4. Offline

    timtower Administrator Administrator Moderator

    @Kajuze You never register the class as Listener.
    And you don't need those logger calls there, Bukkit does that for you already.
     
  5. Offline

    Strahan

    Also I'm surprised that compiles at all; your SlowChatCommand class constructor requires an int, yet you aren't passing one. You could also use HashMap#getOrDefault() to avoid having to nullcheck your get and you really should be doing your Player#isOp() check within the checkCoolDown method instead of externally so as to keep the responsibilities of the method contained.
     
  6. Offline

    Smeary_Subset

    Instead of #isOp(), use sender#hasPermission("slow.use") (or whatever the name of the command is followed by .use)
     
Thread Status:
Not open for further replies.

Share This Page