From 5e86ef3c675ee7431b8dc8530853e355ebab3958 Mon Sep 17 00:00:00 2001 From: youpaishidifu Date: Thu, 30 Jul 2026 22:36:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8A=A0=E5=BC=BA=E7=97=85=E5=8F=A5?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=20=E2=80=94=20=E7=BA=AF=E9=97=AE=E5=8F=A5?= =?UTF-8?q?=E7=A2=8E=E7=89=87=E3=80=81=E9=97=AE=E5=8F=A5+=E4=B9=B1?= =?UTF-8?q?=E7=A0=81=E6=8B=BC=E6=8E=A5=E3=80=81=E4=B8=AD=E6=AE=B5=E6=96=9C?= =?UTF-8?q?=E7=BA=BF=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:OCR捕捉到残余病句'怎么办?/printer...'触发查库, 回复了一串配置文件值(printer相关配置参数)。 根因: 1. '怎么办?'单独出现时无实质内容,但含问词被放行 2. '/printer玩家名'是指令帮助碎片,在消息中段未被拦截 3. 两者拼接后绕过了现有过滤器 修复(OCR级+Poll级双层): - 新增中段斜线命令碎片过滤:(?<=[\s??。!,,])/[A-Za-z]{2,} 拦截'怎么办?/printer玩家名'这种混合碎片 - 新增纯问句碎片过滤:只含疑问词+标点的短句直接丢弃 - 新增问句+乱码拼接过滤:问词开头+斜线/英文乱码特征→丢弃 --- monitor.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/monitor.py b/monitor.py index bd90621..9b6b6f5 100644 --- a/monitor.py +++ b/monitor.py @@ -1783,12 +1783,16 @@ class MessageMonitor: logger.debug(f"[{platform}] OCR 过滤: 指令列表碎片(多/cmd={slash_cmds}) line={line!r}") continue - # —— 斜线开头英文命令碎片:"/sdfl undo撤销导入" "/register密码" —— + # —— 斜线英文命令碎片:"/sdfl undo撤销导入" "/register密码" —— # 首字符是 / 且紧跟 ASCII 字母 → 命令帮助/参考碎片,非用户普通对话 # 不拦截 "/兑换码怎么用"(斜线后是中文) if re.match(r'^/[A-Za-z]', line): logger.debug(f"[{platform}] OCR 过滤: 斜线英文命令 line={line!r}") continue + # 消息中段含 /英文命令(如"怎么办?/printer玩家名")→ 指令碎片拼接 + if re.search(r'(?<=[\s??。!,,])/[A-Za-z]{2,}', line): + logger.debug(f"[{platform}] OCR 过滤: 斜线命令碎片(中段) line={line!r}") + continue # —— OCR 误读斜线为 I/J:"/sdfl"→"Isdfl", "/import"→"Jimport" —— # 特征1:含已知命令关键词(sdfl/sdf1),零误杀 @@ -1990,6 +1994,20 @@ class MessageMonitor: if re.search(r'["""][^"""]*\d{4}[/-]\d{1,2}[/-]\d{1,2}[^"""]*["""]', line): logger.debug(f"[{platform}] OCR 过滤: 病句(引号包裹时间戳) line={line!r}") continue + # 病句9:纯问句碎片(如"怎么办?" "好不好?")无实质内容 + # 只有疑问词+标点,或疑问词+少量无意义字符 + _pure_q = re.match(r'^(怎么办|好不好|行不行|能不能|可以吗|是不是|有没有|是什么|怎么样|在哪里)\s*[??。!]*\s*$', line) + if _pure_q: + logger.debug(f"[{platform}] OCR 过滤: 病句(纯问句碎片) line={line!r}") + continue + # 病句10:问句+乱码碎片拼接(如"怎么办?/printer玩家名") + # 问词开头 + 非自然字符(斜线/英文/数字乱拼) + if re.match(r'^(怎么办|好不好|行不行|能不能|可以吗|是什么|怎么样)', line): + # 检查问词后面是否有乱码特征 + rest = re.sub(r'^(怎么办|好不好|行不行|能不能|可以吗|是什么|怎么样)\s*[??。!]*\s*', '', line) + if rest and (re.search(r'/[A-Za-z]{2,}', rest) or re.search(r'[a-zA-Z]{3,}', rest) or len(rest) < 3): + logger.debug(f"[{platform}] OCR 过滤: 病句(问句+乱码拼接) line={line!r}") + continue texts.append(line) logger.debug(f"[{platform}] OCR -> {len(ocr_lines)} raw, {len(texts)} filtered, " @@ -3637,6 +3655,10 @@ class MessageMonitor: if re.match(r'^/[A-Za-z]', ts): logger.debug(f"[{platform}] Poll过滤: 斜线英文命令 ts={ts!r}") continue + # === 消息中段含 /英文命令(如"怎么办?/printer玩家名")→ 指令碎片拼接 === + if re.search(r'(?<=[\s??。!,,])/[A-Za-z]{2,}', ts): + logger.debug(f"[{platform}] Poll过滤: 斜线命令碎片(中段) ts={ts!r}") + continue # === 下划线+斜线:OCR 左对齐气泡残影 "_ /sdfl undo" === if re.match(r'^_[ /]', ts): logger.debug(f"[{platform}] Poll过滤: 下划线斜线残影 ts={ts!r}") @@ -3695,6 +3717,17 @@ class MessageMonitor: not re.match(r'^[a-zA-Z_][\w]*\s*:\s*/', ts): logger.debug(f"[{platform}] Poll过滤: YAML行 ts={ts!r}") continue + # === 纯问句碎片(如"怎么办?" "好不好?")无实质内容 === + _pure_q = re.match(r'^(怎么办|好不好|行不行|能不能|可以吗|是不是|有没有|是什么|怎么样|在哪里)\s*[??。!]*\s*$', ts) + if _pure_q: + logger.debug(f"[{platform}] Poll过滤: 纯问句碎片 ts={ts!r}") + continue + # === 问句+乱码碎片拼接(如"怎么办?/printer玩家名")=== + if re.match(r'^(怎么办|好不好|行不行|能不能|可以吗|是什么|怎么样)', ts): + rest = re.sub(r'^(怎么办|好不好|行不行|能不能|可以吗|是什么|怎么样)\s*[??。!]*\s*', '', ts) + if rest and (re.search(r'/[A-Za-z]{2,}', rest) or re.search(r'[a-zA-Z]{3,}', rest) or len(rest) < 3): + logger.debug(f"[{platform}] Poll过滤: 问句+乱码拼接 ts={ts!r}") + continue # === 安全阀:UI 子串过滤(兜底,防任何路径漏过)=== if any(sub in ts for sub in _UI_SUBSTR_BLOCKLIST): logger.debug(f"[{platform}] Poll过滤: UI子串 ts={ts!r}")