全站通知:

模块:Dialogue/data/doc

来自站务
跳到导航 跳到搜索
[ 刷新 ]
当前页面是文档页面,会被模块:Dialogue/data引入。查看模板:Documentation获取更多信息。

文件转换

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