@
领地系统大修:新增10个权限事件处理器 + GUI权限补全 + 删除二次确认修复 新增事件处理器: - ProjectileLaunchEvent: 投掷物检测(三叉戟/雪球/风蛋) - PlayerInteractEvent: 门禁交互(按钮/门/压力板/绊线钩) - NotePlayEvent: 音符盒交互 - JukeboxPlay(InteractEvent): 唱片机交互 - PlayerInteractEvent: 红石交互(中继器/比较器) - PlayerInteractEntityEvent: 拴绳使用 - BlockGrowEvent: 农作物收获 - PlayerShearEntityEvent: 剪切羊毛/生物 - EntityBreedEvent: 投喂动物 - RaidTriggerEvent: 袭击侦测 - 周期性扫描: 玩家发光检测 修复: - GUI权限列表: "PVP"→"玩家对战", "Raid"→"袭击侦测", 补全全部29项权限 - 删除二次确认: 防止绕过1分钟延迟 - 移除重复import, 修复InventoryHolder缺失 @
This commit is contained in:
@@ -326,19 +326,32 @@ public class AreaGUIManager implements Listener {
|
||||
perms.add(new PermEntry("移动", !land.denyMove));
|
||||
perms.add(new PermEntry("放置方块", !land.denyBlockPlace));
|
||||
perms.add(new PermEntry("破坏方块", !land.denyBlockBreak));
|
||||
perms.add(new PermEntry("PVP", !land.denyPVP));
|
||||
perms.add(new PermEntry("玩家对战", !land.denyPVP));
|
||||
perms.add(new PermEntry("骑乘坐具", !land.denyMount));
|
||||
perms.add(new PermEntry("投掷末影珍珠", !land.denyEnderPearl));
|
||||
perms.add(new PermEntry("Raid", !land.denyRaid));
|
||||
perms.add(new PermEntry("投掷物(三叉戟/雪球/风蛋)", !land.denyThrownProjectiles));
|
||||
perms.add(new PermEntry("袭击侦测", !land.denyRaid));
|
||||
perms.add(new PermEntry("弓箭射击", !land.denyBow));
|
||||
perms.add(new PermEntry("药水效果", !land.denyPotion));
|
||||
perms.add(new PermEntry("点燃", !land.denyFire));
|
||||
perms.add(new PermEntry("火焰蔓延", !land.denyFireSpread));
|
||||
perms.add(new PermEntry("拾取物品", !land.denyPickup));
|
||||
perms.add(new PermEntry("丢弃物品", !land.denyDrop));
|
||||
perms.add(new PermEntry("弓箭", !land.denyBow));
|
||||
perms.add(new PermEntry("药水", !land.denyPotion));
|
||||
perms.add(new PermEntry("爆炸", !land.denyExplosion));
|
||||
perms.add(new PermEntry("摔落伤害", !land.denyFallDamage));
|
||||
perms.add(new PermEntry("饥饿", !land.denyHunger));
|
||||
perms.add(new PermEntry("所有伤害", !land.denyAllDamage));
|
||||
perms.add(new PermEntry("所有效果", !land.denyAllEffects));
|
||||
perms.add(new PermEntry("展示框交互", !land.denyItemFrame));
|
||||
perms.add(new PermEntry("红石电路(中继器/比较器)", !land.denyRedstoneInteraction));
|
||||
perms.add(new PermEntry("门禁(门/按钮/压力板)", !land.denyDoorInteraction));
|
||||
perms.add(new PermEntry("音频(音符盒/唱片机)", !land.denyNoteblockJukebox));
|
||||
perms.add(new PermEntry("拴绳使用", !land.denyLead));
|
||||
perms.add(new PermEntry("农作物收获", !land.denyCropHarvest));
|
||||
perms.add(new PermEntry("剪切羊毛/生物", !land.denyWoolShear));
|
||||
perms.add(new PermEntry("投喂动物", !land.denyAnimalFeeding));
|
||||
perms.add(new PermEntry("玩家发光", !land.denyGlowing));
|
||||
perms.add(new PermEntry("和平模式", !land.peaceMode));
|
||||
return perms;
|
||||
}
|
||||
|
||||
@@ -363,19 +376,32 @@ public class AreaGUIManager implements Listener {
|
||||
case "移动": land.denyMove = !land.denyMove; break;
|
||||
case "放置方块": land.denyBlockPlace = !land.denyBlockPlace; break;
|
||||
case "破坏方块": land.denyBlockBreak = !land.denyBlockBreak; break;
|
||||
case "PVP": land.denyPVP = !land.denyPVP; break;
|
||||
case "玩家对战": land.denyPVP = !land.denyPVP; break;
|
||||
case "骑乘坐具": land.denyMount = !land.denyMount; break;
|
||||
case "投掷末影珍珠": land.denyEnderPearl = !land.denyEnderPearl; break;
|
||||
case "Raid": land.denyRaid = !land.denyRaid; break;
|
||||
case "投掷物(三叉戟/雪球/风蛋)": land.denyThrownProjectiles = !land.denyThrownProjectiles; break;
|
||||
case "袭击侦测": land.denyRaid = !land.denyRaid; break;
|
||||
case "弓箭射击": land.denyBow = !land.denyBow; break;
|
||||
case "药水效果": land.denyPotion = !land.denyPotion; break;
|
||||
case "点燃": land.denyFire = !land.denyFire; break;
|
||||
case "火焰蔓延": land.denyFireSpread = !land.denyFireSpread; break;
|
||||
case "拾取物品": land.denyPickup = !land.denyPickup; break;
|
||||
case "丢弃物品": land.denyDrop = !land.denyDrop; break;
|
||||
case "弓箭": land.denyBow = !land.denyBow; break;
|
||||
case "药水": land.denyPotion = !land.denyPotion; break;
|
||||
case "爆炸": land.denyExplosion = !land.denyExplosion; break;
|
||||
case "摔落伤害": land.denyFallDamage = !land.denyFallDamage; break;
|
||||
case "饥饿": land.denyHunger = !land.denyHunger; break;
|
||||
case "所有伤害": land.denyAllDamage = !land.denyAllDamage; break;
|
||||
case "所有效果": land.denyAllEffects = !land.denyAllEffects; break;
|
||||
case "展示框交互": land.denyItemFrame = !land.denyItemFrame; break;
|
||||
case "红石电路(中继器/比较器)": land.denyRedstoneInteraction = !land.denyRedstoneInteraction; break;
|
||||
case "门禁(门/按钮/压力板)": land.denyDoorInteraction = !land.denyDoorInteraction; break;
|
||||
case "音频(音符盒/唱片机)": land.denyNoteblockJukebox = !land.denyNoteblockJukebox; break;
|
||||
case "拴绳使用": land.denyLead = !land.denyLead; break;
|
||||
case "农作物收获": land.denyCropHarvest = !land.denyCropHarvest; break;
|
||||
case "剪切羊毛/生物": land.denyWoolShear = !land.denyWoolShear; break;
|
||||
case "投喂动物": land.denyAnimalFeeding = !land.denyAnimalFeeding; break;
|
||||
case "玩家发光": land.denyGlowing = !land.denyGlowing; break;
|
||||
case "和平模式": land.peaceMode = !land.peaceMode; break;
|
||||
}
|
||||
areaProtect.saveAreaToDb(land);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.NotePlayEvent;
|
||||
import org.bukkit.event.entity.*;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -21,13 +22,12 @@ import org.bukkit.event.block.BlockSpreadEvent;
|
||||
import org.bukkit.event.block.BlockGrowEvent;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.EnderPearl;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Container;
|
||||
import java.sql.*;
|
||||
import org.bukkit.event.entity.*;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
@@ -5147,10 +5147,38 @@ public class AreaProtection implements Listener {
|
||||
}
|
||||
// ★ 验证是发起者本人确认(或管理员)
|
||||
PendingDelete pd = pendingDeletes.get(areaName);
|
||||
if (pd != null && !pd.playerName.equals(p.getName()) && !isAreaAdmin(sender)) {
|
||||
if (pd == null) {
|
||||
// 没有待删除记录,先创建一个(防止绕过延迟)
|
||||
sender.sendMessage("§e⚠ 此操作不可逆!请在60秒内输入: §c/protect 删除 " + areaName + " " + areaName);
|
||||
PendingDelete old = pendingDeletes.remove(areaName);
|
||||
if (old != null) old.task.cancel();
|
||||
UUID uid = p.getUniqueId();
|
||||
String finalAreaName = areaName;
|
||||
long start = System.currentTimeMillis();
|
||||
BukkitTask task = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pendingDeletes.remove(finalAreaName);
|
||||
Player online = Bukkit.getPlayer(uid);
|
||||
if (online != null && online.isOnline()) {
|
||||
online.sendMessage("§c§l[防护] §f领地 §e" + finalAreaName + " §f的删除请求已超时失效");
|
||||
}
|
||||
}
|
||||
}.runTaskLater(plugin, 1200L);
|
||||
pendingDeletes.put(areaName, new PendingDelete(areaName, p.getName(), start, task));
|
||||
return true;
|
||||
}
|
||||
if (!pd.playerName.equals(p.getName()) && !isAreaAdmin(sender)) {
|
||||
sender.sendMessage("§c只有发起删除的玩家才能确认");
|
||||
return true;
|
||||
}
|
||||
// ★ 检查是否已超时(1分钟)
|
||||
if (System.currentTimeMillis() - pd.startTime > 60_000) {
|
||||
pendingDeletes.remove(areaName);
|
||||
pd.task.cancel();
|
||||
sender.sendMessage("§c删除请求已超时,请重新发起");
|
||||
return true;
|
||||
}
|
||||
// ★ 冻结期间如果玩家操作了领地,则自动取消
|
||||
pendingDeletes.remove(areaName);
|
||||
if (pd != null) pd.task.cancel();
|
||||
@@ -6662,6 +6690,93 @@ public class AreaProtection implements Listener {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
|
||||
// ===== ★ 拴绳使用(给生物拴绳或拉拽)=====
|
||||
@EventHandler
|
||||
public void onLeash(PlayerInteractEntityEvent e) {
|
||||
if (!(e.getPlayer() instanceof Player)) return;
|
||||
Player p = e.getPlayer();
|
||||
Entity entity = e.getRightClicked();
|
||||
// 检查玩家所在位置或实体位置
|
||||
AreaConfig ac = getArea(
|
||||
p.getWorld().getName(),
|
||||
p.getLocation().getBlockX(),
|
||||
p.getLocation().getBlockY(),
|
||||
p.getLocation().getBlockZ());
|
||||
if (ac == null) {
|
||||
ac = getArea(
|
||||
entity.getWorld().getName(),
|
||||
entity.getLocation().getBlockX(),
|
||||
entity.getLocation().getBlockY(),
|
||||
entity.getLocation().getBlockZ());
|
||||
}
|
||||
if (ac == null || !ac.denyLead) return;
|
||||
if (hasPermission(p, ac, PermissionLevel.OWNER)) return;
|
||||
// 只拦截拴绳操作(主手持拴绳)
|
||||
ItemStack hand = p.getInventory().getItemInMainHand();
|
||||
if (hand != null && hand.getType() == Material.LEAD) {
|
||||
e.setCancelled(true);
|
||||
p.sendMessage("§c§l[区域防护] §f禁止在此区域使用拴绳");
|
||||
}
|
||||
}
|
||||
|
||||
// ===== ★ 投喂动物 =====
|
||||
@EventHandler
|
||||
public void onPlayerFeedAnimal(EntityBreedEvent e) {
|
||||
if (!(e.getBreeder() instanceof Player)) return;
|
||||
Player p = (Player) e.getBreeder();
|
||||
Entity entity = e.getEntity();
|
||||
AreaConfig ac = getArea(
|
||||
p.getWorld().getName(),
|
||||
p.getLocation().getBlockX(),
|
||||
p.getLocation().getBlockY(),
|
||||
p.getLocation().getBlockZ());
|
||||
if (ac == null) {
|
||||
ac = getArea(
|
||||
entity.getWorld().getName(),
|
||||
entity.getLocation().getBlockX(),
|
||||
entity.getLocation().getBlockY(),
|
||||
entity.getLocation().getBlockZ());
|
||||
}
|
||||
if (ac == null || !ac.denyAnimalFeeding) return;
|
||||
if (hasPermission(p, ac, PermissionLevel.OWNER)) return;
|
||||
e.setCancelled(true);
|
||||
p.sendMessage("§c§l[区域防护] §f禁止在此区域繁殖动物");
|
||||
}
|
||||
|
||||
// ===== ★ 袭击侦听(玩家触发袭击时检测)=====
|
||||
@EventHandler
|
||||
public void onRaidTrigger(org.bukkit.event.raid.RaidTriggerEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
AreaConfig ac = getArea(
|
||||
p.getWorld().getName(),
|
||||
p.getLocation().getBlockX(),
|
||||
p.getLocation().getBlockY(),
|
||||
p.getLocation().getBlockZ());
|
||||
if (ac == null || !ac.denyRaid) return;
|
||||
if (hasPermission(p, ac, PermissionLevel.OWNER)) return;
|
||||
e.setCancelled(true);
|
||||
p.sendMessage("§c§l[区域防护] §f此区域禁止触发袭击事件");
|
||||
}
|
||||
|
||||
// ===== ★ 玩家发光检测(通过定期扫描清除区域内发光效果)=====
|
||||
// 在onEnable中注册repeating task,此处提供public方法供Main调用
|
||||
public void checkGlowingPlayers() {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
AreaConfig ac = getArea(
|
||||
p.getWorld().getName(),
|
||||
p.getLocation().getBlockX(),
|
||||
p.getLocation().getBlockY(),
|
||||
p.getLocation().getBlockZ());
|
||||
if (ac != null && ac.denyGlowing) {
|
||||
if (hasPermission(p, ac, PermissionLevel.OWNER)) continue;
|
||||
if (p.hasPotionEffect(PotionEffectType.GLOWING)) {
|
||||
p.removePotionEffect(PotionEffectType.GLOWING);
|
||||
p.sendMessage("§c§l[区域防护] §f此区域禁止使用发光效果");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void savePeaceWhitelist(AreaConfig ac) {
|
||||
File file = new File(rootDir, ac.name + ".txt");
|
||||
|
||||
@@ -513,11 +513,12 @@ public class Main extends JavaPlugin
|
||||
getServer().getPluginManager()
|
||||
.registerEvents(areaGUIManager, this);
|
||||
|
||||
// 效果清除定时器(只留一个)
|
||||
// 发光效果检测(每2秒扫描一次)
|
||||
getServer().getScheduler().runTaskTimer(this, () -> {
|
||||
if (areaProtection != null) {
|
||||
areaProtection.checkGlowingPlayers();
|
||||
}
|
||||
}, 20L, 20L);
|
||||
}, 20L, 40L);
|
||||
|
||||
// 和平模式独立检测
|
||||
getServer().getScheduler().runTaskTimer(this, () -> {
|
||||
|
||||
Reference in New Issue
Block a user