全站通知:
模块:Dialogue/data/doc
刷
历
编
< 模块:Dialogue | data
跳到导航
跳到搜索
文件转换
import json
from pathlib import Path
class DialogueMerger:
SUBDIRS = [
"Characters/Dialogue",
# "Data/Events",
"Data/Festivals",
"Strings/schedules"
]
SPECIFIC_FILES = [
"Strings/1_6_Strings.zh-CN.json",
"Strings/animationDescriptions.zh-CN.json",
"Strings/Characters.zh-CN.json",
"Strings/Events.zh-CN.json",
"Strings/SpeechBubbles.zh-CN.json",
"Strings/StringsFromCSFiles.zh-CN.json"
]
def __init__(self):
self.base_dir = Path(__file__).parent
self.output_file = self.base_dir / "merged_dialogues.json"
self.merged_data = {}
self.processed_files = []
self.failed_files = []
def process_json_file(self, json_file, file_key):
try:
with open(json_file, 'r', encoding='utf-8') as f:
content = json.load(f)
if isinstance(content, dict):
content = {
"order": list(content.keys()),
"data": content
}
self.merged_data[file_key] = content
self.processed_files.append(file_key)
return True
except Exception as e:
self.failed_files.append((file_key, str(e)))
return False
def process_subdirectories(self):
for subdir in self.SUBDIRS:
subdir_path = self.base_dir / subdir
if not subdir_path.exists():
continue
for json_file in subdir_path.glob("*.zh-CN.json"):
relative_path = json_file.relative_to(self.base_dir)
file_key = str(relative_path).replace("\\", "/").replace(".zh-CN.json", "")
self.process_json_file(json_file, file_key)
def process_specific_files(self):
for file_path in self.SPECIFIC_FILES:
json_file = self.base_dir / file_path
if not json_file.exists():
continue
file_key = file_path.replace("\\", "/").replace(".zh-CN.json", "")
self.process_json_file(json_file, file_key)
def save_merged_file(self):
try:
with open(self.output_file, 'w', encoding='utf-8') as f:
json.dump(self.merged_data, f, ensure_ascii=False, indent=2)
return True
except Exception as e:
print(f"❌ 保存失败: {e}")
return False
def print_summary(self):
print(f"\n{'='*50}")
print(f"✅ 成功处理: {len(self.processed_files)} 个文件")
if self.failed_files:
print(f"❌ 失败: {len(self.failed_files)} 个文件")
for file_key, error in self.failed_files:
print(f" - {file_key}: {error}")
file_size = self.output_file.stat().st_size / 1024
unit = "KB" if file_size < 1024 else "MB"
size_value = file_size if unit == "KB" else file_size / 1024
print(f"\n📄 输出文件: {self.output_file.name}")
print(f"📦 文件大小: {size_value:.2f} {unit}")
print(f"{'='*50}")
def merge(self):
print("🔍 扫描文件中...\n")
self.process_subdirectories()
self.process_specific_files()
if not self.merged_data:
print("❌ 未找到任何文件")
return False
if self.save_merged_file():
self.print_summary()
return True
return False
def main():
print("=" * 50)
print("📝 对话文件合并工具")
print("=" * 50 + "\n")
merger = DialogueMerger()
success = merger.merge()
return 0 if success else 1
if __name__ == "__main__":
exit(main())
import json
import re
from pathlib import Path
from typing import Any
class JsonToLuaConverter:
LUA_KEYWORDS = {
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for',
'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
'return', 'then', 'true', 'until', 'while'
}
def __init__(self):
self.base_dir = Path(__file__).parent
self.converted_files = []
self.failed_files = []
@staticmethod
def escape_string(s: str) -> str:
if not isinstance(s, str):
return str(s)
return s.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r').replace('\t', '\\t')
@classmethod
def is_keyword(cls, s: str) -> bool:
return s in cls.LUA_KEYWORDS
def format_value(self, value: Any, indent_level: int = 0) -> str:
indent = "\t" * indent_level
if isinstance(value, dict):
if not value:
return "{}"
lines = ["{"]
for k, v in value.items():
if not k.isidentifier() or re.match(r'^\d', k) or self.is_keyword(k):
key_str = f'["{self.escape_string(k)}"]'
else:
key_str = k
value_str = self.format_value(v, indent_level + 1)
lines.append(f"{indent}\t{key_str} = {value_str},")
lines.append(f"{indent}}}")
return "\n".join(lines)
elif isinstance(value, (list, tuple)):
if not value:
return "{}"
lines = ["{"]
for item in value:
value_str = self.format_value(item, indent_level + 1)
lines.append(f"{indent}\t{value_str},")
lines.append(f"{indent}}}")
return "\n".join(lines)
elif isinstance(value, str):
return f'"{self.escape_string(value)}"'
elif isinstance(value, bool):
return "true" if value else "false"
elif isinstance(value, (int, float)):
return str(value)
elif value is None:
return "nil"
else:
return f'"{self.escape_string(str(value))}"'
def convert_file(self, json_file: Path) -> bool:
try:
with open(json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
lua_file = json_file.with_suffix('.lua')
lua_content = [
"local data = " + self.format_value(data),
"",
"return data"
]
with open(lua_file, 'w', encoding='utf-8') as f:
f.write("\n".join(lua_content))
self.converted_files.append((json_file.name, lua_file.name, lua_file.stat().st_size))
return True
except Exception as e:
self.failed_files.append((json_file.name, str(e)))
return False
def convert_all(self):
json_files = list(self.base_dir.glob("*.json"))
if not json_files:
print("❌ 未找到任何 JSON 文件")
return False
for json_file in json_files:
self.convert_file(json_file)
return True
def print_summary(self):
print(f"\n{'='*50}")
print(f"✅ 成功转换: {len(self.converted_files)} 个文件")
if self.converted_files:
total_size = sum(size for _, _, size in self.converted_files)
size_mb = total_size / (1024 * 1024)
print(f"📦 总大小: {size_mb:.2f} MB\n")
for json_name, lua_name, size in self.converted_files:
size_kb = size / 1024
print(f" {json_name} → {lua_name} ({size_kb:.2f} KB)")
if self.failed_files:
print(f"\n❌ 失败: {len(self.failed_files)} 个文件")
for file_name, error in self.failed_files:
print(f" - {file_name}: {error}")
print(f"{'='*50}")
def main():
print("=" * 50)
print("🔄 JSON 转 Lua 转换器")
print("=" * 50 + "\n")
converter = JsonToLuaConverter()
if converter.convert_all():
converter.print_summary()
return 0
return 1
if __name__ == "__main__":
exit(main())

沪公网安备 31011002002714 号