62 lines
3.2 KiB
Python
62 lines
3.2 KiB
Python
from pathlib import Path
|
|
import ast, csv, io, hashlib, json, re
|
|
|
|
ROOT=Path(__file__).resolve().parents[3]
|
|
OUT=ROOT/'HEROLL_OUTGAME_DEV_v1.0'
|
|
OLD=ROOT/'HEROLL_OUTGAME_2.0.1'
|
|
CORE=ROOT/'HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive'
|
|
SOURCE=CORE/'resource-tables/extracted/csv'
|
|
LOC=CORE/'unity/assets/bin/Data/65724e71f83a175409c383f97a5a8ed9'
|
|
|
|
def sha(p): return hashlib.sha256(p.read_bytes()).hexdigest()
|
|
def snapshot():
|
|
return {p.relative_to(OLD).as_posix():dict(size=p.stat().st_size,mtime_ns=p.stat().st_mtime_ns,sha256=sha(p)) for p in OLD.rglob('*') if p.is_file()}
|
|
def constants(path):
|
|
result={}
|
|
for node in ast.parse(path.read_text(encoding='utf-8')).body:
|
|
if isinstance(node,ast.Assign) and len(node.targets)==1 and isinstance(node.targets[0],ast.Name):
|
|
try: result[node.targets[0].id]=ast.literal_eval(node.value)
|
|
except (ValueError,TypeError): pass
|
|
return result
|
|
def write(p,s):
|
|
assert p.resolve().is_relative_to(OUT.resolve()),p
|
|
p.parent.mkdir(parents=True,exist_ok=True); p.write_text(s,encoding='utf-8')
|
|
def savecsv(p,rows,fields=None):
|
|
assert p.resolve().is_relative_to(OUT.resolve()),p
|
|
p.parent.mkdir(parents=True,exist_ok=True)
|
|
if fields is None: fields=list(rows[0]) if rows else ['说明']
|
|
with p.open('w',encoding='utf-8-sig',newline='') as f:
|
|
w=csv.DictWriter(f,fieldnames=fields);w.writeheader();w.writerows(rows)
|
|
def md(headers,rows):
|
|
def esc(x): return str(x).replace('|','\\|').replace('\r','').replace('\n','<br>').replace('<sprite','<sprite')
|
|
return '| '+' | '.join(headers)+' |\n| '+' | '.join(['---']*len(headers))+' |\n'+''.join('| '+' | '.join(esc(v) for v in row)+' |\n' for row in rows)
|
|
def load():
|
|
c=constants(OLD/'99-审计与证据/工具/build_outgame.py')
|
|
modules=[]
|
|
for line in c['SPECS'].strip().splitlines():
|
|
k,name,tables,role,flow,unknown,terms=line.split('|')
|
|
modules.append(dict(id=k,name=name,folder=k+'-'+name,tables=tables.split(),role=role,flow=flow,unknown=c['DETAILS'].get(k,unknown),facts=c['FACTS'][k]))
|
|
tables={}
|
|
for p in sorted(SOURCE.glob('*.csv')):
|
|
with p.open(encoding='utf-8-sig',newline='') as f: raw=list(csv.reader(f))
|
|
h=next(i for i,r in enumerate(raw) if 'Id' in r and 'StringId' in r)
|
|
assert all(len(r)==len(raw[h]) for r in raw[h+2:] if any(r)),p
|
|
tables[p.stem]=dict(headers=raw[h],types=raw[h+1],comments=raw[h-1],rows=[dict(zip(raw[h],r)) for r in raw[h+2:] if any(r)])
|
|
text=LOC.read_bytes().decode('utf-8',errors='ignore').replace('\r\n','\n')
|
|
marker=',ko,en,ja,zh-tw,it,fr,th,tl,zh-cn,es,de,id\n'
|
|
start=text.index(marker)+len(marker); local={}
|
|
for row in csv.reader(io.StringIO(text[start:])):
|
|
if len(row)!=13: continue
|
|
key=row[0].strip('\x00 ')
|
|
if key and re.fullmatch(r'[A-Za-z0-9_. -]+',key):
|
|
local[key]={'zh':row[9],'en':row[2],'tw':row[4]}
|
|
return modules,tables,local,c
|
|
|
|
if __name__=='__main__':
|
|
modules,tables,local,c=load()
|
|
print('localization_entries',len(local))
|
|
for name in ['equipment','relic','pet','mount','starchallenge','item']:
|
|
print(name)
|
|
for r in tables[name]['rows'][:4]:
|
|
print(r['StringId'],[(k,local[v]['zh']) for k,v in r.items() if v in local and local[v]['zh']][:4])
|