Find D2R window using win32api instead of pattern matching (#453)
This commit is contained in:
+45
-21
@@ -5,6 +5,7 @@ import time
|
||||
from logger import Logger
|
||||
from typing import Tuple
|
||||
from config import Config
|
||||
from utils import misc
|
||||
from utils.misc import load_template
|
||||
import os
|
||||
|
||||
@@ -24,12 +25,42 @@ class Screen:
|
||||
self._config = Config()
|
||||
self._monitor_roi = self._sct.monitors[monitor_idx]
|
||||
# auto find offests
|
||||
self.found_offsets = False
|
||||
position = None
|
||||
if self._config.general["find_window_via_win32_api"] :
|
||||
Logger.debug("Using WinAPI to search for window under D2R.exe process")
|
||||
position = self.find_window_via_winapi()
|
||||
if position is None:
|
||||
Logger.debug("Can't find any window owned by D2R.exe falling back to matching via assets. Make sure D2R is in focus and you are on the hero selection screen")
|
||||
|
||||
if position is None:
|
||||
position = self.find_window_via_assets(wait)
|
||||
|
||||
if position is not None:
|
||||
self._set_window_position(*position)
|
||||
else:
|
||||
if self._config.general["info_screenshots"]:
|
||||
cv2.imwrite("./info_screenshots/error_d2r_window_not_found_" + time.strftime("%Y%m%d_%H%M%S") + ".png", self.grab())
|
||||
Logger.error("Could not find hero selection or template for ingame, shutting down")
|
||||
Logger.error("Could not determine window offset. Please make sure you have the D2R window " +
|
||||
f"focused and that you are on the hero selection screen when pressing {self._config.general['resume_key']}")
|
||||
|
||||
def _set_window_position(self, offset_x: int, offset_y: int):
|
||||
Logger.debug(f"Set offsets: left {offset_x}px, top {offset_y}px")
|
||||
self._monitor_roi["top"] += offset_y
|
||||
self._monitor_roi["left"] += offset_x
|
||||
self._monitor_x_range = (self._monitor_roi["left"] + 10, self._monitor_roi["left"] + self._monitor_roi["width"] - 10)
|
||||
self._monitor_y_range = (self._monitor_roi["top"] + 10, self._monitor_roi["top"] + self._monitor_roi["height"] - 10)
|
||||
self._monitor_roi["width"] = self._config.ui_pos["screen_width"]
|
||||
self._monitor_roi["height"] = self._config.ui_pos["screen_height"]
|
||||
self.found_offsets = True
|
||||
|
||||
|
||||
def find_window_via_assets(self, wait: int) -> Tuple[int, int]:
|
||||
template = load_template(f"assets/templates/main_menu_top_left.png", 1.0)
|
||||
template_ingame = load_template(f"assets/templates/window_ingame_offset_reference.png", 1.0)
|
||||
start = time.time()
|
||||
self.found_offsets = False
|
||||
Logger.info("Searching for window offsets. Make sure D2R is in focus and you are on the hero selection screen")
|
||||
debug_max_val = 0
|
||||
start = time.time()
|
||||
while time.time() - start < wait:
|
||||
img = self.grab()
|
||||
self._sct = mss()
|
||||
@@ -53,25 +84,18 @@ class Screen:
|
||||
if max_val < 0.93:
|
||||
Logger.warning(f"Your template match score to calc corner was lower then usual ({max_val*100:.1f}% confidence). " +
|
||||
"You might run into template matching issues along the way!")
|
||||
offset_left, offset_top = max_pos
|
||||
Logger.debug(f"Set offsets: left {offset_left}px, top {offset_top}px")
|
||||
self._monitor_roi["top"] += offset_top
|
||||
self._monitor_roi["left"] += offset_left
|
||||
self._monitor_x_range = (self._monitor_roi["left"] + 10, self._monitor_roi["left"] + self._monitor_roi["width"] - 10)
|
||||
self._monitor_y_range = (self._monitor_roi["top"] + 10, self._monitor_roi["top"] + self._monitor_roi["height"] - 10)
|
||||
self._monitor_roi["width"] = self._config.ui_pos["screen_width"]
|
||||
self._monitor_roi["height"] = self._config.ui_pos["screen_height"]
|
||||
self.found_offsets = True
|
||||
break
|
||||
if not self.found_offsets:
|
||||
if self._config.general["info_screenshots"]:
|
||||
cv2.imwrite("./info_screenshots/error_d2r_window_not_found_" + time.strftime("%Y%m%d_%H%M%S") + ".png", self.grab())
|
||||
Logger.error("Could not find hero selection or template for ingame, shutting down")
|
||||
Logger.error(f"The max score that could be found was: ({debug_max_val*100:.1f}% confidence)")
|
||||
Logger.error("Could not determine window offset. Please make sure you have the D2R window " +
|
||||
f"focused and that you are on the hero selection screen when pressing {self._config.general['resume_key']}")
|
||||
|
||||
return max_pos
|
||||
Logger.error(f"The max score that could be found was: ({debug_max_val*100:.1f}% confidence)")
|
||||
return None
|
||||
|
||||
def find_window_via_winapi(self) -> Tuple[int, int]:
|
||||
position = misc.find_d2r_window()
|
||||
if position is None:
|
||||
return None
|
||||
|
||||
offset_x, offset_y, _, _ = position
|
||||
return offset_x, offset_y
|
||||
|
||||
def convert_monitor_to_screen(self, screen_coord: Tuple[float, float]) -> Tuple[float, float]:
|
||||
return (screen_coord[0] - self._monitor_roi["left"], screen_coord[1] - self._monitor_roi["top"])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user