1414from mss import mss
1515from PIL import Image
1616import win32gui
17- import time
17+ import time , math
1818import keyboard , mouse
1919import sys , os
2020import json
@@ -34,7 +34,7 @@ def is_admin():
3434 # Re-run the program with admin rights
3535 # ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv+[bundle_dir]), None, 1)
3636 input ('请在右键菜单选择以管理员模式运行' )
37- exit (0 )
37+ sys . exit (0 )
3838
3939def captureRect (rect ):
4040 with mss () as sct :
@@ -124,8 +124,8 @@ def scanRows(rows):
124124 rows = list (rows )
125125 if len (rows )< 1 :
126126 return True
127- art_center_x = first_art_x + (art_width + art_gap_x - 0.5 )* 0 + art_width / 2
128- art_center_y = first_art_y + (art_height + art_gap_y - 0.5 )* rows [0 ]+ art_height / 2
127+ art_center_x = first_art_x + (art_width + art_gap_x )* 0 + art_width / 2
128+ art_center_y = first_art_y + (art_height + art_gap_y )* rows [0 ]+ art_height / 2
129129 mouse .move (left + art_center_x , top + art_center_y )
130130 mouse .click ()
131131 for art_row in rows :
@@ -140,8 +140,8 @@ def scanRows(rows):
140140 else :
141141 art_col += 1
142142 if art_row in rows :
143- art_center_x = first_art_x + (art_width + art_gap_x - 0.5 )* art_col + art_width / 2
144- art_center_y = first_art_y + (art_height + art_gap_y - 0.5 )* art_row + art_height / 2
143+ art_center_x = first_art_x + (art_width + art_gap_x )* art_col + art_width / 2
144+ art_center_y = first_art_y + (art_height + art_gap_y )* art_row + art_height / 2
145145 mouse .move (left + art_center_x , top + art_center_y )
146146 mouse .click ()
147147 info = ocr_model .detect_info (art_img )
@@ -165,7 +165,7 @@ def alignFirstRow():
165165 scrollToRow (0 )
166166
167167
168- def scrollToRow (target_row , max_scrolls = 20 ):
168+ def scrollToRow (target_row , max_scrolls = 20 , extra_scroll = 0 ):
169169 in_between_row = False
170170 rows_scrolled = 0
171171 lines_scrolled = 0
@@ -181,6 +181,8 @@ def scrollToRow(target_row, max_scrolls=20):
181181 lines_scrolled = 0
182182 # print(f'已翻{rows_scrolled}行')
183183 if rows_scrolled >= target_row :
184+ for _ in range (extra_scroll ):
185+ mouse .wheel (- 1 )
184186 return rows_scrolled
185187 if lines_scrolled > max_scrolls :
186188 return rows_scrolled
@@ -211,9 +213,9 @@ def scrollToRow(target_row, max_scrolls=20):
211213 w , h = eval (input ("如果要强行继续运行,请输入原神的分辨率,格式是\" 宽,高\" ,例如 1920,1080(不用引号):" ))
212214 left , top = 0 , 0
213215
214- if abs (w / h - 2560 / 1440 )> 0.05 :
215- print ('只支持16:9分辨率' )
216- sys .exit (0 )
216+ # if abs(w/h-2560/1440)>0.05:
217+ # input ('只支持16:9分辨率')
218+ # sys.exit(0)
217219
218220
219221# initialization
@@ -230,39 +232,71 @@ def to_stop():
230232
231233# All Parameters
232234DRY_RUN = False
233- art_cols = 7
234- art_rows = 5
235235
236- first_art_x = 276 / 2560 * w
237- first_art_y = 161 / 1440 * h
238- art_width = 165 / 2560 * w
239- art_height = 203 / 1440 * h
240- art_expand = 6 / 2560 * w
236+ scale_ratio = min (w / 2560 , h / 1440 )
237+
238+ art_width = 164.39 * scale_ratio
239+ art_height = 203.21 * scale_ratio
240+ art_expand = 6 * scale_ratio
241+
242+ art_gap_x = 30.89 * scale_ratio
243+ art_gap_y = 30.35 * scale_ratio
244+
245+ art_info_width = 656 * scale_ratio
246+ art_info_height = 1119 * scale_ratio
247+
248+ left_margin = (199.33 if w < 2 * h else 295.33 )* scale_ratio
249+ right_margin = (871.33 if w < 2 * h else 967.33 )* scale_ratio
250+ info_margin = 0 if w < 2 * h else 96 * scale_ratio
251+
252+ art_cols = int (math .floor ((w - left_margin - right_margin + art_gap_x )/ (art_width + art_gap_x )))
253+
254+ art_shift = ((w - left_margin - right_margin + art_gap_x ) - art_cols * (art_width + art_gap_x ))/ 2
255+
241256
242- art_gap_x = 31 / 2560 * w
243- art_gap_y = 31 / 1440 * h
257+ first_art_x = left_margin + art_shift
258+ first_art_y = 161 * scale_ratio
244259
245- art_info_top = 160 / 1440 * h
246- art_info_left = 1723 / 2560 * w
247- art_info_width = 656 / 2560 * w
248- art_info_height = 1119 / 1440 * h
249260
250- scroll_keypt_x = 435 / 2560 * w
251- scroll_keypt_y = 1270 / 1440 * h
261+ art_info_top = 160 * scale_ratio
262+ art_info_left = w - 837 * scale_ratio - info_margin
263+
264+ scroll_keypt_x = left_margin + art_shift + 158 * scale_ratio
265+ scroll_keypt_y = 1270 * scale_ratio + h - 1440 * scale_ratio
266+ scroll_fin_keypt_x = left_margin + art_shift + 10 * scale_ratio
267+ scroll_fin_keypt_y = 335 * scale_ratio
268+
269+ art_rows = int (round ((scroll_keypt_y - first_art_y + art_gap_y )/ (art_height + art_gap_y )))
270+
271+
272+ # print(art_cols, art_rows)
273+ # import win32api, win32ui
274+ # dc = win32gui.GetDC(0)
275+ # dcObj = win32ui.CreateDCFromHandle(dc)
276+ # hwnd = win32gui.WindowFromPoint((0,0))
277+ # red = win32api.RGB(255, 0, 0)
278+ # monitor = (0, 0, win32api.GetSystemMetrics(0), win32api.GetSystemMetrics(1))
279+ # while True:
280+ # dcObj.Rectangle((int(left+first_art_x), int(top+first_art_y), int(left+first_art_x)+10, int(top+first_art_y)+10))
281+ # dcObj.Rectangle((int(left+art_info_left), int(top+art_info_top), int(left+art_info_left)+10, int(top+art_info_top)+10))
282+ # dcObj.Rectangle((int(left+art_info_left+art_info_width), int(top+art_info_top+art_info_height), int(left+art_info_left+art_info_width)+10, int(top+art_info_top+art_info_height)+10))
283+ # dcObj.Rectangle((int(left+scroll_keypt_x), int(top+scroll_keypt_y), int(left+scroll_keypt_x)+10, int(top+scroll_keypt_y)+10))
284+ # win32gui.InvalidateRect(hwnd, monitor, True)
252285
253286# # star color=255,204,50
254287# scroll_fin_keypt_x = 358
255288# scroll_fin_keypt_y = 320
256289
257290# margin near level number, color=233,229,220
258- scroll_fin_keypt_x = 285 / 2560 * w
259- scroll_fin_keypt_y = 335 / 1440 * h
291+
292+
260293
261294if not DRY_RUN :
262295 os .makedirs ('artifacts' , exist_ok = True )
263296
264297
265298input ('请打开圣遗物背包界面,最好翻到圣遗物列表最上面。按回车继续' )
299+ input (f'自动判断圣遗物背包有{ art_rows } 行{ art_cols } 列,请务必确认是否正确!!错误请退出并更改分辨率后尝试' )
266300input ('运行期间请保持原神在前台,请勿遮挡窗口或操作鼠标,按鼠标中键停止。按回车继续' )
267301input ('开始后将尝试自动对齐第一行以方便识别,若对齐结果有误,请立刻按中键停止。按回车开始执行' )
268302print ('程序将于5秒后自动开始运行,若此条提示显示时未自动切换到原神窗口,请手动点击原神窗口切到前台' )
@@ -274,6 +308,7 @@ def to_stop():
274308
275309time .sleep (5 )
276310
311+
277312print ('正在自动对齐' )
278313mouse .move (left + first_art_x , top + first_art_y )
279314alignFirstRow ()
@@ -284,12 +319,19 @@ def to_stop():
284319 while True :
285320 if stopped or not scanRows (rows = range (start_row , art_rows )) or start_row != 0 :
286321 break
287- start_row = 5 - scrollToRow (5 , max_scrolls = 20 )
288- if start_row == 5 :
322+ start_row = art_rows - scrollToRow (art_rows , max_scrolls = 20 , extra_scroll = 1 )
323+ if start_row == art_rows :
289324 break
325+ print ()
326+ if stopped :
327+ print ("用户已中断扫描" )
328+ elif start_row == art_rows :
329+ print ("没有检测到下一页圣遗物,自动终止" )
330+ else :
331+ print ("在最后点击位置未检测到圣遗物,自动终止" )
290332except Exception as e :
333+ print ()
291334 print (f"因为\" { e } \" 而意外停止扫描,将保存已扫描的圣遗物信息" )
292- print ()
293335if saved :
294336 with open ('artifacts.genshinart.json' , "wb" ) as f :
295337 s = json .dumps (result , ensure_ascii = False )
0 commit comments