135 lines
5.0 KiB
Python
135 lines
5.0 KiB
Python
"""查明粘贴草稿后 _chat_surface_signature() 的哪个分量发生了变化。
|
||
|
||
会临时往输入框粘贴一段文字,测完立即 Ctrl+A + Backspace 清除,并还原剪贴板。
|
||
绝不按 Enter,不会发出任何消息。
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import time
|
||
|
||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||
|
||
import numpy as np
|
||
import pyautogui
|
||
import pyperclip
|
||
from PIL import Image
|
||
|
||
import wechat_bot as bot_module
|
||
|
||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||
_PROBE_DRAFT = "诊断用草稿请忽略"
|
||
|
||
|
||
def measure(bot):
|
||
"""分别返回聊天区布局指纹、选中行预览指纹和整体指纹。"""
|
||
full = bot._capture_full_window()
|
||
list_x1 = max(0, int(bot._list_x))
|
||
list_y1 = max(0, int(bot._list_y))
|
||
list_x2 = min(full.shape[1], list_x1 + int(bot._list_w))
|
||
list_y2 = min(full.shape[0], list_y1 + int(bot._list_h))
|
||
chat_x1 = max(0, int(bot._chat_rel_x))
|
||
chat_y1 = max(0, int(bot._chat_rel_y))
|
||
chat_x2 = min(full.shape[1], chat_x1 + int(bot._chat_rel_w))
|
||
chat_y2 = min(full.shape[0], chat_y1 + int(bot._chat_rel_h))
|
||
session_list = full[list_y1:list_y2, list_x1:list_x2]
|
||
chat = full[chat_y1:chat_y2, chat_x1:chat_x2]
|
||
selected_y = bot.detect_selected_row(session_list)
|
||
activity = (
|
||
bot._session_row_activity_signature(session_list, selected_y)
|
||
if selected_y >= 0
|
||
else b""
|
||
)
|
||
return {
|
||
"chat_layout": bot._chat_layout_signature(chat).hex(),
|
||
"selected_y": selected_y,
|
||
"row_preview": activity.hex(),
|
||
"overall": bot._chat_surface_signature().hex(),
|
||
"chat_box": (chat_x1, chat_y1, chat_x2, chat_y2),
|
||
"session_list": session_list,
|
||
"chat": chat,
|
||
}
|
||
|
||
|
||
def main():
|
||
bot = bot_module.WeChatBot()
|
||
bot.safe_window_mode = True
|
||
bot.auto_activate_window = True
|
||
if not bot.connect(activate=False, wait_if_missing=False):
|
||
print("[-] 未挂载到企业微信窗口")
|
||
return
|
||
if not bot._ensure_visible():
|
||
print("[-] 企业微信未能切到前台")
|
||
return
|
||
bot._refresh_message_geometry(bot._capture_full_window())
|
||
|
||
print(f"聊天区裁剪框(窗口内): x {bot._chat_rel_x}~{bot._chat_rel_x + bot._chat_rel_w}"
|
||
f" y {bot._chat_rel_y}~{bot._chat_rel_y + bot._chat_rel_h}")
|
||
print(f"_composer_rel_top : {bot._composer_rel_top}")
|
||
|
||
before = measure(bot)
|
||
print("\n[粘贴草稿前]")
|
||
print(f" 聊天区布局 : {before['chat_layout']}")
|
||
print(f" 选中行 y : {before['selected_y']}")
|
||
print(f" 会话行预览 : {before['row_preview']}")
|
||
print(f" 整体指纹 : {before['overall']}")
|
||
|
||
old_clipboard = ""
|
||
try:
|
||
old_clipboard = pyperclip.paste()
|
||
except Exception:
|
||
pass
|
||
|
||
try:
|
||
pyperclip.copy(_PROBE_DRAFT)
|
||
pyautogui.click(bot.input_x, bot.input_y)
|
||
time.sleep(0.2)
|
||
pyautogui.hotkey("ctrl", "v")
|
||
time.sleep(0.6)
|
||
|
||
after = measure(bot)
|
||
print("\n[粘贴草稿后]")
|
||
print(f" 聊天区布局 : {after['chat_layout']}"
|
||
f" {'← 变化' if after['chat_layout'] != before['chat_layout'] else '(未变)'}")
|
||
print(f" 选中行 y : {after['selected_y']}")
|
||
print(f" 会话行预览 : {after['row_preview']}"
|
||
f" {'← 变化' if after['row_preview'] != before['row_preview'] else '(未变)'}")
|
||
print(f" 整体指纹 : {after['overall']}"
|
||
f" {'← 变化' if after['overall'] != before['overall'] else '(未变)'}")
|
||
print(f" _composer_rel_top 重算: "
|
||
f"{bot_module.infer_composer_top(bot._capture_full_window(), int(bot._list_x + bot._list_w), bot.scale)}")
|
||
|
||
Image.fromarray(before["chat"][:, :, :3][:, :, ::-1]).save(
|
||
os.path.join(_HERE, "surface_chat_before.png")
|
||
)
|
||
Image.fromarray(after["chat"][:, :, :3][:, :, ::-1]).save(
|
||
os.path.join(_HERE, "surface_chat_after.png")
|
||
)
|
||
Image.fromarray(after["session_list"][:, :, :3][:, :, ::-1]).save(
|
||
os.path.join(_HERE, "surface_list_after.png")
|
||
)
|
||
diff = np.abs(
|
||
before["chat"][:, :, :3].astype(np.int16)
|
||
- after["chat"][:, :, :3].astype(np.int16)
|
||
).max(axis=2)
|
||
rows = np.flatnonzero((diff > 12).any(axis=1))
|
||
if rows.size:
|
||
print(f" 聊天区裁剪内实际变化的行(裁剪内坐标): {rows.min()} ~ {rows.max()}"
|
||
f" (裁剪高度 {diff.shape[0]})")
|
||
else:
|
||
print(" 聊天区裁剪内像素没有任何变化")
|
||
print(" 已保存 tmp/surface_chat_before.png / surface_chat_after.png / surface_list_after.png")
|
||
finally:
|
||
pyautogui.hotkey("ctrl", "a")
|
||
pyautogui.press("backspace")
|
||
time.sleep(0.2)
|
||
try:
|
||
pyperclip.copy(old_clipboard)
|
||
except Exception:
|
||
pass
|
||
print("\n[清理] 已清除诊断草稿并还原剪贴板。")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|