diff --git a/monitor.py b/monitor.py index e707a22..fbdaa51 100644 --- a/monitor.py +++ b/monitor.py @@ -649,6 +649,19 @@ class MessageMonitor: # 先切 QQ 到前台再截屏,避免 CMD 窗口遮挡→OCR 读到终端文字 self._ensure_foreground(hwnd) time.sleep(0.15) + + # 点一下消息面板区域设置焦点(TIM 默认焦点在会话列表,VK_END 只会滚会话列表) + try: + click_x = int(win_w * 0.72) # 消息面板中心偏右 + click_y = int(win_h * 0.50) + lparam = win32api.MAKELONG(click_x, click_y) + win32gui.PostMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lparam) + win32gui.PostMessage(hwnd, win32con.WM_LBUTTONUP, 0, lparam) + logger.debug(f"[qq] 点击消息面板({click_x},{click_y})设置焦点") + time.sleep(0.15) + except Exception as e: + logger.debug(f"[qq] 点击消息面板失败: {e}") + # Ctrl+End 滚动到底部,只截最新消息(避开历史堆积+bot 旧回复) VK_CONTROL = 0x11 VK_END = 0x23 @@ -710,18 +723,22 @@ class MessageMonitor: # QQ NT OCR 将所有可见消息合并为一段无换行文本,消息间以时间戳分隔 # 按时间戳分割恢复独立消息,避免整坨变成一条"新消息" expanded = [] - for rl in ocr_lines: + for i, rl in enumerate(ocr_lines): + before = rl rl = self._normalize_ocr_text(rl) + logger.debug(f"[ocr] stage[{i}] normalize: {before[:50]!r} -> {rl[:50]!r}") # 先清理 & 碎片(OCR 把时间戳右边缘的 : 读成 &) # 必须在时间戳分割前做,否则 "13:5&07" 无法被时间戳正则捕获 rl = rl.replace('&', '') # 把全角 :统一成半角 :,让后续正则统一匹配 rl = rl.replace(':', ':') + logger.debug(f"[ocr] stage[{i}] clean: {rl[:80]!r}") # 分割"msg1 14:24 msg2 13:27 msg3" → ["msg1", "msg2", "msg3"] # 使用更宽松的 \d{1,2}(允许单数字),因为 & 移除后 "5&07"→"507" # 打破的时间戳如 "13:5 07" 也尽量捕获 rl = re.sub(r'\s+', ' ', rl) # 多重空格压为一个 parts = re.split(r'(\d{1,2}:\d{1,2}(?::\d{1,2})?)', rl) + logger.debug(f"[ocr] stage[{i}] split -> {len(parts)} parts: {[p[:30] for p in parts if p.strip()]}") buf = '' for part in parts: if re.match(r'^\d{1,2}:\d{1,2}', part):