From 3d1d43b35df2bfc538b142334dbd909c86c371b1 Mon Sep 17 00:00:00 2001 From: KevinVG207 Date: Tue, 26 Mar 2024 19:19:37 +0100 Subject: [PATCH 1/3] Fix issue where settings would be changed for all presets. --- umalauncher/settings_elements.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/umalauncher/settings_elements.py b/umalauncher/settings_elements.py index 9eac541..724cce2 100644 --- a/umalauncher/settings_elements.py +++ b/umalauncher/settings_elements.py @@ -1,4 +1,5 @@ import enum +import copy from loguru import logger class SettingType(enum.Enum): @@ -67,7 +68,7 @@ class NewSettings(): def __init__(self): for key, value in self._settings.items(): - self.__setattr__(key, value) + self.__setattr__(key, copy.deepcopy(value)) def keys(self): return list(self._settings.keys()) @@ -77,7 +78,8 @@ def to_dict(self): for key, value in self._settings.items(): if value.type in (SettingType.MESSAGE, SettingType.DIVIDER, SettingType.COMMANDBUTTON): continue - ret_dict[key] = value.value + attr = getattr(self, key) + ret_dict[key] = attr.value return ret_dict def from_dict(self, settings_dict, keep_undefined=False): @@ -116,12 +118,12 @@ def __contains__(self, key): def __getitem__(self, key): if not key in self._settings: raise KeyError(f"Setting {key} not found in settings.") - return self._settings[key] + return getattr(self, key) def __setitem__(self, key, value): if not key in self._settings: raise KeyError(f"Setting {key} not found in settings.") - self._settings[key].value = value + getattr(self, key).value = value def __repr__(self): return str(self.to_dict()) From bbc712d42f30a15a9b565bc3ea2ad8d1f6e3ae12 Mon Sep 17 00:00:00 2001 From: KevinVG207 <19467234+KevinVG207@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:52:33 +0100 Subject: [PATCH 2/3] Stop crash when game is moved off screen by Uma Launcher and reset the coordinates if that happens. (#312) * Stop crash when game is moved off screen by Uma Launcher and reset the coordinates if that happens. * Fix saved game pos getting reset on closing the game. --- umalauncher/screenstate.py | 2 +- umalauncher/settings.py | 4 +++- umalauncher/util.py | 3 +++ umalauncher/windowmover.py | 35 +++++++++++++++++++++++++++-------- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/umalauncher/screenstate.py b/umalauncher/screenstate.py index 7265641..3fb6bf8 100644 --- a/umalauncher/screenstate.py +++ b/umalauncher/screenstate.py @@ -211,7 +211,7 @@ def screenshot_to_clipboard(self): win32clipboard.CloseClipboard() def check_game(self): - game_handle = util.get_window_handle("umamusume", type=util.EXACT) + game_handle = util.get_game_handle() if game_handle: self.game_handle = game_handle self.game_seen = True diff --git a/umalauncher/settings.py b/umalauncher/settings.py index c7d70c2..7a1218b 100644 --- a/umalauncher/settings.py +++ b/umalauncher/settings.py @@ -436,8 +436,10 @@ def save_game_position(self, pos, portrait): if util.is_minimized(self.threader.screenstate.game_handle): # logger.warning(f"Game minimized, cannot save {constants.ORIENTATION_DICT[portrait]}: {pos}") return + + orientation_key = constants.ORIENTATION_DICT[portrait] - if (pos[0] == -32000 and pos[1] == -32000): + if pos is not None and pos[0] == -32000 and pos[1] == -32000: # logger.warning(f"Game minimized, cannot save {constants.ORIENTATION_DICT[portrait]}: {pos}") return diff --git a/umalauncher/util.py b/umalauncher/util.py index 4198b1a..c0fb7c7 100644 --- a/umalauncher/util.py +++ b/umalauncher/util.py @@ -328,6 +328,9 @@ def get_window_handle(query: str, type=LAZY) -> str: win32gui.EnumWindows(type, query) return window_handle +def get_game_handle(): + return get_window_handle("umamusume", type=EXACT) + def get_position_rgb(image: Image.Image, position: tuple[float,float]) -> tuple[int,int,int]: pixel_color = None diff --git a/umalauncher/windowmover.py b/umalauncher/windowmover.py index bf1e924..03c2654 100644 --- a/umalauncher/windowmover.py +++ b/umalauncher/windowmover.py @@ -1,6 +1,7 @@ import time from loguru import logger import util +import win32gui class GameWindow(): @@ -18,23 +19,40 @@ def get_rect(self): return None, None return rect, rect_is_portrait(rect) - def set_pos(self, pos): + def set_pos(self, pos, is_portrait): if pos[2] < 1 or pos[3] < 1: logger.error(f"Trying to set window to invalid size: {pos}") - logger.error("Skipping") + logger.error("Resetting to defaults.") + self.threader.settings.save_game_position(None, is_portrait) return False + + prev_rect = util.get_window_rect(self.handle) success = util.move_window(self.handle, pos[0], pos[1], pos[2], pos[3], True) if not success: logger.error(f"Could not move window. {self.handle}") + + workspace = self.get_workspace_rect() + if not workspace: + if not win32gui.IsWindow(self.handle): + return False + + logger.error("Could not get workspace rect after setting position.") + logger.error("Resetting to defaults.") + util.move_window(self.handle, prev_rect[0], prev_rect[1], prev_rect[2], prev_rect[3], True) + self.threader.settings.save_game_position(None, is_portrait) + return False + return success def get_workspace_rect(self): monitor = util.monitor_from_window(self.handle) if not monitor: - raise Exception("Cannot determine monitor used by game window.") + # raise Exception("Cannot determine monitor used by game window.") + return None monitor_info = util.get_monitor_info(monitor) if not monitor_info: - raise Exception("Cannot get monitor info.") + # raise Exception("Cannot get monitor info.") + return None return monitor_info.get("Work") def calc_max_and_center_pos(self): @@ -95,7 +113,8 @@ def calc_max_and_center_pos(self): return new_game_pos, is_portrait def maximize_and_center(self): - self.set_pos(self.calc_max_and_center_pos()[0]) + new_game_pos, is_portrait = self.calc_max_and_center_pos() + self.set_pos(new_game_pos, is_portrait) return @@ -141,7 +160,7 @@ def try_maximize(self): if self.window: new_pos, is_portrait = self.window.calc_max_and_center_pos() self.threader.settings.save_game_position(new_pos, is_portrait) - self.window.set_pos(new_pos) + self.window.set_pos(new_pos, is_portrait) # self.threader.carrotjuicer.reset_browser = True def stop(self): @@ -187,11 +206,11 @@ def run(self): # If None: maximize. new_pos = self.threader.settings.load_game_position(portrait=is_portrait) if new_pos: - self.window.set_pos(new_pos) + self.window.set_pos(new_pos, is_portrait) else: new_pos, is_portrait = self.window.calc_max_and_center_pos() self.threader.settings.save_game_position(new_pos, is_portrait) - self.window.set_pos(new_pos) + self.window.set_pos(new_pos, is_portrait) # Position may have changed: update variables. game_rect, is_portrait = self.window.get_rect() From 100ea310ce5f56bef7fefe964a0634582c556c17 Mon Sep 17 00:00:00 2001 From: KevinVG207 Date: Tue, 26 Mar 2024 19:53:36 +0100 Subject: [PATCH 3/3] Version bump --- umalauncher/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umalauncher/version.py b/umalauncher/version.py index d4f154f..8685a21 100644 --- a/umalauncher/version.py +++ b/umalauncher/version.py @@ -11,7 +11,7 @@ import gui import glob -VERSION = "1.13.0" +VERSION = "1.13.1" def parse_version(version_string: str): """Convert version string to tuple."""