async def __call__(self, owned_title_id, paths=None): local_games: Dict[str, LocalHumbleGame] = {} not_found = owned_title_id.copy() # match using registry self._reg.refresh() while self._reg.uninstall_keys: uk = self._reg.uninstall_keys.pop() try: for human_name, machine_name in owned_title_id.items(): if self._matches(human_name, uk): exe = self._find_executable(human_name, uk) if exe is not None: game = LocalHumbleGame(machine_name, exe, uk.install_location_path, uk.uninstall_string) logger.info(f'New local game found: {game}') local_games[machine_name] = game del not_found[human_name] break logger.warning( f"Uninstall key matched, but cannot find \ game exe for [{human_name}]; uk: {uk}") except Exception: self._reg.uninstall_keys.add(uk) raise await asyncio.sleep(0) # makes this method non blocking # try to match the rest using folders scan if paths is not None: local_games.update(await super().__call__(not_found, paths)) return local_games
async def test_get_size_mac(tmp_path, create_file_at): app = tmp_path / 'mac.app' exe = app / 'Contents' / 'MacOS' / 'Game' create_file_at(exe, b'1' * 100), create_file_at(app / 'Resources' / 'ext-lib.apk', b'1' * 100) game = LocalHumbleGame('mock', executable=exe, install_location=app) assert await game.get_size() == 200
async def test_uninstall_game(plugin, overgrowth): id_ = overgrowth['product']['machine_name'] plugin._local_games = { id_: LocalHumbleGame(id_, '', uninstall_cmd="unins000.exe") } with patch('subprocess.Popen') as subproc: await plugin.uninstall_game(id_) subproc.assert_called_once_with('unins000.exe')
async def test_launch_game(plugin_mock, overgrowth): id_ = overgrowth['product']['machine_name'] plugin_mock._local_games = { id_: LocalHumbleGame(id_, pathlib.Path('mock.exe')) } with patch('subprocess.Popen') as subproc: with patch('psutil.Process'): await plugin_mock.launch_game(id_) subproc.assert_called_once_with('mock.exe')
async def test_get_size_no_install_location(tmp_path, create_file_at): """Executable parent should be inspected as install dir as most reasonable fallback""" root = tmp_path expected_size = sum([ create_file_at(root / 'game.exe', b'exe_content'), create_file_at(root / 'assets' / 'data0.dat', b'data/32\fxxxxxxx'), create_file_at(root / 'assets' / 'data1.dat', b'da/32') ]) game = LocalHumbleGame('mock', root / 'game.exe', install_location=None) assert await game.get_size() == expected_size
async def test_get_size_win(tmp_path, create_file_at): game_root = tmp_path / 'root' expected_size = sum([ create_file_at(game_root / 'bin' / 'game.exe', b'exe_content'), create_file_at(game_root / 'assets' / 'data0.dat', b'data/32\fxxxxxxx'), create_file_at(game_root / 'assets' / 'data1.dat', b'da/32') ]) create_file_at(tmp_path / 'another_dir' / 'exe', b'00000xxxx') # do not count this game = LocalHumbleGame('mock', tmp_path / 'bin' / 'game.exe', install_location=game_root) assert await game.get_size() == expected_size
async def __call__(self, owned_title_id: Dict[str, str], paths: Set[pathlib.Path]) -> Dict[str, LocalHumbleGame]: """ :param owned_title_id: human_name: machine_name dictionary """ start = time.time() found_games = await self._scan_folders(paths, set(owned_title_id)) local_games = { owned_title_id[title]: LocalHumbleGame(owned_title_id[title], gl.exe, install_location=gl.root) for title, gl in found_games.items() } logger.debug(f'Scanning folders took {time.time() - start}') return local_games
async def test_launch_game(plugin, overgrowth): id_ = overgrowth['product']['machine_name'] plugin._local_games = { id_: LocalHumbleGame(id_, pathlib.Path('game_dir') / 'mock.exe') } with patch('subprocess.Popen') as subproc: with patch('psutil.Process'): await plugin.launch_game(id_) if CURRENT_SYSTEM == HP.WINDOWS: subproc.assert_called_once_with('game_dir\\mock.exe', creationflags=8, cwd=pathlib.Path('game_dir')) elif CURRENT_SYSTEM == HP.MAC: subproc.assert_called_once()
async def find_local_games(self, owned_games: List[HumbleGame]) -> List[LocalHumbleGame]: local_games = [] while self._reg.uninstall_keys: uk = self._reg.uninstall_keys.pop() try: for og in owned_games: if isinstance(og, Key): continue if self._matches(og.human_name, uk): exe = self._find_executable(og.human_name, uk) if exe is not None: game = LocalHumbleGame(og.machine_name, exe, uk.uninstall_string) logging.info(f'New local game found: {game}') local_games.append(game) break logging.warning(f"Uninstall key matched, but cannot find \ game exe for [{og.human_name}]; uk: {uk}") except Exception: self._reg.uninstall_keys.add(uk) raise await asyncio.sleep(0.001) # makes this method non blocking return local_games