From dcc14588b092061affed1dbcc2ef5ebc8cf48c33 Mon Sep 17 00:00:00 2001 From: naipu Date: Wed, 30 Sep 2026 19:10:24 +0800 Subject: [PATCH] fix(commands): avoid concurrent command tree rebuilds --- .../internal/service/RegisterCommands.kt | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/plugin/src/main/kotlin/trplugins/menu/module/internal/service/RegisterCommands.kt b/plugin/src/main/kotlin/trplugins/menu/module/internal/service/RegisterCommands.kt index 753c2037..26d44bc9 100644 --- a/plugin/src/main/kotlin/trplugins/menu/module/internal/service/RegisterCommands.kt +++ b/plugin/src/main/kotlin/trplugins/menu/module/internal/service/RegisterCommands.kt @@ -7,7 +7,6 @@ import taboolib.common.platform.command.command import taboolib.common.platform.function.adaptPlayer import taboolib.common.platform.function.submit import taboolib.common.platform.function.unregisterCommand -import taboolib.platform.util.onlinePlayers import trplugins.menu.TrMenu import trplugins.menu.TrMenu.actionHandle import trplugins.menu.api.reaction.Reactions @@ -21,6 +20,7 @@ import trplugins.menu.util.conf.Property object RegisterCommands { private val registered = mutableSetOf() + private var loadedConfiguration: Map? = null private fun ofReaction(any: Any?): Reactions { return Reactions.ofReaction(actionHandle, Property.asAnyList(any)) @@ -33,11 +33,17 @@ object RegisterCommands { } return } + + val section = TrMenu.SETTINGS.getConfigurationSection("RegisterCommands") + val configuration = section?.getValues(true)?.toMap() ?: emptyMap() + if (configuration == loadedConfiguration) { + return + } + val unregisterList = registered.toList() unregisterList.forEach { unregisterCommand(it) } registered.clear() - val section = TrMenu.SETTINGS.getConfigurationSection("RegisterCommands") section?.let { it -> for (main in it.getKeys(false)) { val section = it.getConfigurationSection(main) ?: continue @@ -81,15 +87,6 @@ object RegisterCommands { } } } - - // 延迟同步命令到所有在线玩家,避免与 Paper 异步命令发送线程冲突 - // Paper 的 sendAsync 会在异步线程遍历命令树,直接调用 updateCommands 可能触发 ConcurrentModificationException - submit(delay = 1) { - val players = onlinePlayers - if (players.isEmpty()) { - return@submit - } - players.forEach { it.updateCommands() } - } + loadedConfiguration = configuration } }