Version 3.2.0: fast lists with loading spinners, names from the game files, INT docs and screenshots, cleanup
This commit is contained in:
@@ -17,7 +17,7 @@ import os
|
||||
import random
|
||||
|
||||
from .. import banks, classify, subtitles
|
||||
from ..catalog import (Catalog, apply_lines, available_archives, bank_sounds, build_lines, character_of, hash_names,
|
||||
from ..catalog import (Catalog, apply_lines, available_archives, bank_names, bank_sounds, build_lines, character_of,
|
||||
is_shipped, line_names, load_archive, load_banks, load_characters, read_csv, scan_archive)
|
||||
from ..inject import read_target
|
||||
from ..paths import catalog_dir
|
||||
@@ -44,16 +44,16 @@ class Report:
|
||||
return not self.issues
|
||||
|
||||
|
||||
def _expected_category(s):
|
||||
def _expected_category(s, names):
|
||||
if s.archive == banks.ARCHIVE:
|
||||
return classify.classify(s.name, bank=s.bank)
|
||||
pack = None
|
||||
if s.is_pack_media:
|
||||
pack = hash_names().get(int(s.target.split("/")[0], 16), s.target.split("/")[0])
|
||||
pack = names.get(int(s.target.split("/")[0], 16), s.target.split("/")[0])
|
||||
return classify.classify(s.name, pack=pack)
|
||||
|
||||
|
||||
def _check_rows(rep, archive, rows, characters):
|
||||
def _check_rows(rep, archive, rows, characters, names):
|
||||
seen_t, seen_n = set(), {}
|
||||
for s in rows:
|
||||
rep.checked[archive] += 1
|
||||
@@ -66,7 +66,7 @@ def _check_rows(rep, archive, rows, characters):
|
||||
if n in seen_n or (s.language and ("", n[1]) in seen_n):
|
||||
rep.add(archive, "duplicate", s.key, "name %s (also %s)" % (s.name, seen_n.get(n) or seen_n[("", n[1])]))
|
||||
seen_n[n] = s.key
|
||||
g, c = _expected_category(s)
|
||||
g, c = _expected_category(s, names)
|
||||
if (s.group, s.category) != (g, c):
|
||||
rep.add(archive, "category", s.key, "%s/%s, rules give %s/%s" % (s.group, s.category, g, c))
|
||||
want = character_of(s, characters)
|
||||
@@ -82,7 +82,7 @@ def check_wad(rep, game, archive, rows, characters, lines=None):
|
||||
folder = os.path.basename(os.path.dirname(path)).upper()
|
||||
if FOLDER_LANG.get(folder, archive) != archive:
|
||||
rep.add(archive, "language", archive, "WAD in folder %s" % folder)
|
||||
_check_rows(rep, archive, rows, characters)
|
||||
_check_rows(rep, archive, rows, characters, bank_names(game.cooked))
|
||||
fresh_list = scan_archive(archive, path, characters=characters)
|
||||
if lines is not None and archive in lines.langs:
|
||||
apply_lines(fresh_list, lines, lines.names)
|
||||
@@ -117,7 +117,7 @@ def check_wad(rep, game, archive, rows, characters, lines=None):
|
||||
def check_banks(rep, game, rows, locations, characters, quick=False, sample=40, progress=None):
|
||||
"""BANK rows, copies, prefetch heads and subtitles vs a scan of the packages. The full check (not quick)
|
||||
also derives the game's lines from that scan and returns them (else None)."""
|
||||
_check_rows(rep, banks.ARCHIVE, rows, characters)
|
||||
_check_rows(rep, banks.ARCHIVE, rows, characters, bank_names(game.cooked))
|
||||
files = banks.bank_files(game.cooked)
|
||||
if quick:
|
||||
pk = [f for f in files if f.lower().endswith(".upk")]
|
||||
|
||||
@@ -98,39 +98,6 @@ def search_memory(pid, needles, limit=1 << 32):
|
||||
return found
|
||||
|
||||
|
||||
u32 = ctypes.WinDLL("user32", use_last_error=True)
|
||||
WM_KEYDOWN, WM_KEYUP = 0x0100, 0x0101
|
||||
VK = dict(enter=0x0D, space=0x20, esc=0x1B, up=0x26, down=0x28, left=0x25, right=0x27, e=0x45)
|
||||
|
||||
|
||||
def game_windows(pid):
|
||||
"""Top-level windows of the game process."""
|
||||
found = []
|
||||
cb_t = ctypes.WINFUNCTYPE(wt.BOOL, wt.HWND, wt.LPARAM)
|
||||
|
||||
def cb(hwnd, _):
|
||||
p = wt.DWORD()
|
||||
u32.GetWindowThreadProcessId(hwnd, ctypes.byref(p))
|
||||
if p.value == pid and u32.IsWindowVisible(hwnd):
|
||||
found.append(hwnd)
|
||||
return True
|
||||
u32.EnumWindows(cb_t(cb), 0)
|
||||
return found
|
||||
|
||||
|
||||
def post_key(pid, key, hold=0.08):
|
||||
"""Post a key press to the game's window only (never global SendInput)."""
|
||||
vk = VK[key] if isinstance(key, str) else key
|
||||
sc = u32.MapVirtualKeyW(vk, 0)
|
||||
n = 0
|
||||
for hwnd in game_windows(pid):
|
||||
u32.PostMessageW(hwnd, WM_KEYDOWN, vk, 1 | (sc << 16))
|
||||
time.sleep(hold)
|
||||
u32.PostMessageW(hwnd, WM_KEYUP, vk, 1 | (sc << 16) | (3 << 30))
|
||||
n += 1
|
||||
return n
|
||||
|
||||
|
||||
def running_game_pids():
|
||||
out = subprocess.run(["tasklist", "/FI", "IMAGENAME eq BatmanAC.exe", "/FO", "CSV", "/NH"],
|
||||
capture_output=True, text=True).stdout
|
||||
|
||||
Reference in New Issue
Block a user