You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何开发触发方块破坏事件后向指定玩家发消息的Bukkit插件?

解决Bukkit插件BlockBreakEvent索引越界问题并完整实现监控需求

问题根源分析

  1. 配置文件格式错误:你的config.yml中-me缺少短横线后的空格,YAML语法要求列表项的-后必须跟空格,否则无法被识别为列表,导致getStringList("MinePlayers")返回空列表,触发IndexOutOfBoundsException。
  2. 硬编码索引取值:直接通过get(0)、get(1)获取列表元素,完全忽略列表实际长度,只要列表元素数量不足就会报错。
  3. 变量作用域错误:if(m1!=null)内部重新声明Player tm1=m1;,这是局部变量,不会修改外部的tm1,导致后续调用printmsg时传入的还是初始的null。
  4. 未实现方块检查逻辑:原代码没有对被破坏的方块是否属于指定列表做判断,不符合需求。

完整解决方案

1. 修正配置文件 config.yml

添加监控方块列表,并修正玩家列表格式:

# 需要通知的在线玩家列表
MinePlayers:
  - me
  - someone_else
# 需要监控的方块类型(使用Bukkit官方Material枚举名称)
MonitoredBlocks:
  - DIAMOND_ORE
  - EMERALD_ORE
  - NETHERITE_ORE
  - COAL_ORE

2. 重构监听器代码

优化逻辑,避免索引越界,实现完整需求:

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.plugin.Plugin;

public class AntiXrayListener implements Listener {

    private final Plugin plugin;

    // 通过构造方法注入插件实例,避免静态依赖问题
    public AntiXrayListener(Plugin plugin) {
        this.plugin = plugin;
        // 自动生成默认配置文件(如果不存在)
        plugin.saveDefaultConfig();
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
        Player breaker = event.getPlayer();
        Block brokenBlock = event.getBlock();
        Material blockType = brokenBlock.getType();

        // 先检查当前方块是否在监控列表中,不在则直接返回
        if (!plugin.getConfig().getStringList("MonitoredBlocks").contains(blockType.name())) {
            return;
        }

        // 遍历配置中的玩家列表,仅向在线玩家发送通知
        for (String targetName : plugin.getConfig().getStringList("MinePlayers")) {
            Player targetPlayer = Bukkit.getPlayerExact(targetName);
            if (targetPlayer != null && targetPlayer.isOnline()) {
                sendMonitorMessage(targetPlayer, breaker, blockType);
            }
        }
    }

    // 封装消息发送逻辑,便于修改格式
    private void sendMonitorMessage(Player target, Player breaker, Material blockType) {
        // 自定义消息格式,支持颜色代码(§开头)
        String message = String.format("§e[%s] §7破坏了一个 §b%s§7!", breaker.getName(), blockType.name());
        target.sendMessage(message);
    }
}

3. 插件主类注册监听器

在你的TestPlugin类中正确注册监听器:

import org.bukkit.plugin.java.JavaPlugin;

public class TestPlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        // 注册监听器,传入插件实例
        getServer().getPluginManager().registerEvents(new AntiXrayListener(this), this);
        getLogger().info("方块监控插件已启用!");
    }

    @Override
    public void onDisable() {
        getLogger().info("方块监控插件已禁用!");
    }
}

关键优化点

  • 动态遍历玩家列表:不再依赖固定索引,无论配置中添加多少玩家都不会报错
  • 提前过滤非监控方块:减少不必要的逻辑执行,提升性能
  • 正确处理在线状态:仅向在线玩家发送消息,避免空指针
  • 配置文件自动生成:首次运行会自动生成默认配置,无需手动创建
  • 代码解耦:通过构造方法注入插件实例,避免静态调用的潜在问题

内容的提问来源于stack exchange,提问作者FR0314

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:25:21