-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
175 lines (153 loc) · 7.01 KB
/
Copy pathmain.py
File metadata and controls
175 lines (153 loc) · 7.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import pyautogui
import time
import os
import sys
import ctypes
import keyboard as native_keyboard
from pynput import mouse, keyboard
import threading
# 全局状态
running = True
last_user_activity = 0
SAFE_IDLE_TIME = 1.5 # 用户停止操作后等待 1.5 秒即恢复
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def on_activity(*args, **kwargs):
"""用户活动回调(鼠标移动、点击、按键等)"""
global last_user_activity
last_user_activity = time.time()
def start_listeners():
"""启动全局输入监听器"""
mouse_listener = mouse.Listener(on_move=on_activity, on_click=on_activity, on_scroll=on_activity)
key_listener = keyboard.Listener(on_press=on_activity)
mouse_listener.start()
key_listener.start()
def is_user_active():
"""判断用户当前是否正在操作"""
return (time.time() - last_user_activity) < SAFE_IDLE_TIME
def safe_sleep(seconds):
"""可中断的睡眠,如果检测到用户活动会立即停止等待"""
start = time.time()
while time.time() - start < seconds:
if is_user_active() or not running:
return False
time.sleep(0.1)
return True
def exit_script():
global running
print("\n[!] 检测到退出快捷键 (Ctrl+Shift+Q),正在停止脚本...")
running = False
def click_all_visible_buttons(image_path, confidence=0.8, region=None):
"""找出并点击指定区域内所有可见的目标按钮"""
try:
buttons = list(pyautogui.locateAllOnScreen(image_path, confidence=confidence, grayscale=True, region=region))
if buttons:
print(f"\n[+] 发现 {len(buttons)} 个按钮,准备点击...")
for btn in buttons:
# 每次点击前都要检查用户是否在操作
if is_user_active():
print("\n[*] 点击中断:检测到用户操作")
return False
center = pyautogui.center(btn)
pyautogui.click(center)
print(f" - 已点击坐标: {center}")
time.sleep(0.2)
return True
except:
pass
return False
def main():
global running
if not is_admin():
print("[*] 正在请求管理员权限...")
try:
ret = ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
if int(ret) > 32:
os._exit(0)
except:
pass
# 启动监听器
start_listeners()
native_keyboard.add_hotkey('ctrl+shift+q', exit_script)
app_bg_image = os.path.join("antigravity", "app_bg.png")
app_tag_image = os.path.join("antigravity", "app_tag.png")
template_image = os.path.join("antigravity", "target.png")
scroll_bg_image = os.path.join("antigravity", "scroll_bg.png")
scroll_btn_image = os.path.join("antigravity", "scroll_btn.png")
if not all(os.path.exists(img) for img in [app_bg_image, app_tag_image, template_image]):
print(f"错误: 缺少必要的图片文件")
return
print("="*60)
print(" Antigravity Clicker (App-Specific Mode) ")
print(" - App Background: " + app_bg_image)
print(" - App Tag: " + app_tag_image)
print(" - Target: " + template_image)
print(" - Status: Listening... Auto-resume after 1.5s idle")
print(" - Exit: Ctrl + Shift + Q")
print("="*60)
while running:
# 用户活跃需要等待循环
if is_user_active():
remaining = max(0, (last_user_activity + SAFE_IDLE_TIME) - time.time())
print(f"[*] 检测到用户活跃,避让中... (剩余等待: {remaining:.1f}s)", end="\r")
time.sleep(0.2)
continue
print(f"[*] 正在扫描应用窗口...", end="\r")
try:
# 0. 首先定位应用主体区域
app_bg_res = pyautogui.locateOnScreen(app_bg_image, confidence=0.8, grayscale=True)
if app_bg_res:
# 1. 在主体区域内验证标识 (Tag)
app_tag_res = pyautogui.locateOnScreen(app_tag_image, confidence=0.8, grayscale=True, region=app_bg_res)
if app_tag_res:
# 2. 标识验证通过,执行核心逻辑
# 注意:不再限制在 app_bg_res 区域,因为 app_bg 可能只是一个小的标识位,而按钮和滚动条在它之外
if click_all_visible_buttons(template_image):
print(f"[+] 成功点击目标按钮。")
safe_sleep(1.0)
else:
# 3. 如果没找到 Accept 按钮,尝试寻找滚动逻辑
if os.path.exists(scroll_bg_image) and os.path.exists(scroll_btn_image):
# 全屏找滚动背景
bg_res = pyautogui.locateOnScreen(scroll_bg_image, confidence=0.8, grayscale=True)
if bg_res:
# 在滚动背景内找滚动按钮 (这个可以限制 region,因为 btn 肯定在 bg 里面)
btn_res = pyautogui.locateOnScreen(scroll_btn_image, confidence=0.8, grayscale=True, region=bg_res)
if btn_res:
scroll_pos = pyautogui.center(btn_res)
if not is_user_active():
print(f"\n[+] 区域定位成功,开始长按滚动按钮 (2s): {scroll_pos}")
pyautogui.mouseDown(scroll_pos)
time.sleep(2)
pyautogui.mouseUp(scroll_pos)
safe_sleep(0.3)
else:
print("\n[*] 找到滚动按钮但用户活跃,跳过点击。", end="\r")
else:
print(f"[*] 找到背景但未发现按钮 '{scroll_btn_image}'...", end="\r")
else:
print(f"[*] 未发现滚动背景区域 '{scroll_bg_image}'...", end="\r")
else:
time.sleep(0.2)
else:
print(f"[*] 找到背景但未发现标识 '{app_tag_image}'...", end="\r")
time.sleep(0.5)
else:
print(f"[*] 未发现应用背景 '{app_bg_image}'...", end="\r")
time.sleep(0.5)
except Exception as e:
print(f"\n[!] 扫描出错: {e}")
time.sleep(0.5)
print("\n[*] 脚本已退出。")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
pass
except Exception as e:
print(f"\n[!] 脚本发生致命错误: {e}")
# 发生错误时才暂停
input("\n按回车键退出...")