Запомни код
package xyz.dragonsfixer;

import com.google.inject.Inject;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.command.CommandExecuteEvent;
import com.velocitypowered.api.event.command.CommandExecuteEvent.CommandResult;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.slf4j.Logger;
import org.yaml.snakeyaml.Yaml;

@Plugin(
        id = "dragonsfixer",
        name = "DragonsFixer",
        version = "1.2",
        description = "Антиспам плагин для Velocity",
        authors = {"boboliii"}
)
public class DragonsFixer {
    private final ProxyServer server;
    private final Path dataDirectory;
    private final Map<UUID, Long> cooldowns = new ConcurrentHashMap<>();
    private final Map<UUID, Integer> warningCounts = new ConcurrentHashMap<>();
    private final Map<UUID, List<Long>> commandTimestamps = new ConcurrentHashMap<>();
    private int cooldownTime = 500;
    private Component spamMessage;
    private int maxWarnings;
    private int kickAfterWarnings;
    private Component kickMessage;
    private final int maxCommandsPerSecond = 5;
    @Inject
    private Logger logger;

    @Inject
    public DragonsFixer(ProxyServer server, @DataDirectory Path dataDirectory) {
        this.server = server;
        this.dataDirectory = dataDirectory;
        this.spamMessage = Component.text("DragonsGrief » Не спамь!").color(NamedTextColor.RED);
        this.maxWarnings = 15;
        this.kickAfterWarnings = 20;
        this.kickMessage = Component.text("DragonsGrief » Вы были кикнуты за спам командами").color(NamedTextColor.RED);
    }

    @Subscribe
    public void onProxyInitialization(ProxyInitializeEvent event) {
        try {
            this.initializeConfiguration();
        } catch (Exception e) {
            this.logger.error("Ошибка инициализации конфигурации", e);
        }
    }

    private void initializeConfiguration() throws IOException {
        Files.createDirectories(this.dataDirectory);
        Path configPath = this.dataDirectory.resolve("config.yml");
        if (Files.notExists(configPath, LinkOption.NOFOLLOW_LINKS)) {
            try (InputStream inputStream = this.getClass().getResourceAsStream("/config.yml")) {
                if (inputStream != null) {
                    Files.copy(inputStream, configPath, new CopyOption[0]);
                } else {
                    this.createDefaultConfig(configPath);
                }
            }
        }
        this.loadConfiguration(configPath);
    }

    private void createDefaultConfig(Path configPath) throws IOException {
        String defaultConfigContent = "cooldown: 500\nmax-warnings: 15\nkick-after-warnings: 20\nspam-message: \"§6DragonsGrief §7» §c§lНе спамь!\"\nkick-message: \"§cВы были кикнуты за спам командами\"\n";
        Files.write(configPath, defaultConfigContent.getBytes(), new OpenOption[0]);
    }

    private void loadConfiguration(Path configPath) throws IOException {
        try (InputStream input = Files.newInputStream(configPath)) {
            Yaml yaml = new Yaml();
            Map<String, Object> config = yaml.load(input);
            this.cooldownTime = (Integer) config.getOrDefault("cooldown", 500);
            this.maxWarnings = (Integer) config.getOrDefault("max-warnings", 15);
            this.kickAfterWarnings = (Integer) config.getOrDefault("kick-after-warnings", 20);
            this.spamMessage = LegacyComponentSerializer.legacyAmpersand().deserialize(
                    (String) config.getOrDefault("spam-message", "§6DragonsGrief §7» §c§lНе спамь!"));
            this.kickMessage = LegacyComponentSerializer.legacyAmpersand().deserialize(
                    (String) config.getOrDefault("kick-message", "§cВы были кикнуты за спам командами"));
        }
    }

    @Subscribe
    public void onCommand(CommandExecuteEvent event) {
        CommandSource source = event.getCommandSource();
        if (source instanceof Player) {
            Player player = (Player) source;
            UUID playerId = player.getUniqueId();

            // Получаем список временных меток команд игрока
            List<Long> timestamps = this.commandTimestamps.computeIfAbsent(playerId, k -> new ArrayList<>());
            long currentTime = System.currentTimeMillis();

            // Убираем старые команды (старше 1 секунды)
            timestamps.removeIf(timestamp -> currentTime - timestamp > 1000L);

            // Добавляем текущую команду
            timestamps.add(currentTime);

            // Проверяем количество команд за последнюю секунду
            if (timestamps.size() > maxCommandsPerSecond) {
                this.addWarning(playerId, player);
                event.setResult(CommandResult.denied());
                player.sendMessage(this.spamMessage);
                return;
            }

            // Проверка кулдауна на команды
            if (this.isInCooldown(playerId)) {
                event.setResult(CommandResult.denied());
                player.sendMessage(this.spamMessage);
                this.addWarning(playerId, player);
            } else {
                // Установка кулдауна
                this.cooldowns.put(playerId, currentTime + cooldownTime);
            }
        }
    }

    private boolean isInCooldown(UUID playerId) {
        return System.currentTimeMillis() < this.cooldowns.getOrDefault(playerId, 0L);
    }

    private void addWarning(UUID playerId, Player player) {
        int warnings = this.warningCounts.merge(playerId, 1, Integer::sum);
        if (warnings >= this.kickAfterWarnings) {
            player.disconnect(this.kickMessage);
            this.warningCounts.remove(playerId);
            this.commandTimestamps.remove(playerId);
        }
    }
}


config.yml

cooldown: 500
max-warnings: 25
kick-after-warnings: 35
spam-message: "§6DragonsGrief §7» §c§lНе спамь!"
kick-message: "§cВы были кикнуты за спам командами"


Сделай так чтобы игроков просто так никогда не кикало, нужно чтобы был просто кд на команды, кд на ввод комманд 500 миллисекунд и сделай чтобы кикало игрока за спам командами только тогда, когда игрок вводил за секунду или полторы секунды столько команд, сколько указано в конфиге (kick-after-warnings: 35)