修复: PVP显式随机种子(根除固定-5092种子) + 菜单控制台指令+玩家名变量 + 商店跳过.web.md(PHP专属商品)
- PVPArenaManager: createPVPWorld改用worldSeedRandom.nextLong()显式设定随机种子(用户实测连续多次createWorld返回相同种子-5092048402667366605);增加删除后验证日志(确认目录消失或告警)
- Main.java(两处菜单点击): 新增permType提取→控制台/console身份执行(Bukkit.getConsoleSender);玩家名变量替换{player}/%player%/<player>/[player]/(player)等所有括号形式
- ShopManager: loadCategories文件过滤器增加!.web.md条件,游戏内不加载.web.md文件(PHP端专属商品)
This commit is contained in:
@@ -3573,6 +3573,14 @@ public class Main extends JavaPlugin
|
||||
p.sendMessage("§c指令为空");
|
||||
return;
|
||||
}
|
||||
// ★ 提取权限类型(控制台/玩家/OP)
|
||||
String permType = "玩家";
|
||||
for (String pl : subLm.getLore()) {
|
||||
if (pl.contains("§7权限: §f")) {
|
||||
permType = pl.replace("§7权限: §f", "").trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
p.closeInventory();
|
||||
if (cmd.startsWith("/")) {
|
||||
cmd = cmd.substring(1);
|
||||
@@ -3581,7 +3589,20 @@ public class Main extends JavaPlugin
|
||||
if (cmd.endsWith(".txt")) {
|
||||
gui.openSubMenu(p, cmd);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(p, cmd);
|
||||
// ★ 替换玩家名变量:{player} %player% <player> [player] (player) 等
|
||||
String playerName = p.getName();
|
||||
cmd = cmd.replaceAll("\\{player\\}", playerName)
|
||||
.replaceAll("%player%", playerName)
|
||||
.replaceAll("<player>", playerName)
|
||||
.replaceAll("\\[player\\]", playerName)
|
||||
.replaceAll("\\(player\\)", playerName);
|
||||
// ★ 根据权限类型选择执行身份
|
||||
if ("控制台".equals(permType) || "console".equalsIgnoreCase(permType)) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
|
||||
p.sendMessage("§a[菜单] 已以控制台身份执行: /" + cmd);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(p, cmd);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3840,6 +3861,14 @@ public class Main extends JavaPlugin
|
||||
p.sendMessage("§c指令为空");
|
||||
return;
|
||||
}
|
||||
// ★ 提取权限类型(控制台/玩家/OP)
|
||||
String permType = "玩家";
|
||||
for (String pl : meta.getLore()) {
|
||||
if (pl.contains("§7权限: §f")) {
|
||||
permType = pl.replace("§7权限: §f", "").trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
p.closeInventory();
|
||||
if (cmd.startsWith("/")) {
|
||||
cmd = cmd.substring(1);
|
||||
@@ -3847,7 +3876,20 @@ public class Main extends JavaPlugin
|
||||
if (cmd.endsWith(".txt")) {
|
||||
gui.openSubMenu(p, cmd);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(p, cmd);
|
||||
// ★ 替换玩家名变量
|
||||
String playerName = p.getName();
|
||||
cmd = cmd.replaceAll("\\{player\\}", playerName)
|
||||
.replaceAll("%player%", playerName)
|
||||
.replaceAll("<player>", playerName)
|
||||
.replaceAll("\\[player\\]", playerName)
|
||||
.replaceAll("\\(player\\)", playerName);
|
||||
// ★ 根据权限类型选择执行身份
|
||||
if ("控制台".equals(permType) || "console".equalsIgnoreCase(permType)) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
|
||||
p.sendMessage("§a[菜单] 已以控制台身份执行: /" + cmd);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(p, cmd);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -241,14 +241,30 @@ public class PVPArenaManager implements Listener {
|
||||
WorldCreator creator = new WorldCreator(PVP_WORLD_NAME);
|
||||
creator.environment(World.Environment.NORMAL);
|
||||
creator.type(WorldType.NORMAL);
|
||||
// ★ 不设 seed:让 MC 自行随机决定地形种子(插件对地形零干预)。
|
||||
// 创建后通过 getSeed() 读取 MC 选定的种子并记录日志,便于排查"出生点脚下是水"的失败种子。
|
||||
// ★ 显式设置随机种子:避免 MC 内部 RNG 在特定条件下产生相同种子导致地形重复。
|
||||
// 用户实测发现连续多次 createWorld 返回相同种子(-5092048402667366605),
|
||||
// 显式指定 worldSeedRandom.nextLong() 保证每次地形不同。
|
||||
long seed = worldSeedRandom.nextLong();
|
||||
creator.seed(seed);
|
||||
plugin.getLogger().info("[PVP] 显式设定种子=" + seed + " (确保每次地形不同)");
|
||||
|
||||
// ★ 彻底清理磁盘上可能残留的旧世界目录:旧版本曾干预出生点(setSpawnLocation)并强制造陆,
|
||||
// 若上次删除因 Windows 文件锁失败,createWorld 会误加载到旧世界(出生点被锁定/小岛地形)。
|
||||
// 这里重试删除确保目录消失,保证每次进入都是 MC 自然生成的全新主世界与自然出生点。
|
||||
deleteExistingPVPWorldFolder();
|
||||
|
||||
// ★ 验证:确认旧目录确实已消失
|
||||
File folder = new File(Bukkit.getWorldContainer(), PVP_WORLD_NAME);
|
||||
if (folder.exists()) {
|
||||
plugin.getLogger().severe("[PVP] ⚠ 警告:deleteExistingPVPWorldFolder 执行后 pvp_arena 目录仍然存在!createWorld 可能复用旧世界");
|
||||
moveWorldToTrash(folder);
|
||||
if (folder.exists()) {
|
||||
plugin.getLogger().severe("[PVP] ❌ 无法删除 pvp_arena 目录,本次可能仍会使用旧地形/旧种子");
|
||||
}
|
||||
} else {
|
||||
plugin.getLogger().info("[PVP] ✅ 确认旧 pvp_arena 目录已清除,将生成全新世界");
|
||||
}
|
||||
|
||||
World pvpWorld = creator.createWorld();
|
||||
long dt = System.currentTimeMillis() - t0;
|
||||
if (pvpWorld == null) {
|
||||
|
||||
@@ -985,12 +985,14 @@ public class ShopManager implements Listener {
|
||||
|
||||
File[] allMd = dir.listFiles(
|
||||
(d, n) -> n.endsWith(".md")
|
||||
&& !n.equals("coupons.md"));
|
||||
&& !n.equals("coupons.md")
|
||||
&& !n.contains(".web")); // ★ 跳过 .web.md 文件(PHP专属商品,游戏内不加载)
|
||||
if (allMd == null || allMd.length == 0) {
|
||||
createDefaultCategories(dir);
|
||||
allMd = dir.listFiles(
|
||||
(d, n) -> n.endsWith(".md")
|
||||
&& !n.equals("coupons.md"));
|
||||
&& !n.equals("coupons.md")
|
||||
&& !n.contains(".web")); // ★ 跳过 .web.md(PHP专属商品)
|
||||
}
|
||||
if (allMd == null) {
|
||||
plugin.getLogger().warning(
|
||||
|
||||
Reference in New Issue
Block a user