diff --git a/admin.php b/admin.php
index 54830f1..4d430a1 100644
--- a/admin.php
+++ b/admin.php
@@ -2662,6 +2662,9 @@ function showLandConfig() {
const cfg = window._landCfgData || {};
const price = cfg.create_price_per_sqm || '10';
const maxLands = cfg.max_lands_per_player || '5';
+ const refundRatio = cfg.refund_ratio_per_cent || '100';
+ const maxFreeArea = cfg.max_free_area_sqm || '3500';
+ const maxSide = cfg.max_land_side_blocks || '7000';
const html = `
`;
showModal('领地配置', '', null, html);
@@ -2680,6 +2695,9 @@ function showLandConfig() {
async function saveLandConfig() {
const price = document.getElementById('cfgPrice')?.value || '10';
const maxLands = document.getElementById('cfgMaxLands')?.value || '5';
+ const refundRatio = document.getElementById('cfgRefundRatio')?.value || '100';
+ const maxFreeArea = document.getElementById('cfgMaxFreeArea')?.value || '3500';
+ const maxSide = document.getElementById('cfgMaxSide')?.value || '7000';
try {
await fetch('api/land_api.php?action=update_config', {
method: 'POST',
@@ -2691,6 +2709,21 @@ async function saveLandConfig() {
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'key=max_lands_per_player&value=' + encodeURIComponent(maxLands) + '&secret=' + SECRET + ''
});
+ await fetch('api/land_api.php?action=update_config', {
+ method: 'POST',
+ headers: {'Content-Type': 'application/x-www-form-urlencoded'},
+ body: 'key=refund_ratio_per_cent&value=' + encodeURIComponent(refundRatio) + '&secret=' + SECRET + ''
+ });
+ await fetch('api/land_api.php?action=update_config', {
+ method: 'POST',
+ headers: {'Content-Type': 'application/x-www-form-urlencoded'},
+ body: 'key=max_free_area_sqm&value=' + encodeURIComponent(maxFreeArea) + '&secret=' + SECRET + ''
+ });
+ await fetch('api/land_api.php?action=update_config', {
+ method: 'POST',
+ headers: {'Content-Type': 'application/x-www-form-urlencoded'},
+ body: 'key=max_land_side_blocks&value=' + encodeURIComponent(maxSide) + '&secret=' + SECRET + ''
+ });
document.querySelector('.modal-close')?.click();
loadLands(document.getElementById('C'));
} catch(e) {
diff --git a/api/land_api.php b/api/land_api.php
index 106eea0..b1220b3 100644
--- a/api/land_api.php
+++ b/api/land_api.php
@@ -147,6 +147,8 @@ $PERM_DEFAULT_COLS = [
'denyWoolShear' => ['col' => 'deny_wool_shear'],
'denyAnimalFeeding' => ['col' => 'deny_animal_feeding'],
'denyMobAttack' => ['col' => 'deny_mob_attack'],
+ 'denySpawnEgg' => ['col' => 'deny_spawn_egg'],
+ 'denyWax' => ['col' => 'deny_wax'],
'peaceMode' => ['col' => 'peace_mode'],
];
@@ -649,6 +651,8 @@ function initLandTables($db) {
'deny_wool_shear' => "INTEGER DEFAULT 0",
'deny_animal_feeding' => "INTEGER DEFAULT 0",
'deny_mob_attack' => "INTEGER DEFAULT 0",
+ 'deny_spawn_egg' => "INTEGER DEFAULT 0",
+ 'deny_wax' => "INTEGER DEFAULT 0",
'deny_container' => "INTEGER DEFAULT 0",
'peace_mode' => "INTEGER DEFAULT 0",
'peace_mode_duration' => "INTEGER DEFAULT 0",
@@ -833,6 +837,7 @@ function handleSyncLands($db, $post) {
confiscate_msg, deny_thrown_projectiles, deny_glowing, deny_redstone_interaction,
deny_door_interaction, deny_noteblock_jukebox, deny_lead, deny_crop_harvest,
deny_wool_shear, deny_animal_feeding,
+ deny_spawn_egg, deny_wax,
warp_x, warp_y, warp_z, warp_yaw, warp_pitch, warp_world,
deny_container, deny_mob_attack,
enable_announce, announce_template, txt_content, deny_fluid, is_public_building, allow_visitor_teleport)
@@ -848,6 +853,7 @@ function handleSyncLands($db, $post) {
:confiscate_msg, :deny_thrown_projectiles, :deny_glowing, :deny_redstone_interaction,
:deny_door_interaction, :deny_noteblock_jukebox, :deny_lead, :deny_crop_harvest,
:deny_wool_shear, :deny_animal_feeding,
+ :deny_spawn_egg, :deny_wax,
:warp_x, :warp_y, :warp_z, :warp_yaw, :warp_pitch, :warp_world,
:deny_container, :deny_mob_attack,
:enable_announce, :announce_template, :txt_content, :deny_fluid, :is_public_building, :allow_visitor_teleport)");
@@ -912,6 +918,8 @@ function handleSyncLands($db, $post) {
$stmt->bindValue(':deny_crop_harvest', (int)($land['deny_crop_harvest'] ?? 0), SQLITE3_INTEGER);
$stmt->bindValue(':deny_wool_shear', (int)($land['deny_wool_shear'] ?? 0), SQLITE3_INTEGER);
$stmt->bindValue(':deny_animal_feeding', (int)($land['deny_animal_feeding'] ?? 0), SQLITE3_INTEGER);
+ $stmt->bindValue(':deny_spawn_egg', (int)($land['deny_spawn_egg'] ?? 0), SQLITE3_INTEGER);
+ $stmt->bindValue(':deny_wax', (int)($land['deny_wax'] ?? 0), SQLITE3_INTEGER);
// ★ 传送点
$stmt->bindValue(':warp_x', (float)($land['warp_x'] ?? 0), SQLITE3_FLOAT);
$stmt->bindValue(':warp_y', (float)($land['warp_y'] ?? 0), SQLITE3_FLOAT);
@@ -1048,6 +1056,13 @@ function handleUpdateConfig($db, $post) {
// ★ 去除前导零:01 → 1,防止静默失败
if (is_numeric($value)) $value = (string)(int)$value;
+ // ★ 面积限制/退费比例:服务端钳制,防脏值
+ if ($key === 'refund_ratio_per_cent') {
+ $value = (string)max(0, min(100, (int)$value));
+ } elseif ($key === 'max_free_area_sqm' || $key === 'max_land_side_blocks') {
+ $value = (string)max(1, (int)$value);
+ }
+
$stmt = $db->prepare("INSERT OR REPLACE INTO web_area_config (key, value) VALUES (:key, :val)");
$stmt->bindValue(':key', $key, SQLITE3_TEXT);
$stmt->bindValue(':val', $value, SQLITE3_TEXT);
@@ -1670,7 +1685,7 @@ function handleUpdateLandField($db, $playerName, $post) {
'deny_item_frame', 'deny_glowing', 'deny_redstone_interaction',
'deny_door_interaction', 'deny_noteblock_jukebox', 'deny_lead',
'deny_crop_harvest', 'deny_wool_shear', 'deny_animal_feeding',
- 'deny_mob_attack', 'deny_fluid',
+ 'deny_mob_attack', 'deny_fluid', 'deny_spawn_egg', 'deny_wax',
// 高级设置
'confiscate_items', 'deny_use_items', 'punish_commands',
'peace_mode', 'peace_mode_duration', 'enforce_game_mode',
diff --git a/api/sync.php b/api/sync.php
index e8405cf..d3afadf 100644
--- a/api/sync.php
+++ b/api/sync.php
@@ -489,6 +489,8 @@ function syncLands() {
try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN deny_raid INTEGER DEFAULT 0"); } catch (\Throwable $e) {}
try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN deny_container INTEGER DEFAULT 0"); } catch (\Throwable $e) {}
try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN deny_mob_attack INTEGER DEFAULT 0"); } catch (\Throwable $e) {}
+ try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN deny_spawn_egg INTEGER DEFAULT 0"); } catch (\Throwable $e) {}
+ try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN deny_wax INTEGER DEFAULT 0"); } catch (\Throwable $e) {}
try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN is_public_building INTEGER DEFAULT 0"); } catch (\Throwable $e) {}
try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN allow_visitor_teleport INTEGER DEFAULT 0"); } catch (\Throwable $e) {}
try { $db->exec("ALTER TABLE web_area_lands ADD COLUMN confiscate_items TEXT DEFAULT ''"); } catch (\Throwable $e) {}
@@ -505,7 +507,7 @@ function syncLands() {
deny_item_frame, deny_entity_interact, deny_move, deny_pickup, deny_drop, deny_explosion, deny_fall_damage, deny_hunger,
deny_all_damage, clear_effects, give_effects, clear_all_bad,
admin_changed, deny_thrown_projectiles, deny_glowing, deny_redstone_interaction, deny_door_interaction,
- deny_noteblock_jukebox, deny_lead, deny_crop_harvest, deny_wool_shear, deny_animal_feeding,
+ deny_noteblock_jukebox, deny_lead, deny_crop_harvest, deny_wool_shear, deny_animal_feeding, deny_spawn_egg, deny_wax,
warp_x, warp_y, warp_z, warp_yaw, warp_pitch, warp_world,
deny_mount, deny_ender_pearl, deny_bow, deny_potion, deny_fire, deny_raid,
deny_container, deny_mob_attack, is_public_building, allow_visitor_teleport,
@@ -517,7 +519,7 @@ function syncLands() {
:deny_item_frame, :deny_entity_interact, :deny_move, :deny_pickup, :deny_drop, :deny_explosion, :deny_fall_damage, :deny_hunger,
:deny_all_damage, :clear_effects, :give_effects, :clear_all_bad,
:admin_changed, :deny_thrown_projectiles, :deny_glowing, :deny_redstone_interaction, :deny_door_interaction,
- :deny_noteblock_jukebox, :deny_lead, :deny_crop_harvest, :deny_wool_shear, :deny_animal_feeding,
+ :deny_noteblock_jukebox, :deny_lead, :deny_crop_harvest, :deny_wool_shear, :deny_animal_feeding, :deny_spawn_egg, :deny_wax,
:warp_x, :warp_y, :warp_z, :warp_yaw, :warp_pitch, :warp_world,
:deny_mount, :deny_ender_pearl, :deny_bow, :deny_potion, :deny_fire, :deny_raid,
:deny_container, :deny_mob_attack, :is_public_building, :allow_visitor_teleport,
@@ -578,6 +580,8 @@ function syncLands() {
$stmt->bindValue(':deny_crop_harvest', (int)($land['deny_crop_harvest'] ?? 0), SQLITE3_INTEGER);
$stmt->bindValue(':deny_wool_shear', (int)($land['deny_wool_shear'] ?? 0), SQLITE3_INTEGER);
$stmt->bindValue(':deny_animal_feeding', (int)($land['deny_animal_feeding'] ?? 0), SQLITE3_INTEGER);
+ $stmt->bindValue(':deny_spawn_egg', (int)($land['deny_spawn_egg'] ?? 0), SQLITE3_INTEGER);
+ $stmt->bindValue(':deny_wax', (int)($land['deny_wax'] ?? 0), SQLITE3_INTEGER);
$stmt->bindValue(':warp_x', (double)($land['warp_x'] ?? 0), SQLITE3_FLOAT);
$stmt->bindValue(':warp_y', (double)($land['warp_y'] ?? 0), SQLITE3_FLOAT);
$stmt->bindValue(':warp_z', (double)($land['warp_z'] ?? 0), SQLITE3_FLOAT);
diff --git a/player.php b/player.php
index deec3f2..92a3d98 100644
--- a/player.php
+++ b/player.php
@@ -3468,6 +3468,8 @@ async function renderLandDetail(el, landName) {
['deny_wool_shear', '剪切羊毛/生物', false],
['deny_animal_feeding', '投喂动物', false],
['deny_mob_attack', '攻击生物', false],
+ ['deny_spawn_egg', '生物蛋(生成/孵化)', false],
+ ['deny_wax', '涂蜡/刮蜡', false],
['deny_fluid', '流体放置', false],
['allow_visitor_teleport', '允许传送', true],
['is_public_building', '公共建筑设施', true],