package com.playerblocklife; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import java.util.logging.Level; /** * PlayerBlockLife插件主类 - PlayerBlockLife生存游戏模式的核心控制器 * *

这个插件为Minecraft服务器添加了一个独特的生存游戏模式:每个非OP玩家拥有一定数量的生命方块, * 这些方块使用不同颜色的羊毛、玻璃或水泥方块表示。当其他玩家挖光某个玩家的所有生命方块时,该玩家会被淘汰。 * 游戏需要管理员使用/pbl start命令开始,支持限时模式,最后存活的玩家获胜。

* *

主要功能:

* * * @author xiaobai * @version 2.2.0-1.20.4 * @since 1.0.0 */ public class PlayerBlockLife extends JavaPlugin { private static PlayerBlockLife instance; private PlayerBlockManager blockManager; private SkinManager skinManager; private LifeSystem lifeSystem; private ConfigManager configManager; private MessageManager messageManager; private GameStateManager gameStateManager; /** * 插件启用时调用,执行初始化操作 * *

初始化流程: *

    *
  1. 保存默认配置文件
  2. *
  3. 初始化所有管理器(注意依赖顺序)
  4. *
  5. 加载配置和消息数据
  6. *
  7. 注册事件监听器
  8. *
  9. 注册命令执行器
  10. *
  11. 加载玩家数据和皮肤缓存
  12. *
  13. 启动定时任务
  14. *
* * @see #onDisable() */ @Override public void onEnable() { instance = this; // 第一步:保存默认配置 saveDefaultConfig(); // 第二步:初始化管理器(注意顺序!) this.configManager = new ConfigManager(this); this.messageManager = new MessageManager(this); this.skinManager = new SkinManager(this); this.blockManager = new PlayerBlockManager(this, skinManager); this.lifeSystem = new LifeSystem(this); // 第三步:加载数据(必须在管理器初始化之后) this.configManager.loadConfig(); this.messageManager.loadMessages(); // 第四步:注册事件监听器 getServer().getPluginManager().registerEvents(new BlockBreakListener(this), this); getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(this), this); // 第五步:注册命令 getCommand("setlifeblocks").setExecutor(new SetLifeBlocksCommand(this)); getCommand("checklifeblocks").setExecutor(new CheckLifeBlocksCommand(this)); getCommand("pblreload").setExecutor(new AdminCommands(this)); getCommand("pbldelete").setExecutor(new AdminCommands(this)); getCommand("pblrevive").setExecutor(new AdminCommands(this)); getCommand("pblstats").setExecutor(new AdminCommands(this)); getCommand("pbl").setExecutor(new PBLCommands(this)); // 第六步:初始化游戏状态管理器(先于其他数据加载) this.gameStateManager = new GameStateManager(this); // 第七步:加载其他数据 // 注意:在新模式下,我们不再使用原有的blockManager和skinManager // 因此不再调用blockManager.loadData()和skinManager.loadAllSkins() // 第八步:启动定时任务 startScheduler(); getLogger().info("§a========================================"); getLogger().info("§ePlayerBlockLife v" + getDescription().getVersion() + " 已启用"); getLogger().info("§e作者: " + getDescription().getAuthors()); getLogger().info("§a========================================"); } /** * 插件禁用时调用,执行清理操作 * *

执行以下清理操作: *

* * @see #onEnable() */ @Override public void onDisable() { // 保存数据 if (blockManager != null) { blockManager.saveData(); } if (skinManager != null) { skinManager.saveSkinData(); } getLogger().info("§cPlayerBlockLife 插件已禁用"); } /** * 重写 reloadConfig 方法,避免循环依赖 */ @Override public void reloadConfig() { // 只调用父类的reloadConfig,不调用configManager的方法 super.reloadConfig(); getLogger().info("基础配置文件已重新加载"); } /** * 插件的完整重载方法(用于命令) * *

重新加载所有插件配置和数据,包括: *

* *

这个方法通常由管理员通过/pblreload命令调用。

*/ public void reloadPluginConfig() { if (configManager != null) { configManager.reloadConfig(); } if (messageManager != null) { messageManager.reloadMessages(); } if (blockManager != null) { blockManager.loadData(); } if (skinManager != null) { skinManager.loadAllSkins(); } getLogger().info("插件配置已完全重载"); } private void startScheduler() { // 每5分钟自动保存数据 getServer().getScheduler().runTaskTimerAsynchronously(this, () -> { if (blockManager != null) { blockManager.saveData(); } if (skinManager != null) { skinManager.saveSkinData(); } getLogger().info("数据已自动保存"); }, 6000L, 6000L); // 每10秒检查玩家生命方块 getServer().getScheduler().runTaskTimer(this, () -> { if (lifeSystem != null) { lifeSystem.checkAllPlayers(); } // 每10秒检查游戏结束条件 if (gameStateManager != null) { gameStateManager.checkGameEnd(); } }, 200L, 200L); // 每分钟清理一次过期缓存 getServer().getScheduler().runTaskTimerAsynchronously(this, () -> { if (skinManager != null) { skinManager.cleanupOldCache(); } }, 1200L, 1200L); // 每秒更新计分板 getServer().getScheduler().runTaskTimer(this, () -> { if (gameStateManager != null) { gameStateManager.updateScoreboard(); } }, 20L, 20L); } /** * 获取插件单例实例 * *

提供全局访问点,允许其他类访问插件主实例。

* * @return PlayerBlockLife插件实例 * @throws IllegalStateException 如果插件尚未启用(实例为null) */ public static PlayerBlockLife getInstance() { return instance; } /** * 获取方块管理器 * * @return 方块管理器实例 */ public PlayerBlockManager getBlockManager() { return blockManager; } /** * 获取皮肤管理器 * * @return 皮肤管理器实例 */ public SkinManager getSkinManager() { return skinManager; } /** * 获取生命值系统 * * @return 生命值系统实例 */ public LifeSystem getLifeSystem() { return lifeSystem; } /** * 获取配置管理器 * * @return 配置管理器实例 */ public ConfigManager getConfigManager() { return configManager; } /** * 获取消息管理器 * * @return 消息管理器实例 */ public MessageManager getMessageManager() { return messageManager; } /** * 获取游戏状态管理器 * * @return 游戏状态管理器实例 */ public GameStateManager getGameStateManager() { return gameStateManager; } /** * 记录信息级别日志 * * @param message 日志消息 */ public void logInfo(String message) { getLogger().info(message); } /** * 记录警告级别日志 * * @param message 日志消息 */ public void logWarning(String message) { getLogger().warning(message); } /** * 记录错误级别日志 * * @param message 日志消息 * @param throwable 异常对象 */ public void logError(String message, Throwable throwable) { getLogger().log(Level.SEVERE, message, throwable); } }