64 lines
3.3 KiB
Python
64 lines
3.3 KiB
Python
"""Extend a CW catalog with identity-checked native star rows (no guessed rows)."""
|
|
import argparse
|
|
import copy
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
def main():
|
|
p = argparse.ArgumentParser(description=__doc__)
|
|
p.add_argument('--capture', type=Path, required=True)
|
|
p.add_argument('--catalog', type=Path, required=True)
|
|
p.add_argument('--output', type=Path, required=True)
|
|
a = p.parse_args()
|
|
raw = a.capture.read_bytes()
|
|
lines = raw.decode('utf-8-sig').splitlines()
|
|
if any('[GAC_CW_ROLE_STARS] ERROR' in line for line in lines):
|
|
raise ValueError('capture reports an error')
|
|
rows = [json.loads(line.split(' ROW ', 1)[1]) for line in lines if '[GAC_CW_ROLE_STARS] ROW ' in line]
|
|
c = json.loads(a.catalog.read_text(encoding='utf-8-sig'))
|
|
bases = {}
|
|
for r in c['captured_role_variants']:
|
|
identity = r['Config']['ID']
|
|
if identity not in bases or r['Star'] < bases[identity]['Star']:
|
|
bases[identity] = r
|
|
variants = {(r['Config']['ID'], r['Star']): r for r in c['captured_role_variants']}
|
|
seen = set()
|
|
for row in rows:
|
|
key = row['ID'], row['Star']
|
|
star = row['StarConfig']
|
|
if key in seen or (star['ID'], star['Star']) != key:
|
|
raise ValueError(f'duplicate or clamped star row: {key}')
|
|
seen.add(key)
|
|
base = bases.get(key[0])
|
|
if base is None or not 0 < key[1] <= base['MaxStar']:
|
|
raise ValueError(f'missing role configuration: {key}')
|
|
if key in variants:
|
|
if variants[key]['StarConfig'] != star or variants[key]['ServantStarConfig'] != row['ServantStarConfig']:
|
|
raise ValueError(f'row differs from earlier capture: {key}')
|
|
continue
|
|
v = copy.deepcopy(base)
|
|
v.update(Star=key[1], StarConfig=star, ServantStarConfig=row['ServantStarConfig'], SellPrice=0, SaleQuoteKnown=False)
|
|
# Only ordinary roles whose default quote matches the current rarity
|
|
# table can use that table at a higher star. Special quotes stay unknown.
|
|
constants = c['constants']['ConstValueCommonExcelTable']
|
|
default = constants.get(f"GridFight_AvatarSnippetSellGoldStar{base['Star']}", {}).get('ArrayValue', [])
|
|
target = constants.get(f'GridFight_AvatarSnippetSellGoldStar{key[1]}', {}).get('ArrayValue', [])
|
|
rarity = base['Config']['Rarity'] - 1
|
|
if rarity < len(default) and rarity < len(target) and default[rarity]['IntValue'] == base['SellPrice']:
|
|
v.update(SellPrice=target[rarity]['IntValue'], SaleQuoteKnown=True)
|
|
variants[key] = v
|
|
if not rows:
|
|
raise ValueError('no native star rows')
|
|
c['captured_role_variants'] = [variants[k] for k in sorted(variants)]
|
|
c['provenance']['star_rows_capture_sha256'] = hashlib.sha256(raw).hexdigest()
|
|
c['provenance']['star_rows_capture_complete'] = any(line.startswith('[GAC_CW_ROLE_STARS] END ') for line in lines)
|
|
c['provenance']['star_rows_source'] = 'Initialized RoleConfig.GetStarConfig(star), identity checked; four rows per heartbeat, paused in Battle. Uncaptured variants remain unavailable.'
|
|
a.output.write_text(json.dumps(c, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
|
|
print(f'Imported {len(rows)} native rows; catalog contains {len(variants)} variants')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|