Compare commits
17 Commits
1.0.0
...
f899540449
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f899540449 | ||
|
|
1fbd92ec72 | ||
|
|
c15b30f666 | ||
|
|
8d8cdcb244 | ||
|
|
c7d09c3039 | ||
|
|
a3cb82c1b7 | ||
|
|
c9035d488c | ||
|
|
e3b46b6946 | ||
|
|
f92fdb40c6 | ||
|
|
dd6c570fa7 | ||
|
|
68fadf4e1a | ||
|
|
1e6b0cb19e | ||
|
|
e588ca9866 | ||
| 9e113fc37d | |||
|
|
e40fcb344f | ||
|
|
231e1acdf5 | ||
| c44219ad7b |
18
LICENSE
Normal file
18
LICENSE
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 xiaobai
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
|
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||||
|
following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||||
|
portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||||
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||||
|
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -19,7 +19,7 @@ PlayerBlockLife is a unique Minecraft plugin that adds a novel gameplay mechanic
|
|||||||
### 🚀 Quick Start
|
### 🚀 Quick Start
|
||||||
|
|
||||||
#### Installation
|
#### Installation
|
||||||
1. Download the plugin from the ./Releases folder
|
1. Download the plugin from the ./Releases folder or https://gt.funmc.cn/xiaobai/PlayerBlockLife/releases
|
||||||
2. Place the JAR file in your server's `plugins` folder
|
2. Place the JAR file in your server's `plugins` folder
|
||||||
3. Restart your server
|
3. Restart your server
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ If you want to build the plugin yourself:
|
|||||||
5. The compiled JAR will be in `build/libs/`
|
5. The compiled JAR will be in `build/libs/`
|
||||||
|
|
||||||
### 📦 Releases
|
### 📦 Releases
|
||||||
Pre-compiled versions are available in the ./Releases folder. We recommend downloading from there for stable builds.
|
Pre-compiled versions are available in the ./Releases folder or https://gt.funmc.cn/xiaobai/PlayerBlockLife/releases. We recommend downloading from there for stable builds.
|
||||||
|
|
||||||
### 🎯 Gameplay
|
### 🎯 Gameplay
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ PlayerBlockLife 是一个独特的Minecraft插件,为服务器增加了一种
|
|||||||
### 🚀 快速开始
|
### 🚀 快速开始
|
||||||
|
|
||||||
#### 安装方法
|
#### 安装方法
|
||||||
1. 从./Releases文件夹下载插件
|
1. 从./Releases文件夹或者https://gt.funmc.cn/xiaobai/PlayerBlockLife/releases下载插件
|
||||||
2. 将JAR文件放入服务器的`plugins`文件夹
|
2. 将JAR文件放入服务器的`plugins`文件夹
|
||||||
3. 重启服务器
|
3. 重启服务器
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ PlayerBlockLife 是一个独特的Minecraft插件,为服务器增加了一种
|
|||||||
5. 编译后的JAR文件位于 `build/libs/`
|
5. 编译后的JAR文件位于 `build/libs/`
|
||||||
|
|
||||||
### 📦 发布版本
|
### 📦 发布版本
|
||||||
预编译的版本可以在 ./Releases 文件夹中找到。我们建议从这里下载以获得稳定版本。
|
预编译的版本可以在 ./Releases 文件夹或https://gt.funmc.cn/xiaobai/PlayerBlockLife/releases中找到。我们建议从这里下载以获得稳定版本。
|
||||||
|
|
||||||
### 🎯 游戏玩法
|
### 🎯 游戏玩法
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -4,7 +4,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = 'com.playerblocklife'
|
group = 'com.playerblocklife'
|
||||||
version = '1.0.0'
|
version = '1.0.1-1.20.4'
|
||||||
|
|
||||||
sourceCompatibility = 17
|
sourceCompatibility = 17
|
||||||
targetCompatibility = 17
|
targetCompatibility = 17
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ org.gradle.caching=true
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
|
|
||||||
# ????
|
# ????
|
||||||
pluginVersion=1.0.0
|
pluginVersion=1.0.1-1.20.4
|
||||||
mcVersion=1.20.4
|
mcVersion=1.20.4
|
||||||
@@ -23,10 +23,9 @@ public class AdminCommands implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (command.getName().equalsIgnoreCase("pblreload")) {
|
if (command.getName().equalsIgnoreCase("pblreload")) {
|
||||||
plugin.reloadConfig();
|
// 调用插件的完整重载方法
|
||||||
plugin.getBlockManager().loadData();
|
plugin.reloadPluginConfig();
|
||||||
plugin.getSkinManager().loadAllSkins();
|
sender.sendMessage("§a插件配置已完全重载!");
|
||||||
sender.sendMessage("§a插件配置已重载!");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +43,12 @@ public class AdminCommands implements CommandExecutor {
|
|||||||
targetId = target.getUniqueId();
|
targetId = target.getUniqueId();
|
||||||
} else {
|
} else {
|
||||||
// 尝试从离线玩家获取UUID
|
// 尝试从离线玩家获取UUID
|
||||||
targetId = Bukkit.getOfflinePlayer(targetName).getUniqueId();
|
try {
|
||||||
|
targetId = Bukkit.getOfflinePlayer(targetName).getUniqueId();
|
||||||
|
} catch (Exception e) {
|
||||||
|
sender.sendMessage("§c找不到玩家: " + targetName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.getBlockManager().clearPlayerBlocks(targetId);
|
plugin.getBlockManager().clearPlayerBlocks(targetId);
|
||||||
@@ -69,12 +73,21 @@ public class AdminCommands implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.getLifeSystem().revivePlayer(target);
|
if (plugin.getLifeSystem() != null) {
|
||||||
sender.sendMessage("§a玩家 " + target.getName() + " 已复活!");
|
plugin.getLifeSystem().revivePlayer(target);
|
||||||
|
sender.sendMessage("§a玩家 " + target.getName() + " 已复活!");
|
||||||
|
} else {
|
||||||
|
sender.sendMessage("§c复活失败:生命系统未初始化");
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.getName().equalsIgnoreCase("pblstats")) {
|
if (command.getName().equalsIgnoreCase("pblstats")) {
|
||||||
|
if (plugin.getBlockManager() == null) {
|
||||||
|
sender.sendMessage("§c方块管理器未初始化");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int totalPlayers = plugin.getBlockManager().getPlayerBlocksCount();
|
int totalPlayers = plugin.getBlockManager().getPlayerBlocksCount();
|
||||||
int totalBlocks = plugin.getBlockManager().getTotalBlocksCount();
|
int totalBlocks = plugin.getBlockManager().getTotalBlocksCount();
|
||||||
|
|
||||||
@@ -85,9 +98,11 @@ public class AdminCommands implements CommandExecutor {
|
|||||||
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
int blocks = plugin.getBlockManager().getRemainingBlocks(player.getUniqueId());
|
int blocks = plugin.getBlockManager().getRemainingBlocks(player.getUniqueId());
|
||||||
sender.sendMessage("§7- " + player.getName() + ": §e" + blocks + " §7/ §a5");
|
String status = blocks > 0 ? "§a存活" : "§c已淘汰";
|
||||||
|
sender.sendMessage("§7- " + player.getName() + ": §e" + blocks + " §7/ §a5 §7(" + status + "§7)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sender.sendMessage("§a=================================");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +1,209 @@
|
|||||||
package com.playerblocklife;
|
package com.playerblocklife;
|
||||||
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class ConfigManager {
|
public class ConfigManager {
|
||||||
private final PlayerBlockLife plugin;
|
private final PlayerBlockLife plugin;
|
||||||
private FileConfiguration config;
|
private FileConfiguration config;
|
||||||
|
private File configFile;
|
||||||
|
|
||||||
public ConfigManager(PlayerBlockLife plugin) {
|
public ConfigManager(PlayerBlockLife plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
loadConfig();
|
this.configFile = new File(plugin.getDataFolder(), "config.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载配置
|
||||||
|
*/
|
||||||
public void loadConfig() {
|
public void loadConfig() {
|
||||||
plugin.saveDefaultConfig();
|
// 确保配置文件夹存在
|
||||||
config = plugin.getConfig();
|
if (!plugin.getDataFolder().exists()) {
|
||||||
|
plugin.getDataFolder().mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果配置文件不存在,从JAR中复制默认配置
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
plugin.saveDefaultConfig();
|
||||||
|
plugin.logInfo("创建默认配置文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新加载配置
|
||||||
|
reloadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新加载配置
|
||||||
|
*/
|
||||||
public void reloadConfig() {
|
public void reloadConfig() {
|
||||||
plugin.reloadConfig();
|
// 重新从磁盘加载配置
|
||||||
config = plugin.getConfig();
|
config = YamlConfiguration.loadConfiguration(configFile);
|
||||||
|
|
||||||
|
// 加载默认配置作为后备
|
||||||
|
InputStream defaultConfigStream = plugin.getResource("config.yml");
|
||||||
|
if (defaultConfigStream != null) {
|
||||||
|
YamlConfiguration defaultConfig = YamlConfiguration.loadConfiguration(
|
||||||
|
new InputStreamReader(defaultConfigStream, StandardCharsets.UTF_8));
|
||||||
|
config.setDefaults(defaultConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查配置版本,如果需要则更新
|
||||||
|
checkConfigVersion();
|
||||||
|
|
||||||
|
plugin.logInfo("配置已加载");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查配置版本并更新
|
||||||
|
*/
|
||||||
|
private void checkConfigVersion() {
|
||||||
|
int currentVersion = config.getInt("config-version", 1);
|
||||||
|
int latestVersion = 1; // 最新配置版本
|
||||||
|
|
||||||
|
if (currentVersion < latestVersion) {
|
||||||
|
plugin.logWarning("检测到旧版配置文件,正在更新...");
|
||||||
|
updateConfig(currentVersion, latestVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新配置文件
|
||||||
|
*/
|
||||||
|
private void updateConfig(int fromVersion, int toVersion) {
|
||||||
|
if (fromVersion == 1 && toVersion == 2) {
|
||||||
|
// 示例:添加新配置项
|
||||||
|
if (!config.contains("new-feature.enabled")) {
|
||||||
|
config.set("new-feature.enabled", true);
|
||||||
|
config.set("new-feature.duration", 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新版本号
|
||||||
|
config.set("config-version", toVersion);
|
||||||
|
|
||||||
|
try {
|
||||||
|
config.save(configFile);
|
||||||
|
plugin.logInfo("配置文件已更新到版本 " + toVersion);
|
||||||
|
} catch (IOException e) {
|
||||||
|
plugin.logError("保存更新后的配置文件失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存配置
|
||||||
|
*/
|
||||||
|
public void saveConfig() {
|
||||||
|
try {
|
||||||
|
config.save(configFile);
|
||||||
|
} catch (IOException e) {
|
||||||
|
plugin.logError("保存配置文件失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取配置对象
|
||||||
|
*/
|
||||||
|
public FileConfiguration getConfig() {
|
||||||
|
if (config == null) {
|
||||||
|
reloadConfig();
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 以下为配置项的获取方法
|
||||||
|
|
||||||
public int getBlocksPerPlayer() {
|
public int getBlocksPerPlayer() {
|
||||||
return config.getInt("blocks.amount", 5);
|
return getConfig().getInt("blocks.amount", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSpreadRange() {
|
public int getSpreadRange() {
|
||||||
return config.getInt("blocks.spread", 5);
|
return getConfig().getInt("blocks.spread", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDepth() {
|
public int getDepth() {
|
||||||
return config.getInt("blocks.depth", -1);
|
return getConfig().getInt("blocks.depth", -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBlockMaterial() {
|
||||||
|
return getConfig().getString("blocks.material", "player_head");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDieWhenBlocksGone() {
|
public boolean isDieWhenBlocksGone() {
|
||||||
return config.getBoolean("game.die_when_blocks_gone", true);
|
return getConfig().getBoolean("game.die_when_blocks_gone", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBecomeSpectator() {
|
public boolean isBecomeSpectator() {
|
||||||
return config.getBoolean("game.become_spectator", true);
|
return getConfig().getBoolean("game.become_spectator", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHealthSystemEnabled() {
|
public boolean isHealthSystemEnabled() {
|
||||||
return config.getBoolean("game.health_system", true);
|
return getConfig().getBoolean("game.health_system", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSkinSystemEnabled() {
|
public boolean isSkinSystemEnabled() {
|
||||||
return config.getBoolean("skin.enabled", true);
|
return getConfig().getBoolean("skin.enabled", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSkinSource() {
|
public String getSkinSource() {
|
||||||
return config.getString("skin.source", "player_profile");
|
return getConfig().getString("skin.source", "player_profile");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCacheExpireDays() {
|
||||||
|
return getConfig().getInt("skin.cache.expire_days", 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutoSaveEnabled() {
|
||||||
|
return getConfig().getBoolean("storage.auto_save.enabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAutoSaveInterval() {
|
||||||
|
return getConfig().getInt("storage.auto_save.interval", 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStorageType() {
|
||||||
|
return getConfig().getString("storage.type", "yaml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBroadcastOnBlockBreak() {
|
||||||
|
return getConfig().getBoolean("game.broadcast.on_block_break", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBroadcastOnPlayerDeath() {
|
||||||
|
return getConfig().getBoolean("game.broadcast.on_player_death", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBroadcastRange() {
|
||||||
|
return getConfig().getInt("game.broadcast.range", 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGiveExpReward() {
|
||||||
|
return getConfig().getBoolean("game.break_rewards.give_exp", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExpRewardAmount() {
|
||||||
|
return getConfig().getInt("game.break_rewards.exp_amount", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isProtectFromExplosions() {
|
||||||
|
return getConfig().getBoolean("protection.protect_from_explosions", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isProtectFromFire() {
|
||||||
|
return getConfig().getBoolean("protection.protect_from_fire", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isProtectFromPistons() {
|
||||||
|
return getConfig().getBoolean("protection.protect_from_pistons", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage(String path, String defaultValue) {
|
public String getMessage(String path, String defaultValue) {
|
||||||
String message = config.getString("messages." + path, defaultValue);
|
String message = getConfig().getString("messages." + path, defaultValue);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
message = message.replace("&", "§");
|
message = message.replace("&", "§");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.playerblocklife;
|
package com.playerblocklife;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class PlayerBlockLife extends JavaPlugin {
|
public class PlayerBlockLife extends JavaPlugin {
|
||||||
@@ -10,36 +12,40 @@ public class PlayerBlockLife extends JavaPlugin {
|
|||||||
private LifeSystem lifeSystem;
|
private LifeSystem lifeSystem;
|
||||||
private ConfigManager configManager;
|
private ConfigManager configManager;
|
||||||
|
|
||||||
// 在 PlayerBlockLife.java 中添加:
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reloadConfig() {
|
|
||||||
super.reloadConfig();
|
|
||||||
configManager.reloadConfig();
|
|
||||||
getLogger().info("配置已重新加载");
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
|
// 第一步:保存默认配置
|
||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
|
|
||||||
|
// 第二步:初始化管理器(注意顺序!)
|
||||||
this.configManager = new ConfigManager(this);
|
this.configManager = new ConfigManager(this);
|
||||||
this.skinManager = new SkinManager(this);
|
this.skinManager = new SkinManager(this);
|
||||||
this.blockManager = new PlayerBlockManager(this, skinManager);
|
this.blockManager = new PlayerBlockManager(this, skinManager);
|
||||||
this.lifeSystem = new LifeSystem(this);
|
this.lifeSystem = new LifeSystem(this);
|
||||||
|
|
||||||
|
// 第三步:加载数据(必须在管理器初始化之后)
|
||||||
|
this.configManager.loadConfig();
|
||||||
|
|
||||||
|
// 第四步:注册事件监听器
|
||||||
getServer().getPluginManager().registerEvents(new BlockBreakListener(this), this);
|
getServer().getPluginManager().registerEvents(new BlockBreakListener(this), this);
|
||||||
getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this);
|
getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this);
|
||||||
getServer().getPluginManager().registerEvents(new PlayerQuitListener(this), this);
|
getServer().getPluginManager().registerEvents(new PlayerQuitListener(this), this);
|
||||||
|
|
||||||
|
// 第五步:注册命令
|
||||||
getCommand("setlifeblocks").setExecutor(new SetLifeBlocksCommand(this));
|
getCommand("setlifeblocks").setExecutor(new SetLifeBlocksCommand(this));
|
||||||
getCommand("checklifeblocks").setExecutor(new CheckLifeBlocksCommand(this));
|
getCommand("checklifeblocks").setExecutor(new CheckLifeBlocksCommand(this));
|
||||||
getCommand("pblreload").setExecutor(new AdminCommands(this));
|
getCommand("pblreload").setExecutor(new AdminCommands(this));
|
||||||
getCommand("pbldelete").setExecutor(new AdminCommands(this));
|
getCommand("pbldelete").setExecutor(new AdminCommands(this));
|
||||||
|
getCommand("pblrevive").setExecutor(new AdminCommands(this));
|
||||||
|
getCommand("pblstats").setExecutor(new AdminCommands(this));
|
||||||
|
|
||||||
|
// 第六步:加载其他数据
|
||||||
blockManager.loadData();
|
blockManager.loadData();
|
||||||
skinManager.loadAllSkins();
|
skinManager.loadAllSkins();
|
||||||
|
|
||||||
|
// 第七步:启动定时任务
|
||||||
startScheduler();
|
startScheduler();
|
||||||
|
|
||||||
getLogger().info("§a========================================");
|
getLogger().info("§a========================================");
|
||||||
@@ -50,6 +56,7 @@ public class PlayerBlockLife extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
// 保存数据
|
||||||
if (blockManager != null) {
|
if (blockManager != null) {
|
||||||
blockManager.saveData();
|
blockManager.saveData();
|
||||||
}
|
}
|
||||||
@@ -59,15 +66,57 @@ public class PlayerBlockLife extends JavaPlugin {
|
|||||||
getLogger().info("§cPlayerBlockLife 插件已禁用");
|
getLogger().info("§cPlayerBlockLife 插件已禁用");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重写 reloadConfig 方法,避免循环依赖
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void reloadConfig() {
|
||||||
|
// 只调用父类的reloadConfig,不调用configManager的方法
|
||||||
|
super.reloadConfig();
|
||||||
|
getLogger().info("基础配置文件已重新加载");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插件的完整重载方法(用于命令)
|
||||||
|
*/
|
||||||
|
public void reloadPluginConfig() {
|
||||||
|
if (configManager != null) {
|
||||||
|
configManager.reloadConfig();
|
||||||
|
}
|
||||||
|
if (blockManager != null) {
|
||||||
|
blockManager.loadData();
|
||||||
|
}
|
||||||
|
if (skinManager != null) {
|
||||||
|
skinManager.loadAllSkins();
|
||||||
|
}
|
||||||
|
getLogger().info("插件配置已完全重载");
|
||||||
|
}
|
||||||
|
|
||||||
private void startScheduler() {
|
private void startScheduler() {
|
||||||
|
// 每5分钟自动保存数据
|
||||||
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
|
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
|
||||||
blockManager.saveData();
|
if (blockManager != null) {
|
||||||
skinManager.saveSkinData();
|
blockManager.saveData();
|
||||||
|
}
|
||||||
|
if (skinManager != null) {
|
||||||
|
skinManager.saveSkinData();
|
||||||
|
}
|
||||||
|
getLogger().info("数据已自动保存");
|
||||||
}, 6000L, 6000L);
|
}, 6000L, 6000L);
|
||||||
|
|
||||||
|
// 每10秒检查玩家生命方块
|
||||||
getServer().getScheduler().runTaskTimer(this, () -> {
|
getServer().getScheduler().runTaskTimer(this, () -> {
|
||||||
lifeSystem.checkAllPlayers();
|
if (lifeSystem != null) {
|
||||||
|
lifeSystem.checkAllPlayers();
|
||||||
|
}
|
||||||
}, 200L, 200L);
|
}, 200L, 200L);
|
||||||
|
|
||||||
|
// 每分钟清理一次过期缓存
|
||||||
|
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
|
||||||
|
if (skinManager != null) {
|
||||||
|
skinManager.cleanupOldCache();
|
||||||
|
}
|
||||||
|
}, 1200L, 1200L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerBlockLife getInstance() {
|
public static PlayerBlockLife getInstance() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# PlayerBlockLife 配置文件
|
# PlayerBlockLife 配置文件
|
||||||
# 版本: 1.0.0
|
config-version: 1
|
||||||
|
|
||||||
# 方块设置
|
# 方块设置
|
||||||
blocks:
|
blocks:
|
||||||
@@ -10,28 +10,7 @@ blocks:
|
|||||||
# 方块埋藏深度(0为地面,负数为地下)
|
# 方块埋藏深度(0为地面,负数为地下)
|
||||||
depth: -1
|
depth: -1
|
||||||
# 方块材质类型
|
# 方块材质类型
|
||||||
# 可选值: player_head, custom_block, default
|
|
||||||
material: player_head
|
material: player_head
|
||||||
# 是否在生成方块时自动填充周围的方块
|
|
||||||
fill_around: true
|
|
||||||
|
|
||||||
# 当使用玩家头颅时的设置
|
|
||||||
player_head:
|
|
||||||
# 是否随机旋转头颅方向
|
|
||||||
random_rotation: true
|
|
||||||
# 是否显示玩家名字
|
|
||||||
show_player_name: true
|
|
||||||
# 是否显示特殊效果
|
|
||||||
show_effects: true
|
|
||||||
|
|
||||||
# 当使用自定义方块时的设置
|
|
||||||
custom_block:
|
|
||||||
# 自定义方块材质
|
|
||||||
material: DIAMOND_BLOCK
|
|
||||||
# 是否发光
|
|
||||||
glowing: true
|
|
||||||
# 发光等级 (0-15)
|
|
||||||
light_level: 3
|
|
||||||
|
|
||||||
# 游戏规则
|
# 游戏规则
|
||||||
game:
|
game:
|
||||||
@@ -39,59 +18,8 @@ game:
|
|||||||
die_when_blocks_gone: true
|
die_when_blocks_gone: true
|
||||||
# 死亡后是否变成观察者
|
# 死亡后是否变成观察者
|
||||||
become_spectator: true
|
become_spectator: true
|
||||||
# 观察者模式
|
|
||||||
spectator_mode:
|
|
||||||
# 是否可以飞行
|
|
||||||
can_fly: true
|
|
||||||
# 是否可以看到其他玩家
|
|
||||||
can_see_players: true
|
|
||||||
# 是否可以穿墙
|
|
||||||
can_clip: true
|
|
||||||
|
|
||||||
# 是否启用生命值系统
|
# 是否启用生命值系统
|
||||||
health_system: true
|
health_system: true
|
||||||
# 生命值计算公式
|
|
||||||
health_formula:
|
|
||||||
# 方块数量与生命值的关系
|
|
||||||
# 格式: 方块数量:生命值
|
|
||||||
5: 20
|
|
||||||
4: 16
|
|
||||||
3: 12
|
|
||||||
2: 8
|
|
||||||
1: 4
|
|
||||||
0: 0
|
|
||||||
|
|
||||||
# 状态效果
|
|
||||||
status_effects:
|
|
||||||
# 当剩余2个方块时
|
|
||||||
two_blocks_left:
|
|
||||||
- type: SLOW
|
|
||||||
amplifier: 1
|
|
||||||
duration: 100
|
|
||||||
# 当剩余1个方块时
|
|
||||||
one_block_left:
|
|
||||||
- type: SLOW
|
|
||||||
amplifier: 2
|
|
||||||
duration: 100
|
|
||||||
- type: WEAKNESS
|
|
||||||
amplifier: 0
|
|
||||||
duration: 100
|
|
||||||
- type: BLINDNESS
|
|
||||||
amplifier: 0
|
|
||||||
duration: 100
|
|
||||||
|
|
||||||
# 挖掘奖励
|
|
||||||
break_rewards:
|
|
||||||
# 是否给予经验
|
|
||||||
give_exp: true
|
|
||||||
# 经验数量
|
|
||||||
exp_amount: 5
|
|
||||||
# 是否给予物品
|
|
||||||
give_items: false
|
|
||||||
# 物品列表
|
|
||||||
items:
|
|
||||||
- DIAMOND:1
|
|
||||||
- GOLD_INGOT:3
|
|
||||||
|
|
||||||
# 广播设置
|
# 广播设置
|
||||||
broadcast:
|
broadcast:
|
||||||
@@ -101,58 +29,29 @@ game:
|
|||||||
range: 30
|
range: 30
|
||||||
# 玩家死亡时是否全服广播
|
# 玩家死亡时是否全服广播
|
||||||
on_player_death: true
|
on_player_death: true
|
||||||
# 新玩家加入时是否广播
|
|
||||||
on_player_join: false
|
# 挖掘奖励
|
||||||
|
break_rewards:
|
||||||
|
# 是否给予经验
|
||||||
|
give_exp: true
|
||||||
|
# 经验数量
|
||||||
|
exp_amount: 5
|
||||||
|
|
||||||
# 皮肤系统
|
# 皮肤系统
|
||||||
skin:
|
skin:
|
||||||
# 是否启用皮肤系统
|
# 是否启用皮肤系统
|
||||||
enabled: true
|
enabled: true
|
||||||
# 皮肤来源
|
# 皮肤来源 (player_profile, local_cache)
|
||||||
source: player_profile
|
source: player_profile
|
||||||
# 可选值: player_profile, mojang_api, local_cache
|
|
||||||
# player_profile: 从玩家本地缓存获取(推荐,不调用外部API)
|
|
||||||
# mojang_api: 从Mojang API获取(需要网络)
|
|
||||||
# local_cache: 从本地缓存获取
|
|
||||||
|
|
||||||
# 缓存设置
|
# 缓存设置
|
||||||
cache:
|
cache:
|
||||||
# 是否启用缓存
|
|
||||||
enabled: true
|
|
||||||
# 缓存过期时间(天)
|
# 缓存过期时间(天)
|
||||||
expire_days: 7
|
expire_days: 7
|
||||||
# 缓存最大大小(MB)
|
|
||||||
max_size_mb: 100
|
|
||||||
|
|
||||||
# 默认皮肤(当无法获取玩家皮肤时)
|
|
||||||
default_skin:
|
|
||||||
# 使用哪个玩家的皮肤作为默认
|
|
||||||
player_name: Steve
|
|
||||||
# 或使用自定义UUID
|
|
||||||
uuid: 8667ba71-b85a-4004-af54-457a9734eed7
|
|
||||||
# 是否随机分配默认皮肤
|
|
||||||
random_default: false
|
|
||||||
# 可选的默认皮肤列表
|
|
||||||
available_skins:
|
|
||||||
- Steve
|
|
||||||
- Alex
|
|
||||||
- Enderman
|
|
||||||
|
|
||||||
# 皮肤处理
|
|
||||||
processing:
|
|
||||||
# 是否异步处理皮肤
|
|
||||||
async: true
|
|
||||||
# 处理线程数
|
|
||||||
threads: 2
|
|
||||||
# 超时时间(秒)
|
|
||||||
timeout: 10
|
|
||||||
# 重试次数
|
|
||||||
retry_times: 3
|
|
||||||
|
|
||||||
# 数据存储
|
# 数据存储
|
||||||
storage:
|
storage:
|
||||||
# 存储类型
|
# 存储类型 (yaml, json, sqlite)
|
||||||
# 可选值: yaml, json, sqlite, mysql
|
|
||||||
type: yaml
|
type: yaml
|
||||||
|
|
||||||
# 自动保存
|
# 自动保存
|
||||||
@@ -162,221 +61,22 @@ storage:
|
|||||||
# 保存间隔(秒)
|
# 保存间隔(秒)
|
||||||
interval: 300
|
interval: 300
|
||||||
|
|
||||||
# YAML存储设置
|
|
||||||
yaml:
|
|
||||||
# 数据文件编码
|
|
||||||
encoding: UTF-8
|
|
||||||
# 是否压缩
|
|
||||||
compress: false
|
|
||||||
|
|
||||||
# SQLite设置
|
|
||||||
sqlite:
|
|
||||||
# 数据库文件路径
|
|
||||||
file: plugins/PlayerBlockLife/data.db
|
|
||||||
# 连接池大小
|
|
||||||
pool_size: 5
|
|
||||||
|
|
||||||
# MySQL设置
|
|
||||||
mysql:
|
|
||||||
# 数据库主机
|
|
||||||
host: localhost
|
|
||||||
# 数据库端口
|
|
||||||
port: 3306
|
|
||||||
# 数据库名
|
|
||||||
database: minecraft
|
|
||||||
# 用户名
|
|
||||||
username: root
|
|
||||||
# 密码
|
|
||||||
password: password
|
|
||||||
# 表前缀
|
|
||||||
table_prefix: pbl_
|
|
||||||
# 连接池设置
|
|
||||||
pool:
|
|
||||||
max_connections: 10
|
|
||||||
min_connections: 2
|
|
||||||
connection_timeout: 30000
|
|
||||||
idle_timeout: 600000
|
|
||||||
|
|
||||||
# 消息配置
|
|
||||||
messages:
|
|
||||||
# 消息前缀
|
|
||||||
prefix: "&6[&ePlayerBlockLife&6]&r "
|
|
||||||
# 消息颜色
|
|
||||||
colors:
|
|
||||||
success: "&a"
|
|
||||||
error: "&c"
|
|
||||||
warning: "&e"
|
|
||||||
info: "&7"
|
|
||||||
highlight: "&6"
|
|
||||||
|
|
||||||
# 命令消息
|
|
||||||
commands:
|
|
||||||
setlifeblocks:
|
|
||||||
success: "&a已为你生成 {blocks} 个生命方块!"
|
|
||||||
already_has: "&c你已经有生命方块了!使用 /checklifeblocks 查看位置"
|
|
||||||
no_skin: "&e你的皮肤正在加载中,请稍候..."
|
|
||||||
failed: "&c无法生成生命方块,请确保周围有足够空间"
|
|
||||||
|
|
||||||
checklifeblocks:
|
|
||||||
no_blocks: "&c你还没有设置生命方块!使用 /setlifeblocks 来设置"
|
|
||||||
info: "&a你的生命方块信息:"
|
|
||||||
location: "&7{index}. &e世界: {world} &7坐标: &a{x}&7, &a{y}&7, &a{z}"
|
|
||||||
remaining: "&7剩余方块: &e{remaining}&7/&a5"
|
|
||||||
health: "&7当前生命值: &c{health} ❤"
|
|
||||||
|
|
||||||
admin:
|
|
||||||
reload: "&a插件配置已重载!"
|
|
||||||
delete_success: "&a已删除玩家 {player} 的生命方块"
|
|
||||||
delete_failed: "&c删除失败,玩家不存在或没有生命方块"
|
|
||||||
revive_success: "&a玩家 {player} 已复活!"
|
|
||||||
revive_failed: "&c复活失败,玩家不存在或未死亡"
|
|
||||||
|
|
||||||
# 游戏消息
|
|
||||||
game:
|
|
||||||
block_destroyed:
|
|
||||||
owner: "&c⚠ 警告!你的生命方块被 {breaker} 破坏了!"
|
|
||||||
breaker: "&a你破坏了 {owner} 的生命方块!"
|
|
||||||
remaining: "&7对方剩余生命方块: &a{remaining}"
|
|
||||||
broadcast: "&7[附近] &e一个生命方块被破坏了!"
|
|
||||||
|
|
||||||
death:
|
|
||||||
title: "&4☠ 你死了!"
|
|
||||||
subtitle: "&c所有生命方块已被挖光"
|
|
||||||
broadcast: "&4☠ 玩家 {player} 的生命方块已被全部挖光,惨遭淘汰!"
|
|
||||||
spectator: "&e你已被淘汰,可以观察其他玩家。等待下一轮游戏开始..."
|
|
||||||
|
|
||||||
warning:
|
|
||||||
low_blocks: "&c⚠ 警告!生命方块即将耗尽!"
|
|
||||||
last_block: "&4⚠ 警告!这是最后一个生命方块!"
|
|
||||||
health_low: "&4⚠ 警告!生命值过低!"
|
|
||||||
|
|
||||||
# 加入消息
|
|
||||||
join:
|
|
||||||
welcome: "&e欢迎加入游戏!"
|
|
||||||
welcome_back: "&e欢迎回来,{player}!"
|
|
||||||
rules: |
|
|
||||||
&6游戏规则:
|
|
||||||
&7- 每个玩家有5个生命方块
|
|
||||||
&7- 方块被其他玩家挖光时,你将死亡
|
|
||||||
&7- 方块使用你的皮肤作为材质
|
|
||||||
&7- 你可以自由移动,但方块固定位置
|
|
||||||
remaining_blocks: "&7你还有 {blocks} 个生命方块"
|
|
||||||
commands: "&7使用 &e/setlifeblocks &7来设置你的生命方块"
|
|
||||||
|
|
||||||
# 效果设置
|
|
||||||
effects:
|
|
||||||
# 方块放置效果
|
|
||||||
place:
|
|
||||||
particles:
|
|
||||||
- type: ENCHANTMENT_TABLE
|
|
||||||
count: 30
|
|
||||||
offset_x: 0.3
|
|
||||||
offset_y: 0.3
|
|
||||||
offset_z: 0.3
|
|
||||||
speed: 0.1
|
|
||||||
sounds:
|
|
||||||
- type: BLOCK_ANVIL_PLACE
|
|
||||||
volume: 0.5
|
|
||||||
pitch: 1.2
|
|
||||||
|
|
||||||
# 方块破坏效果
|
|
||||||
break:
|
|
||||||
particles:
|
|
||||||
- type: BLOCK_CRACK
|
|
||||||
count: 50
|
|
||||||
offset_x: 0.5
|
|
||||||
offset_y: 0.5
|
|
||||||
offset_z: 0.5
|
|
||||||
speed: 0.5
|
|
||||||
data: PLAYER_HEAD
|
|
||||||
- type: SMOKE_LARGE
|
|
||||||
count: 20
|
|
||||||
offset_x: 0.3
|
|
||||||
offset_y: 0.3
|
|
||||||
offset_z: 0.3
|
|
||||||
speed: 0.05
|
|
||||||
sounds:
|
|
||||||
- type: ENTITY_ITEM_BREAK
|
|
||||||
volume: 1.0
|
|
||||||
pitch: 0.8
|
|
||||||
- type: BLOCK_GLASS_BREAK
|
|
||||||
volume: 0.8
|
|
||||||
pitch: 1.0
|
|
||||||
knockback:
|
|
||||||
enabled: true
|
|
||||||
power: 0.5
|
|
||||||
vertical: 0.3
|
|
||||||
|
|
||||||
# 玩家受伤效果
|
|
||||||
damage:
|
|
||||||
particles:
|
|
||||||
- type: DAMAGE_INDICATOR
|
|
||||||
count: 10
|
|
||||||
sounds:
|
|
||||||
- type: ENTITY_PLAYER_HURT
|
|
||||||
volume: 1.0
|
|
||||||
pitch: 1.0
|
|
||||||
|
|
||||||
# 玩家死亡效果
|
|
||||||
player_death:
|
|
||||||
particles:
|
|
||||||
- type: EXPLOSION_HUGE
|
|
||||||
count: 5
|
|
||||||
sounds:
|
|
||||||
- type: ENTITY_WITHER_DEATH
|
|
||||||
volume: 0.7
|
|
||||||
pitch: 0.8
|
|
||||||
- type: ENTITY_LIGHTNING_BOLT_THUNDER
|
|
||||||
volume: 1.0
|
|
||||||
pitch: 0.5
|
|
||||||
|
|
||||||
# 保护设置
|
# 保护设置
|
||||||
protection:
|
protection:
|
||||||
# 是否保护生命方块不被非玩家破坏
|
|
||||||
protect_from_non_players: true
|
|
||||||
# 是否保护生命方块不被爆炸破坏
|
# 是否保护生命方块不被爆炸破坏
|
||||||
protect_from_explosions: true
|
protect_from_explosions: true
|
||||||
# 是否保护生命方块不被火焰烧毁
|
# 是否保护生命方块不被火焰烧毁
|
||||||
protect_from_fire: true
|
protect_from_fire: true
|
||||||
# 是否保护生命方块不被活塞推动
|
# 是否保护生命方块不被活塞推动
|
||||||
protect_from_pistons: true
|
protect_from_pistons: true
|
||||||
# 是否允许TNT破坏生命方块
|
|
||||||
allow_tnt_damage: false
|
|
||||||
# 是否允许苦力怕爆炸破坏生命方块
|
|
||||||
allow_creeper_explosions: false
|
|
||||||
# 是否允许末影龙破坏生命方块
|
|
||||||
allow_ender_dragon_damage: false
|
|
||||||
# 是否允许其他插件修改生命方块
|
|
||||||
allow_plugin_modification: false
|
|
||||||
|
|
||||||
# 世界保护
|
# 消息配置(可选,插件会使用默认消息)
|
||||||
world_guard:
|
messages:
|
||||||
# 是否与WorldGuard集成
|
commands:
|
||||||
enabled: false
|
setlifeblocks:
|
||||||
# 需要保护的地区标志
|
success: "&a已为你生成 {blocks} 个生命方块!"
|
||||||
region_flags:
|
already_has: "&c你已经有生命方块了!使用 /checklifeblocks 查看位置"
|
||||||
- block-break
|
game:
|
||||||
- block-place
|
block_destroyed:
|
||||||
- pvp
|
owner: "&c⚠ 警告!你的生命方块被 {breaker} 破坏了!"
|
||||||
# 白名单地区(允许破坏生命方块的地区)
|
breaker: "&a你破坏了 {owner} 的生命方块!"
|
||||||
whitelist_regions: []
|
|
||||||
# 黑名单地区(不允许破坏生命方块的地区)
|
|
||||||
blacklist_regions: []
|
|
||||||
|
|
||||||
# 调试设置
|
|
||||||
debug:
|
|
||||||
# 是否启用调试模式
|
|
||||||
enabled: false
|
|
||||||
# 调试级别
|
|
||||||
# 可选值: INFO, WARNING, ERROR, DEBUG
|
|
||||||
level: INFO
|
|
||||||
# 是否记录到文件
|
|
||||||
log_to_file: true
|
|
||||||
# 日志文件路径
|
|
||||||
log_file: plugins/PlayerBlockLife/debug.log
|
|
||||||
# 是否显示详细事件日志
|
|
||||||
verbose_events: false
|
|
||||||
# 是否记录性能数据
|
|
||||||
log_performance: false
|
|
||||||
# 性能日志间隔(秒)
|
|
||||||
performance_log_interval: 60
|
|
||||||
@@ -1,35 +1,75 @@
|
|||||||
|
name: PlayerBlockLife
|
||||||
|
version: 1.0.1-1.20.4
|
||||||
|
main: com.playerblocklife.PlayerBlockLife
|
||||||
|
api-version: 1.20
|
||||||
|
author: xiaobai
|
||||||
|
description: 玩家生命方块系统 - 方块被挖光则死亡
|
||||||
|
website: https://github.com/yourname/PlayerBlockLife
|
||||||
|
prefix: PBL
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
setlifeblocks:
|
setlifeblocks:
|
||||||
description: 设置你的生命方块(使用你的皮肤)
|
description: 设置你的生命方块(使用你的皮肤)
|
||||||
usage: /<command>
|
usage: |
|
||||||
|
/<command> - 设置你的生命方块
|
||||||
|
/<command> help - 显示帮助
|
||||||
|
/<command> reset - 重置生命方块位置
|
||||||
|
/<command> other <玩家> - 为其他玩家设置(管理员)
|
||||||
aliases: [sbl, lifeblocks, setblocks]
|
aliases: [sbl, lifeblocks, setblocks]
|
||||||
permission: playerblocklife.set
|
permission: playerblocklife.set
|
||||||
|
permission-message: "§c你没有权限使用此命令!"
|
||||||
|
|
||||||
checklifeblocks:
|
checklifeblocks:
|
||||||
description: 查看你的生命方块位置
|
description: 查看你的生命方块位置
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
aliases: [cbl, checklife, myblocks]
|
aliases: [cbl, checklife, myblocks]
|
||||||
permission: playerblocklife.check
|
permission: playerblocklife.check
|
||||||
|
permission-message: "§c你没有权限使用此命令!"
|
||||||
|
|
||||||
pblreload:
|
pblreload:
|
||||||
description: 重载插件配置
|
description: 重载插件配置
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
aliases: [pblr, pblreload]
|
aliases: [pblr]
|
||||||
permission: playerblocklife.admin
|
permission: playerblocklife.admin
|
||||||
|
permission-message: "§c你没有权限使用此命令!"
|
||||||
|
|
||||||
pbldelete:
|
pbldelete:
|
||||||
description: 删除指定玩家的生命方块
|
description: 删除指定玩家的生命方块
|
||||||
usage: /<command> <玩家>
|
usage: /<command> <玩家>
|
||||||
aliases: [pbldel, deleteblocks]
|
aliases: [pbldel, deleteblocks]
|
||||||
permission: playerblocklife.admin
|
permission: playerblocklife.admin
|
||||||
|
permission-message: "§c你没有权限使用此命令!"
|
||||||
|
|
||||||
pblrevive:
|
pblrevive:
|
||||||
description: 复活被淘汰的玩家
|
description: 复活被淘汰的玩家
|
||||||
usage: /<command> [玩家]
|
usage: /<command> [玩家]
|
||||||
aliases: [revive]
|
aliases: [revive]
|
||||||
permission: playerblocklife.admin
|
permission: playerblocklife.admin
|
||||||
|
permission-message: "§c你没有权限使用此命令!"
|
||||||
|
|
||||||
pblstats:
|
pblstats:
|
||||||
description: 查看插件统计信息
|
description: 查看插件统计信息
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
permission: playerblocklife.admin
|
permission: playerblocklife.admin
|
||||||
|
permission-message: "§c你没有权限使用此命令!"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
playerblocklife.*:
|
||||||
|
description: 所有 PlayerBlockLife 权限
|
||||||
|
children:
|
||||||
|
playerblocklife.set: true
|
||||||
|
playerblocklife.check: true
|
||||||
|
playerblocklife.admin: true
|
||||||
|
default: op
|
||||||
|
|
||||||
|
playerblocklife.set:
|
||||||
|
description: 允许设置生命方块
|
||||||
|
default: true
|
||||||
|
|
||||||
|
playerblocklife.check:
|
||||||
|
description: 允许查看生命方块
|
||||||
|
default: true
|
||||||
|
|
||||||
|
playerblocklife.admin:
|
||||||
|
description: 管理员权限
|
||||||
|
default: op
|
||||||
Reference in New Issue
Block a user