Files
GaCy-GO/tools/import_cw_role_stars.py
T

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()