Example #1
0
def test_round_trip(spoiler: bool, layout: dict, default_echoes_preset,
                    mocker):
    # Setup
    random_uuid = uuid.uuid4()
    mocker.patch("uuid.uuid4", return_value=random_uuid)

    preset = Preset(
        name="{} Custom".format(default_echoes_preset.game.long_name),
        description="A customized preset.",
        uuid=random_uuid,
        base_preset_uuid=default_echoes_preset.uuid,
        game=default_echoes_preset.game,
        configuration=dataclasses.replace(default_echoes_preset.configuration,
                                          **layout),
    )

    params = GeneratorParameters(
        seed_number=1000,
        spoiler=spoiler,
        presets=[preset],
    )

    # Run
    after = GeneratorParameters.from_bytes(params.as_bytes)

    # Assert
    assert params == after
Example #2
0
def test_round_trip(spoiler: bool, layout: dict, default_preset, mocker):
    # Setup
    random_uuid = uuid.uuid4()
    mocker.patch("uuid.uuid4", return_value=random_uuid)

    preset = Preset(
        name="{} Custom".format(default_preset.name),
        description="A customized preset.",
        uuid=random_uuid,
        base_preset_uuid=default_preset.uuid,
        game=default_preset.game,
        configuration=dataclasses.replace(default_preset.configuration,
                                          **layout),
    )

    link = Permalink(
        seed_number=1000,
        spoiler=spoiler,
        presets={0: preset},
    )

    # Run
    after = Permalink.from_str(link.as_base64_str)

    # Assert
    assert link == after
Example #3
0
 def ensure_converted(self):
     if not self._converted:
         try:
             self._preset = Preset.from_json_dict(convert_to_current_version(copy.deepcopy(self.data)))
         except (ValueError, KeyError) as e:
             self.exception = InvalidPreset(e)
             raise self.exception from e
Example #4
0
def _decode_preset(decoder: BitPackDecoder, manager: PresetManager) -> Preset:
    included_presets = [versioned.get_preset() for versioned in manager.included_presets]

    is_custom_preset = bitpacking.decode_bool(decoder)
    reference_preset = decoder.decode_element(included_presets)
    if is_custom_preset:
        patcher_configuration = PatcherConfiguration.bit_pack_unpack(
            decoder, {"reference": reference_preset.patcher_configuration})
        layout_configuration = LayoutConfiguration.bit_pack_unpack(
            decoder, {"reference": reference_preset.layout_configuration})
        preset = Preset(
            name="{} Custom".format(reference_preset.name),
            description="A customized preset.",
            base_preset_name=reference_preset.name,
            patcher_configuration=patcher_configuration,
            layout_configuration=layout_configuration,
        )

    else:
        preset = reference_preset
    included_data_hash = decoder.decode_single(256)
    expected_data_hash = _dictionary_byte_hash(preset.layout_configuration.game_data)
    if included_data_hash != expected_data_hash:
        raise ValueError("Given permalink is for a Randovania database with hash '{}', "
                         "but current database has hash '{}'.".format(included_data_hash, expected_data_hash))
    return preset
Example #5
0
def customized_preset(default_preset) -> Preset:
    return Preset(name="{} Custom".format(default_preset.name),
                  description="A customized preset.",
                  uuid=uuid.uuid4(),
                  base_preset_uuid=default_preset.uuid,
                  game=default_preset.game,
                  configuration=default_preset.configuration)
Example #6
0
 def create_custom_preset_with(self) -> Preset:
     return Preset(
         name=self.name,
         description="A preset that was customized.",
         base_preset_name=self._base_preset_name,
         patcher_configuration=self.patcher_configuration,
         layout_configuration=self.layout_configuration,
     )
Example #7
0
 def create_custom_preset_with(self) -> Preset:
     return Preset(
         name=self.name,
         description="A preset that was customized.",
         base_preset_name=self._base_preset_name,
         game=self._game,
         configuration=self.configuration,
     )
Example #8
0
 def from_json_dict(cls, param: dict) -> "Permalink":
     return Permalink(
         seed_number=param["seed"],
         spoiler=param["spoiler"],
         presets={
             index: Preset.from_json_dict(preset)
             for index, preset in enumerate(param["presets"])
         },
     )
Example #9
0
def test_decode_mock_other(
    mock_packer_unpack: MagicMock,
    mock_layout_unpack: MagicMock,
    default_preset,
    encoded,
    num_players,
):
    patcher_configuration = mock_packer_unpack.return_value
    layout_configuration = mock_layout_unpack.return_value
    preset = Preset(
        name="{} Custom".format(default_preset.name),
        description="A customized preset.",
        base_preset_name=default_preset.name,
        patcher_configuration=patcher_configuration,
        layout_configuration=layout_configuration,
    )

    expected = Permalink(
        seed_number=1000,
        spoiler=True,
        presets={i: preset
                 for i in range(num_players)},
    )
    patcher_configuration.bit_pack_encode.return_value = []
    layout_configuration.bit_pack_encode.return_value = []
    mock_layout_unpack.return_value.game_data = {"test": True}

    # Uncomment this line to quickly get the new encoded permalink
    # assert expected.as_str == ""
    # print(expected.as_str)

    # Run
    round_trip = expected.as_str
    link = Permalink.from_str(encoded)

    # Assert
    assert link == expected
    assert encoded == round_trip
    mock_packer_unpack.assert_called_once()
    mock_layout_unpack.assert_called_once()
    patcher_configuration.bit_pack_encode.assert_called_once_with(
        {"reference": default_preset.patcher_configuration})
    layout_configuration.bit_pack_encode.assert_called_once_with(
        {"reference": default_preset.layout_configuration})
Example #10
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "GeneratorParameters":
        games = decode_game_list(decoder)
        seed_number = decoder.decode_single(_PERMALINK_MAX_SEED)
        spoiler = bitpacking.decode_bool(decoder)

        manager = PresetManager(None)
        presets = [
            Preset.bit_pack_unpack(decoder, {"manager": manager, "game": game})
            for game in games
        ]
        for game in _get_unique_games(presets):
            included_data_hash = decoder.decode_single(256)
            expected_data_hash = _game_db_hash(game)
            if included_data_hash != expected_data_hash:
                raise ValueError("Given permalink is for a Randovania {} database with hash '{}', "
                                 "but current database has hash '{}'.".format(game.long_name,
                                                                              included_data_hash,
                                                                              expected_data_hash))

        return GeneratorParameters(seed_number, spoiler, presets)
Example #11
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "Permalink":
        version, seed_number = decoder.decode(_PERMALINK_MAX_VERSION, _PERMALINK_MAX_SEED)
        cls._raise_if_different_version(version)

        spoiler = bitpacking.decode_bool(decoder)
        player_count = bitpacking.decode_int_with_limits(decoder, _PERMALINK_PLAYER_COUNT_LIMITS)
        manager = PresetManager(None)

        previous_unique_presets = []
        presets = {}

        for index in range(player_count):
            in_previous_presets = bitpacking.decode_bool(decoder)
            if in_previous_presets:
                preset = decoder.decode_element(previous_unique_presets)
            else:
                preset = Preset.bit_pack_unpack(decoder, {"manager": manager})
                previous_unique_presets.append(preset)
            presets[index] = preset

        return Permalink(seed_number, spoiler, presets)
Example #12
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "Permalink":
        version, seed, spoiler = decoder.decode(_PERMALINK_MAX_VERSION,
                                                _PERMALINK_MAX_SEED, 2)
        cls._raise_if_different_version(version)

        included_data_hash = decoder.decode_single(256)

        manager = PresetManager(None)
        is_custom_preset = bitpacking.decode_bool(decoder)
        reference_preset = decoder.decode_element(manager.included_presets)

        if is_custom_preset:
            patcher_configuration = PatcherConfiguration.bit_pack_unpack(
                decoder, {"reference": reference_preset.patcher_configuration})
            layout_configuration = LayoutConfiguration.bit_pack_unpack(
                decoder, {"reference": reference_preset.layout_configuration})
            preset = Preset(
                name="{} Custom".format(reference_preset.name),
                description="A customized preset.",
                base_preset_name=reference_preset.name,
                patcher_configuration=patcher_configuration,
                layout_configuration=layout_configuration,
            )

        else:
            preset = reference_preset

        expected_data_hash = _dictionary_byte_hash(
            preset.layout_configuration.game_data)
        if included_data_hash != expected_data_hash:
            raise ValueError(
                "Given permalink is for a Randovania database with hash '{}', "
                "but current database has hash '{}'.".format(
                    included_data_hash, expected_data_hash))

        return Permalink(
            seed,
            bool(spoiler),
            preset,
        )
Example #13
0
def test_round_trip(spoiler: bool, layout: dict, default_preset):
    # Setup
    preset = Preset(
        name="{} Custom".format(default_preset.name),
        description="A customized preset.",
        base_preset_name=default_preset.name,
        game=default_preset.game,
        configuration=dataclasses.replace(default_preset.configuration,
                                          **layout),
    )

    link = Permalink(
        seed_number=1000,
        spoiler=spoiler,
        presets={0: preset},
    )

    # Run
    after = Permalink.from_str(link.as_base64_str)

    # Assert
    assert link == after
Example #14
0
def test_round_trip(spoiler: bool,
                    patcher: dict,
                    layout: dict,
                    preset_manager):
    # Setup
    preset = Preset(
        name="{} Custom".format(preset_manager.default_preset.name),
        description="A customized preset.",
        base_preset_name=preset_manager.default_preset.name,
        patcher_configuration=dataclasses.replace(preset_manager.default_preset.patcher_configuration, **patcher),
        layout_configuration=dataclasses.replace(preset_manager.default_preset.layout_configuration, **layout),
    )

    link = Permalink(
        seed_number=1000,
        spoiler=spoiler,
        preset=preset,
    )

    # Run
    after = Permalink.from_str(link.as_str)

    # Assert
    assert link == after
Example #15
0
 def from_json_dict(cls, param: dict) -> "Permalink":
     return Permalink(
         seed_number=param["seed"],
         spoiler=param["spoiler"],
         preset=Preset.from_json_dict(param["preset"]),
     )
Example #16
0
 def _file_name_for_preset(self, preset: Preset) -> Path:
     return self._data_dir.joinpath("{}.{}".format(preset.slug_name,
                                                   preset.file_extension()))
Example #17
0
def test_apply_layout(
    mock_ensure_no_menu_mod: MagicMock,
    mock_create_pak_backups: MagicMock,
    mock_add_menu_mod_to_files: MagicMock,
    mock_modern_api: MagicMock,
    mock_apply_patches: MagicMock,
    mock_create_progress_update_from_successive_messages: MagicMock,
    mock_save_to_file: MagicMock,
    include_menu_mod: bool,
    has_backup_path: bool,
):
    # Setup
    cosmetic_patches = MagicMock()
    description = LayoutDescription(
        version=randovania.VERSION,
        permalink=Permalink(
            seed_number=1,
            spoiler=False,
            presets={
                0:
                Preset(name="Name",
                       description="Desc",
                       base_preset_name=None,
                       patcher_configuration=PatcherConfiguration(
                           menu_mod=include_menu_mod,
                           warp_to_start=MagicMock(),
                       ),
                       layout_configuration=MagicMock())
            },
        ),
        all_patches={0: MagicMock()},
        item_order=(),
    )

    game_root = MagicMock(spec=Path())
    backup_files_path = MagicMock() if has_backup_path else None
    progress_update = MagicMock()
    player_config = PlayersConfiguration(0, {0: "you"})
    status_update = mock_create_progress_update_from_successive_messages.return_value

    # Run
    claris_randomizer.apply_layout(description, player_config,
                                   cosmetic_patches, backup_files_path,
                                   progress_update, game_root)

    # Assert
    mock_create_progress_update_from_successive_messages.assert_called_once_with(
        progress_update, 400 if include_menu_mod else 100)
    mock_ensure_no_menu_mod.assert_called_once_with(game_root,
                                                    backup_files_path,
                                                    status_update)
    if has_backup_path:
        mock_create_pak_backups.assert_called_once_with(
            game_root, backup_files_path, status_update)
    else:
        mock_create_pak_backups.assert_not_called()
    game_root.joinpath.assert_called_once_with(
        "files", "randovania.{}".format(LayoutDescription.file_extension()))
    mock_save_to_file.assert_called_once_with(description,
                                              game_root.joinpath.return_value)

    mock_modern_api.assert_called_once_with(game_root, status_update,
                                            description, player_config,
                                            cosmetic_patches)
    mock_apply_patches.assert_called_once_with(game_root,
                                               description.all_patches[0],
                                               cosmetic_patches)

    if include_menu_mod:
        mock_add_menu_mod_to_files.assert_called_once_with(
            game_root, status_update)
    else:
        mock_add_menu_mod_to_files.assert_not_called()