def load_from_rawxls(file_path):
    """从 xlsx 文件恢复数据到 lang.csv 的格式

    xlsx 文件可能是 <name, desc> 模式,也可能是 list<text> 模式。

    Args:
        file_path (str): xlsx 文件路径

    Returns:
        category (str): category from lang_def
        csv_data (list[str]): list of [file_id, unknown, index, text],不带前导0
    """

    data = load_xls(file_path)[1:]
    # 判断文件模式
    id_split = data[0][1].split('-')
    if len(id_split) > 3 and id_split[-1].isdigit() and id_split[-2].isdigit(
    ) and id_split[-3].isdigit():
        # list of text
        return load_from_list_category(data)
    elif len(id_split) > 1 and id_split[-1].isdigit():
        # name_desc
        return load_from_pair_category(data)
    else:
        log.error('load %s failed.' % file_path)
        return '', []
Example #2
0
def main():
    lang = 'zh'

    if len(sys.argv) != 2:
        usage()
        sys.exit(2)

    xls_path = sys.argv[1]

    cd = sys.path[0]
    translation_path = os.path.join(cd, '../translation')
    translate_file = os.path.join(translation_path, '%s_translate.txt' % lang)

    ui_mgr = UiMgr()

    # load lua
    pregame_src = os.path.join(translation_path, 'en_pregame.lua')
    ui_mgr.load_lua_file(pregame_src)

    client_src = os.path.join(translation_path, 'en_client.lua')
    ui_mgr.load_lua_file(client_src)

    # load translation
    data_from_xls = load_xls(xls_path)
    ui_mgr.apply_translate_from_xls(data_from_xls, need_check=False)

    # save result
    txt_lines = ui_mgr.get_txt_lines(replace=True)
    with open(translate_file, 'wt', encoding='utf-8') as fp:
        fp.writelines(txt_lines)
        log.info('save translate file succeed.')
def main():
    lang = 'zh'

    if len(sys.argv) != 2:
        usage()
        sys.exit(2)

    xls_path = sys.argv[1]

    cd = sys.path[0]
    translation_path = os.path.join(cd, '../translation')
    translate_file = os.path.join(translation_path, '%s_translate.txt' % lang)

    ui_mgr = UiMgr()

    # load lua
    pregame_src = os.path.join(translation_path, 'en_pregame.lua')
    ui_mgr.load_lua_file(pregame_src)

    client_src = os.path.join(translation_path, 'en_client.lua')
    ui_mgr.load_lua_file(client_src)

    # load translation
    data_from_xls = load_xls(xls_path)
    ui_mgr.apply_translate_from_xls(data_from_xls)
    ui_mgr.apply_translate_from_xls(data_from_xls)

    # save result
    txt_lines = ui_mgr.get_txt_lines(replace=True)
    with open(translate_file, 'wt', encoding='utf-8') as fp:
        fp.writelines(txt_lines)
        print('save translate file succeed.')
Example #4
0
def load_from_langxls(file_path, lang, need_check=False, load_ui=False):
    """从 xlsx 文件中读取 lang.csv 的翻译

    xlsx 文件可能是 <name, desc> 模式,也可能是 list<text> 模式。

    Args:
        file_path (str): xlsx 文件路径
        lang (str): "zh"/"en", 读中文还是英文
        need_check (bool): 是否检查
        load_ui (bool): 是否读取ui汉化文件的内容

    Returns:
        category (str): category from lang_def
        translated_data (list[str]): list of [file_id, unknown, index, text],不带前导0
    """

    data = load_xls(file_path)[1:]
    # 判断文件模式
    id_split = data[0][1].split('-')
    if len(id_split) > 3 and id_split[-1].isdigit() and id_split[-2].isdigit() and id_split[-3].isdigit():
        # list of text
        return load_from_list_category(data, lang, need_check)
    elif len(id_split) > 1 and id_split[-1].isdigit():
        # name_desc
        return load_from_pair_category(data, lang, need_check)
    elif len(id_split) == 1 and '_' in id_split[0] \
            and id_split[0][0].isalpha() and id_split[0][-1].isalpha():
        if load_ui:
            return load_from_ui_fake(data, lang, need_check)
        else:
            log.info('skip ui file %s.' % file_path)
            return '', []
    else:
        log.error('load %s failed.' % file_path)
        return '', []
Example #5
0
def load_from_rawxls(file_path):
    """从 xlsx 文件恢复数据到 lang.csv 的格式

    xlsx 文件可能是 <name, desc> 模式,也可能是 list<text> 模式。

    Args:
        file_path (str): xlsx 文件路径

    Returns:
        category (str): category from lang_def
        csv_data (list[str]): list of [file_id, unknown, index, text],不带前导0
    """

    data = load_xls(file_path)[1:]
    # 判断文件模式
    id_split = data[0][1].split('-')
    if len(id_split) > 3 and id_split[-1].isdigit() and id_split[-2].isdigit() and id_split[-3].isdigit():
        # list of text
        return load_from_list_category(data)
    elif len(id_split) > 1 and id_split[-1].isdigit():
        # name_desc
        return load_from_pair_category(data)
    else:
        log.error('load %s failed.' % file_path)
        return '', []
Example #6
0
def check_xls(src_path, column_id, origin_column_id):
    """检查xls

    Args:
        src_path (str): 待检查的 xlsx 文件的路径
        column_id (int): 翻译后的列的 id
        origin_column_id (int): 原文的列的 id
    """
    data = load_xls(src_path)
    for line in data:
        text_is_ok = False
        try:
            text_to_check = line[column_id]
            # skip empty line
            if text_to_check == '':
                continue
            text_is_ok = check_string(text_to_check)
            if origin_column_id is not None:
                text_is_ok &= check_string_with_origin(line[column_id],
                                                       line[origin_column_id])
        except Exception as e:
            log.warning(line)
            log.warning(e)
        if not text_is_ok:
            log.warning('Failed when checking:\n%s\n' % ', '.join(line))
Example #7
0
def join_all_xls(file_path):
    """合并文件夹里的所有 xls 文件,合并成两类

    Args:
        file_path (str): 要遍历的路径

    Returns:
        data_pair (list): pair 格式的数据
        data_list (list): list 格式的数据
    """
    data_pair = []
    data_list = []

    for filename in walk_xlsx_files(file_path):
        # 读取数据
        data = load_xls(filename)
        category = get_category_of_id(data[1][1])
        # 判断是哪一类
        if category in lang_def.file_id_of_pair:
            if len(data_pair) > 0:  # header 只留一次
                data = data[1:]
            data_pair.extend(data)
        else:
            if len(data_list) > 0:
                data = data[1:]
            data_list.extend(data)
    return data_pair, data_list
Example #8
0
def merge_translation_file(dest_xls_path,
                           src_xls_path,
                           conflict_xls_file,
                           check_category=True):
    """合并两个文件中的数据,写回 dest 文件

    Args:
        dest_xls_path (str): 合并目标文件路径,当发生冲突时以此文件为准
        src_xls_path (str): 合并源文件路径
        conflict_xls_file (str | None): 冲突数据存放文件
        check_category (bool): 检查类型是否相等
    """

    # check category
    if check_category:
        category = get_category(dest_xls_path)
        category_src = get_category(src_xls_path)
        if category != category_src:
            log.error('category not equal.')
            raise RuntimeError('category not equal.')

    # load
    log.info('load %s' % dest_xls_path)
    dest_data = load_xls(dest_xls_path)
    header, dest_data = dest_data[0], dest_data[1:]
    log.info('load %s' % src_xls_path)
    src_data = load_xls(src_xls_path)[1:]

    category = get_category_of_id(dest_data[0][1])

    # merge
    merged_data, conflict_data = merge_translation_data(
        category, dest_data, src_data)

    # sort
    merged_data = sorted(merged_data, key=lambda row: row[1])
    conflict_data = sorted(conflict_data, key=lambda row: row[1])

    # save
    log.info('%d conflicts.' % len(conflict_data))
    log.info('save %s' % dest_xls_path)
    save_xlsx(dest_xls_path, merged_data, header=header)
    if conflict_xls_file is not None and len(conflict_data) > 0:
        log.info('save %s' % conflict_xls_file)
        save_xlsx(conflict_xls_file, conflict_data, header=header)
Example #9
0
def merge_translation_file(dest_xls_path, src_xls_path, conflict_xls_file, check_category=True):
    """合并两个文件中的数据,写回 dest 文件

    Args:
        dest_xls_path (str): 合并目标文件路径,当发生冲突时以此文件为准
        src_xls_path (str): 合并源文件路径
        conflict_xls_file (str | None): 冲突数据存放文件
        check_category (bool): 检查类型是否相等
    """

    # check category
    if check_category:
        category = get_category(dest_xls_path)
        category_src = get_category(src_xls_path)
        if category != category_src:
            log.error('category not equal.')
            raise RuntimeError('category not equal.')

    # load
    log.info('load %s' % dest_xls_path)
    dest_data = load_xls(dest_xls_path)
    header, dest_data = dest_data[0], dest_data[1:]
    log.info('load %s' % src_xls_path)
    src_data = load_xls(src_xls_path)[1:]

    category = get_category_of_id(dest_data[0][1])

    # merge
    merged_data, conflict_data = merge_translation_data(category, dest_data, src_data)

    # sort
    merged_data = sorted(merged_data, key=lambda row: row[1])
    conflict_data = sorted(conflict_data, key=lambda row: row[1])

    # save
    log.info('%d conflicts.' % len(conflict_data))
    log.info('save %s' % dest_xls_path)
    save_xlsx(dest_xls_path, merged_data, header=header)
    if conflict_xls_file is not None and len(conflict_data) > 0:
        log.info('save %s' % conflict_xls_file)
        save_xlsx(conflict_xls_file, conflict_data, header=header)
Example #10
0
def apply_format(file_path):
    """xlsx 套用格式"""
    data = load_xls(file_path)
    if len(data) < 2:
        return
    header = data[0]
    data = data[1:]
    if len(header) in (8, 9, 12):
        save_xlsx_template(file_path, data, header=header)
    else:
        print('unknown xls %s.' % file_path)
    print('save %s' % file_path)
Example #11
0
def apply_format(file_path):
    """xlsx 套用格式"""
    log.debug('start %s' % file_path)
    data = load_xls(file_path)
    if len(data) < 2:
        return
    header = data[0]
    data = data[1:]
    if len(header) in (8, 9, 12):
        save_xlsx_template(file_path, data, header=header)
        log.info('save %s' % file_path)
    else:
        log.error('unknown xls %s.' % file_path)
Example #12
0
def apply_format(file_path):
    """xlsx 套用格式"""
    log.debug('start %s' % file_path)
    data = load_xls(file_path)
    if len(data) < 2:
        return
    header = data[0]
    data = data[1:]
    if len(header) in (8, 9, 12):
        save_xlsx_template(file_path, data, header=header)
        log.info('save %s' % file_path)
    else:
        log.error('unknown xls %s.' % file_path)
Example #13
0
def merge_translation_file(dest_xls_path, src_xls_path, conflict_xls_file):
    """合并两个文件中的数据,写回 dest 文件

    Args:
        dest_xls_path (str): 合并目标文件路径,当发生冲突时以此文件为准
        src_xls_path (str): 合并源文件路径
        conflict_xls_file (str | None): 冲突数据存放文件
    """

    # load
    print('load %s' % dest_xls_path)
    dest_data = load_xls(dest_xls_path)
    header, dest_data = dest_data[0], dest_data[1:]
    print('load %s' % src_xls_path)
    src_data = load_xls(src_xls_path)[1:]

    # check
    if not (dest_data[0][1].startswith('SI_')
            and src_data[0][1].startswith('SI_')):
        raise RuntimeError('invalid ui xls file')

    # merge
    merged_data, conflict_data = merge_translation_by_col(
        dest_data,
        src_data,
        id_col=1,
        origin_col_ids=[
            2,
        ],
        translation_col_ids=[3, 4, 5, 6, 7])

    # save
    print('%d conflicts.' % len(conflict_data))
    print('save %s' % dest_xls_path)
    save_xlsx(dest_xls_path, merged_data, header=header)
    if conflict_xls_file is not None and len(conflict_data) > 0:
        print('save %s' % conflict_xls_file)
        save_xlsx(conflict_xls_file, conflict_data, header=header)
Example #14
0
def merge_diff_files(files, output_path):
    """按要求合并翻译文件,并写入文件"""
    if len(files) <= 0:
        return

    header = None
    all_diff_data = []
    for filename in files:
        log.info('loading %s...' % os.path.basename(filename))
        diff_data = load_xls(filename)
        header, diff_data = diff_data[0], diff_data[1:]
        all_diff_data.extend(diff_data)

    # 去空
    category = get_category_of_id(all_diff_data[0][1])
    if category in lang_def.file_id_of_array or category in lang_def.file_id_of_list:
        all_diff_data = [row for row in all_diff_data if row[4] != '']
    elif category in lang_def.file_id_of_pair:
        all_diff_data = [row for row in all_diff_data if row[4] + row[7] != '']
    else:
        log.error('unknown category %s.' % category)
        raise RuntimeError('unknown category')

    # 去重
    all_diff_data_by_id = {}
    for row in all_diff_data:
        row = tuple(row)
        key = row[0]
        if key not in all_diff_data_by_id:
            all_diff_data_by_id[key] = {row}
        else:
            if row not in all_diff_data_by_id:
                all_diff_data_by_id[key].add(row)

    # 按顺序重排
    all_diff_data = []
    for _, rows_set in sorted(all_diff_data_by_id.items()):
        all_diff_data.extend(rows_set)

    output_name = os.path.basename(output_path)
    if len(all_diff_data) > 0:
        log.info('saving %s...' % output_name)
        save_xlsx(output_path, all_diff_data, header=header)
    else:
        log.info('skip %s' % output_name)
Example #15
0
def merge_diff_files(files, output_path):
    """按要求合并翻译文件,并写入文件"""
    if len(files) <= 0:
        return

    header = None
    all_diff_data = []
    for filename in files:
        log.info('loading %s...' % os.path.basename(filename))
        diff_data = load_xls(filename)
        header, diff_data = diff_data[0], diff_data[1:]
        all_diff_data.extend(diff_data)

    # 去空
    category = get_category_of_id(all_diff_data[0][1])
    if category in lang_def.file_id_of_array or category in lang_def.file_id_of_list:
        all_diff_data = [row for row in all_diff_data if row[4] != '']
    elif category in lang_def.file_id_of_pair:
        all_diff_data = [row for row in all_diff_data if row[4] + row[7] != '']
    else:
        log.error('unknown category %s.' % category)
        raise RuntimeError('unknown category')

    # 去重
    all_diff_data_by_id = {}
    for row in all_diff_data:
        row = tuple(row)
        key = row[0]
        if key not in all_diff_data_by_id:
            all_diff_data_by_id[key] = {row}
        else:
            if row not in all_diff_data_by_id:
                all_diff_data_by_id[key].add(row)

    # 按顺序重排
    all_diff_data = []
    for _, rows_set in sorted(all_diff_data_by_id.items()):
        all_diff_data.extend(rows_set)

    output_name = os.path.basename(output_path)
    if len(all_diff_data) > 0:
        log.info('saving %s...' % output_name)
        save_xlsx(output_path, all_diff_data, header=header)
    else:
        log.info('skip %s' % output_name)
Example #16
0
def main():
    if len(sys.argv) not in (2, 3):
        usage()
        sys.exit(2)

    # init path
    input_path = sys.argv[1]
    if len(sys.argv) == 3:
        output_path = sys.argv[2]
    else:
        if input_path.lower().endswith('.xlsx'):
            output_path = input_path[:-5] + '.csv'
        else:
            output_path = input_path + '.csv'

    # convert
    print(input_path, output_path)
    csv_data = load_xls(input_path)
    lines = []
    for row in csv_data:
        lines.append('\t'.join(row) + '\n')
    with open(output_path, 'wt', encoding='utf-8') as fp:
        fp.writelines(lines)
Example #17
0
def check_xls(src_path, column_id, origin_column_id):
    """检查xls

    Args:
        src_path (str): 待检查的 xlsx 文件的路径
        column_id (int): 翻译后的列的 id
        origin_column_id (int): 原文的列的 id
    """
    data = load_xls(src_path)
    for line in data:
        text_is_ok = False
        try:
            text_to_check = line[column_id]
            # skip empty line
            if text_to_check == '':
                continue
            text_is_ok = check_string(text_to_check)
            if origin_column_id is not None:
                text_is_ok &= check_string_with_origin(line[column_id], line[origin_column_id])
        except Exception as e:
            log.warning(line)
            log.warning(e)
        if not text_is_ok:
            log.warning('Failed when checking:\n%s\n' % ', '.join(line))
Example #18
0
def main():
    if len(sys.argv) not in (2, 3):
        usage()
        sys.exit(2)

    # init path
    input_path = sys.argv[1]
    if len(sys.argv) == 3:
        output_path = sys.argv[2]
    else:
        if input_path.lower().endswith('.xlsx'):
            output_path = input_path[:-5] + '.csv'
        else:
            output_path = input_path + '.csv'

    # convert
    log.info('input path: %s' % input_path)
    log.info('out path: %s' % output_path)
    csv_data = load_xls(input_path)
    lines = []
    for row in csv_data:
        lines.append('\t'.join(row) + '\n')
    with open(output_path, 'wt', encoding='utf-8') as fp:
        fp.writelines(lines)
Example #19
0
def gen_chs():
    """1. 简体"""
    NEED_CLEAR = True
    log.info(os.getcwd())

    if NEED_CLEAR:
        print('### 正在清理...')
        log.debug('正在清理...')
        # 清理输出目录
        dirs = ('../../输出/生成简体插件/', )
        for dir in dirs:
            if os.path.exists(dir):
                log.info('clear %s' % dir)
                shutil.rmtree(dir)
        # 清理翻译中间目录
        log.info('clear csv and xlsx')
        for root, dirs, files in os.walk('../../translation/lang/translated/'):
            for f in files:
                if f.endswith('.csv') or f.endswith('.xlsx') or f.endswith(
                        '.lang'):
                    filename = os.path.join(root, f)
                    log.debug('remove %s' % filename)
                    os.remove(filename)
            break
        for root, dirs, files in os.walk('../../translation/'):
            for f in files:
                if f.endswith('.csv') or f.endswith('.xlsx'):
                    filename = os.path.join(root, f)
                    log.debug('remove %s' % filename)
                    os.remove(filename)
            break
        files = (
            '../../translation/zh_translate.txt',
            '../../translation/zh_translate.xlsx',
        )
        for f in files:
            if os.path.exists(f):
                log.debug('remove %s' % f)
                os.remove(f)

    print('### 创建目录...')
    log.debug('创建目录...')
    dirs = ('../../输出/生成简体插件/', )
    for dir in dirs:
        if not os.path.isdir(dir):
            log.info('create %s' % dir)
            os.makedirs(dir)

    print('### 拷贝文件...')
    log.debug('拷贝文件...')
    for root, dirs, files in os.walk('汉化xlsx/'):
        for f in files:
            if f.endswith('.xlsx') and not f.startswith('~'):
                filename = os.path.join(root, f)
                data = load_xls(filename)
                if len(data[1]) == 8:  # ui 汉化文件
                    dst = '../../translation/'
                    ui_xls_file = f
                    log.info('copy %s to %s' % (filename, dst))
                    shutil.copy(filename, dst)
                dst = '../../translation/lang/translated/'
                log.info('copy %s to %s' % (filename, dst))
                shutil.copy(filename, dst)

    os.chdir('../../scripts/')
    log.info(os.getcwd())
    print('### 转换UI文本...')
    log.debug('转换UI文本...')
    execute('python export_uixls_to_txt.py ../translation/%s' % ui_xls_file)
    execute('python convert_txt_to_str.py -m translation')

    print('### 转换其他文本...')
    log.debug('转换其他文本...')
    execute('python export_langxls_to_csv.py')

    os.chdir('../translation/lang/translated/')
    log.info(os.getcwd())
    print('### 正在编码...')
    log.debug('正在编码...')
    execute('EsoExtractData.exe -x zh.lang.csv')

    print('### 正在校验...')
    log.debug('正在校验...')
    shutil.copy('zh.lang', 'zh1.lang')
    execute('EsoExtractData -l zh1.lang')
    num1 = get_linenum('../en.lang.csv')
    num2 = get_linenum('zh.lang.csv')
    num3 = get_linenum('zh1.lang.csv')
    log.info('validate line num: %d, %d, %d' % (num1, num2, num3))
    if not num1 == num2 == num3:
        log.error('校验失败')
        sys.exit(-1)

    os.chdir('../../../')
    log.info(os.getcwd())
    print('### 正在打包...')
    log.debug('正在打包...')
    log.info('copy AddOns')
    shutil.copytree('AddOns/', '输出/生成简体插件/AddOns')
    log.info('copy lang')
    shutil.copy('translation/lang/translated/zh.lang',
                '输出/生成简体插件/AddOns/gamedata/lang/')
    log.info('copy readme')
    shutil.copy('工具/生成插件/README_chs.txt', '输出/生成简体插件/README.txt')
    log.info('clear AddOns')
    os.remove('输出/生成简体插件/AddOns/EsoUI/lang/.gitignore')
    os.remove('输出/生成简体插件/AddOns/EsoZH/fonts/README.md')
    os.remove('输出/生成简体插件/AddOns/gamedata/lang/.gitignore')

    os.chdir('输出/生成简体插件/')
    log.info(os.getcwd())
    with open('README.txt', 'rt', encoding='utf-8') as fp:
        desc = fp.read()
    zip_name = 'ESO汉化插件.zip'
    zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
    zipf.comment = bytes(desc, encoding='gbk')
    for root, dirs, files in os.walk('.'):
        for f in files:
            if f != zip_name:
                zipf.write(os.path.join(root, f))
    zipf.close()
Example #20
0
def gen_chs():
    """1. 简体"""
    NEED_CLEAR = True
    log.info(os.getcwd())

    if NEED_CLEAR:
        print('### 正在清理...')
        log.debug('正在清理...')
        # 清理输出目录
        dirs = (
            '../../输出/生成简体插件/',
        )
        for dir in dirs:
            if os.path.exists(dir):
                log.info('clear %s' % dir)
                shutil.rmtree(dir)
        # 清理翻译中间目录
        log.info('clear csv and xlsx')
        for root, dirs, files in os.walk('../../translation/lang/translated/'):
            for f in files:
                if f.endswith('.csv') or f.endswith('.xlsx') or f.endswith('.lang'):
                    filename = os.path.join(root, f)
                    log.debug('remove %s' % filename)
                    os.remove(filename)
            break
        for root, dirs, files in os.walk('../../translation/'):
            for f in files:
                if f.endswith('.csv') or f.endswith('.xlsx'):
                    filename = os.path.join(root, f)
                    log.debug('remove %s' % filename)
                    os.remove(filename)
            break
        files = (
            '../../translation/zh_translate.txt',
            '../../translation/zh_translate.xlsx',
        )
        for f in files:
            if os.path.exists(f):
                log.debug('remove %s' % f)
                os.remove(f)

    print('### 创建目录...')
    log.debug('创建目录...')
    dirs = (
        '../../输出/生成简体插件/',
    )
    for dir in dirs:
        if not os.path.isdir(dir):
            log.info('create %s' % dir)
            os.makedirs(dir)

    print('### 拷贝文件...')
    log.debug('拷贝文件...')
    for root, dirs, files in os.walk('汉化xlsx/'):
        for f in files:
            if f.endswith('.xlsx') and not f.startswith('~'):
                filename = os.path.join(root, f)
                data = load_xls(filename)
                if len(data[1]) == 8:  # ui 汉化文件
                    dst = '../../translation/'
                    ui_xls_file = f
                    log.info('copy %s to %s' % (filename, dst))
                    shutil.copy(filename, dst)
                dst = '../../translation/lang/translated/'
                log.info('copy %s to %s' % (filename, dst))
                shutil.copy(filename, dst)

    os.chdir('../../scripts/')
    log.info(os.getcwd())
    print('### 转换UI文本...')
    log.debug('转换UI文本...')
    execute('python export_uixls_to_txt.py ../translation/%s' % ui_xls_file)
    execute('python convert_txt_to_str.py -m translation')

    print('### 转换其他文本...')
    log.debug('转换其他文本...')
    execute('python export_langxls_to_csv.py')

    os.chdir('../translation/lang/translated/')
    log.info(os.getcwd())
    print('### 正在编码...')
    log.debug('正在编码...')
    execute('EsoExtractData.exe -x zh.lang.csv')

    print('### 正在校验...')
    log.debug('正在校验...')
    shutil.copy('zh.lang', 'zh1.lang')
    execute('EsoExtractData -l zh1.lang')
    num1 = get_linenum('../en.lang.csv')
    num2 = get_linenum('zh.lang.csv')
    num3 = get_linenum('zh1.lang.csv')
    log.info('validate line num: %d, %d, %d' % (num1, num2, num3))
    if not num1 == num2 == num3:
        log.error('校验失败')
        sys.exit(-1)

    os.chdir('../../../')
    log.info(os.getcwd())
    print('### 正在打包...')
    log.debug('正在打包...')
    log.info('copy AddOns')
    shutil.copytree('AddOns/', '输出/生成简体插件/AddOns')
    log.info('copy lang')
    shutil.copy('translation/lang/translated/zh.lang', '输出/生成简体插件/AddOns/gamedata/lang/')
    log.info('copy readme')
    shutil.copy('工具/生成插件/README_chs.txt', '输出/生成简体插件/README.txt')
    log.info('clear AddOns')
    os.remove('输出/生成简体插件/AddOns/EsoUI/lang/.gitignore')
    os.remove('输出/生成简体插件/AddOns/EsoZH/fonts/README.md')
    os.remove('输出/生成简体插件/AddOns/gamedata/lang/.gitignore')

    os.chdir('输出/生成简体插件/')
    log.info(os.getcwd())
    with open('README.txt', 'rt', encoding='utf-8') as fp:
        desc = fp.read()
    zip_name = 'ESO汉化插件.zip'
    zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
    zipf.comment = bytes(desc, encoding='gbk')
    for root, dirs, files in os.walk('.'):
        for f in files:
            if f != zip_name:
                zipf.write(os.path.join(root, f))
    zipf.close()