@@ -102,6 +102,7 @@ async def dispatch(self, event: Event, sender: Any) -> bool:
102102 if not handlers :
103103 return False
104104 scene : int = _event_scene (event )
105+ matched : list [tuple [dict [str , Any ], re .Match [str ]]] = []
105106 for h in handlers :
106107 ab = h ['_allowed_bots' ]
107108 if ab is not None and appid not in ab :
@@ -111,13 +112,13 @@ async def dispatch(self, event: Event, sender: Any) -> bool:
111112 continue
112113 if h ['_smask' ] & ~ scene :
113114 continue
114- plugin_name : str = h [ 'name' ] or h . get ( '_plugin' , '' )
115- log_service = self . _get_log_service ( event )
116- event . _reply_log_cb = _make_reply_log_cb ( plugin_name , log_service )
117- event . _reply_plugin_name = plugin_name or ''
118- asyncio . create_task ( self . _run_handler ( h , event , m , plugin_name , user_id , et , content ))
119- return True
120- return False
115+ matched . append (( h , m ) )
116+ if h . get ( 'block' , False ): # 默认放行, block=True 时拦截后续
117+ break
118+ if not matched :
119+ return False
120+ asyncio . create_task ( self . _run_chain ( matched , event , user_id , et , content ))
121+ return True
121122
122123 # ── 消息事件: 完整检查链 ──
123124 _get = cfg .get_bot_setting
@@ -212,7 +213,8 @@ def _match_handlers(
212213 content : str ,
213214 skip_at_other : bool = False ,
214215 ) -> bool :
215- """内循环: 遍历 handler 尝试匹配, 匹配成功则 fire-and-forget 并返回 True"""
216+ """内循环: 收集命中的 handler, 遇到 block=True 即停止, 随后顺序执行"""
217+ matched : list [tuple [dict [str , Any ], re .Match [str ]]] = []
216218 for h in handlers :
217219 # 快速过滤: bot 白名单
218220 ab = h ['_allowed_bots' ]
@@ -230,8 +232,9 @@ def _match_handlers(
230232 continue
231233 # 场景过滤 (位掩码): handler 要求的场景位 & 事件不具备的场景位 → 不匹配
232234 if h ['_smask' ] & ~ scene :
233- # 群聊专属指令在私聊环境 → 明确告知用户
235+ # 群聊专属指令在私聊环境 → 告知用户并终止
234236 if h ['group_only' ] and not is_non_at :
237+ self ._fire_chain (matched , event , user_id , et , content )
235238 asyncio .create_task (
236239 event .reply (
237240 template_name = 'group_only' ,
@@ -242,6 +245,7 @@ def _match_handlers(
242245 continue
243246 # 权限
244247 if h ['owner_only' ] and not self ._is_owner (event ):
248+ self ._fire_chain (matched , event , user_id , et , content )
245249 if not is_non_at :
246250 asyncio .create_task (
247251 event .reply (
@@ -250,16 +254,46 @@ def _match_handlers(
250254 )
251255 )
252256 return True
253- # 日志绑定
254- plugin_name : str = h ['name' ] or h .get ('_plugin' , '' )
255- log_service = self ._get_log_service (event )
256- event ._reply_log_cb = _make_reply_log_cb (plugin_name , log_service )
257- event ._reply_plugin_name = plugin_name or ''
258- asyncio .create_task (self ._run_handler (h , event , m , plugin_name , user_id , et , content ))
259- return True
260- return False
257+ matched .append ((h , m ))
258+ if h .get ('block' , False ): # 默认放行, block=True 时拦截后续
259+ break
260+ if not matched :
261+ return False
262+ self ._fire_chain (matched , event , user_id , et , content )
263+ return True
264+
265+ def _fire_chain (
266+ self ,
267+ matched : list [tuple [dict [str , Any ], re .Match [str ]]],
268+ event : Event ,
269+ user_id : str ,
270+ et : str ,
271+ content : str ,
272+ ) -> None :
273+ """调度命中的 handler 链顺序执行 (空则跳过)"""
274+ if matched :
275+ asyncio .create_task (self ._run_chain (matched , event , user_id , et , content ))
276+
277+ async def _run_chain (
278+ self ,
279+ matched : list [tuple [dict [str , Any ], re .Match [str ]]],
280+ event : Event ,
281+ user_id : str ,
282+ et : str ,
283+ content : str ,
284+ ) -> None :
285+ """顺序执行 handler 链: 逐个绑定日志上下文, 结束后清理 event 引用"""
286+ try :
287+ for h , match in matched :
288+ plugin_name : str = h ['name' ] or h .get ('_plugin' , '' )
289+ log_service = self ._get_log_service (event )
290+ event ._reply_log_cb = _make_reply_log_cb (plugin_name , log_service )
291+ event ._reply_plugin_name = plugin_name or ''
292+ await self ._exec_handler (h , event , match , plugin_name , user_id , et , content )
293+ finally :
294+ event .raw = event ._reply_log_cb = None
261295
262- async def _run_handler (
296+ async def _exec_handler (
263297 self ,
264298 h : dict [str , Any ],
265299 event : Event ,
0 commit comments