From b65049daa95e3782f2b38a04994d878db1b4f743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=98=BF=E9=B9=B0?= Date: Sun, 14 Dec 2025 23:05:54 +0800 Subject: [PATCH 1/3] =?UTF-8?q?chore(plugin):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E5=B9=B6=E4=BC=98=E5=8C=96=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=B3=A8=E5=86=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将插件版本从 3.9.12 升级至 3.9.13 - 在命令注册过程中添加延迟同步机制,防止与 Paper 异步命令发送线程产生冲突 - 使用 submit 方法确保命令注销操作在主线程中执行 - 添加异常捕获以增强命令更新过程的稳定性 --- gradle.properties | 2 +- .../internal/service/RegisterCommands.kt | 20 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 115c165a..14b0968d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ group=me.arasple.mc.trmenu -version=3.9.12 \ No newline at end of file +version=3.9.13 \ No newline at end of file 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 14f83b1b..6c14366b 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 @@ -1,9 +1,11 @@ package trplugins.menu.module.internal.service +import org.bukkit.Bukkit import org.bukkit.entity.Player import taboolib.common.platform.command.PermissionDefault 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 trplugins.menu.TrMenu import trplugins.menu.TrMenu.actionHandle @@ -24,9 +26,12 @@ object RegisterCommands { } fun load() { - registered.removeIf { - unregisterCommand(it) - true + submit { + registered.removeIf { + unregisterCommand(it) + true + } + } TrMenu.SETTINGS.getConfigurationSection("RegisterCommands")?.let { it -> @@ -72,6 +77,13 @@ object RegisterCommands { } } } - } + // 延迟同步命令到所有在线玩家,避免与 Paper 异步命令发送线程冲突 + // Paper 的 sendAsync 会在异步线程遍历命令树,直接调用 updateCommands 可能触发 ConcurrentModificationException + submit(delay = 1) { + try { + Bukkit.getOnlinePlayers().forEach { it.updateCommands() } + } catch (_: Throwable) {} + } + } } \ No newline at end of file From 7623ad2d209025d84c0f425d664a9761abe8e088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=98=BF=E9=B9=B0?= Date: Tue, 16 Dec 2025 17:30:04 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(menu):=20=E6=B7=BB=E5=8A=A0=E8=99=9A?= =?UTF-8?q?=E6=8B=9FOP=E5=91=BD=E4=BB=A4=E6=89=A7=E8=A1=8C=E9=80=89?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增配置项 COMMAND_FAKE_OP 控制是否使用虚拟OP执行命令 - 在 CommandOp 动作中实现真实OP权限切换逻辑 - 更新菜单序列化器以支持新的命令执行配置 - 升级 TabooLib 版本依赖 - 增加插件版本号至 3.9.14 --- build.gradle.kts | 2 +- .../kotlin/trplugins/menu/util/conf/Property.kt | 7 ++++++- gradle.properties | 2 +- .../menu/api/action/impl/send/CommandOp.kt | 17 ++++++++++++++++- .../menu/module/conf/MenuSerializer.kt | 4 +++- .../menu/module/display/MenuSettings.kt | 3 ++- 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 29b1c533..c103ebca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -72,7 +72,7 @@ subprojects { disableOnSkippedVersion = false } version { - taboolib = "6.2.4-abd325ee" + taboolib = "6.2.4-65252583" coroutines = null } } diff --git a/common/src/main/kotlin/trplugins/menu/util/conf/Property.kt b/common/src/main/kotlin/trplugins/menu/util/conf/Property.kt index a8d453db..df36e485 100644 --- a/common/src/main/kotlin/trplugins/menu/util/conf/Property.kt +++ b/common/src/main/kotlin/trplugins/menu/util/conf/Property.kt @@ -271,7 +271,12 @@ enum class Property(val default: String, val regex: Regex) { /** * 菜单内置国际化 */ - LANG("Lang", "lang(uage)?|internationalization|i18n"); + LANG("Lang", "lang(uage)?|internationalization|i18n"), + + /** + * 菜单内虚拟OP命令 + */ + COMMAND_FAKE_OP("Command-Fake-Op", "command-?fake_?op"); constructor(default: String, regex: String) : this(default, Regex("(?i)$regex")) diff --git a/gradle.properties b/gradle.properties index 14b0968d..50c841e5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ group=me.arasple.mc.trmenu -version=3.9.13 \ No newline at end of file +version=3.9.14 \ No newline at end of file diff --git a/plugin/src/main/kotlin/trplugins/menu/api/action/impl/send/CommandOp.kt b/plugin/src/main/kotlin/trplugins/menu/api/action/impl/send/CommandOp.kt index facb7b36..78d85060 100644 --- a/plugin/src/main/kotlin/trplugins/menu/api/action/impl/send/CommandOp.kt +++ b/plugin/src/main/kotlin/trplugins/menu/api/action/impl/send/CommandOp.kt @@ -7,6 +7,7 @@ import taboolib.expansion.dispatchCommandAsOp import trplugins.menu.api.action.ActionHandle import trplugins.menu.api.action.base.ActionBase import trplugins.menu.api.action.base.ActionContents +import trplugins.menu.module.display.session /** * TrMenu @@ -20,9 +21,23 @@ class CommandOp(handle: ActionHandle) : ActionBase(handle) { override val regex = "op(erator)?s?".toRegex() override fun onExecute(contents: ActionContents, player: ProxyPlayer, placeholderPlayer: ProxyPlayer) { + val fakeOp = player.session().menu?.settings?.commandFakeOp ?: true contents.stringContent().parseContentSplited(placeholderPlayer, ";").forEach { submit(async = false) { - player.cast().dispatchCommandAsOp(it) + if (fakeOp) { + player.cast().dispatchCommandAsOp(it) + } else { + player.isOp.let { isOp -> + player.isOp = true + try { + player.performCommand(it) + } catch (e: Throwable) { + e.printStackTrace() + } finally { + player.isOp = isOp + } + } + } } } } diff --git a/plugin/src/main/kotlin/trplugins/menu/module/conf/MenuSerializer.kt b/plugin/src/main/kotlin/trplugins/menu/module/conf/MenuSerializer.kt index d6d52778..7f863280 100644 --- a/plugin/src/main/kotlin/trplugins/menu/module/conf/MenuSerializer.kt +++ b/plugin/src/main/kotlin/trplugins/menu/module/conf/MenuSerializer.kt @@ -168,6 +168,7 @@ object MenuSerializer : ISerializer { val eventOpen = Property.EVENT_OPEN.ofList(events) val eventClose = Property.EVENT_CLOSE.ofList(events) val eventClick = Property.EVENT_CLICK.ofList(events) + val commandFakeOp = Property.COMMAND_FAKE_OP.ofBoolean(options, true) val settings = MenuSettings( CycleList(title), @@ -199,7 +200,8 @@ object MenuSerializer : ISerializer { ) } }, - funs.map { ScriptFunction(it.key, it.value.toString()) }.toSet() + funs.map { ScriptFunction(it.key, it.value.toString()) }.toSet(), + commandFakeOp ) // i18n diff --git a/plugin/src/main/kotlin/trplugins/menu/module/display/MenuSettings.kt b/plugin/src/main/kotlin/trplugins/menu/module/display/MenuSettings.kt index 7ae3f021..8518a861 100644 --- a/plugin/src/main/kotlin/trplugins/menu/module/display/MenuSettings.kt +++ b/plugin/src/main/kotlin/trplugins/menu/module/display/MenuSettings.kt @@ -33,7 +33,8 @@ class MenuSettings( val closeEvent: Reactions, val clickEvent: Reactions, val tasks: List, - val internalFunctions: Set + val internalFunctions: Set, + val commandFakeOp: Boolean = true, ) { companion object { From 68e71b7ec52813366b087e156e76c68f5b79d621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=98=BF=E9=B9=B0?= Date: Tue, 16 Dec 2025 17:33:36 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix(conf):=20=E4=BF=AE=E6=AD=A3=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E5=86=85=E8=99=9A=E6=8B=9FOP=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E7=9A=84=E6=AD=A3=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将命令正则从 command-?fake_?op 更改为 command-?fake-?op - 保持构造函数逻辑不变,仅调整正则表达式格式 --- common/src/main/kotlin/trplugins/menu/util/conf/Property.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/kotlin/trplugins/menu/util/conf/Property.kt b/common/src/main/kotlin/trplugins/menu/util/conf/Property.kt index df36e485..4c102888 100644 --- a/common/src/main/kotlin/trplugins/menu/util/conf/Property.kt +++ b/common/src/main/kotlin/trplugins/menu/util/conf/Property.kt @@ -276,7 +276,7 @@ enum class Property(val default: String, val regex: Regex) { /** * 菜单内虚拟OP命令 */ - COMMAND_FAKE_OP("Command-Fake-Op", "command-?fake_?op"); + COMMAND_FAKE_OP("Command-Fake-Op", "command-?fake-?op"); constructor(default: String, regex: String) : this(default, Regex("(?i)$regex"))