Error occurred while enabling AdminPasswordPlugin v1.2 (Is it up to date?)
java.lang.IllegalArgumentException: The embedded resource 'config.yml' cannot be found in plugins\adminpasswordplugin.jar
        at org.bukkit.plugin.java.JavaPlugin.saveResource(JavaPlugin.java:209) ~[purpur-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.plugin.java.JavaPlugin.saveDefaultConfig(JavaPlugin.java:196) ~[purpur-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at com.example.adminpasswordplugin.Main.onEnable(Main.java:19) ~[adminpasswordplugin.jar:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:281) ~[purpur-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at io.papermc.paper.plugin.manager.PaperPluginInstanceManager.enablePlugin(PaperPluginInstanceManager.java:189) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.enablePlugin(PaperPluginManagerImpl.java:104) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:507) ~[purpur-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.craftbukkit.v1_20_R1.CraftServer.enablePlugin(CraftServer.java:656) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at org.bukkit.craftbukkit.v1_20_R1.CraftServer.enablePlugins(CraftServer.java:567) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:640) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:439) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:345) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1116) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:322) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[14:07:23 INFO]: [AdminPasswordPlugin] Disabling AdminPasswordPlugin v1.2
[14:07:23 ERROR]: Error occurred (in the plugin loader) while disabling AdminPasswordPlugin v1.2 (Is it up to date?)
java.lang.NullPointerException: Cannot invoke "com.example.adminpasswordplugin.AdminManager.saveData()" because "this.adminManager" is null
        at com.example.adminpasswordplugin.Main.onDisable(Main.java:38) ~[adminpasswordplugin.jar:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:283) ~[purpur-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at io.papermc.paper.plugin.manager.PaperPluginInstanceManager.disablePlugin(PaperPluginInstanceManager.java:224) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.disablePlugin(PaperPluginManagerImpl.java:109) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at org.bukkit.plugin.SimplePluginManager.disablePlugin(SimplePluginManager.java:537) ~[purpur-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at io.papermc.paper.plugin.manager.PaperPluginInstanceManager.enablePlugin(PaperPluginInstanceManager.java:193) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.enablePlugin(PaperPluginManagerImpl.java:104) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:507) ~[purpur-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.craftbukkit.v1_20_R1.CraftServer.enablePlugin(CraftServer.java:656) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at org.bukkit.craftbukkit.v1_20_R1.CraftServer.enablePlugins(CraftServer.java:567) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:640) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:439) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:345) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1116) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:322) ~[purpur-1.20.1.jar:git-Purpur-2062]
        at java.lang.Thread.run(Thread.java:1583) ~[?:?]

package com.example.adminpasswordplugin;

import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class AdminManager {

    private final Main plugin;
    private final Map<String, AdminCredentials> adminCredentialsMap;
    private final Map<String, Boolean> adminLoggedIn;

    private static final String CONFIG_SECTION = "admin-credentials";
    private static final int SALT_LENGTH = 16; // bytes
    private static final int HASH_ITERATIONS = 65536;
    private static final int KEY_LENGTH = 256; // bits

    public AdminManager(Main plugin) {
        this.plugin = plugin;
        this.adminCredentialsMap = new HashMap<>();
        this.adminLoggedIn = new HashMap<>();
        loadData();
    }

    /**
     * Registers a new admin password.
     *
     * @param player  The player registering the password.
     * @param password The password to register.
     * @return True if registration is successful, false if already registered or error occurs.
     */
    public boolean registerPassword(Player player, String password) {
        String playerName = player.getName().toLowerCase();
        if (adminCredentialsMap.containsKey(playerName)) {
            return false; // Already registered
        }

        byte[] salt = generateSalt();
        String saltEncoded = Base64.getEncoder().encodeToString(salt);
        String hashedPassword = hashPassword(password, salt);

        if (hashedPassword == null) {
            return false; // Hashing failed
        }

        AdminCredentials credentials = new AdminCredentials(saltEncoded, hashedPassword);
        adminCredentialsMap.put(playerName, credentials);
        adminLoggedIn.put(playerName, false);
        saveData();
        return true;
    }

    /**
     * Authenticates an admin using the provided password.
     *
     * @param player  The player attempting to log in.
     * @param password The password provided.
     * @return True if authentication is successful, false otherwise.
     */
    public boolean login(Player player, String password) {
        String playerName = player.getName().toLowerCase();
        if (!adminCredentialsMap.containsKey(playerName)) {
            return false; // Not registered
        }

        AdminCredentials credentials = adminCredentialsMap.get(playerName);
        byte[] salt = Base64.getDecoder().decode(credentials.getSalt());
        String hashedInput = hashPassword(password, salt);

        if (hashedInput == null) {
            return false; // Hashing failed
        }

        if (hashedInput.equals(credentials.getHash())) {
            adminLoggedIn.put(playerName, true);
            return true;
        }

        return false;
    }

    /**
     * Checks if an admin is currently logged in.
     *
     * @param player The player to check.
     * @return True if logged in, false otherwise.
     */
    public boolean isLoggedIn(Player player) {
        String playerName = player.getName().toLowerCase();
        return adminLoggedIn.getOrDefault(playerName, false);
    }

    /**
     * Logs out an admin, resetting their authentication state.
     *
     * @param player The player to log out.
     */
    public void logout(Player player) {
        String playerName = player.getName().toLowerCase();
        adminLoggedIn.put(playerName, false);
    }

    /**
     * Changes an admin's password.
     *
     * @param player     The player changing the password.
     * @param oldPassword The current password.
     * @param newPassword The new password to set.
     * @return True if the password was successfully changed, false otherwise.
     */
    public boolean changePassword(Player player, String oldPassword, String newPassword) {
        String playerName = player.getName().toLowerCase();
        if (!adminCredentialsMap.containsKey(playerName)) {
            return false; // Not registered
        }

        AdminCredentials credentials = adminCredentialsMap.get(playerName);
        byte[] salt = Base64.getDecoder().decode(credentials.getSalt());
        String hashedOldPassword = hashPassword(oldPassword, salt);

        if (hashedOldPassword == null || !hashedOldPassword.equals(credentials.getHash())) {
            return false; // Old password incorrect or hashing failed
        }

        // Generate new salt and hash for the new password
        byte[] newSalt = generateSalt();
        String newSaltEncoded = Base64.getEncoder().encodeToString(newSalt);
        String newHashedPassword = hashPassword(newPassword, newSalt);

        if (newHashedPassword == null) {
            return false; // Hashing failed
        }

        // Update credentials
        AdminCredentials newCredentials = new AdminCredentials(newSaltEncoded, newHashedPassword);
        adminCredentialsMap.put(playerName, newCredentials);
        saveData();
        return true;
    }

    /**
     * Generates a random salt.
     *
     * @return A byte array representing the salt.
     */
    private byte[] generateSalt() {
        SecureRandom sr = new SecureRandom();
        byte[] salt = new byte[SALT_LENGTH];
        sr.nextBytes(salt);
        return salt;
    }

    /**
     * Hashes a password using PBKDF2 with the provided salt.
     *
     * @param password The password to hash.
     * @param salt     The salt to use.
     * @return The hashed password encoded in Base64, or null if hashing fails.
     */
    private String hashPassword(String password, byte[] salt) {
        try {
            PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, HASH_ITERATIONS, KEY_LENGTH);
            SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
            byte[] hash = skf.generateSecret(spec).getEncoded();
            return Base64.getEncoder().encodeToString(hash);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            plugin.getLogger().severe("Ошибка при хэшировании пароля: " + e.getMessage());
            return null;
        }
    }

    /**
     * Loads admin credentials from config.yml.
     */
    private void loadData() {
        FileConfiguration config = plugin.getConfig();
        if (config.contains(CONFIG_SECTION)) {
            ConfigurationSection section = config.getConfigurationSection(CONFIG_SECTION);
            for (String playerName : section.getKeys(false)) {
                String salt = section.getString(playerName + ".salt");
                String hash = section.getString(playerName + ".hash");
                if (salt != null && hash != null) {
                    AdminCredentials credentials = new AdminCredentials(salt, hash);
                    adminCredentialsMap.put(playerName, credentials);
                }
            }
        }
    }

    /**
     * Saves admin credentials to config.yml.
     */
    public void saveData() {
        FileConfiguration config = plugin.getConfig();
        ConfigurationSection section = config.createSection(CONFIG_SECTION);
        for (Map.Entry<String, AdminCredentials> entry : adminCredentialsMap.entrySet()) {
            String playerName = entry.getKey();
            AdminCredentials credentials = entry.getValue();
            section.set(playerName + ".salt", credentials.getSalt());
            section.set(playerName + ".hash", credentials.getHash());
        }
        plugin.saveConfig();
    }

    /**
     * Inner class to store admin credentials.
     */
    private static class AdminCredentials {
        private final String salt;
        private final String hash;

        public AdminCredentials(String salt, String hash) {
            this.salt = salt;
            this.hash = hash;
        }

        public String getSalt() {
            return salt;
        }

        public String getHash() {
            return hash;
        }
    }
}
package com.example.adminpasswordplugin;

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

public class CommandBlockListener implements Listener {

    private final Main plugin;
    private final AdminManager adminManager;

    public CommandBlockListener(Main plugin, AdminManager adminManager) {
        this.plugin = plugin;
        this.adminManager = adminManager;
    }

    @EventHandler
    public void onCommandPreprocess(PlayerCommandPreprocessEvent event) {
        Player player = event.getPlayer();
        String message = event.getMessage().toLowerCase();
        String command = message.split(" ")[0];

        // Allow access to registration, login, and password change commands without restriction
        if (command.equals("/adminreg") || command.equals("/adminlogin") || command.equals("/adminchangepassword")) {
            return;
        }

        // Check if the player has admin permissions
        if (player.hasPermission("adminpasswordplugin.admin")) {
            // Check if the admin is logged in
            if (!adminManager.isLoggedIn(player)) {
                // Block the command
                event.setCancelled(true);
                player.sendMessage(ChatColor.RED + plugin.getMessage("command_blocked"));
            }
        }
    }
}
package com.example.adminpasswordplugin;

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

public class CommandHandler implements CommandExecutor {

    private final Main plugin;
    private final AdminManager adminManager;

    public CommandHandler(Main plugin, AdminManager adminManager) {
        this.plugin = plugin;
        this.adminManager = adminManager;

        // Register commands
        PluginCommand adminRegCommand = plugin.getCommand("adminreg");
        if (adminRegCommand != null) {
            adminRegCommand.setExecutor(this);
        }

        PluginCommand adminLoginCommand = plugin.getCommand("adminlogin");
        if (adminLoginCommand != null) {
            adminLoginCommand.setExecutor(this);
        }

        PluginCommand adminChangePasswordCommand = plugin.getCommand("adminchangepassword");
        if (adminChangePasswordCommand != null) {
            adminChangePasswordCommand.setExecutor(this);
        }
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage(plugin.getMessage("not_player"));
            return true;
        }

        Player player = (Player) sender;
        String cmdName = command.getName().toLowerCase();

        switch (cmdName) {
            case "adminreg":
                handleAdminReg(player, args);
                break;
            case "adminlogin":
                handleAdminLogin(player, args);
                break;
            case "adminchangepassword":
                handleAdminChangePassword(player, args);
                break;
            default:
                return false;
        }

        return true;
    }

    /**
     * Handles the /adminreg command for registering admin passwords.
     *
     * @param player The player executing the command.
     * @param args   Command arguments.
     */
    private void handleAdminReg(Player player, String[] args) {
        if (!player.hasPermission("adminpasswordplugin.register")) {
            player.sendMessage(plugin.getMessage("no_permission"));
            return;
        }

        if (args.length != 1) {
            player.sendMessage(plugin.getMessage("usage_adminreg"));
            return;
        }

        String password = args[0];
        boolean registered = adminManager.registerPassword(player, password);

        if (registered) {
            player.sendMessage(plugin.getMessage("register_success"));
        } else {
            player.sendMessage(plugin.getMessage("register_already"));
        }
    }

    /**
     * Handles the /adminlogin command for admin authentication.
     *
     * @param player The player executing the command.
     * @param args   Command arguments.
     */
    private void handleAdminLogin(Player player, String[] args) {
        if (!player.hasPermission("adminpasswordplugin.login")) {
            player.sendMessage(plugin.getMessage("no_permission"));
            return;
        }

        if (args.length != 1) {
            player.sendMessage(plugin.getMessage("usage_adminlogin"));
            return;
        }

        String password = args[0];
        boolean loggedIn = adminManager.login(player, password);

        if (loggedIn) {
            player.sendMessage(plugin.getMessage("login_success"));
        } else {
            player.sendMessage(plugin.getMessage("login_failure"));
        }
    }

    /**
     * Handles the /adminchangepassword command for changing admin passwords.
     *
     * @param player The player executing the command.
     * @param args   Command arguments.
     */
    private void handleAdminChangePassword(Player player, String[] args) {
        if (!player.hasPermission("adminpasswordplugin.change_password")) {
            player.sendMessage(plugin.getMessage("no_permission"));
            return;
        }

        if (args.length != 2) {
            player.sendMessage(plugin.getMessage("password_change_usage"));
            return;
        }

        String oldPassword = args[0];
        String newPassword = args[1];
        boolean changed = adminManager.changePassword(player, oldPassword, newPassword);

        if (changed) {
            player.sendMessage(plugin.getMessage("password_change_success"));
        } else {
            player.sendMessage(plugin.getMessage("password_change_failure"));
        }
    }
}
package com.example.adminpasswordplugin;

import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;

import java.io.File;
import java.io.IOException;

public class Main extends JavaPlugin {

    private AdminManager adminManager;
    private File messagesFile;
    private FileConfiguration messagesConfig;

    @Override
    public void onEnable() {
        // Save default config.yml and messages.yml
        saveDefaultConfig();
        createMessagesConfig();

        // Initialize AdminManager
        adminManager = new AdminManager(this);

        // Register command handlers
        new CommandHandler(this, adminManager);

        // Register event listeners
        getServer().getPluginManager().registerEvents(new CommandBlockListener(this, adminManager), this);
        getServer().getPluginManager().registerEvents(new PlayerListener(this, adminManager), this);

        getLogger().info("AdminPasswordPlugin успешно включён!");
    }

    @Override
    public void onDisable() {
        // Save admin credentials when plugin is disabled
        adminManager.saveData();
        getLogger().info("AdminPasswordPlugin отключён!");
    }

    /**
     * Creates and loads the messages.yml configuration file.
     */
    private void createMessagesConfig() {
        messagesFile = new File(getDataFolder(), "messages.yml");
        if (!messagesFile.exists()) {
            saveResource("messages.yml", false);
        }
        messagesConfig = YamlConfiguration.loadConfiguration(messagesFile);
    }

    /**
     * Retrieves a message from messages.yml.
     *
     * @param path The path to the message.
     * @return The formatted message.
     */
    public String getMessage(String path) {
        return messagesConfig.getString("messages." + path, "Message not found!");
    }

    /**
     * Retrieves the AdminManager instance.
     *
     * @return The AdminManager.
     */
    public AdminManager getAdminManager() {
        return adminManager;
    }
}
package com.example.adminpasswordplugin;

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

public class PlayerListener implements Listener {

    private final Main plugin;
    private final AdminManager adminManager;

    public PlayerListener(Main plugin, AdminManager adminManager) {
        this.plugin = plugin;
        this.adminManager = adminManager;
    }

    @EventHandler
    public void onPlayerQuit(PlayerQuitEvent event) {
        Player player = event.getPlayer();
        adminManager.logout(player);
    }
}
Напиши полный код