From 6483969957da18463d6ccddbe1120aec80ea9139 Mon Sep 17 00:00:00 2001 From: Jeffrey Tan Date: Sat, 28 May 2022 16:09:33 -0700 Subject: [PATCH] restarting mss every calibration, fixed resolution change errors --- src/modules/capture.py | 156 +++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 90 deletions(-) diff --git a/src/modules/capture.py b/src/modules/capture.py index e3ff130f..9a626bb4 100644 --- a/src/modules/capture.py +++ b/src/modules/capture.py @@ -9,7 +9,6 @@ import numpy as np from src.common import config, utils from ctypes import wintypes -# from PIL import ImageGrab user32 = ctypes.windll.user32 user32.SetProcessDPIAware() @@ -53,7 +52,6 @@ def __init__(self): self.minimap_ratio = 1 self.minimap_sample = None self.sct = None - # self.window = (0, 0, 1366, 768) self.window = { 'left': 0, 'top': 0, @@ -76,96 +74,74 @@ def _main(self): """Constantly monitors the player's position and in-game events.""" mss.windows.CAPTUREBLT = 0 - with mss.mss() as self.sct: - while True: - if not self.calibrated: - handle = user32.FindWindowW(None, 'MapleStory') - rect = wintypes.RECT() - user32.GetWindowRect(handle, ctypes.pointer(rect)) - rect = (rect.left, rect.top, rect.right, rect.bottom) - rect = tuple(max(0, x) for x in rect) - - # Preliminary window to template match minimap - # self.window = ( - # rect[0], - # rect[1], - # max(rect[2], rect[0] + MMT_WIDTH), # Make room for minimap templates - # max(rect[3], rect[1] + MMT_HEIGHT) - # ) - self.window['left'] = rect[0] - self.window['top'] = rect[1] - self.window['width'] = max(rect[2] - rect[0], MMT_WIDTH) - self.window['height'] = max(rect[3] - rect[1], MMT_HEIGHT) - - # Calibrate by finding the bottom right corner of the minimap + while True: + # Calibrate screen capture + handle = user32.FindWindowW(None, 'MapleStory') + rect = wintypes.RECT() + user32.GetWindowRect(handle, ctypes.pointer(rect)) + rect = (rect.left, rect.top, rect.right, rect.bottom) + rect = tuple(max(0, x) for x in rect) + + self.window['left'] = rect[0] + self.window['top'] = rect[1] + self.window['width'] = max(rect[2] - rect[0], MMT_WIDTH) + self.window['height'] = max(rect[3] - rect[1], MMT_HEIGHT) + + # Calibrate by finding the bottom right corner of the minimap + with mss.mss() as self.sct: + self.frame = self.screenshot() + if self.frame is None: + continue + tl, _ = utils.single_match(self.frame, MM_TL_TEMPLATE) + _, br = utils.single_match(self.frame, MM_BR_TEMPLATE) + mm_tl = ( + tl[0] + MINIMAP_BOTTOM_BORDER, + tl[1] + MINIMAP_TOP_BORDER + ) + mm_br = ( + max(mm_tl[0] + PT_WIDTH, br[0] - MINIMAP_BOTTOM_BORDER), + max(mm_tl[1] + PT_HEIGHT, br[1] - MINIMAP_BOTTOM_BORDER) + ) + self.minimap_ratio = (mm_br[0] - mm_tl[0]) / (mm_br[1] - mm_tl[1]) + self.minimap_sample = self.frame[mm_tl[1]:mm_br[1], mm_tl[0]:mm_br[0]] + self.calibrated = True + + with mss.mss() as self.sct: + while True: + if not self.calibrated: + break + + # Take screenshot self.frame = self.screenshot() if self.frame is None: continue - # self.frame = cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR) - tl, _ = utils.single_match(self.frame, MM_TL_TEMPLATE) - _, br = utils.single_match(self.frame, MM_BR_TEMPLATE) - mm_tl = ( - tl[0] + MINIMAP_BOTTOM_BORDER, - tl[1] + MINIMAP_TOP_BORDER - ) - mm_br = ( - max(mm_tl[0] + PT_WIDTH, br[0] - MINIMAP_BOTTOM_BORDER), - max(mm_tl[1] + PT_HEIGHT, br[1] - MINIMAP_BOTTOM_BORDER) - ) - - # Resize window to encompass minimap if needed - # self.window = ( - # rect[0], - # rect[1], - # max(rect[2], mm_br[0]), - # max(rect[3], mm_br[1]) - # ) - - self.minimap_ratio = (mm_br[0] - mm_tl[0]) / (mm_br[1] - mm_tl[1]) - self.minimap_sample = self.frame[mm_tl[1]:mm_br[1], mm_tl[0]:mm_br[0]] - self.calibrated = True - - # Take screenshot - self.frame = self.screenshot() - if self.frame is None: - continue - # self.frame = cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR) - - # Crop the frame to only show the minimap - minimap = self.frame[mm_tl[1]:mm_br[1], mm_tl[0]:mm_br[0]] - - # Determine the player's position - player = utils.multi_match(minimap, PLAYER_TEMPLATE, threshold=0.8) - if player: - config.player_pos = utils.convert_to_relative(player[0], minimap) - - # Package display information to be polled by GUI - self.minimap = { - 'minimap': minimap, - 'rune_active': config.bot.rune_active, - 'rune_pos': config.bot.rune_pos, - 'path': config.path, - 'player_pos': config.player_pos - } - - if not self.ready: - self.ready = True - time.sleep(0.001) - - # def screenshot(self, delay=1): - # try: - # return np.array(ImageGrab.grab(self.window)) - # except OSError: - # print(f'\n[!] Error while taking screenshot, retrying in {delay} second' - # + ('s' if delay != 1 else '')) - # time.sleep(delay) + + # Crop the frame to only show the minimap + minimap = self.frame[mm_tl[1]:mm_br[1], mm_tl[0]:mm_br[0]] + + # Determine the player's position + player = utils.multi_match(minimap, PLAYER_TEMPLATE, threshold=0.8) + if player: + config.player_pos = utils.convert_to_relative(player[0], minimap) + + # Package display information to be polled by GUI + self.minimap = { + 'minimap': minimap, + 'rune_active': config.bot.rune_active, + 'rune_pos': config.bot.rune_pos, + 'path': config.path, + 'player_pos': config.player_pos + } + + if not self.ready: + self.ready = True + time.sleep(0.001) def screenshot(self, delay=1): - if self.sct is not None: - try: - return np.array(self.sct.grab(self.window)) - except mss.exception.ScreenShotError: - print(f'\n[!] Error while taking screenshot, retrying in {delay} second' - + ('s' if delay != 1 else '')) - print(self.window) - time.sleep(delay) + try: + return np.array(self.sct.grab(self.window)) + except mss.exception.ScreenShotError: + print(f'\n[!] Error while taking screenshot, retrying in {delay} second' + + ('s' if delay != 1 else '')) + print(self.window) + time.sleep(delay)