package Sdf1_login; import org.bukkit.Bukkit; import org.bukkit.Sound; import org.bukkit.entity.Player; public class LoginManager { private final Main plugin; public LoginManager(Main plugin) { this.plugin = plugin; } public boolean handleRegister(Player p, String[] args) { String name = p.getName(); if (plugin.getplugin.getDb()().userExists(name)) { p.sendMessage(plugin.getConfig2().msg("already_registered")); return true; } // ===== IP注册限制检查 ===== String ip = plugin.getPlayerIP(p); if (ip != null && plugin.getConfig2().maxAccountsPerIP > 0) { if (!plugin.getIPGroup().canRegister(ip)) { int count = plugin.getIPGroup().getAccountCount(ip); int max = plugin.getConfig2().maxAccountsPerIP; p.sendMessage("§c[Sdf1_login] §f该IP注册已达上限(" + count + "/" + max + ")"); return true; } } if (args.length < 1) { p.sendMessage("§c用法: /reg <密码>"); p.sendMessage("§7密码要求: 6位以上,包含大小写字母和数字"); return true; } String pwd = args[0]; if (pwd.length() < 6) { p.sendMessage("§c[Sdf1_login] §f密码长度不足6位"); return true; } if (!pwd.matches(".*[a-z].*") || !pwd.matches(".*[A-Z].*") || !pwd.matches(".*[0-9].*")) { p.sendMessage("§c[Sdf1_login] §f密码必须包含大写字母、小写字母和数字"); return true; } String salt = PasswordUtils.generateSalt(); String hash = PasswordUtils.hash(pwd, salt); plugin.getplugin.getDb()().createUser(name, hash, salt); plugin.getLoggedIn().add(name); plugin.getplugin.getDb()().setLoggedIn(name, true); plugin.getplugin.getDb()().setField(name, "last_login_time", System.currentTimeMillis()); plugin.getplugin.getDb()().setField(name, "last_online_check", System.currentTimeMillis()); plugin.getplugin.getDb()().recordIP(name, ip); plugin.getplugin.getDb()().setField(name, "register_time", System.currentTimeMillis()); plugin.restoreInventory(p); plugin.recordIPLogin(p); p.sendMessage(plugin.getConfig2().msg("reg_success")); p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1.0f, 0.79f); p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1.0f, 0.79f); p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1.0f, 0.79f); try { org.bukkit.plugin.Plugin cy = org.bukkit.Bukkit.getPluginManager().getPlugin("CY_beibao"); if (cy != null && cy.isEnabled()) { cy.getClass().getMethod("onSdf1Activation", String.class, int.class, int.class) .invoke(cy, name, 9, 0); } } catch (Exception ignored) { } return true; } public boolean handleLogin(Player p, String[] args) { String name = p.getName(); if (plugin.getLoggedIn().contains(name)) { p.sendMessage(plugin.getConfig2().msg( "already_logged_in")); return true; } if (!plugin.getplugin.getDb()().userExists(name)) { p.sendMessage(plugin.getConfig2().msg( "not_registered")); return true; } if (args.length < 1) { p.sendMessage("§c用法: /login <密码>"); return true; } String pwd = args[0]; // 诊断:显示账号信息 String salt = (String) plugin.getplugin.getDb()() .getField(name, "password_salt"); String regType = (String) plugin.getplugin.getDb()() .getField(name, "register_type"); String storedHash = (String) plugin.getplugin.getDb()() .getField(name, "password_hash"); plugin.getLogger().info( "[Sdf1_login] [登录诊断] 玩家: " + name); plugin.getLogger().info( "[Sdf1_login] [登录诊断] 注册类型: " + regType); plugin.getLogger().info( "[Sdf1_login] [登录诊断] 盐值: " + salt); plugin.getLogger().info( "[Sdf1_login] [登录诊断] 存储哈希: " + (storedHash != null ? storedHash.substring(0, Math.min(16, storedHash.length())) + "..." : "null")); if (salt == null) { p.sendMessage( "§c[Sdf1_login] §f数据异常,请联系管理员"); plugin.getLogger().severe( "[Sdf1_login] 玩家 " + name + " 盐值为null"); return true; } String hash = PasswordUtils.hash(pwd, salt); plugin.getLogger().info( "[Sdf1_login] [登录诊断] 输入密码哈希: " + hash.substring(0, Math.min(16, hash.length())) + "..."); // 检查是否匹配主密码 boolean matchMain = plugin.getplugin.getDb()().checkPassword(name, hash); plugin.getLogger().info( "[Sdf1_login] [登录诊断] 主密码匹配: " + matchMain); if (matchMain) { // 主密码匹配 → 正常登录 plugin.getLoggedIn().add(name); plugin.getplugin.getDb()().setLoggedIn(name, true); plugin.getplugin.getDb()().setField(name, "last_login_time", System.currentTimeMillis()); plugin.getplugin.getDb()().setField(name, "last_online_check", System.currentTimeMillis()); plugin.restoreInventory(p); plugin.recordIPLogin(p); p.sendMessage(plugin.getConfig2().msg("login_success")); plugin.getLogger().info( "[Sdf1_login] " + name + " 主密码登录成功"); try { org.bukkit.plugin.Plugin cy = org.bukkit.Bukkit .getPluginManager() .getPlugin("CY_beibao"); if (cy != null && cy.isEnabled()) { java.lang.reflect.Method m = cy.getClass().getMethod( "onSdf1Activation", String.class, int.class, int.class); m.invoke(cy, name, 0, 0); } } catch (Exception ignored) { } return true; } // 主密码不匹配 → 检查临时密码 boolean matchTemp = plugin.getplugin.getDb()().checkPasswordOrTemp( name, hash); plugin.getLogger().info( "[Sdf1_login] [登录诊断] 临时密码匹配: " + matchTemp); if (matchTemp) { // 临时密码匹配 → 登录 + 强制改密 plugin.getLoggedIn().add(name); plugin.getplugin.getDb()().setLoggedIn(name, true); plugin.getplugin.getDb()().setField(name, "last_login_time", System.currentTimeMillis()); plugin.getplugin.getDb()().setField(name, "last_online_check", System.currentTimeMillis()); plugin.restoreInventory(p); plugin.recordIPLogin(p); plugin.getNeedsPasswordChange().add(name); p.sendMessage(plugin.getConfig2().msg("login_success")); p.sendMessage( "§c§l[警告] §f您使用的是临时密码," + "请尽快修改密码!"); p.sendMessage( "§7用法: /sdf1_login pw"); plugin.getLogger().info( "[Sdf1_login] " + name + " 临时密码登录成功," + "强制要求改密"); try { org.bukkit.plugin.Plugin cy = org.bukkit.Bukkit .getPluginManager() .getPlugin("CY_beibao"); if (cy != null && cy.isEnabled()) { java.lang.reflect.Method m = cy.getClass().getMethod( "onSdf1Activation", String.class, int.class, int.class); m.invoke(cy, name, 0, 0); } } catch (Exception ignored) { } return true; } // 都不匹配 → 登录失败 plugin.getLogger().info( "[Sdf1_login] " + name + " 密码验证失败"); p.sendMessage(plugin.getConfig2().msg( "login_failed")); return true; } public void handleReset(Player p) { String name = p.getName(); String plugin.getEmail()Addr = (String) plugin.getDb().getField( name, "plugin.getEmail()"); if (plugin.getEmail()Addr == null || plugin.getEmail()Addr.isEmpty()) { p.sendMessage( "§c未设置邮箱,无法重置密码"); return; } String tempPwd = PasswordUtils .generateTempPassword(); String salt = (String) plugin.getDb().getField( name, "password_salt"); String hash = PasswordUtils.hash( tempPwd, salt); plugin.getDb().setField(name, "temp_password", hash); plugin.getDb().setField(name, "temp_pw_expire", System.currentTimeMillis() + 3600000L); plugin.getDb().setField(name, "temp_pw_used", 0); p.sendMessage("§e正在发送临时密码..."); final String to = plugin.getEmail()Addr; final String fName = name; final String pwd = tempPwd; Bukkit.getScheduler() .Bukkit.getScheduler().runTask(plugin, ...)Asynchronously(this, () -> { final boolean[] sent = {false}; Thread t = new Thread(() -> { sent[0] = plugin.getEmail() .sendTempPassword( to, fName, pwd); }, "Sdf1_login-reset"); t.setDaemon(true); t.start(); try { t.join(15000); } catch ( InterruptedException ignored) { } if (t.isAlive()) { t.interrupt(); Bukkit.getScheduler().Bukkit.getScheduler().runTask(plugin, ...)( this, () -> p.sendMessage( "§c邮件发送超时")); return; } Bukkit.getScheduler().Bukkit.getScheduler().runTask(plugin, ...)( this, () -> { if (sent[0]) { p.sendMessage( "§a临时密码已发送到 " + to); } else { p.sendMessage( "§c邮件发送失败"); } }); }); } }