修复领地系统3个bug:

1. JSON解析崩溃:addConvertEffectsForFrontend将Java自定义格式转JSON数组
   - give_effects: 夜视:1:99999|SPEED:2:60 → [[夜视,1,99999],[SPEED,2,60]]
   - clear_effects: POISON,WITHER → [POISON,WITHER]
2. admin.php配置key名修复:land_price_per_sqm→create_price_per_sqm, max_lands→max_lands_per_player
3. handleUpdateLandField存储时将JSON数组转回Java格式
This commit is contained in:
ypsdf1
2026-06-27 14:52:34 +08:00
parent b8dd9b7cd0
commit bbd0049602
2 changed files with 67 additions and 10 deletions
+10 -6
View File
@@ -2277,6 +2277,7 @@ async function loadLands(el) {
// 配置信息
const cfg = configRes.config || {};
window._landCfgData = cfg; // 缓存供showLandConfig使用
html += `<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:20px">`;
const lands = landsRes.lands || [];
html += `<div style="background:var(--card);border:1px solid var(--border);border-radius:8px;padding:12px;text-align:center">
@@ -2288,8 +2289,8 @@ async function loadLands(el) {
<div style="font-size:24px;font-weight:bold;color:#4caf50">${shopItems.length}</div>
<div style="font-size:12px;color:var(--dim);margin-top:4px">在售权限</div>
</div>`;
const pricePerSqM = cfg.land_price_per_sqm || '10';
const maxLands = cfg.max_lands || '5';
const pricePerSqM = cfg.create_price_per_sqm || '10';
const maxLands = cfg.max_lands_per_player || '5';
html += `<div style="background:var(--card);border:1px solid var(--border);border-radius:8px;padding:12px;text-align:center">
<div style="font-size:24px;font-weight:bold;color:#ff9800">${pricePerSqM}</div>
<div style="font-size:12px;color:var(--dim);margin-top:4px">每平米价格(债券)</div>
@@ -2362,15 +2363,18 @@ async function loadLands(el) {
}
function showLandConfig() {
const cfg = window._landCfgData || {};
const price = cfg.create_price_per_sqm || '10';
const maxLands = cfg.max_lands_per_player || '5';
const html = `<div style="padding:16px">
<h3 style="margin:0 0 12px;color:var(--fg)">⚙️ 领地配置</h3>
<div style="margin-bottom:12px">
<label style="display:block;font-size:12px;color:var(--dim);margin-bottom:4px">每平米价格(债券)</label>
<input id="cfgPrice" type="number" value="10" min="1" style="width:100%;padding:8px;background:var(--bg);border:1px solid var(--border);border-radius:4px;color:var(--fg)">
<input id="cfgPrice" type="number" value="${price}" min="1" style="width:100%;padding:8px;background:var(--bg);border:1px solid var(--border);border-radius:4px;color:var(--fg)">
</div>
<div style="margin-bottom:12px">
<label style="display:block;font-size:12px;color:var(--dim);margin-bottom:4px">每人最大领地数</label>
<input id="cfgMaxLands" type="number" value="5" min="1" style="width:100%;padding:8px;background:var(--bg);border:1px solid var(--border);border-radius:4px;color:var(--fg)">
<input id="cfgMaxLands" type="number" value="${maxLands}" min="1" style="width:100%;padding:8px;background:var(--bg);border:1px solid var(--border);border-radius:4px;color:var(--fg)">
</div>
<button onclick="saveLandConfig()" style="width:100%;padding:8px;background:var(--accent);color:#fff;border:none;border-radius:4px;cursor:pointer">保存</button>
</div>`;
@@ -2384,12 +2388,12 @@ async function saveLandConfig() {
await fetch('api/land_api.php?action=update_config', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'key=land_price_per_sqm&value=' + encodeURIComponent(price) + '&secret=sdf1_web_comm_2026_ypshidifu'
body: 'key=create_price_per_sqm&value=' + encodeURIComponent(price) + '&secret=sdf1_web_comm_2026_ypshidifu'
});
await fetch('api/land_api.php?action=update_config', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'key=max_lands&value=' + encodeURIComponent(maxLands) + '&secret=sdf1_web_comm_2026_ypshidifu'
body: 'key=max_lands_per_player&value=' + encodeURIComponent(maxLands) + '&secret=sdf1_web_comm_2026_ypshidifu'
});
document.querySelector('.modal-close')?.click();
loadLands(document.getElementById('C'));
+57 -4
View File
@@ -7,6 +7,34 @@
header('Content-Type: application/json; charset=utf-8');
error_reporting(E_ERROR | E_PARSE);
/**
* ★ 将Java自定义格式转换为JSON数组
* give_effects: "夜视:1:99999|SPEED:2:60" → [["夜视","1","99999"],["SPEED","2","60"]]
* clear_effects: "POISON,WITHER" → ["POISON","WITHER"]
*/
function convertEffectsForFrontend($row) {
if (!empty($row['give_effects']) && $row['give_effects'][0] !== '[') {
$parts = explode('|', $row['give_effects']);
$arr = [];
foreach ($parts as $p) {
$p = trim($p);
if (empty($p)) continue;
$pieces = explode(':', $p);
if (count($pieces) >= 2) {
$arr[] = $pieces;
} else {
$arr[] = [$pieces[0], '1', '99999'];
}
}
$row['give_effects'] = json_encode($arr);
}
if (!empty($row['clear_effects']) && $row['clear_effects'][0] !== '[') {
$names = array_filter(explode(',', $row['clear_effects']), function($n) { return !empty(trim($n)); });
$row['clear_effects'] = json_encode(array_values(array_map('trim', $names)));
}
return $row;
}
try {
// ★ 加载core.php(与sync.php相同的加载方式)
$coreFile = dirname(__DIR__) . '/core.php';
@@ -546,7 +574,7 @@ function handleListLands($db) {
$result = $db->query("SELECT * FROM web_area_lands ORDER BY synced_at DESC");
$lands = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$lands[] = $row;
$lands[] = convertEffectsForFrontend($row);
}
echo json_encode(['success' => true, 'lands' => $lands]);
}
@@ -714,7 +742,7 @@ function handleMyLands($db, $playerName) {
$lands = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$lands[] = $row;
$lands[] = convertEffectsForFrontend($row);
}
echo json_encode(['success' => true, 'lands' => $lands, 'player' => $playerName]);
@@ -755,7 +783,7 @@ function handleLandDetail($db, $playerName, $landName) {
$visitors[] = $row;
}
echo json_encode(['success' => true, 'land' => $land, 'visitors' => $visitors]);
echo json_encode(['success' => true, 'land' => convertEffectsForFrontend($land), 'visitors' => $visitors]);
}
// ==================== 玩家端:添加访客 ====================
@@ -887,9 +915,34 @@ function handleUpdateLandField($db, $playerName, $post) {
// 确保字段存在(容错)
try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN {$field} TEXT DEFAULT ''"); } catch (\Throwable $e) {}
// ★ 将JSON数组转回Java格式再存储
$storeValue = $value;
if (($field === 'give_effects' || $field === 'clear_effects') && !empty($value) && $value[0] === '[') {
$arr = json_decode($value, true);
if (is_array($arr)) {
if ($field === 'give_effects') {
// [["夜视","1","99999"]] → "夜视:1:99999"
$parts = [];
foreach ($arr as $e) {
if (is_array($e)) {
$parts[] = implode(':', $e);
} else {
$parts[] = (string)$e;
}
}
$storeValue = implode('|', $parts);
} else {
// clear_effects: ["POISON","WITHER"] → "POISON,WITHER"
$storeValue = implode(',', array_map(function($e) {
return is_array($e) ? $e[0] : (string)$e;
}, $arr));
}
}
}
// 更新
$stmt2 = $db->prepare("UPDATE web_area_lands SET {$field} = :value, admin_changed = 1 WHERE name = :name");
$stmt2->bindValue(':value', $value, SQLITE3_TEXT);
$stmt2->bindValue(':value', $storeValue, SQLITE3_TEXT);
$stmt2->bindValue(':name', $name, SQLITE3_TEXT);
$stmt2->execute();