第42批:修复垃圾站启停状态热重载断链(日志喊了true→false但垃圾站照跑)
Check Source / check (push) Successful in 4s
Auto Release / build (push) Successful in 4m10s
Simple Test / test (push) Successful in 2s
Test Env / test (push) Successful in 1s

This commit is contained in:
youpaishidifu
2026-10-22 14:28:17 +08:00
parent a5cb5afba7
commit 22e4d262dc
3 changed files with 97 additions and 6 deletions
+87 -4
View File
@@ -34,6 +34,12 @@ public class GarbageManager implements Listener {
private boolean enabled = true;
private int currentRound = 0;
/**
* ★ 第42批:自动清理任务引用(BukkitRunnable)。
* 热停用时 cancel 该任务;applyEnabledState() 用它判断是否已在跑。
*/
private BukkitRunnable cleanupTask = null;
/**
* ★ 第36批:上一轮「清扫」进回收站的掉落物数量(血条展示)。
* -1 = 还没跑过任何一轮(血条不显示该字段)。
@@ -178,9 +184,28 @@ public class GarbageManager implements Listener {
public void startAutoCleanup() {
if (!enabled) return;
new BukkitRunnable() {
// ★ 第42批:已在跑则不再重复调度(applyEnabledState 可能被多路热重载同时触发)
if (cleanupTask != null) return;
cleanupTask = new BukkitRunnable() {
@Override
public void run() {
// ★ 第42批:启停状态热更兜底 —— ConfigManager.garbageEnabled 变 false 后
// (插件设置.txt 热重载),任务自己收摊:撤血条+清状态+取消自身。
// 反向 false→true 时任务已不存在,靠 applyEnabledState() 重新拉起。
if (!plugin.getConfig2().garbageEnabled) {
enabled = false;
hideAllBossBars();
roundStartMs = 0L;
announcedMask = 0;
pendingDrops.clear();
cleanupTask = null;
plugin.getLogger().info(
"[Garbage] 垃圾站_启用 热更关闭:自动清理任务已自停、血条已撤");
this.cancel();
return;
}
enabled = true;
// 在线人数≤0时暂停
if (Bukkit.getOnlinePlayers()
.isEmpty()) {
@@ -250,8 +275,14 @@ public class GarbageManager implements Listener {
if (nodeHit) {
// ★ 第31批(#204/#205):垃圾箱进入下一节点 → 查一次 插件设置.txt,
// 有变化整份重载(ConfigManager 内部比对,无变化静默、有变化打日志)
plugin.getConfig2()
.reloadSettingsIfChanged();
// ★ 第42批:重载成功后把「垃圾站_启用」应用到运行态 ——
// 此前只更新 ConfigManager 字段,GarbageManager.enabled 没人回写,
// 导致日志喊了「true→false」但任务照跑、血条照显示(用户截图根因)。
if (plugin.getConfig2()
.reloadSettingsIfChanged()) {
applyEnabledState();
if (!enabled) return; // 本轮已被热停 → 不再往下跑
}
}
if (remain <= 5 && remain > 0)
broadcast("§e§l[垃圾站] §c" + remain + "§f...");
@@ -267,7 +298,59 @@ public class GarbageManager implements Listener {
// ★ 第34批:remain 取自墙钟唯一时间源,与广播/抢救打印同源
updateBossBars(remain);
}
}.runTaskTimer(plugin, 20L, 20L);
};
cleanupTask.runTaskTimer(plugin, 20L, 20L);
}
/**
* ★ 第42批:停止自动清理任务并复位运行态(热停用时用)。
* 撤血条 + 清按键状态 + 复位墙钟起点与节点位图,下次启用从满格重新计时。
*/
public void stopAutoCleanup() {
if (cleanupTask != null) {
try {
cleanupTask.cancel();
} catch (IllegalStateException ignored) {
}
cleanupTask = null;
}
enabled = false;
hideAllBossBars();
roundStartMs = 0L;
announcedMask = 0;
pendingDrops.clear();
}
/**
* ★ 第42批:把 ConfigManager.garbageEnabled(插件设置.txt 的「垃圾站_启用」)
* 应用到 GarbageManager 运行态(双向:false→true 重新拉起任务 / true→false 停任务撤血条)。
*
* <p>根因(第42批用户截图):reloadSettingsIfChanged() 整份重载后只更新了
* ConfigManager 的字段并打了「已整份重载」日志,但 GarbageManager.enabled
* 是启动时 loadConfig() 拷贝的运行态快照,没人回写 → 日志喊了 true→false,
* 垃圾站照常运行。反向(false→true)更糟:启动时任务就没创建,
* 之后改 true 也没人调 startAutoCleanup(),垃圾站永远起不来。
*
* <p>调用点:Web 热重载 / 垃圾站节点热重载 / /sdf1_login reload 命令。
* 非主线程调用会自动切回主线程(BossBar 撤除必须主线程)。
*/
public void applyEnabledState() {
if (!Bukkit.isPrimaryThread()) {
Bukkit.getScheduler().runTask(plugin, this::applyEnabledState);
return;
}
boolean want = plugin.getConfig2().garbageEnabled;
if (want == enabled) return; // 状态一致 → no-op(防多路触发重复打日志)
if (want) {
enabled = true;
startAutoCleanup();
plugin.getLogger().info(
"[Garbage] 垃圾站_启用 热更生效:自动清理任务已启动");
} else {
stopAutoCleanup();
plugin.getLogger().info(
"[Garbage] 垃圾站_启用 热更生效:自动清理任务已停止、血条已撤");
}
}
/**
+4
View File
@@ -9821,6 +9821,8 @@ public class Main extends JavaPlugin
// ★ 第31批(#205):/reload 此前漏了 loadSettings,
// 插件设置.txt 改完 reload 不生效(启发式拦截/垃圾间隔没动静的根因)
if (config != null) config.loadSettings();
// ★ 第42批:整份重载后把垃圾站启停应用到运行态
if (garbage != null) garbage.applyEnabledState();
if (areaProtection != null) areaProtection.reload();
if (webManager != null) webManager.reloadWebConfig();
sender.sendMessage("§a[§2Sdf1_login§a] 插件全部设置已重载");
@@ -10011,6 +10013,8 @@ public class Main extends JavaPlugin
config.loadMessages();
config.loadSmtp();
config.loadSettings();
// ★ 第42批:整份重载后把垃圾站启停应用到运行态
if (garbage != null) garbage.applyEnabledState();
chatFilter.loadConfig();
if (radio != null) radio.reload();
if (getMenu() != null) {
+6 -2
View File
@@ -161,8 +161,12 @@ public class WebManager {
// ★ 第31批(#204):web 感知到 插件设置.txt 变化 → 拉起整份文件重载
// (垃圾站等其他模块的配置字段;ConfigManager 内部比对,无变化静默)
if (plugin.getConfig2() != null) {
plugin.getConfig2().reloadSettingsIfChanged();
// ★ 第42批:重载成功后把垃圾站启停应用到运行态(否则只改字段不生效)
if (plugin.getConfig2() != null
&& plugin.getConfig2().reloadSettingsIfChanged()) {
if (plugin.getGarbage() != null) {
plugin.getGarbage().applyEnabledState();
}
}
if (!urlChanged && !secretChanged && !enableChanged && !othersChanged) {