修复: 成员权限显示未合并领地默认权限

handleGetMemberPerms 新增返回领地默认权限映射(default_perms),
严格对齐 Java getLandDefaultDeny 语义(含 denyDrop/denyPickup 反向列)。
前端 renderMemberPermDetail 对无自定义覆盖的权限键回退到领地默认,
与游戏内 getEffectiveDeny 的领地默认回退逻辑一致,
修复网页端显示"允许"而游戏内实际"禁止/限制"的权限不同步问题。
This commit is contained in:
ypsdf1
2026-07-12 10:32:10 +08:00
parent 9b39c9e56f
commit 0b283483a7
2 changed files with 64 additions and 3 deletions
+57
View File
@@ -72,6 +72,62 @@ $PERM_TYPES = [
'peaceMode' => '和平模式', 'peaceMode' => '和平模式',
]; ];
// ★ 领地默认权限列映射:perm键 → web_area_lands 列名
// reverse=true 表示该列存储的是 allow 标志(1=允许),需取反得到 deny 默认值
// 与 Java AreaProtection.getLandDefaultDeny 完全对齐
// (注意:denyDrop/denyPickup 在 area_lands 表中以 deny_drop/deny_pickup 列存储 allow 标志,实际存的是反义)
$PERM_DEFAULT_COLS = [
'denyMove' => ['col' => 'deny_move'],
'denyBlockPlace' => ['col' => 'deny_block_place'],
'denyBlockBreak' => ['col' => 'deny_block_break'],
'denyContainer' => ['col' => 'deny_container'],
'denyPVP' => ['col' => 'deny_pvp'],
'denyFallDamage' => ['col' => 'deny_fall_damage'],
'denyHunger' => ['col' => 'deny_hunger'],
'denyAllDamage' => ['col' => 'deny_all_damage'],
'denyDrop' => ['col' => 'deny_drop', 'reverse' => true],
'denyMount' => ['col' => 'deny_mount'],
'denyEnderPearl' => ['col' => 'deny_ender_pearl'],
'denyBow' => ['col' => 'deny_bow'],
'denyPotion' => ['col' => 'deny_potion'],
'denyExplosion' => ['col' => 'deny_explosion'],
'denyRaid' => ['col' => 'deny_raid'],
'denyFireSpread' => ['col' => 'deny_fire_spread'],
'denyAllEffects' => ['col' => 'deny_all_effects'],
'denyItemFrame' => ['col' => 'deny_item_frame'],
'denyEntityInteract' => ['col' => 'deny_entity_interact'],
'denyPickup' => ['col' => 'deny_pickup', 'reverse' => true],
'denyFire' => ['col' => 'deny_fire'],
'denyThrownProjectiles' => ['col' => 'deny_thrown_projectiles'],
'denyGlowing' => ['col' => 'deny_glowing'],
'denyRedstoneInteraction' => ['col' => 'deny_redstone_interaction'],
'denyDoorInteraction' => ['col' => 'deny_door_interaction'],
'denyNoteblockJukebox' => ['col' => 'deny_noteblock_jukebox'],
'denyLead' => ['col' => 'deny_lead'],
'denyCropHarvest' => ['col' => 'deny_crop_harvest'],
'denyWoolShear' => ['col' => 'deny_wool_shear'],
'denyAnimalFeeding' => ['col' => 'deny_animal_feeding'],
'denyMobAttack' => ['col' => 'deny_mob_attack'],
'peaceMode' => ['col' => 'peace_mode'],
];
// ★ 计算领地默认权限映射(与游戏内 getEffectiveDeny 的"领地默认"回退一致)
// 普通 deny* 列:1=禁止;denyDrop/denyPickup 列存 allow 标志,需取反
function getLandDefaultPerms($land) {
global $PERM_DEFAULT_COLS;
$defaults = [];
foreach ($PERM_DEFAULT_COLS as $key => $info) {
$raw = isset($land[$info['col']]) ? (int)$land[$info['col']] : 0;
if (!empty($info['reverse'])) {
// 列存 allow 标志(1=允许)→ 取反得 deny 默认
$defaults[$key] = ($raw !== 1);
} else {
$defaults[$key] = ($raw === 1);
}
}
return $defaults;
}
try { try {
// ★ 加载core.php(与sync.php相同的加载方式) // ★ 加载core.php(与sync.php相同的加载方式)
$coreFile = dirname(__DIR__) . '/core.php'; $coreFile = dirname(__DIR__) . '/core.php';
@@ -1900,6 +1956,7 @@ function handleGetMemberPerms($db, $playerName, $landName) {
echo json_encode([ echo json_encode([
'success' => true, 'success' => true,
'land' => $land, 'land' => $land,
'default_perms' => getLandDefaultPerms($land),
'members' => $members, 'members' => $members,
'perm_types' => $PERM_TYPES 'perm_types' => $PERM_TYPES
]); ]);
+7 -3
View File
@@ -3475,6 +3475,7 @@ async function renderMemberPermDetail(el, landName, targetPlayer) {
} }
const permMap = member.perm_map || {}; const permMap = member.perm_map || {};
const defaultPerms = data.default_perms || {};
const permEntries = Object.entries(permTypes); const permEntries = Object.entries(permTypes);
let html = `<div class="card"> let html = `<div class="card">
@@ -3487,14 +3488,17 @@ async function renderMemberPermDetail(el, landName, targetPlayer) {
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px">`; <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px">`;
for (const [key, label] of permEntries) { for (const [key, label] of permEntries) {
const denied = permMap[key] === true; // true = deny类权限激活=禁止 // ★ 与游戏内 getEffectiveDeny 一致:有自定义覆盖用自定义,否则回退领地默认
const hasCustom = Object.prototype.hasOwnProperty.call(permMap, key);
const denied = hasCustom ? (permMap[key] === true) : (defaultPerms[key] === true);
const isDefault = !hasCustom; // 继承领地默认
html += `<div onclick="toggleMemberPerm('${escHtml(landName)}','${escHtml(targetPlayer)}','${key}',this)" html += `<div onclick="toggleMemberPerm('${escHtml(landName)}','${escHtml(targetPlayer)}','${key}',this)"
style="background:${denied ? 'rgba(239,68,68,0.1)' : 'rgba(34,197,94,0.1)'}; style="background:${denied ? 'rgba(239,68,68,0.1)' : 'rgba(34,197,94,0.1)'};
border:1px solid ${denied ? 'var(--red)' : 'var(--green)'}; border:1px solid ${denied ? 'var(--red)' : 'var(--green)'};
border-radius:8px;padding:12px;cursor:pointer;transition:all 0.2s"> border-radius:8px;padding:12px;cursor:pointer;transition:all 0.2s;${isDefault ? 'opacity:.82' : ''}">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:4px"> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:4px">
<span style="color:var(--fg);font-size:13px;font-weight:500">${label}</span> <span style="color:var(--fg);font-size:13px;font-weight:500">${label}${isDefault ? ' <span style="font-size:9px;color:var(--dim)">默认</span>' : ''}</span>
<span style="font-size:11px;color:${denied ? 'var(--red)' : 'var(--green)'}"> <span style="font-size:11px;color:${denied ? 'var(--red)' : 'var(--green)'}">
${denied ? '✗ 禁止' : '✓ 允许'} ${denied ? '✗ 禁止' : '✓ 允许'}
</span> </span>