CyuQuiz | 更有意思的趣味问答[1.13-1.21]

服务端插件 CyuQuiz | 更有意思的趣味问答[1.13-1.21] 1.0

请登录后获取
插件有一个bug我询问了豆包

[MD] 这个错误是 **Minecraft 服务器插件开发中典型的“异步线程操作主线程安全资源”问题**,核心原因是 `cyuquiz` 插件在**异步线程**(处理玩家聊天事件的线程)中直接执行了需要在**服务器主线程**(Main Thread)中运行的命令,违反了 Bukkit/Spigot/Paper 服务器的线程安全规范。### 一、错误核心解析#### 1. 关键错误信息- 核心提示:`Asynchronous Command Dispatched Async: money give ncov0748 50!` (在异步线程中调度了命令:给玩家 `ncov0748` 发放 50 货币)- 根本原因:`java.lang.IllegalStateException`(非法状态异常),由 `AsyncCatcher`(Spigot/Paper 的异步操作检测器)触发。#### 2. 线程安全背景Minecraft 服务器(Bukkit 生态)是**单线程核心架构**:- **主线程(Main Thread)**:负责处理所有核心逻辑(如实体移动、方块更新、命令执行、玩家数据修改等),是“线程安全区”。- **异步线程(Async Thread)**:用于处理耗时操作(如数据库查询、网络请求、聊天事件预处理等),避免阻塞主线程导致服务器卡顿。**规则**:所有修改服务器状态的操作(如执行命令、修改玩家背包/货币、操作方块)**必须在主线程中执行**。异步线程中直接调用这些操作会触发 `AsyncCatcher` 检测,抛出上述错误。### 二、错误溯源(从堆栈信息看)堆栈信息清晰标注了错误发生的代码路径,可定位到 `cyuquiz` 插件的具体问题位置:1. **触发入口**:玩家发送聊天 → 触发 `AsyncPlayerChatEvent`(异步事件,运行在异步线程)。2. **插件处理**:`ChatListener.onChat(ChatListener.java:23)` → 调用 `QuizManager.answer(QuizManager.java:191)`。3. **错误操作**:在 `QuizManager.answer` 方法的第 191 行,调用了 `Bukkit.dispatchCommand(...)`(执行“money give”命令)。4. **检测报错**:`AsyncCatcher` 发现异步线程调用命令,抛出异常,导致事件处理失败。### 三、解决方案(插件代码修复)核心思路:**将“执行命令”这一主线程操作,通过 Bukkit 提供的 API 提交到主线程中运行**。#### 修复方式:使用 `Bukkit.getScheduler()` 调度主线程任务在 `QuizManager.answer` 方法中,不要直接调用 `Bukkit.dispatchCommand`,而是用以下代码将命令执行逻辑“抛”到主线程:```java// 错误写法(直接在异步线程执行)Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "money give ncov0748 50");// 正确写法(调度到主线程执行)Bukkit.getScheduler().runTask( yourPluginInstance, // 插件实例(如 CyuQuiz 主类的对象) () -> { // 匿名任务:要在主线程执行的逻辑 Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "money give ncov0748 50"); });```- **关键参数说明**: - `yourPluginInstance`:必须传入插件的主类实例(实现 `Plugin` 接口),用于绑定任务到插件生命周期(避免插件卸载后任务残留)。 - `runTask(...)`:立即在主线程的下一个tick执行任务(最常用的主线程调度方法)。### 四、延伸注意事项1. **其他需主线程执行的操作**: 除了 `dispatchCommand`,以下操作也必须在主线程中执行,否则会触发类似错误: - 修改玩家数据(背包、经验、权限) - 操作方块(放置、破坏、修改NBT) - 发送带有特殊格式的聊天消息(部分API) - 调用实体相关方法(移动、伤害、生成)2. **避免“反模式”**: 不要为了省事关闭 `AsyncCatcher`(如修改服务器配置 `spigot.yml` 中的 `async-commands: true`),这会绕过线程安全检测,可能导致更隐蔽的bug(如数据丢失、服务器崩溃)。3. **插件调试技巧**: 若不确定当前代码是否在主线程,可在代码中添加判断: ```java if (Bukkit.isPrimaryThread()) { // 当前在主线程 } else { // 当前在异步线程,需调度到主线程 } ```### 总结这个错误的本质是 **插件开发者忽略了 Bukkit 的线程安全规范**。修复只需将 `QuizManager.java` 第 191 行的命令执行逻辑,通过 `Bukkit.getScheduler().runTask(...)` 调度到主线程即可解决。[/B][/FONT][/SIZE] [FONT=AlimamaFangYuanTiVF-Thin][B][SIZE=26px][/MD]
 
插件有一个bug我询问了豆包

[MD] 这个错误是 **Minecraft 服务器插件开发中典型的“异步线程操作主线程安全资源”问题**,核心原因是 `cyuquiz` 插件在**异步线程**(处理玩家聊天事件的线程)中直接执行了需要在**服务器主线程**(Main Thread)中运行的命令,违反了 Bukkit/Spigot/Paper 服务器的线程安全规范。### 一、错误核心解析#### 1. 关键错误信息- 核心提示:`Asynchronous Command Dispatched Async: money give ncov0748 50!` (在异步线程中调度了命令:给玩家 `ncov0748` 发放 50 货币)- 根本原因:`java.lang.IllegalStateException`(非法状态异常),由 `AsyncCatcher`(Spigot/Paper 的异步操作检测器)触发。#### 2. 线程安全背景Minecraft 服务器(Bukkit 生态)是**单线程核心架构**:- **主线程(Main Thread)**:负责处理所有核心逻辑(如实体移动、方块更新、命令执行、玩家数据修改等),是“线程安全区”。- **异步线程(Async Thread)**:用于处理耗时操作(如数据库查询、网络请求、聊天事件预处理等),避免阻塞主线程导致服务器卡顿。**规则**:所有修改服务器状态的操作(如执行命令、修改玩家背包/货币、操作方块)**必须在主线程中执行**。异步线程中直接调用这些操作会触发 `AsyncCatcher` 检测,抛出上述错误。### 二、错误溯源(从堆栈信息看)堆栈信息清晰标注了错误发生的代码路径,可定位到 `cyuquiz` 插件的具体问题位置:1. **触发入口**:玩家发送聊天 → 触发 `AsyncPlayerChatEvent`(异步事件,运行在异步线程)。2. **插件处理**:`ChatListener.onChat(ChatListener.java:23)` → 调用 `QuizManager.answer(QuizManager.java:191)`。3. **错误操作**:在 `QuizManager.answer` 方法的第 191 行,调用了 `Bukkit.dispatchCommand(...)`(执行“money give”命令)。4. **检测报错**:`AsyncCatcher` 发现异步线程调用命令,抛出异常,导致事件处理失败。### 三、解决方案(插件代码修复)核心思路:**将“执行命令”这一主线程操作,通过 Bukkit 提供的 API 提交到主线程中运行**。#### 修复方式:使用 `Bukkit.getScheduler()` 调度主线程任务在 `QuizManager.answer` 方法中,不要直接调用 `Bukkit.dispatchCommand`,而是用以下代码将命令执行逻辑“抛”到主线程:```java// 错误写法(直接在异步线程执行)Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "money give ncov0748 50");// 正确写法(调度到主线程执行)Bukkit.getScheduler().runTask( yourPluginInstance, // 插件实例(如 CyuQuiz 主类的对象) () -> { // 匿名任务:要在主线程执行的逻辑 Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "money give ncov0748 50"); });```- **关键参数说明**: - `yourPluginInstance`:必须传入插件的主类实例(实现 `Plugin` 接口),用于绑定任务到插件生命周期(避免插件卸载后任务残留)。 - `runTask(...)`:立即在主线程的下一个tick执行任务(最常用的主线程调度方法)。### 四、延伸注意事项1. **其他需主线程执行的操作**: 除了 `dispatchCommand`,以下操作也必须在主线程中执行,否则会触发类似错误: - 修改玩家数据(背包、经验、权限) - 操作方块(放置、破坏、修改NBT) - 发送带有特殊格式的聊天消息(部分API) - 调用实体相关方法(移动、伤害、生成)2. **避免“反模式”**: 不要为了省事关闭 `AsyncCatcher`(如修改服务器配置 `spigot.yml` 中的 `async-commands: true`),这会绕过线程安全检测,可能导致更隐蔽的bug(如数据丢失、服务器崩溃)。3. **插件调试技巧**: 若不确定当前代码是否在主线程,可在代码中添加判断: ```java if (Bukkit.isPrimaryThread()) { // 当前在主线程 } else { // 当前在异步线程,需调度到主线程 } ```### 总结这个错误的本质是 **插件开发者忽略了 Bukkit 的线程安全规范**。修复只需将 `QuizManager.java` 第 191 行的命令执行逻辑,通过 `Bukkit.getScheduler().runTask(...)` 调度到主线程即可解决。[/B][/FONT][/SIZE] [FONT=AlimamaFangYuanTiVF-Thin][B][SIZE=26px][/MD]
请直接反馈遇到了什么问题,或者是服务器后台报错信息,不要发这些
 
请直接反馈遇到了什么问题,或者是服务器后台报错信息,不要发这些
[21:18:29 ERROR]: Thread Async Chat Thread - #117 failed main thread check: Command Dispatched Async: money give ncov0748 50java.lang.Throwable: null at org.spigotmc.AsyncCatcher.catchOp(AsyncCatcher.java:9) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:980) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.Bukkit.dispatchCommand(Bukkit.java:1116) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at cyuquiz-1.23.jar/com.cyuquiz.manager.QuizManager.answer(QuizManager.java:191) ~[cyuquiz-1.23.jar:?] at cyuquiz-1.23.jar/com.cyuquiz.listener.ChatListener.onChat(ChatListener.java:23) ~[cyuquiz-1.23.jar:?] at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:71) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at io.papermc.paper.adventure.ChatProcessor.post(ChatProcessor.java:378) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at io.papermc.paper.adventure.ChatProcessor.process(ChatProcessor.java:85) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.chat(ServerGamePacketListenerImpl.java:2492) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.broadcastChatMessage(ServerGamePacketListenerImpl.java:2530) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.lambda$handleChat$10(ServerGamePacketListenerImpl.java:2272) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.util.FutureChain.lambda$append$1(FutureChain.java:25) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[?:?] at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:482) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?][21:18:29 ERROR]: Could not pass event AsyncPlayerChatEvent to cyuquiz v1.23java.lang.IllegalStateException: Asynchronous Command Dispatched Async: money give ncov0748 50! at org.spigotmc.AsyncCatcher.catchOp(AsyncCatcher.java:10) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:980) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.Bukkit.dispatchCommand(Bukkit.java:1116) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at cyuquiz-1.23.jar/com.cyuquiz.manager.QuizManager.answer(QuizManager.java:191) ~[cyuquiz-1.23.jar:?] at cyuquiz-1.23.jar/com.cyuquiz.listener.ChatListener.onChat(ChatListener.java:23) ~[cyuquiz-1.23.jar:?] at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:71) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at io.papermc.paper.adventure.ChatProcessor.post(ChatProcessor.java:378) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at io.papermc.paper.adventure.ChatProcessor.process(ChatProcessor.java:85) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.chat(ServerGamePacketListenerImpl.java:2492) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.broadcastChatMessage(ServerGamePacketListenerImpl.java:2530) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.lambda$handleChat$10(ServerGamePacketListenerImpl.java:2272) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.util.FutureChain.lambda$append$1(FutureChain.java:25) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[?:?] at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:482) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]
 
[21:18:29 ERROR]: Thread Async Chat Thread - #117 failed main thread check: Command Dispatched Async: money give ncov0748 50java.lang.Throwable: null at org.spigotmc.AsyncCatcher.catchOp(AsyncCatcher.java:9) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:980) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.Bukkit.dispatchCommand(Bukkit.java:1116) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at cyuquiz-1.23.jar/com.cyuquiz.manager.QuizManager.answer(QuizManager.java:191) ~[cyuquiz-1.23.jar:?] at cyuquiz-1.23.jar/com.cyuquiz.listener.ChatListener.onChat(ChatListener.java:23) ~[cyuquiz-1.23.jar:?] at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:71) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at io.papermc.paper.adventure.ChatProcessor.post(ChatProcessor.java:378) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at io.papermc.paper.adventure.ChatProcessor.process(ChatProcessor.java:85) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.chat(ServerGamePacketListenerImpl.java:2492) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.broadcastChatMessage(ServerGamePacketListenerImpl.java:2530) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.lambda$handleChat$10(ServerGamePacketListenerImpl.java:2272) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.util.FutureChain.lambda$append$1(FutureChain.java:25) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[?:?] at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:482) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?][21:18:29 ERROR]: Could not pass event AsyncPlayerChatEvent to cyuquiz v1.23java.lang.IllegalStateException: Asynchronous Command Dispatched Async: money give ncov0748 50! at org.spigotmc.AsyncCatcher.catchOp(AsyncCatcher.java:10) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:980) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.Bukkit.dispatchCommand(Bukkit.java:1116) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at cyuquiz-1.23.jar/com.cyuquiz.manager.QuizManager.answer(QuizManager.java:191) ~[cyuquiz-1.23.jar:?] at cyuquiz-1.23.jar/com.cyuquiz.listener.ChatListener.onChat(ChatListener.java:23) ~[cyuquiz-1.23.jar:?] at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:71) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[paper-api-1.21.8-R0.1-SNAPSHOT.jar:?] at io.papermc.paper.adventure.ChatProcessor.post(ChatProcessor.java:378) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at io.papermc.paper.adventure.ChatProcessor.process(ChatProcessor.java:85) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.chat(ServerGamePacketListenerImpl.java:2492) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.broadcastChatMessage(ServerGamePacketListenerImpl.java:2530) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.server.network.ServerGamePacketListenerImpl.lambda$handleChat$10(ServerGamePacketListenerImpl.java:2272) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at net.minecraft.util.FutureChain.lambda$append$1(FutureChain.java:25) ~[paper-1.21.8.jar:1.21.8-60-29c8822] at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:718) ~[?:?] at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:482) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]
稍后我会上传个新版本,请查看新版本会不会复现该问题
 
稍后我会上传个新版本,请查看新版本会不会复现该问题
收到,要炸就炸的暴力点。暴力了
还有一个问题就是我明明有21个问题只显示加载了16,就是怎么知道其他问题格式错在哪里
 
希望可以增加一个使用特定指令让指定玩家回答题目,在增加一个特定题目的变量 希望看到我的建议
 

在线管理成员

在线会员

  • 牙缝会漏风
  • 向着日落许愿
  • 白桦林
  • Nemoa
  • xiaotaozi123
  • 66b
  • qwq_我也不知道yong什么
  • zheng_L
  • User.Time
  • 曾逼问
  • :D-
  • 方漓猫
  • OddFriend
  • 帅气的弯钩
  • Lunar_Dusk
  • YanRan233
  • llp114514
  • verf1y_Ilya
  • 181
  • linziqun
...和 5 更多。
后退
顶部 底部