@
fix: 微信颜色检测放宽+KB精确匹配+自动回复重试 1. monitor.py - 微信白色气泡检测阈值放宽(>=245->>=240, >=3->>=2) 适配新版微信UI颜色变化,减少漏检 2. knowledge_base.py - 精确短语匹配(5x加分)+子串匹配(2.5x/1.5x) 防止查询被不相关文档抢走高分 3. gui.py - 自动回复发送失败重试(3次/5秒间隔) 连续失败退避本轮,避免反复抢焦点 4. .gitignore - 补充build目录下的证书/构建产物 @
This commit is contained in:
@@ -7,6 +7,9 @@ dist/
|
||||
# PyInstaller output (在build目录内),但保留构建脚本
|
||||
build/build/
|
||||
build/*.log
|
||||
build/cert_info.txt
|
||||
build/code_signing_cert.*
|
||||
build/windowmsgbot/
|
||||
|
||||
# Virtual environment
|
||||
venv/
|
||||
|
||||
@@ -383,10 +383,14 @@ class MsgBotApp(ctk.CTk):
|
||||
self.after(200, self._flush_reply_queue)
|
||||
|
||||
def _execute_reply(self, data: dict):
|
||||
"""主线程执行自动回复发送。加上发送锁防止监控轮询干扰。"""
|
||||
"""主线程执行自动回复发送。加上发送锁防止监控轮询干扰。
|
||||
自动重试:失败后延缓5秒重试,连续3次失败视为用户接管,退避本轮。
|
||||
"""
|
||||
platform = data["platform"]
|
||||
answer = data["answer"]
|
||||
sender = data.get("sender")
|
||||
max_retries = 3
|
||||
retry_delay = 5 # 秒
|
||||
|
||||
# 设发送锁,阻止监控轮询切走焦点
|
||||
self.monitor._sending_event.set()
|
||||
@@ -396,12 +400,19 @@ class MsgBotApp(ctk.CTk):
|
||||
found = self.monitor._search_contact(platform, sender)
|
||||
if not found:
|
||||
self._log(f"[{platform}] ⚠ 找不到联系人 {sender},当前会话回复")
|
||||
# 发送(主线程 SetForegroundWindow 可靠,且不受监控干扰)
|
||||
|
||||
# 带重试的发送逻辑
|
||||
for attempt in range(max_retries):
|
||||
ok = self.monitor._paste_and_send(platform, answer)
|
||||
if ok:
|
||||
self._log(f"[{platform}] 🤖 已自动回复: {answer[:60]}...")
|
||||
return # 成功直接退出
|
||||
else:
|
||||
self._log(f"[{platform}] ⚠ 自动回复发送失败(目标窗口无法带到前台)")
|
||||
if attempt < max_retries - 1:
|
||||
self._log(f"[{platform}] ⚠ 自动回复发送失败,{retry_delay}秒后重试({attempt+1}/{max_retries})")
|
||||
time.sleep(retry_delay)
|
||||
else:
|
||||
self._log(f"[{platform}] ⚠ 自动回复发送失败(连续{max_retries}次),用户可能在接管,本轮跳过")
|
||||
finally:
|
||||
self.monitor._sending_event.clear()
|
||||
|
||||
|
||||
@@ -317,6 +317,23 @@ class KnowledgeBase:
|
||||
combined_scores[i] *= 1.3
|
||||
elif body_hits >= 1:
|
||||
combined_scores[i] *= 1.1
|
||||
# ⭐ 精确短语匹配:文档包含完整查询短语 → 巨幅奖励
|
||||
# 防止"php端的管理员密码"匹配到不含"php"的云背包文档
|
||||
full_text = heading + " " + body
|
||||
if query_stripped in full_text:
|
||||
combined_scores[i] *= 5.0
|
||||
elif len(query_stripped) >= 4:
|
||||
# 2字以上子串匹配:如"php端"、"管理员密码"
|
||||
sub_hits = 0
|
||||
for qlen in range(min(len(query_stripped), 6), 3, -1):
|
||||
for start in range(len(query_stripped) - qlen + 1):
|
||||
phrase = query_stripped[start:start+qlen]
|
||||
if phrase in full_text:
|
||||
sub_hits += 1
|
||||
if sub_hits >= 2:
|
||||
combined_scores[i] *= 2.5
|
||||
elif sub_hits == 1:
|
||||
combined_scores[i] *= 1.5
|
||||
|
||||
# 短查询惩罚:分词数 ≤2 的短查询(如图标残片/短词)得分大幅降权
|
||||
# 防止 OCR 碎片中的高 IDF 词(如"下载")获得超过真实用户消息的分数
|
||||
|
||||
+13
-6
@@ -3253,7 +3253,8 @@ class MessageMonitor:
|
||||
"""判定 (x,y) 的纯白像素是否属于"白色气泡"(对方消息),而非:
|
||||
- 聊天浅灰背景(本身不是 >=245 候选)
|
||||
- 彩色(绿/蓝)自身气泡上的白色文字(邻域为彩色底色)
|
||||
规则:四方向(±4px)邻域中 >=3 个也为 near-white(>=245) 才算气泡。
|
||||
规则:四方向(±4px)邻域中 >=2 个也为 near-white(>=240) 才算气泡。
|
||||
⭐ 放宽条件:>=3→>=2,>=245→>=240,适配新版微信UI颜色变化
|
||||
白字笔画的邻域多为彩色气泡底色 → 不通过 → 不被误判为对方消息。
|
||||
"""
|
||||
d = 4
|
||||
@@ -3263,11 +3264,11 @@ class MessageMonitor:
|
||||
if 0 <= nx < w and 0 <= ny < h:
|
||||
try:
|
||||
rr, gg, bb = px[nx, ny][:3]
|
||||
if rr >= 245 and gg >= 245 and bb >= 245:
|
||||
if rr >= 240 and gg >= 240 and bb >= 240:
|
||||
hits += 1
|
||||
except Exception:
|
||||
pass
|
||||
return hits >= 3
|
||||
return hits >= 2
|
||||
|
||||
|
||||
@staticmethod
|
||||
@@ -3347,15 +3348,21 @@ class MessageMonitor:
|
||||
# 其它 = 背景/UI元素
|
||||
if platform == "wechat":
|
||||
# ⭐ 自身消息门禁:右大量绿色(自身) + 左无白色(无对方) → 仅自身,跳过
|
||||
if right_bot >= 3 and left_white < 3:
|
||||
if right_bot >= 3 and left_white < 2:
|
||||
rlogger.debug(f"[wechat] 像素检测: 仅自身消息(右绿={right_bot},左白={left_white}), 跳过")
|
||||
return False
|
||||
|
||||
# 左半区有白色气泡 → 有对方消息,必须OCR
|
||||
if left_white >= 3:
|
||||
# 左半区有白色气泡(>=2) → 有对方消息,必须OCR
|
||||
if left_white >= 2:
|
||||
rlogger.debug(f"[wechat] 像素检测: 有对方消息(左白={left_white}), 继续")
|
||||
return True
|
||||
|
||||
# ⭐ 放宽兜底:左半区有1个白色像素也尝试OCR,防新版UI检测遗漏
|
||||
# (旧逻辑:0个才跳过,可能误杀新UI浅色气泡)
|
||||
if left_white == 1:
|
||||
rlogger.debug(f"[wechat] 像素检测: 左白=1(边缘), 尝试OCR")
|
||||
return True
|
||||
|
||||
# 左半区无白色气泡 → 无对方消息,跳过
|
||||
# (包括:仅自身消息、空聊天、非聊天界面)
|
||||
rlogger.debug(f"[wechat] 像素检测: 无对方白色气泡(左白={left_white}), 跳过")
|
||||
|
||||
Reference in New Issue
Block a user