297 lines
9.2 KiB
Java
297 lines
9.2 KiB
Java
package com.playerblocklife;
|
||
|
||
import org.bukkit.Bukkit;
|
||
import org.bukkit.plugin.java.JavaPlugin;
|
||
|
||
import java.util.logging.Level;
|
||
|
||
/**
|
||
* PlayerBlockLife插件主类 - PlayerBlockLife生存游戏模式的核心控制器
|
||
*
|
||
* <p>这个插件为Minecraft服务器添加了一个独特的生存游戏模式:每个非OP玩家拥有一定数量的生命方块,
|
||
* 这些方块使用不同颜色的羊毛、玻璃或水泥方块表示。当其他玩家挖光某个玩家的所有生命方块时,该玩家会被淘汰。
|
||
* 游戏需要管理员使用/pbl start命令开始,支持限时模式,最后存活的玩家获胜。</p>
|
||
*
|
||
* <p>主要功能:</p>
|
||
* <ul>
|
||
* <li>管理PlayerBlockLife游戏的完整生命周期(等待、进行、结束)</li>
|
||
* <li>为非OP玩家分配独特的颜色生命方块</li>
|
||
* <li>处理生命方块的生成和销毁</li>
|
||
* <li>监控游戏状态和玩家存活情况</li>
|
||
* <li>提供PlayerBlockLife专用命令系统(/pbl start, /pbl rstgm)</li>
|
||
* <li>支持游戏计分板显示</li>
|
||
* <li>管理员可使用传统命令进行管理</li>
|
||
* </ul>
|
||
*
|
||
* @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;
|
||
|
||
/**
|
||
* 插件启用时调用,执行初始化操作
|
||
*
|
||
* <p>初始化流程:
|
||
* <ol>
|
||
* <li>保存默认配置文件</li>
|
||
* <li>初始化所有管理器(注意依赖顺序)</li>
|
||
* <li>加载配置和消息数据</li>
|
||
* <li>注册事件监听器</li>
|
||
* <li>注册命令执行器</li>
|
||
* <li>加载玩家数据和皮肤缓存</li>
|
||
* <li>启动定时任务</li>
|
||
* </ol>
|
||
*
|
||
* @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========================================");
|
||
}
|
||
|
||
/**
|
||
* 插件禁用时调用,执行清理操作
|
||
*
|
||
* <p>执行以下清理操作:
|
||
* <ul>
|
||
* <li>保存玩家方块数据到文件</li>
|
||
* <li>保存皮肤缓存数据</li>
|
||
* <li>记录插件禁用日志</li>
|
||
* </ul>
|
||
*
|
||
* @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("基础配置文件已重新加载");
|
||
}
|
||
|
||
/**
|
||
* 插件的完整重载方法(用于命令)
|
||
*
|
||
* <p>重新加载所有插件配置和数据,包括:
|
||
* <ul>
|
||
* <li>主配置文件 (config.yml)</li>
|
||
* <li>消息配置文件 (messages.yml)</li>
|
||
* <li>玩家方块数据</li>
|
||
* <li>皮肤缓存数据</li>
|
||
* </ul>
|
||
*
|
||
* <p>这个方法通常由管理员通过/pblreload命令调用。</p>
|
||
*/
|
||
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);
|
||
}
|
||
|
||
/**
|
||
* 获取插件单例实例
|
||
*
|
||
* <p>提供全局访问点,允许其他类访问插件主实例。</p>
|
||
*
|
||
* @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);
|
||
}
|
||
} |