42 lines
2.2 KiB
Python
42 lines
2.2 KiB
Python
"""Check the complete authored voice bank and its offline default routing."""
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import re
|
|
import sys
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT / 'tools'))
|
|
from welcome_voice import validate_wav
|
|
from source_bundle import build
|
|
|
|
manifest = json.loads((ROOT / 'docs/bundled-speech.json').read_text())
|
|
assets = json.loads((ROOT / 'docs/bundled-speech-assets.json').read_text())
|
|
assert len(manifest['clips']) == len(assets['clips']) == 37
|
|
soldiers = (ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_SoldierSpeech.c').read_text()
|
|
expected = dict(re.findall(r'case ([\w.]+): return "([^"]+)";', soldiers))
|
|
assert {c['kind']: c['text'] for c in manifest['clips'] if c['category'] == 'soldier'} == expected
|
|
extraction = (ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_ExtractionService.c').read_text()
|
|
radio = set(re.findall(r'Stage\(\d+, "([^"]+)"\)', extraction) + re.findall(r'inbound = "([^"]+)"', extraction))
|
|
assert {c['text'] for c in manifest['clips'] if c['category'] == 'radio'} == radio
|
|
catalog = (ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_BakedSpeech.c').read_text()
|
|
for clip in assets['clips']:
|
|
path = ROOT / 'addons/core/Sounds/ERR/Speech' / (clip['id'] + '.wav')
|
|
audio = validate_wav(path.read_bytes())
|
|
assert hashlib.sha256(audio).hexdigest() == clip['sha256']
|
|
graph = path.with_suffix('.acp').read_text()
|
|
assert ('spatialFactor 1' in graph) == (clip['category'] == 'soldier')
|
|
assert 'name "ERR_SPEECH"' in graph and '"Infinite loop" 0' in graph
|
|
assert clip['graph'] in catalog
|
|
assert f'case "baked:{clip["id"]}":' in catalog
|
|
for resource in (path, path.with_suffix('.acp')):
|
|
meta = resource.with_name(resource.name + '.meta').read_text()
|
|
assert resource.relative_to(ROOT / 'addons/core').as_posix() in meta
|
|
assert all(f' {platform}' in meta for platform in ('PC', 'XBOX_SERIES', 'PS5', 'HEADLESS'))
|
|
_, bundle = build(ROOT)
|
|
files = bundle['files']
|
|
for clip in assets['clips']:
|
|
for suffix in ('.wav', '.wav.meta', '.acp', '.acp.meta'):
|
|
assert 'addons/core/Sounds/ERR/Speech/' + clip['id'] + suffix in files
|
|
print('PASS: all 37 fixed messages have validated exact audio, native graph identities and source-bundle inclusion')
|