def apply_patcher_file(game_root: Path, backup_files_path: Optional[Path], patcher_data: dict, game_specific: EchoesGameSpecific, progress_update: ProgressUpdateCallable, ): """ Applies the modifications listed in the given patcher_data to the game in game_root. :param game_root: :param backup_files_path: :param patcher_data: :param game_specific: :param progress_update: :return: """ menu_mod = patcher_data["menu_mod"] user_preferences = EchoesUserPreferences.from_json_dict(patcher_data["user_preferences"]) status_update = status_update_lib.create_progress_update_from_successive_messages( progress_update, 400 if menu_mod else 100) _ensure_no_menu_mod(game_root, backup_files_path, status_update) if backup_files_path is not None: _create_pak_backups(game_root, backup_files_path, status_update) _run_with_args(_base_args(game_root), json.dumps(patcher_data), "Randomized!", status_update) dol_patcher.apply_patches(game_root, game_specific, user_preferences) if menu_mod: _add_menu_mod_to_files(game_root, status_update)
def test_apply_patches( mock_read_binary_version: MagicMock, mock_get_dol_path: MagicMock, mock_dol_file_constructor: MagicMock, mock_apply_string_display_patch: MagicMock, mock_apply_game_options_patch: MagicMock, mock_apply_energy_tank_capacity_patch: MagicMock, mock_apply_beam_cost_patch: MagicMock, ): # Setup game_root = MagicMock() game_patches = MagicMock() cosmetic_patches = MagicMock() version_patches = dol_patcher._ALL_VERSIONS_PATCHES[0] mock_read_binary_version.return_value = version_patches dol_file = mock_dol_file_constructor.return_value # Run dol_patcher.apply_patches(game_root, game_patches, cosmetic_patches) # Assert mock_read_binary_version.assert_called_once_with(dol_file) mock_get_dol_path.assert_called_once_with(game_root) mock_dol_file_constructor.assert_called_once_with( mock_get_dol_path.return_value) mock_apply_string_display_patch.assert_called_once_with( version_patches.string_display, dol_file) mock_apply_game_options_patch.assert_called_once_with( version_patches.game_options_constructor_address, cosmetic_patches.user_preferences, dol_file) mock_apply_energy_tank_capacity_patch.assert_called_once_with( version_patches.health_capacity, game_patches.game_specific, dol_file) mock_apply_beam_cost_patch.assert_called_once_with( version_patches.beam_cost_addresses, game_patches.game_specific, dol_file)
def test_apply_patches( mock_find_version_for_dol: MagicMock, mock_get_dol_path: MagicMock, mock_dol_file_constructor: MagicMock, mocker, ): # Setup game_root = MagicMock() game_patches = MagicMock() user_preferences = MagicMock() version_patches = dol_patcher.ALL_VERSIONS_PATCHES[0] mock_find_version_for_dol.return_value = version_patches dol_file = mock_dol_file_constructor.return_value mock_apply_string = mocker.patch( "randovania.games.prime.all_prime_dol_patches.apply_remote_execution_patch", autospec=True) mock_apply_game_options: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_game_options_patch", autospec=True) mock_apply_capacity: MagicMock = mocker.patch( "randovania.games.prime.all_prime_dol_patches.apply_energy_tank_capacity_patch", autospec=True) mock_apply_beam_cost_patch: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_beam_cost_patch", autospec=True) mock_apply_starting_visor_patch: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_starting_visor_patch", autospec=True) # Run dol_patcher.apply_patches(game_root, game_patches.game_specific, user_preferences, {"foo": "bar"}) # Assert mock_find_version_for_dol.assert_called_once_with( dol_file, dol_patcher.ALL_VERSIONS_PATCHES) mock_get_dol_path.assert_called_once_with(game_root) mock_dol_file_constructor.assert_called_once_with( mock_get_dol_path.return_value) mock_apply_string.assert_called_once_with(version_patches.string_display, dol_file) mock_apply_game_options.assert_called_once_with( version_patches.game_options_constructor_address, user_preferences, dol_file) mock_apply_capacity.assert_called_once_with( version_patches.health_capacity, game_patches.game_specific, dol_file) mock_apply_beam_cost_patch.assert_called_once_with( version_patches.beam_cost_addresses, game_patches.game_specific, dol_file) mock_apply_starting_visor_patch.assert_called_once_with( version_patches.starting_beam_visor, {"foo": "bar"}, dol_file, )
def apply_patcher_file(game_root: Path, backup_files_path: Optional[Path], patcher_data: dict, game_specific: EchoesGameSpecific, progress_update: ProgressUpdateCallable, ): """ Applies the modifications listed in the given patcher_data to the game in game_root. :param game_root: :param backup_files_path: :param patcher_data: :param game_specific: :param progress_update: :return: """ menu_mod = patcher_data["menu_mod"] user_preferences = EchoesUserPreferences.from_json_dict(patcher_data["user_preferences"]) default_items = patcher_data["default_items"] status_update = status_update_lib.create_progress_update_from_successive_messages( progress_update, 400 if menu_mod else 100) last_version = get_patch_version(game_root) if last_version > CURRENT_PATCH_VERSION: raise RuntimeError(f"Game at {game_root} was last patched with version {last_version}, " f"which is above supported version {CURRENT_PATCH_VERSION}. " f"\nPlease press 'Delete internal copy'.") _ensure_no_menu_mod(game_root, backup_files_path, status_update) if backup_files_path is not None: _create_pak_backups(game_root, backup_files_path, status_update) _run_with_args(_base_args(game_root), json.dumps(patcher_data), "Randomized!", status_update) dol_patcher.apply_patches(game_root, game_specific, user_preferences, default_items) write_patch_version(game_root, CURRENT_PATCH_VERSION) if menu_mod: _add_menu_mod_to_files(game_root, status_update)
def apply_layout( description: LayoutDescription, players_config: PlayersConfiguration, cosmetic_patches: CosmeticPatches, backup_files_path: Optional[Path], progress_update: ProgressUpdateCallable, game_root: Path, ): """ Applies the modifications listed in the given LayoutDescription to the game in game_root. :param description: :param players_config: :param cosmetic_patches: :param game_root: :param backup_files_path: Path to use as pak backup, to remove/add menu mod. :param progress_update: :return: """ patcher_configuration = description.permalink.get_preset( players_config.player_index).patcher_configuration status_update = status_update_lib.create_progress_update_from_successive_messages( progress_update, 400 if patcher_configuration.menu_mod else 100) _ensure_no_menu_mod(game_root, backup_files_path, status_update) if backup_files_path is not None: _create_pak_backups(game_root, backup_files_path, status_update) description.save_to_file( game_root.joinpath("files", f"randovania.{description.file_extension()}")) _modern_api(game_root, status_update, description, players_config, cosmetic_patches) dol_patcher.apply_patches( game_root, description.all_patches[players_config.player_index], cosmetic_patches) if patcher_configuration.menu_mod: _add_menu_mod_to_files(game_root, status_update)
def test_apply_patches( mock_find_version_for_dol: MagicMock, mock_get_dol_path: MagicMock, mock_dol_file_constructor: MagicMock, mocker, ): # Setup game_root = MagicMock() patches_data = MagicMock() version_patches = dol_patcher.ALL_VERSIONS_PATCHES[0] mock_find_version_for_dol.return_value = version_patches dol_file = mock_dol_file_constructor.return_value mock_apply_string = mocker.patch( "randovania.games.prime.all_prime_dol_patches.apply_remote_execution_patch", autospec=True) mock_apply_game_options: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_game_options_patch", autospec=True) mock_apply_capacity: MagicMock = mocker.patch( "randovania.games.prime.all_prime_dol_patches.apply_energy_tank_capacity_patch", autospec=True) mock_apply_beam_cost_patch: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_beam_cost_patch", autospec=True) mock_apply_starting_visor_patch: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_starting_visor_patch", autospec=True) mock_apply_fixes: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_fixes", autospec=True) mock_apply_unvisited_room_names: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_unvisited_room_names", autospec=True) mock_apply_teleporter_sounds: MagicMock = mocker.patch( "randovania.games.prime.echoes_dol_patches.apply_teleporter_sounds", autospec=True) # Run dol_patcher.apply_patches(game_root, patches_data) # Assert mock_find_version_for_dol.assert_called_once_with( dol_file, dol_patcher.ALL_VERSIONS_PATCHES) mock_get_dol_path.assert_called_once_with(game_root) mock_dol_file_constructor.assert_called_once_with( mock_get_dol_path.return_value) mock_apply_string.assert_called_once_with(version_patches.string_display, dol_file) mock_apply_game_options.assert_called_once_with( version_patches.game_options_constructor_address, patches_data.user_preferences, dol_file) mock_apply_capacity.assert_called_once_with( version_patches.health_capacity, patches_data.energy_per_tank, dol_file) mock_apply_beam_cost_patch.assert_called_once_with( version_patches.beam_cost_addresses, patches_data.beam_configuration, dol_file) mock_apply_starting_visor_patch.assert_called_once_with( version_patches.starting_beam_visor, patches_data.default_items, dol_file, ) mock_apply_fixes.assert_called_once_with(version_patches, dol_file) mock_apply_unvisited_room_names.assert_called_once_with( version_patches, dol_file, patches_data.unvisited_room_names) mock_apply_teleporter_sounds.assert_called_once_with( version_patches, dol_file, patches_data.teleporter_sounds)