修复领地权限系统4大bug:DB列缺失+成员不同步+管理员继承+login.db校验
1. AreaProtection.updateVisitorPermFromWeb: INSERT语句去掉不存在的land_name/synced_at列,修复"table area_land_permissions has no column named land_name" 2. AreaProtection.removePlayerFromAreaWhitelist: 移除成员时同步删除area_land_permissions记录,确保admin身份一并清除,不再继承 3. AreaProtection.removeLandMember: GUI移除成员也同步删除area_land_permissions 4. AreaProtection.insertLandPermission: 新增公共方法,PHP添加成员时写入权限表 5. AreaProtection.handlePendingAddMemberInput: 添加成员前校验login.db(DatabaseManager.userExists),拒绝不存在的玩家 6. WebManager: 新增add_visitor/remove_visitor变更类型处理,PHP添加/移除成员后Java自动同步白名单+权限表
This commit is contained in:
@@ -2569,6 +2569,28 @@ public class AreaProtection implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入一条领地权限记录(角色为 member/visitor),已存在则忽略
|
||||
* 用于 PHP 端添加成员时同步到 Java
|
||||
*/
|
||||
public void insertLandPermission(String landName, String playerName, String role) {
|
||||
int landId = getLandIdFromDb(landName);
|
||||
if (landId <= 0 || dbConnection == null) return;
|
||||
try {
|
||||
PreparedStatement stmt = dbConnection.prepareStatement(
|
||||
"INSERT OR IGNORE INTO area_land_permissions (land_id, player_name, role, permissions, granted_at) " +
|
||||
"VALUES (?, ?, ?, '', ?)");
|
||||
stmt.setInt(1, landId);
|
||||
stmt.setString(2, playerName);
|
||||
stmt.setString(3, role != null && !role.isEmpty() ? role : "visitor");
|
||||
stmt.setLong(4, System.currentTimeMillis() / 1000);
|
||||
stmt.executeUpdate();
|
||||
stmt.close();
|
||||
} catch (SQLException e) {
|
||||
// 忽略
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ★ 核心方法:获取玩家的effective deny状态
|
||||
* 优先级:per-player权限 > 领地默认权限
|
||||
@@ -4222,6 +4244,8 @@ public class AreaProtection implements Listener {
|
||||
}
|
||||
saveWhitelists();
|
||||
}
|
||||
// ★ 同步删除 area_land_permissions 记录(确保 admin 身份一并清除)
|
||||
removePlayerFromAreaWhitelist(landName, playerName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8510,14 +8534,14 @@ public class AreaProtection implements Listener {
|
||||
|
||||
// 更新数据库中的自定义权限(同时写回 effectiveRole,确保新记录角色正确)
|
||||
PreparedStatement ps = dbConnection.prepareStatement(
|
||||
"INSERT INTO area_land_permissions (land_id, land_name, player_name, role, permissions, granted_at, synced_at) " +
|
||||
"VALUES (?, ?, ?, ?, ?, 0, 0) " +
|
||||
"INSERT INTO area_land_permissions (land_id, player_name, role, permissions, granted_at) " +
|
||||
"VALUES (?, ?, ?, ?, ?) " +
|
||||
"ON CONFLICT(land_id, player_name) DO UPDATE SET permissions = excluded.permissions, role = excluded.role");
|
||||
ps.setInt(1, landId);
|
||||
ps.setString(2, lname);
|
||||
ps.setString(3, playerName);
|
||||
ps.setString(4, effectiveRole);
|
||||
ps.setString(5, permsJson);
|
||||
ps.setString(2, playerName);
|
||||
ps.setString(3, effectiveRole);
|
||||
ps.setString(4, permsJson);
|
||||
ps.setLong(5, System.currentTimeMillis() / 1000);
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
}
|
||||
@@ -8762,6 +8786,14 @@ public class AreaProtection implements Listener {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ★ 校验玩家是否在login.db中注册(防止添加不存在的玩家)
|
||||
DatabaseManager dbMgr = plugin.getDb();
|
||||
if (dbMgr != null && !dbMgr.userExists(playerName)) {
|
||||
p.sendMessage("§c§l[添加成员] §f玩家 " + playerName + " 不存在(未在login.db中注册)");
|
||||
p.sendMessage("§7请确认玩家名是否正确,或输入 cancel 取消");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 添加成员
|
||||
addLandMember(landName, playerName);
|
||||
p.sendMessage("§a§l[添加成员] §f已成功添加 " + playerName + " 为领地成员");
|
||||
@@ -9603,6 +9635,31 @@ public class AreaProtection implements Listener {
|
||||
boolean ok = wl.remove(playerName);
|
||||
if (!ok) ok = wl.remove(playerName.toLowerCase());
|
||||
if (ok) saveWhitelists();
|
||||
|
||||
// ★ 移除成员时,同步删除 area_land_permissions 记录
|
||||
// 确保 admin 身份一并清除,不再继承
|
||||
if (dbConnection != null) {
|
||||
try {
|
||||
int landId = getLandIdFromDb(areaName);
|
||||
if (landId > 0) {
|
||||
PreparedStatement ps = dbConnection.prepareStatement(
|
||||
"DELETE FROM area_land_permissions WHERE land_id = ? AND player_name = ?");
|
||||
ps.setInt(1, landId);
|
||||
ps.setString(2, playerName);
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
// 同时删小写
|
||||
PreparedStatement ps2 = dbConnection.prepareStatement(
|
||||
"DELETE FROM area_land_permissions WHERE land_id = ? AND player_name = ?");
|
||||
ps2.setInt(1, landId);
|
||||
ps2.setString(2, playerName.toLowerCase());
|
||||
ps2.executeUpdate();
|
||||
ps2.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
plugin.getLogger().warning("[防护] 移除成员时清理权限失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -3886,6 +3886,37 @@ public class WebManager {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "add_visitor": {
|
||||
// ★ PHP端添加成员 → 添加到Java白名单+权限表
|
||||
String playerName2 = changeData.containsKey("player")
|
||||
? String.valueOf(changeData.get("player")) : targetName;
|
||||
String landName2 = String.valueOf(changeData.getOrDefault("land_name", ""));
|
||||
String role2 = String.valueOf(changeData.getOrDefault("role", "visitor"));
|
||||
if (!playerName2.isEmpty() && !landName2.isEmpty()) {
|
||||
areaProtect.addPlayerToAreaWhitelist(landName2, playerName2);
|
||||
// 写入area_land_permissions表:admin走setLandAdmin,其他角色走INSERT OR IGNORE
|
||||
if ("admin".equalsIgnoreCase(role2)) {
|
||||
areaProtect.setLandAdmin(landName2, playerName2, true);
|
||||
} else {
|
||||
areaProtect.insertLandPermission(landName2, playerName2, role2);
|
||||
}
|
||||
plugin.getLogger().info("[Web通信] PHP端添加成员: " + playerName2 + " → " + landName2 + " role=" + role2);
|
||||
applied = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "remove_visitor": {
|
||||
// ★ PHP端移除成员 → 从Java白名单+权限表删除
|
||||
String playerName3 = changeData.containsKey("player")
|
||||
? String.valueOf(changeData.get("player")) : targetName;
|
||||
String landName3 = String.valueOf(changeData.getOrDefault("land_name", ""));
|
||||
if (!playerName3.isEmpty() && !landName3.isEmpty()) {
|
||||
areaProtect.removePlayerFromAreaWhitelist(landName3, playerName3);
|
||||
plugin.getLogger().info("[Web通信] PHP端移除成员: " + playerName3 + " ← " + landName3);
|
||||
applied = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "land_field_change": {
|
||||
String field = String.valueOf(changeData.getOrDefault("field", ""));
|
||||
String value = String.valueOf(changeData.getOrDefault("value", ""));
|
||||
|
||||
Reference in New Issue
Block a user