wess09/dev_tools/utils.py

192 lines
5.3 KiB
Python
Raw Normal View History

import os
import re
from tqdm import tqdm
2022-04-14 16:37:54 -03:00
from dev_tools.slpp import slpp
class LuaLoader:
"""
Load decrypted scripts
"""
server_alias = [
['zh-CN', 'zh-cn', 'cn', 'CN'],
['en-US', 'en-us', 'en', 'EN'],
['ja-JP', 'ja-jp', 'jp', 'JP'],
['zh-TW', 'zh-tw', 'tw', 'TW'],
['ko-KR', 'ko-kr', 'kr', 'KR'],
]
def __init__(self, folder, server='zh-CN'):
2024-06-28 03:19:37 +08:00
self.folder = folder
self._server = ''
self.server = server
@property
def server(self):
return self._server
@server.setter
def server(self, value):
self._server = self.get_alias(value)
def get_alias(self, server):
for alias_list in self.server_alias:
if server in alias_list:
for alias in alias_list:
folder = os.path.join(self.folder, alias)
if os.path.exists(folder) and os.path.isdir(folder):
return alias
return server
def filepath(self, path):
return os.path.join(self.folder, self.server, path)
def _find_matching_brace(self, text, start_index):
depth = 0
in_string = None
escape = False
for i in range(start_index, len(text)):
ch = text[i]
if in_string:
if escape:
escape = False
elif ch == '\\':
escape = True
elif ch == in_string:
in_string = None
else:
if ch in ('"', "'"):
in_string = ch
elif ch == '{':
depth += 1
elif ch == '}':
depth -= 1
if depth == 0:
return i
return -1
def _infer_base_name(self, file, keyword):
if keyword:
keyword = keyword.strip()
if keyword.startswith('pg.base.'):
return keyword[len('pg.base.'):]
if keyword.startswith('pg.'):
return keyword[len('pg.'):]
return keyword
return os.path.splitext(os.path.basename(file))[0]
def _load_pg_base_entries(self, text, base_name):
pattern = rf"pg\.base\.{re.escape(base_name)}\[(\d+)\]\s*=\s*\{{"
result = {}
for m in re.finditer(pattern, text):
start = m.end() - 1
end = self._find_matching_brace(text, start)
if end == -1:
continue
table_text = text[start:end + 1]
result[int(m.group(1))] = slpp.decode(table_text)
return result
def _load_file(self, file, keyword=None):
"""
Args:
file (str):
Returns:
dict:
"""
with open(self.filepath(file), 'r', encoding='utf-8') as f:
text = f.read()
if 'pg.base.' in text:
base_name = self._infer_base_name(file, keyword)
if not base_name:
m = re.search(r"pg\.base\.([A-Za-z0-9_]+)\[", text)
base_name = m.group(1) if m else None
if base_name:
result = self._load_pg_base_entries(text, base_name)
if result:
return result
result = {}
2025-12-18 18:00:39 +08:00
matched = re.findall('function \(\)(.*?)end[()]', text, re.S)
if matched:
# Most files are in this format
"""
pg = pg or {}
slot0 = pg
slot0.chapter_template = {}
(function ()
...
end)()
"""
for func in matched:
add = slpp.decode('{' + func + '}')
result.update(add)
elif text.startswith('pg'):
# Old format
"""
pg = pg or {}
pg.item_data_statistics = {
...
}
"""
# or
"""
pg = pg or {}
rawset(pg, "item_data_statistics", rawget(pg, "item_data_statistics") or {
...
}
"""
text = '{' + text.split('{', 2)[2]
result = slpp.decode(text)
else:
2025-12-18 18:00:39 +08:00
# Another format, just bare data
"""
_G.pg.expedition_data_template[...] = {
...
}
_G.pg.expedition_data_template[...] = {
...
}
...
"""
text = '{' + text + '}'
result = slpp.decode(text)
return result
def load(self, path, keyword=None):
"""
Load a lua file to python dictionary, handling the differences
Args:
path (str): Relavice path from {folder}/{server}.
Can be a file or a directory
Returns:
dict:
"""
print(f'Loading {path}')
if os.path.isdir(self.filepath(path)):
result = {}
for file in tqdm(os.listdir(self.filepath(path))):
result.update(self._load_file(f'./{path}/{file}', keyword=keyword))
else:
result = self._load_file(path, keyword=keyword)
print(f'{len(result.keys())} items loaded')
return result
if __name__ == '__main__':
# Use example
lua = LuaLoader(r'xxx/AzurLaneData', server='en-US')
res = lua.load('./sharecfg/item_data_statistics.lua')