示例#1
0
def test_parse_component(storage, monkeypatch, arg, str_value):
    def request_get(path):
        return mock_response(b'1.2.0.0\r\n1.0.0.0\r\n')

    monkeypatch.setattr(storage, 'request_get', request_get)
    component = parse_component(storage, arg)
    assert str(component) == str_value
示例#2
0
def test_parse_component_patch(storage, monkeypatch, arg, str_value):
    def gen_versions(storage, stored):
        assert stored == False
        for v in ('7.23', '7.21', '7.20', '7.19'):
            yield PatchVersion._create(storage, Version(v), [])

    monkeypatch.setattr(PatchVersion, 'versions', gen_versions)

    component = parse_component(storage, arg)
    assert str(component) == str_value
示例#3
0
def test_patch_version_versions(storage, monkeypatch, solution_versions,
                                patch_versions):
    def patch_version(self):
        return solution_versions[str(self)]

    monkeypatch.setattr(SolutionVersion, 'patch_version', patch_version)

    for sv in solution_versions:
        sv = parse_component(storage, sv)
        os.makedirs(f"{storage.path}/{sv.path}", exist_ok=True)

    result = list(PatchVersion.versions(storage, stored=True))
    result = [(str(p.version), [str(sv) for sv in p.solutions()])
              for p in result]
    assert result == patch_versions
示例#4
0
def command_hashes_guess(parser, args):
    hashes = load_hashes(args.hashes)

    wad_paths = []
    for path_or_component in args.wad:
        try:
            component = parse_component(args.storage, path_or_component)
        except ValueError:
            wad_paths.append(path_or_component)
            continue
        # component, get wad paths
        if isinstance(component, ProjectVersion):
            it = component.filepaths()
        elif isinstance(component, SolutionVersion):
            it = component.filepaths(langs=True)
        elif isinstance(component, PatchVersion):
            # there must be one solution
            for sv in component.solutions(latest=True):
                if sv.name == 'league_client_sln':
                    it = sv.filepaths(langs=True)
            else:
                it = []
        else:
            parser.error(f"command cannot be used on {component}")
        wad_paths.extend(
            args.storage.fspath(p) for p in it if p.endswith('.wad'))

    wads = [Wad(path) for path in wad_paths]
    unknown_hashes = set()
    for wad in wads:
        unknown_hashes |= set(wadfile.path_hash for wadfile in wad.files)
    unknown_hashes -= set(hashes)

    new_hashes = {}
    if args.search:
        for wad in wads:
            new_hashes.update(wad.guess_hashes(unknown_hashes))
    new_hashes.update(Wad.guess_hashes_from_known(hashes, unknown_hashes))

    for h, path in new_hashes.items():
        print(f"{h:016x} {path}")

    if not args.dry_run and new_hashes:
        hashes.update(new_hashes)
        save_hashes(args.hashes, hashes)
示例#5
0
def parse_component_arg(parser, storage: Storage, component: str):
    """Wrapper around parse_component() to parse CLI arguments"""
    try:
        return parse_component(storage, component)
    except ValueError:
        parser.error(f"invalid component: {component}")
示例#6
0
def test_parse_component_error(arg):
    with pytest.raises(ValueError):
        parse_component(None, arg)
示例#7
0
def command_hashes_guess(parser, args):
    all_methods = [
        ("grep", "search for hashes in WAD files"),
        ("numbers", "substitute numbers in basenames"),
        ("basenames", "substitute basenames"),
        ("words", "substitute known words in basenames"),
        ("ext", "substitute extensions"),
        ("regionlang", "substitute region and lang (LCU only)"),
        ("plugin", "substitute plugin name (LCU only)"),
        ("skin-num", "substitute skinNN numbers (game only)"),
        ("character", "substitute character name (game only)"),
        ("prefixes", "check basename prefixes (game only)"),
    ]
    all_method_names = [name for name, _ in all_methods]

    if args.list_methods:
        name_width = max(len(name) for name in all_method_names)
        for name, desc in all_methods:
            print(f"  {name:{name_width}}  {desc}")
        return
    elif not args.wad:
        parser.error(
            "neither \"wad\" nor \"--list-methods\" argument was found")

    if not args.methods:
        method_names = [
            name for name in all_method_names
            if name not in ("basenames", "words")
        ]
    else:
        method_names = [s.strip() for s in args.methods.split(',')]
        for name in method_names:
            if name not in all_method_names:
                parser.error(f"unknown guessing method: {name}")

    # collect WAD paths
    wads = []
    for path_or_component in args.wad:
        try:
            component = parse_component(args.storage, path_or_component)
        except ValueError:
            wads.append(Wad(path_or_component))
            continue
        wads += wads_from_component(component)

    # guess LCU hashes
    guesser = LcuHashGuesser.from_wads(wads)
    if guesser.unknown:
        nunknown = len(guesser.unknown)
        if "grep" in method_names:
            for wad in guesser.wads:
                wad.guess_extensions()
                guesser.grep_wad(wad)
        if "numbers" in method_names:
            guesser.substitute_numbers()
        if "basenames" in method_names:
            guesser.substitute_basenames()
        if "words" in method_names:
            guesser.substitute_basename_words()
        if "ext" in method_names:
            guesser.substitute_extensions()
        if "regionlang" in method_names:
            guesser.substitute_region_lang()
        if "plugin" in method_names:
            guesser.substitute_plugin()

        nfound = nunknown - len(guesser.unknown)
        if nfound:
            print(f"found LCU hashes: {nfound}")
            if not args.dry_run:
                guesser.save()

    # guess game hashes
    guesser = GameHashGuesser.from_wads(wads)
    if guesser.unknown:
        nunknown = len(guesser.unknown)
        if "grep" in method_names:
            for wad in guesser.wads:
                wad.guess_extensions()
                guesser.grep_wad(wad)
        if "numbers" in method_names:
            guesser.substitute_numbers()
        if "basenames" in method_names:
            guesser.substitute_basenames()
        if "words" in method_names:
            guesser.substitute_basename_words()
        if "ext" in method_names:
            guesser.substitute_extensions()
        if "skin-num" in method_names:
            guesser.substitute_skin_numbers()
        if "character" in method_names:
            guesser.substitute_character()
        if "prefixes" in method_names:
            guesser.check_basename_prefixes()

        nfound = nunknown - len(guesser.unknown)
        if nfound:
            print(f"found game hashes: {nfound}")
            if not args.dry_run:
                guesser.save()