package com.yourname.authadminplugin;

import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

/**
 * Обработчик команды аутентификации администратора.
 */
public class AdminLoginCommand implements CommandExecutor {

    private final AuthAdminPlugin plugin;

    public AdminLoginCommand(AuthAdminPlugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

        // Команду могут выполнять только игроки
        if (!(sender instanceof Player)) {
            sender.sendMessage(ChatColor.RED + "Только игроки могут использовать эту команду.");
            return true;
        }

        Player player = (Player) sender;

        // Проверка на наличие в blacklist
        if (plugin.isBlacklisted(player.getName())) {
            player.sendMessage(ChatColor.RED + "Вы заблокированы и не можете аутентифицироваться.");
            plugin.logEvent(player.getName() + " попытался аутентифицироваться, но он в blacklist.");
            return true;
        }

        // Проверка количества аргументов
        if (args.length != 1) {
            player.sendMessage(ChatColor.RED + "Использование: /adminlogin <password>");
            return true;
        }

        String password = args[0];

        // Аутентификация администратора
        if (plugin.authenticateAdmin(player, password)) {
            // `op` доступ выдается на сессию, дополнительных действий не требуется
        }

        return true;
    }
}
package com.yourname.authadminplugin;

import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

/**
 * Обработчик команды деаутентификации администратора.
 */
public class AdminLogoutCommand implements CommandExecutor {

    private final AuthAdminPlugin plugin;

    public AdminLogoutCommand(AuthAdminPlugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

        // Команду могут выполнять только игроки
        if (!(sender instanceof Player)) {
            sender.sendMessage(ChatColor.RED + "Только игроки могут использовать эту команду.");
            return true;
        }

        Player player = (Player) sender;

        if (plugin.getAuthenticatedAdmins().contains(player.getName())) {
            plugin.deauthenticateAdmin(player);
        } else {
            player.sendMessage(ChatColor.YELLOW + "Вы не имеете `op` доступа.");
        }

        return true;
    }
}
package com.yourname.authadminplugin;

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;

/**
 * Слушатель события выхода игрока из игры.
 */
public class AdminLogoutListener implements Listener {

    private final AuthAdminPlugin plugin;

    public AdminLogoutListener(AuthAdminPlugin plugin) {
        this.plugin = plugin;
    }

    @EventHandler
    public void onPlayerQuit(PlayerQuitEvent event) {
        String playerName = event.getPlayer().getName();
        if (plugin.getAuthenticatedAdmins().contains(playerName)) {
            plugin.deauthenticateAdmin(event.getPlayer());
            plugin.logEvent(playerName + " вышел из игры и `op` доступ был снят.");
        }
    }
}
package com.yourname.authadminplugin;

import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

/**
 * Обработчик команды регистрации администратора.
 */
public class AdminRegisterCommand implements CommandExecutor {

    private final AuthAdminPlugin plugin;

    public AdminRegisterCommand(AuthAdminPlugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

        // Команду могут выполнять только игроки
        if (!(sender instanceof Player)) {
            sender.sendMessage(ChatColor.RED + "Только игроки могут использовать эту команду.");
            return true;
        }

        Player player = (Player) sender;

        // Проверка количества аргументов
        if (args.length != 1) {
            player.sendMessage(ChatColor.RED + "Использование: /adminregister <password>");
            return true;
        }

        String password = args[0];

        // Регистрация администратора
        if (plugin.registerAdmin(player, password)) {
            // Дополнительные действия при успешной регистрации, если необходимо
        }

        return true;
    }
}
package com.yourname.authadminplugin;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.PluginManager;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class AuthAdminPlugin extends JavaPlugin {

    private File adminFile;
    private File blacklistFile;
    private FileConfiguration adminConfig;
    private FileConfiguration blacklistConfig;

    private Set<String> authenticatedAdmins = ConcurrentHashMap.newKeySet();
    private Map<String, Integer> failedAttempts = new ConcurrentHashMap<>();
    private Set<String> blacklist = ConcurrentHashMap.newKeySet<>();

    @Override
    public void onEnable() {
        // Создание папки плагина, если не существует
        if (!getDataFolder().exists()) {
            getDataFolder().mkdirs();
        }

        // Загрузка admins.yml
        adminFile = new File(getDataFolder(), "admins.yml");
        if (!adminFile.exists()) {
            saveResource("admins.yml", false);
        }
        adminConfig = YamlConfiguration.loadConfiguration(adminFile);

        // Загрузка blacklist.yml
        blacklistFile = new File(getDataFolder(), "blacklist.yml");
        if (!blacklistFile.exists()) {
            saveResource("blacklist.yml", false);
        }
        blacklistConfig = YamlConfiguration.loadConfiguration(blacklistFile);
        loadBlacklist();

        // Регистрация команд
        this.getCommand("adminregister").setExecutor(new AdminRegisterCommand(this));
        this.getCommand("adminlogin").setExecutor(new AdminLoginCommand(this));
        this.getCommand("adminlogout").setExecutor(new AdminLogoutCommand(this));

        // Регистрация событий
        PluginManager pm = getServer().getPluginManager();
        pm.registerEvents(new AdminLogoutListener(this), this);
        pm.registerEvents(new PlayerJoinListener(this), this);

        getLogger().info("AuthAdminPlugin включен!");
    }

    @Override
    public void onDisable() {
        // Снимаем `op` с всех аутентифицированных админов
        for (String playerName : authenticatedAdmins) {
            Player player = Bukkit.getPlayerExact(playerName);
            if (player != null && player.isOp()) {
                player.setOp(false);
                logEvent(playerName + " был деопирован при отключении плагина.");
            }
        }
        getLogger().info("AuthAdminPlugin отключен!");
    }

    /**
     * Регистрация администратора.
     *
     * @param player  Игрок, который регистрируется.
     * @param password Пароль для администратора.
     * @return true, если регистрация успешна, иначе false.
     */
    public boolean registerAdmin(Player player, String password) {
        String playerName = player.getName();

        if (adminConfig.contains("admins." + playerName)) {
            player.sendMessage(ChatColor.RED + "Вы уже зарегистрированы как администратор.");
            return false;
        }

        String hashedPassword = PasswordUtils.hashPassword(password);
        adminConfig.set("admins." + playerName + ".password", hashedPassword);
        try {
            adminConfig.save(adminFile);
        } catch (IOException e) {
            getLogger().severe("Не удалось сохранить admins.yml: " + e.getMessage());
            player.sendMessage(ChatColor.RED + "Произошла ошибка при регистрации. Попробуйте позже.");
            return false;
        }

        player.sendMessage(ChatColor.GREEN + "Вы успешно зарегистрированы как администратор.");
        logEvent(playerName + " успешно зарегистрировался как администратор.");
        return true;
    }

    /**
     * Аутентификация администратора.
     *
     * @param player  Игрок, который аутентифицируется.
     * @param password Пароль для аутентификации.
     * @return true, если аутентификация успешна, иначе false.
     */
    public boolean authenticateAdmin(Player player, String password) {
        String playerName = player.getName();

        if (isBlacklisted(playerName)) {
            player.sendMessage(ChatColor.RED + "Вы заблокированы и не можете аутентифицироваться.");
            logEvent(playerName + " попытался аутентифицироваться, но он в blacklist.");
            return false;
        }

        if (adminConfig.contains("admins." + playerName)) {
            String hashedPassword = adminConfig.getString("admins." + playerName + ".password");
            if (hashedPassword != null && PasswordUtils.checkPassword(password, hashedPassword)) {
                authenticatedAdmins.add(playerName);
                player.setOp(true);
                logEvent(playerName + " успешно аутентифицирован и получил `op` доступ.");
                player.sendMessage(ChatColor.GREEN + "Вы успешно аутентифицировались как администратор.");

                // Сброс счетчика неудачных попыток
                failedAttempts.remove(playerName);
                return true;
            } else {
                incrementFailedAttempts(playerName);
                player.sendMessage(ChatColor.RED + "Неверный пароль.");
                logEvent(playerName + " попытался аутентифицироваться с неверным паролем.");
                return false;
            }
        } else {
            player.sendMessage(ChatColor.RED + "Вы не зарегистрированы как администратор. Используйте /adminregister <password>");
            return false;
        }
    }

    /**
     * Деаутентификация администратора.
     *
     * @param player Игрок, который деаутентифицируется.
     */
    public void deauthenticateAdmin(Player player) {
        String playerName = player.getName();
        if (authenticatedAdmins.contains(playerName)) {
            player.setOp(false);
            authenticatedAdmins.remove(playerName);
            logEvent(playerName + " деаутентифицирован и `op` доступ снят.");
            player.sendMessage(ChatColor.YELLOW + "Ваш `op` доступ был снят.");
        }
    }

    /**
     * Увеличение счётчика неудачных попыток аутентификации.
     *
     * @param playerName Имя игрока.
     */
    private void incrementFailedAttempts(String playerName) {
        int attempts = failedAttempts.getOrDefault(playerName, 0) + 1;
        failedAttempts.put(playerName, attempts);
        if (attempts >= 3) {
            // Блокировка игрока
            banPlayer(playerName);
            failedAttempts.remove(playerName);
        }
    }

    /**
     * Бан игрока за 3 неудачные попытки аутентификации.
     *
     * @param playerName Имя игрока.
     */
    private void banPlayer(String playerName) {
        blacklist.add(playerName);
        blacklistConfig.set("blacklist", new ArrayList<>(blacklist));
        try {
            blacklistConfig.save(blacklistFile);
        } catch (IOException e) {
            getLogger().severe("Не удалось сохранить blacklist.yml: " + e.getMessage());
        }

        // Деоп игрока, если он был опом
        Player player = Bukkit.getPlayerExact(playerName);
        if (player != null) {
            if (player.isOp()) {
                player.setOp(false);
                logEvent(playerName + " был деопнут из-за 3 неудачных попыток аутентификации.");
            }
            // Бан игрока на сервере
            Bukkit.getBanList(org.bukkit.BanList.Type.NAME).addBan(playerName, "3 неудачные попытки аутентификации администратора.", null, "AuthAdminPlugin");
            player.kickPlayer("Вы были забанены за 3 неудачные попытки аутентификации администратора.");
            logEvent(playerName + " был заблокирован (занесён в blacklist) за 3 неудачные попытки аутентификации.");
        } else {
            // Если игрок офлайн, просто записать в blacklist
            logEvent(playerName + " добавлен в blacklist за 3 неудачные попытки аутентификации.");
        }
    }

    /**
     * Загрузка чёрного списка из конфигурационного файла.
     */
    private void loadBlacklist() {
        if (blacklistConfig.contains("blacklist")) {
            List<String> blacklistedPlayers = blacklistConfig.getStringList("blacklist");
            blacklist.addAll(blacklistedPlayers);
        }
    }

    /**
     * Проверка, находится ли игрок в чёрном списке.
     *
     * @param playerName Имя игрока.
     * @return true, если игрок в blacklist, иначе false.
     */
    public boolean isBlacklisted(String playerName) {
        return blacklist.contains(playerName);
    }

    /**
     * Логирование событий с временной меткой.
     *
     * @param message Сообщение для логирования.
     */
    public void logEvent(String message) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        getLogger().info("[" + timestamp + "] " + message);
        // Дополнительно можно реализовать запись в отдельный файл логов
    }

    /**
     * Получение набора аутентифицированных администраторов.
     *
     * @return Набор имен администраторов.
     */
    public Set<String> getAuthenticatedAdmins() {
        return authenticatedAdmins;
    }
}
(Cannot resolve symbol 'newKeySet'
';' expected
Expression expected
Unexpected token)
package com.yourname.authadminplugin;

import org.mindrot.jbcrypt.BCrypt;

/**
 * Утилиты для работы с паролями.
 */
public class PasswordUtils {

    /**
     * Генерация хэша пароля с использованием bcrypt.
     *
     * @param plainTextPassword Пароль в открытом виде.
     * @return Хэшированный пароль.
     */
    public static String hashPassword(String plainTextPassword) {
        return BCrypt.hashpw(plainTextPassword, BCrypt.gensalt(12));
    }

    /**
     * Проверка пароля на соответствие хэшу.
     *
     * @param plainTextPassword Пароль в открытом виде.
     * @param hashedPassword    Хэшированный пароль.
     * @return true, если пароль совпадает с хэшем, иначе false.
     */
    public static boolean checkPassword(String plainTextPassword, String hashedPassword) {
        if (hashedPassword == null || !hashedPassword.startsWith("$2a$")) {
            throw new IllegalArgumentException("Некорректный хэш пароля");
        }
        return BCrypt.checkpw(plainTextPassword, hashedPassword);
    }
}
Cannot resolve symbol 'mindrot'
Cannot resolve symbol 'BCrypt'
Cannot resolve symbol 'BCrypt'
Cannot resolve symbol 'BCrypt'
package com.yourname.authadminplugin;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

/**
 * Слушатель события входа игрока в игру.
 */
public class PlayerJoinListener implements Listener {

    private final AuthAdminPlugin plugin;

    public PlayerJoinListener(AuthAdminPlugin plugin) {
        this.plugin = plugin;
    }

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        String playerName = player.getName();

        // Проверка, зарегистрирован ли игрок как администратор
        if (plugin.getAdminConfig().contains("admins." + playerName)) {
            // Игрок зарегистрирован, ничего не делаем
            return;
        } else {
            // Игрок не зарегистрирован как администратор, ничего не делаем
            // Регистрация должна происходить только с помощью команды
            // Однако, можно отправить сообщение напоминание о регистрации, если нужно
            player.sendMessage(ChatColor.YELLOW + "Если вы администратор, зарегистрируйтесь с помощью команды /adminregister <password>");
        }
    }
}
Cannot resolve method 'getAdminConfig' in 'AuthAdminPlugin'

1) Без зависимостей сделаем
2)Исправь баги
3) Улучши:
Команды для Управления Blacklist:
Добавьте команды, позволяющие администраторам управлять чёрным списком, например, /blacklist add <player> и /blacklist remove <player>.
Защита Конфигурационных Файлов:
Убедитесь, что файлы конфигурации (admins.yml и blacklist.yml) защищены от доступа посторонних лиц, особенно если они содержат чувствительные данные.
Улучшение Логирования:
Реализуйте запись логов в отдельный файл для более удобного анализа действий администраторов.
Более Гибкие Разрешения:
Возможно, впоследствии захочется добавить уровни доступа или различные роли среди администраторов. Это можно реализовать, добавив соответствующие поля в admins.yml.
Уведомления Администраторам:
При добавлении или удалении из чёрного списка, отправляйте уведомления другим администраторам или ведите соответствующие записи.
4) Напиши полный код, на русском