예제 #1
0
def test_GameSession_create_session_entry(clean_database, has_description, test_files_dir, mocker):
    # Setup
    description = LayoutDescription.from_file(test_files_dir.joinpath("log_files", "seed_a.rdvgame"))
    someone = database.User.create(name="Someone")
    s = database.GameSession.create(name="Debug", num_teams=1, creator=someone)
    game_details = None
    if has_description:
        s.layout_description = description
        s.save()
        game_details = {
            'seed_hash': '5IENQWDS',
            'spoiler': True,
            'word_hash': 'Biostorage Cavern Watch',
        }

    # Run
    session = database.GameSession.get_by_id(1)
    result = session.create_session_entry()
    readable_result = construct_lib.convert_to_raw_python(BinaryGameSessionEntry.parse(result))

    # Assert
    assert readable_result == {
        'allowed_games': ['prime1', 'prime2'],
        'game_details': game_details,
        'generation_in_progress': None,
        'id': 1,
        'name': 'Debug',
        'players': [],
        'presets': [],
        'state': 'setup',
    }
예제 #2
0
def _create_patch_data(test_files_dir, mocker, in_file, out_file, cosmetic):
    # Setup
    f = test_files_dir.joinpath("log_files", "cave_story",
                                f"{in_file}.rdvgame")
    description = LayoutDescription.from_file(f)
    players_config = PlayersConfiguration(0, {0: "Cave Story"})

    mocker.patch(
        "randovania.layout.layout_description.LayoutDescription.shareable_hash_bytes",
        new_callable=PropertyMock,
        return_value=b'\x00\x00\x00\x00\x00')

    # Run
    data = CSPatchDataFactory(description, players_config,
                              cosmetic).create_data()

    # Expected Result

    # strip mychar to just the filename rather than full path
    if data["mychar"] is not None:
        mychar = Path(data["mychar"])
        data["mychar"] = mychar.name

    # Uncomment the following lines to update:
    # with test_files_dir.joinpath("caver_expected_data", f"{out_file}.json").open("w") as f:
    #     json.dump(data, f)

    with test_files_dir.joinpath("caver_expected_data",
                                 f"{out_file}.json").open("r") as f:
        expected_data = json.load(f)

    assert data == expected_data
예제 #3
0
def validate_command_logic(args):
    debug.set_level(args.debug)

    description = LayoutDescription.from_file(args.layout_file)
    if description.player_count != 1:
        raise ValueError(
            f"Validator does not support layouts with more than 1 player.")

    configuration = description.get_preset(0).configuration
    patches = description.all_patches[0]
    total_times = []

    final_state_by_resolve = None
    for _ in range(args.repeat):
        before = time.perf_counter()
        final_state_by_resolve = asyncio.run(
            resolver.resolve(configuration=configuration, patches=patches))
        after = time.perf_counter()
        total_times.append(after - before)
        print("Took {:.3f} seconds. Game is {}.".format(
            total_times[-1], "possible"
            if final_state_by_resolve is not None else "impossible"))
    if args.repeat > 1:
        cli_lib.print_report_multiple_times(total_times)

    if args.repeat < 1:
        raise ValueError("Expected at least 1 repeat")
    return 0 if final_state_by_resolve is not None else 1
def test_update_content(skip_qtbot, test_files_dir):
    # Setup
    description = LayoutDescription.from_file(test_files_dir.joinpath("log_files", "seed_a.rdvgame"))
    tab = TranslatorGateDetailsTab(None, RandovaniaGame.METROID_PRIME_ECHOES)

    # Run
    tab.update_content(
        description.get_preset(0).configuration,
        description.all_patches,
        PlayersConfiguration(0, {0: "You"}),
    )

    # Assert
    counts = {}
    for i in range(tab.tree_widget.topLevelItemCount()):
        item = tab.tree_widget.topLevelItem(i)
        counts[item.text(0)] = item.childCount()

    assert counts == {
        'Agon Wastes': 2,
        'Great Temple': 3,
        'Sanctuary Fortress': 2,
        'Temple Grounds': 7,
        'Torvus Bog': 3,
    }
예제 #5
0
def _test_preset(rdvgame_file, expected_results_file, mocker):
    # Setup
    description = LayoutDescription.from_file(rdvgame_file)
    players_config = PlayersConfiguration(0, {0: "Prime", 1: "Echoes"})
    cosmetic_patches = PrimeCosmeticPatches(use_hud_color=True,
                                            hud_color=(255, 0, 0),
                                            suit_color_rotations=(0, 40, 350,
                                                                  12))

    mocker.patch(
        "randovania.layout.layout_description.LayoutDescription.shareable_hash_bytes",
        new_callable=PropertyMock,
        return_value=b"\x00\x00\x00\x00\x00")

    # Run
    data = PrimePatchDataFactory(description, players_config,
                                 cosmetic_patches).create_data()

    # Expected Result
    with expected_results_file.open("r") as file:
        expected_data = json.load(file)

    # Uncomment to easily view diff of failed test
    # with expected_results_file.open("w") as file:
    #     file.write(json.dumps(data, indent=4, separators=(',', ': ')))

    # Ignore the part of the main menu message which has the randovania version in it
    data["gameConfig"]["mainMenuMessage"] = data["gameConfig"][
        "mainMenuMessage"].split("\n")[1]
    expected_data["gameConfig"]["mainMenuMessage"] = expected_data[
        "gameConfig"]["mainMenuMessage"].split("\n")[1]

    assert data == expected_data
예제 #6
0
def show_game_details(app: QApplication, options, game: Path):
    from randovania.layout.layout_description import LayoutDescription
    from randovania.gui.seed_details_window import SeedDetailsWindow

    layout = LayoutDescription.from_file(game)
    details_window = SeedDetailsWindow(None, options)
    details_window.update_layout_description(layout)
    details_window.show()
    app.details_window = details_window
예제 #7
0
def show_game_details(app: QtWidgets.QApplication, options, game: Path):
    from randovania.layout.layout_description import LayoutDescription
    from randovania.gui.game_details.game_details_window import GameDetailsWindow

    layout = LayoutDescription.from_file(game)
    details_window = GameDetailsWindow(None, options)
    details_window.update_layout_description(layout)
    logger.info("Displaying game details")
    details_window.show()
    app.details_window = details_window
예제 #8
0
    def __init__(self, json_path: Path):
        super().__init__()
        self.setupUi(self)
        set_default_window_icon(self)
        self.layout_description = LayoutDescription.from_file(json_path)

        # Keep the Layout Description visualizer ready, but invisible.
        self._create_pickup_spoilers()

        # And update
        self.update_layout_description(self.layout_description)
예제 #9
0
    def dropEvent(self, event: QtGui.QDropEvent):
        from randovania.layout.versioned_preset import VersionedPreset

        for url in event.mimeData().urls():
            path = Path(url.toLocalFile())
            if path.suffix == f".{LayoutDescription.file_extension()}":
                self.open_game_details(LayoutDescription.from_file(path))
                return

            elif path.suffix == f".{VersionedPreset.file_extension()}":
                self.main_tab_widget.setCurrentWidget(self.tab_create_seed)
                self.generate_seed_tab.import_preset_file(path)
                return
예제 #10
0
def validate_command_logic(args):
    debug.set_level(args.debug)
    data = prime_database.decode_data_file(args)
    game = data_reader.decode_data(data)

    description = LayoutDescription.from_file(args.layout_file)
    configuration = description.permalink.layout_configuration
    patches = description.patches

    final_state_by_resolve = resolver.resolve(configuration=configuration,
                                              game=game,
                                              patches=patches)
    print(final_state_by_resolve)
예제 #11
0
def test_dangerous_settings(test_files_dir,
                            rdvgame_filename="prime1_crazy_seed.rdvgame"):
    rdvgame = test_files_dir.joinpath("log_files", rdvgame_filename)
    layout_description = LayoutDescription.from_file(rdvgame)
    preset = layout_description.get_preset(0)

    assert preset.dangerous_settings() == [
        'One-way anywhere elevators',
        'Shuffled Item Position',
        'Room Randomizer',
        'Extra Superheated Rooms',
        'Submerged Rooms',
        'Dangerous Gravity Suit Logic',
    ]
예제 #12
0
async def test_resolver_with_log_file(test_files_dir, seed_name: str):
    # Setup
    debug.set_level(2)

    description = LayoutDescription.from_file(test_files_dir.joinpath("log_files", seed_name))
    configuration = description.permalink.presets[0].configuration
    patches = description.all_patches[0]

    # Run
    final_state_by_resolve = await resolver.resolve(configuration=configuration,
                                                    patches=patches)

    # Assert
    assert final_state_by_resolve is not None
    def _randomize_from_file(self):
        if not self._pre_export_checks([self._check_has_output_directory]):
            return

        json_path = prompt_user_for_seed_log(self)
        if json_path is None:
            return

        layout = LayoutDescription.from_file(json_path)

        self._background_exporter(
            simplified_patcher.patch_game_with_existing_layout,
            message="Randomizing...",
            layout=layout)
예제 #14
0
def test_resolver_with_log_file(test_files_dir):
    # Setup
    debug.set_level(0)

    description = LayoutDescription.from_file(test_files_dir.joinpath("log_files", "seed_a.json"))
    configuration = description.permalink.presets[0].layout_configuration
    patches = description.all_patches[0]

    # Run
    final_state_by_resolve = resolver.resolve(configuration=configuration,
                                              patches=patches)

    # Assert
    assert final_state_by_resolve is not None
def test_generate_patcher_data(test_files_dir):
    # Setup
    description = LayoutDescription.from_file(
        test_files_dir.joinpath("log_files", "seed_a.rdvgame"))
    player_index = 0
    preset = description.get_preset(player_index)
    cosmetic_patches = EchoesCosmeticPatches()
    assert isinstance(preset.configuration, EchoesConfiguration)

    # Run
    result = patch_data_factory.generate_patcher_data(
        description, PlayersConfiguration(player_index, {0: "you"}),
        cosmetic_patches)

    # Assert
    assert isinstance(result["spawn_point"], dict)

    assert isinstance(result["pickups"], list)
    assert len(result["pickups"]) == 119

    assert isinstance(result["elevators"], list)
    assert len(result["elevators"]) == 22

    assert isinstance(result["translator_gates"], list)
    assert len(result["translator_gates"]) == 17

    assert isinstance(result["string_patches"], list)
    assert len(result["string_patches"]) == 61

    assert result["specific_patches"] == {
        "hive_chamber_b_post_state": True,
        "intro_in_post_state": True,
        "warp_to_start": preset.configuration.warp_to_start,
        "credits_length": 75 if cosmetic_patches.speed_up_credits else 259,
        "disable_hud_popup": cosmetic_patches.disable_hud_popup,
        "pickup_map_icons": cosmetic_patches.pickup_markers,
        "full_map_at_start": cosmetic_patches.open_map,
        "dark_world_varia_suit_damage": preset.configuration.varia_suit_damage,
        "dark_world_dark_suit_damage": preset.configuration.dark_suit_damage,
        "always_up_gfmc_compound": True,
        "always_up_torvus_temple": True,
        "always_up_great_temple": False,
        'hud_color': None,
    }
    # TODO: check all fields?
    assert result["dol_patches"]["default_items"] == {
        "visor": "Combat Visor",
        "beam": "Power Beam",
    }
예제 #16
0
def test_update_layout_description_actual_seed(skip_qtbot, test_files_dir):
    description = LayoutDescription.from_file(
        test_files_dir.joinpath("log_files", "seed_a.rdvgame"))

    # Run
    window = SeedDetailsWindow(None, MagicMock())
    skip_qtbot.addWidget(window)
    window.update_layout_description(description)

    # Assert
    assert len(window.pickup_spoiler_buttons) == 119
    assert window.pickup_spoiler_show_all_button.text() == "Show All"
    skip_qtbot.mouseClick(window.pickup_spoiler_show_all_button,
                          QtCore.Qt.LeftButton)
    assert window.pickup_spoiler_show_all_button.text() == "Hide All"
예제 #17
0
def test_create_patch_data(test_files_dir, mocker):
    # Setup
    file = test_files_dir.joinpath("log_files", "dread_1.rdvgame")
    description = LayoutDescription.from_file(file)
    players_config = PlayersConfiguration(0, {0: "Dread"})
    cosmetic_patches = DreadCosmeticPatches()

    # Run
    data = DreadPatchDataFactory(description, players_config,
                                 cosmetic_patches).create_data()

    # Expected Result
    with test_files_dir.joinpath("dread_expected_data.json").open("r") as file:
        expected_data = json.load(file)

    assert data == expected_data
예제 #18
0
def validate_command_logic(args):
    debug.set_level(args.debug)

    description = LayoutDescription.from_file(args.layout_file)

    if description.permalink.player_count != 1:
        raise ValueError(f"Validator does not support layouts with more than 1 player.")

    configuration = description.permalink.presets[0].layout_configuration
    patches = description.all_patches[0]

    final_state_by_resolve = resolver.resolve(
        configuration=configuration,
        patches=patches
    )
    print(final_state_by_resolve)
예제 #19
0
def test_resolver_with_log_file(test_files_dir):
    # Setup
    debug.set_level(0)

    description = LayoutDescription.from_file(
        test_files_dir.joinpath("log_files", "seed_a.json"))
    configuration = description.permalink.layout_configuration
    game = data_reader.decode_data(configuration.game_data)
    patches = description.patches

    # Run
    final_state_by_resolve = resolver.resolve(configuration=configuration,
                                              game=game,
                                              patches=patches)

    # Assert
    assert final_state_by_resolve is not None
예제 #20
0
파일: echoes.py 프로젝트: xisi/randovania
def validate_command_logic(args):
    debug._DEBUG_LEVEL = args.debug
    data = prime_database.decode_data_file(args)
    game = data_reader.decode_data(data)

    if args.layout_file is not None:
        description = LayoutDescription.from_file(Path(args.layout_file))
        configuration = description.permalink.layout_configuration
        patches = description.patches
    else:
        configuration = LayoutConfiguration.default()
        patches = GamePatches.with_game(game).assign_pickup_assignment(
            game.pickup_database.original_pickup_mapping)

    final_state_by_resolve = resolver.resolve(configuration=configuration,
                                              game=game,
                                              patches=patches)
    print(final_state_by_resolve)
예제 #21
0
def test_create_patcher_file(test_files_dir):
    # Setup
    description = LayoutDescription.from_file(
        test_files_dir.joinpath("log_files", "seed_a.rdvgame"))
    player_index = 0
    preset = description.permalink.get_preset(player_index)
    cosmetic_patches = CosmeticPatches()

    # Run
    result = patcher_file.create_patcher_file(
        description, PlayersConfiguration(player_index, {0: "you"}),
        cosmetic_patches)

    # Assert
    assert isinstance(result["spawn_point"], dict)

    assert isinstance(result["pickups"], list)
    assert len(result["pickups"]) == 119

    assert isinstance(result["elevators"], list)
    assert len(result["elevators"]) == 22

    assert isinstance(result["translator_gates"], list)
    assert len(result["translator_gates"]) == 17

    assert isinstance(result["string_patches"], list)
    assert len(result["string_patches"]) == 60

    assert result["specific_patches"] == {
        "hive_chamber_b_post_state": True,
        "intro_in_post_state": True,
        "warp_to_start": preset.patcher_configuration.warp_to_start,
        "speed_up_credits": cosmetic_patches.speed_up_credits,
        "disable_hud_popup": cosmetic_patches.disable_hud_popup,
        "pickup_map_icons": cosmetic_patches.pickup_markers,
        "full_map_at_start": cosmetic_patches.open_map,
        "dark_world_varia_suit_damage":
        preset.patcher_configuration.varia_suit_damage,
        "dark_world_dark_suit_damage":
        preset.patcher_configuration.dark_suit_damage,
        "always_up_gfmc_compound": True,
        "always_up_torvus_temple": True,
        "always_up_great_temple": False,
    }
예제 #22
0
def validate_command_logic(args):
    debug.set_level(args.debug)

    description = LayoutDescription.from_file(args.layout_file)
    if description.player_count != 1:
        raise ValueError(
            f"Validator does not support layouts with more than 1 player.")

    configuration = description.get_preset(0).configuration
    patches = description.all_patches[0]

    before = time.perf_counter()
    final_state_by_resolve = asyncio.run(
        resolver.resolve(configuration=configuration, patches=patches))
    after = time.perf_counter()
    print("Took {} seconds. Game is {}.".format(
        after - before,
        "possible" if final_state_by_resolve is not None else "impossible"))
    return 0 if final_state_by_resolve is not None else 1
예제 #23
0
async def patcher_data_command_logic_async(args):
    from randovania.interface_common.players_configuration import PlayersConfiguration
    from randovania.layout.layout_description import LayoutDescription

    layout_description = LayoutDescription.from_file(args.log_file)
    players_config = PlayersConfiguration(
        args.player_index,
        {i: f"Player {i + 1}"
         for i in range(layout_description.player_count)})
    preset = layout_description.get_preset(players_config.player_index)

    cosmetic_patches = preset.game.data.layout.cosmetic_patches.default()
    data_factory = preset.game.patch_data_factory(layout_description,
                                                  players_config,
                                                  cosmetic_patches)
    patch_data = data_factory.create_data()
    print(json.dumps(
        patch_data,
        indent=4,
    ))
예제 #24
0
def randomize_command_logic(args):
    def status_update(s):
        if args.verbose:
            print(s)

    if args.permalink is not None:
        layout_description = generator.generate_description(permalink=Permalink.from_str(args.permalink),
                                                            status_update=status_update,
                                                            validate_after_generation=True)
    else:
        layout_description = LayoutDescription.from_file(args.log_file)

    cosmetic_patches = CosmeticPatches(
        disable_hud_popup=args.disable_hud_popup,
        speed_up_credits=args.speed_up_credits)

    claris_randomizer.apply_layout(description=layout_description,
                                   cosmetic_patches=cosmetic_patches,
                                   backup_files_path=args.backup_files,
                                   progress_update=lambda x, _: status_update(x),
                                   game_root=args.game_files,
                                   )
예제 #25
0
async def randomize_command_logic_async(args):
    from randovania.games.patcher_provider import PatcherProvider
    from randovania.generator import generator
    from randovania.interface_common.cosmetic_patches import CosmeticPatches
    from randovania.interface_common.players_configuration import PlayersConfiguration
    from randovania.layout.layout_description import LayoutDescription
    from randovania.layout.permalink import Permalink
    from randovania.interface_common.options import Options

    def status_update(s):
        if args.verbose:
            print(s)

    if args.permalink is not None:
        permalink = Permalink.from_str(args.permalink)
        layout_description = await generator.generate_and_validate_description(
            permalink=permalink,
            status_update=status_update,
            validate_after_generation=True,
        )
    else:
        layout_description = LayoutDescription.from_file(args.log_file)

    cosmetic_patches = CosmeticPatches(
        disable_hud_popup=args.disable_hud_popup,
        speed_up_credits=args.speed_up_credits)

    players_config = PlayersConfiguration(args.player_index,
                                          {i: f"Player {i + 1}"
                                           for i in range(layout_description.permalink.player_count)})
    preset = layout_description.permalink.get_preset(players_config.player_index)

    game_files_path = Options.with_default_data_dir().game_files_path
    patcher_provider = PatcherProvider()
    patcher = patcher_provider.patcher_for_game(preset.game)

    patch_data = patcher.create_patch_data(layout_description, players_config, cosmetic_patches)
    patcher.patch_game(args.input_file, args.output_file, patch_data, game_files_path, lambda x, _: status_update(x))
def test_create_patch_data(test_files_dir, mocker):
    # Setup
    file = test_files_dir.joinpath("log_files", "dread_1.rdvgame")
    description = LayoutDescription.from_file(file)
    players_config = PlayersConfiguration(0, {0: "Dread"})
    cosmetic_patches = DreadCosmeticPatches()
    mocker.patch(
        "randovania.layout.layout_description.LayoutDescription.shareable_word_hash",
        new_callable=PropertyMock,
        return_value="Words Hash")
    mocker.patch(
        "randovania.layout.layout_description.LayoutDescription.shareable_hash",
        new_callable=PropertyMock,
        return_value="$$$$$")

    # Run
    data = DreadPatchDataFactory(description, players_config,
                                 cosmetic_patches).create_data()

    # Expected Result
    with test_files_dir.joinpath("dread_expected_data.json").open("r") as file:
        expected_data = json.load(file)

    assert data == expected_data
예제 #27
0
 def _import_spoiler_log(self):
     json_path = common_qt_lib.prompt_user_for_input_game_log(self)
     if json_path is not None:
         layout = LayoutDescription.from_file(json_path)
         self.open_game_details(layout)