Пример #1
0
    def __searchMark(self, filename):
        line_num = 0
        charset = self.__detectCharset(filename)
        regex = r'\s*?' + self.__options__['mark_format'] + r'\s*?'

        if '../../src/'.replace('/', os.path.sep) in filename and charset.upper() != 'UTF-8-SIG':
            Message.ShowWarning('期望文件 %s 的编码为 UTF-8-SIG 而实际上是 %s' % (filename, charset.upper()))
            return

        try:
            textfile = open(filename, encoding=charset)
            for line in textfile:
                line_num = line_num + 1
                if '//' not in line:
                    continue

                re_match = re.match(regex, line)
                if not re_match:
                    continue

                if str(re_match.group(1)) in self.mark_dict:
                    Message.ShowError('发现重复的代码注入标记: ' + re_match.group(0))
                    Common.exit_with_pause(-1)

                self.mark_dict[re_match.group(1)] = {
                    'index' : int(re_match.group(1)),
                    'filepath' : filename,
                    'line' : line_num
                }
            textfile.close()
        except Exception as err:
            Message.ShowError('文件 : %s | 错误信息 : %s' % (filename, err))
Пример #2
0
def process_sub(export_file, renewal, langinfo):
    print('')
    
    # 确认当前的版本号
    version = Common.get_pandas_ver(os.path.abspath(project_slndir), 'v')

    Message.ShowStatus('正在准备生成 {model} - {lang} 的打包目录...'.format(
        model = '复兴后(RE)' if renewal else '复兴前(PRE)',
        lang = langinfo['name']
    ))

    # 构建解压的打包目录
    packagedir = '../Release/Pandas/{version}/Pandas_{version}_{timestamp}_{model}_{lang}'.format(
        version = version, model = 'RE' if renewal else 'PRE',
        timestamp = Common.timefmt(True), lang = langinfo['dirname']
    )

    # 获取压缩文件的保存路径
    zipfilename = os.path.abspath(project_slndir + packagedir) + '.zip'

    # 获取打包的绝对路径
    packagedir = os.path.abspath(project_slndir + packagedir) + os.path.sep
    
    # 确保目标文件夹存在
    os.makedirs(os.path.dirname(packagedir), exist_ok = True)
    
    # 若之前目录已经存在, 先删掉
    if os.path.exists(packagedir) and os.path.isdir(packagedir):
        shutil.rmtree(packagedir)
    
    # 将 zip 文件解压到指定的目录中去
    Message.ShowStatus('正在解压归档文件到: %s' % os.path.relpath(
        packagedir, os.path.abspath(os.path.join(packagedir, r'../../'))
    ))
    if not zip_unpack(export_file, packagedir):
        clean(export_file)
        Message.ShowError('很抱歉, 解压归档文件失败, 程序终止.')
        Common.exit_with_pause(-1)
    
    # 进行文本的翻译工作
    trans.process(packagedir, langinfo['trans'], True)
    
    # 进行后期处理
    Message.ShowStatus('正在对打包源目录进行后期处理...')
    if renewal:
        arrange_renewal(packagedir)
    else:
        arrange_pre_renewal(packagedir)
    Message.ShowStatus('后期处理完毕, 即将把打包源压缩成 ZIP 文件...')
    
    # 执行打包操作
    if not zip_pack(packagedir, zipfilename):
        clean(export_file)
        Message.ShowError('打包成 zip 文件时失败了, 请联系开发者协助定位问题, 程序终止.')
        Common.exit_with_pause(-1)

    Message.ShowStatus('已成功构建 {model} - {lang} 的压缩文件.'.format(
        model = '复兴后(RE)' if renewal else '复兴前(PRE)',
        lang = langinfo['name']
    ))
Пример #3
0
    def requireSelect(self, options):
        print('-' * 70)
        select_name = options['name']
        select_data = options['data']
        Message.ShowSelect('请选择%s, 可选值为 [0~%d], 分别代表:' %
                           (select_name, len(select_data) - 1))
        print('')
        for select in select_data:
            Message.ShowMenu('%s' % select['desc'])
        print('')
        Message.ShowSelect('请选择%s [0~%d]:' %
                           (select_name, len(select_data) - 1),
                           end="")
        user_select = input()

        if not user_select or not user_select.isnumeric():
            Message.ShowError('您输入了无效的地图标记类型, 程序终止')
            print('-' * 70)
            Common.exitWithPause(-1)

        user_select = int(user_select)

        if user_select < 0 or user_select >= len(select_data):
            Message.ShowError('您输入了无效的地图标记类型, 程序终止')
            print('-' * 70)
            Common.exitWithPause(-1)

        print('')
        Message.ShowInfo('您选择的是: %s' % select_data[user_select]['name'])
        print('-' * 70)
        print('\n')
        return user_select
Пример #4
0
def compile_renewal(version):
    '''
    编译复兴后版本
    '''
    time.sleep(3)
    print('')

    define_options = {}

    if os.getenv("DEFINE_CRASHRPT_APPID"):
        define_options["CRASHRPT_APPID"] = '_CT(\\"%s\\")' % os.getenv(
            "DEFINE_CRASHRPT_APPID")
    if os.getenv("DEFINE_CRASHRPT_PUBLICKEY"):
        define_options["CRASHRPT_PUBLICKEY"] = '_CT(\\"%s\\")' % os.getenv(
            "DEFINE_CRASHRPT_PUBLICKEY")

    define_options["GIT_BRANCH"] = '\\"%s\\"' % Common.get_pandas_branch(
        project_slndir)
    define_options["GIT_HASH"] = '\\"%s\\"' % Common.get_pandas_hash(
        project_slndir)

    define_values = define_builder(define_options)

    if not compile_sub(define_values, '复兴后', version):
        Message.ShowError('编译复兴前版本时发生了一些错误, 请检查...')
        Common.exit_with_pause(-1)

    print('')
Пример #5
0
def main():
    os.chdir(os.path.split(os.path.realpath(__file__))[0])

    Common.welcome('版本号修改辅助脚本')

    print('')

    # 读取当前的 Pandas 主程序版本号
    pandas_ver = Common.get_pandas_ver(os.path.abspath(project_slndir),
                                       origin=True)
    Message.ShowInfo('当前模拟器的主版本是 %s' % pandas_ver)

    print('')

    # 询问获取升级后的目标版本
    newver = Inputer().requireText(
        {'tips': '请输入新的版本号 (四段式: 1.0.0.1, 最后一段为 1 则表示为开发版)'})

    if not isVersionFormatValid(newver):
        Message.ShowError('你输入的版本号: %s 不符合四段式规则, 请重试...' % newver)
        Common.exit_with_pause(-1)

    # 执行更新操作
    ver = VersionUpdater(options)
    ver.updateDirectory(slndir('src'), newver)

    Common.exit_with_pause()
Пример #6
0
    def convertFile(self, filepath, to_charset, directory):
        '''
        给定一个文本文件, 将它转换成指定的编码并保存
        '''
        origin_charset = self.__detectCharset(filepath).upper()
        to_charset = to_charset.upper()

        if origin_charset == to_charset:
            return False

        try:
            absolutely_path = os.path.abspath(filepath)

            Message.ShowInfo(
                '将 {filename} 的编码从 {origin_charset} 转换为 {to_charset}'.format(
                    filename=os.path.relpath(absolutely_path, directory),
                    origin_charset=origin_charset,
                    to_charset=to_charset))

            origin_file = codecs.open(filepath, 'r', origin_charset)
            content = origin_file.read()
            origin_file.close()

            target_file = codecs.open(filepath, 'w', to_charset)
            target_file.write(content)
            target_file.close()

            return True
        except IOError as err:
            Message.ShowError("I/O error: {0}".format(err))
            return False
Пример #7
0
    def dump(self, filename):
        '''
        将当前 self.body 列表中的内容转储到本地指定文件
        '''
        try:
            Message.ShowInfo('正在保存翻译对照表...')
            _body = []
            for x in self.body:
                _body.append({
                    'Original': quoted(x['Original']),
                    'Translation': quoted(x['Translation'])
                })
            
            restruct = {
                'Header': {
                    'Type': self.header_type,
                    'Version': self.header_version
                },
                'Body' : _body
            }

            with open(filename, 'w+', encoding='UTF-8-SIG') as f:
                yaml.dump(
                    restruct, f, allow_unicode=True,
                    default_flow_style=False, width=2048, sort_keys=False
                )
                f.close()

            Message.ShowInfo('保存到: %s' % os.path.relpath(os.path.abspath(filename), project_slndir))
            return os.path.abspath(filename)
        except Exception as _err:
            print(_err)
            Message.ShowError('保存翻译对照表期间发生错误, 请重试...')
            return None
Пример #8
0
def compile_renewal(version):
    '''
    编译复兴后版本
    '''
    time.sleep(3)
    print('')

    define_options = {}

    if os.getenv("DEFINE_CRASHRPT_APPID"):
        define_options["CRASHRPT_APPID"] = '\\"%s\\"' % os.getenv(
            "DEFINE_CRASHRPT_APPID")
    if os.getenv("DEFINE_CRASHRPT_PUBLICKEY"):
        define_options["CRASHRPT_PUBLICKEY"] = '\\"%s\\"' % os.getenv(
            "DEFINE_CRASHRPT_PUBLICKEY")

    define_options["GIT_BRANCH"] = '\\"%s\\"' % Common.get_pandas_branch(
        project_slndir)
    define_options["GIT_HASH"] = '\\"%s\\"' % Common.get_pandas_hash(
        project_slndir)

    define_values = define_builder(define_options)

    if not compile_sub(define_values, '复兴后', version):
        Message.ShowError('编译复兴前版本时发生了一些错误, 请检查...')
        Common.exit_with_pause(-1)

    # 将之前 compile_prere 中临时重命名的复兴前产物全部改回正常的文件名
    if 'pre' in os.getenv('DEFINE_COMPILE_MODE').split(','):
        move_product_files('-pre-t', '-pre')

    print('')
Пример #9
0
def compile_prere(version):
    '''
    编译复兴前版本
    '''
    time.sleep(3)
    print('')
    
    define_options = {
        "PRERE": ""
    }
    
    if os.getenv("DEFINE_CRASHRPT_APPID"):
        define_options["CRASHRPT_APPID"] = '\\"%s\\"' % os.getenv("DEFINE_CRASHRPT_APPID")
    if os.getenv("DEFINE_CRASHRPT_PUBLICKEY"):
        define_options["CRASHRPT_PUBLICKEY"] = '\\"%s\\"' % os.getenv("DEFINE_CRASHRPT_PUBLICKEY")
        
    define_options["GIT_BRANCH"] = '\\"%s\\"' % Common.get_pandas_branch(project_slndir)
    define_options["GIT_HASH"] = '\\"%s\\"' % Common.get_pandas_hash(project_slndir)

    define_values = define_builder(define_options)
    
    if not compile_sub(define_values, '复兴前', version):
        Message.ShowError('编译复兴前版本时发生了一些错误, 请检查...')
        Common.exit_with_pause(-1)

    # 将复兴前版本的编译产物重命名一下, 避免编译复兴后版本时被覆盖
	# 因 ab7a827 的修改每次清理工程时, 也会同时清理复兴前的编译产物, 所以这里需要临时重命名
    shutil.move(slndir('login-server.exe'), slndir('login-server-pre-t.exe'))
    shutil.move(slndir('login-server.pdb'), slndir('login-server-pre-t.pdb'))
    shutil.move(slndir('char-server.exe'), slndir('char-server-pre-t.exe'))
    shutil.move(slndir('char-server.pdb'), slndir('char-server-pre-t.pdb'))
    shutil.move(slndir('map-server.exe'), slndir('map-server-pre-t.exe'))
    shutil.move(slndir('map-server.pdb'), slndir('map-server-pre-t.pdb'))
    
    print('')
Пример #10
0
    def detect(self, src_dir):
        if isinstance(src_dir, str):
            src_dir = [src_dir]

        for single_dir in src_dir:
            for dirpath, _dirnames, filenames in os.walk(single_dir):
                for filename in filenames:
                    _base_name, extension_name = os.path.splitext(filename.lower())

                    if extension_name not in self.__options__['process_exts']:
                        continue

                    fullpath = os.path.normpath('%s/%s' % (dirpath, filename))
                    self.__searchMark(fullpath)

        bMarkPassed = True
        for configure in self.__options__['mark_configure']:
            if str(int(configure['id'])) not in self.mark_dict:
                Message.ShowError('无法定位代码注入点: {index} : {constant} : {desc}'.format(
                    index = str(int(configure['id'])),
                    constant = str(configure['id']),
                    desc = configure['desc']
                ))
                bMarkPassed = False
        return bMarkPassed
Пример #11
0
def compile_sub(define_val, name, version, scheme='Release|Win32'):
    '''
    用于执行编译
    '''
    # 获取第一个支持的 Visual Studio 对应的 vcvarsall 路径
    vcvarsall = get_vcvarsall_path()

    # 根据名称确定一下标记
    modetag = ('RE' if name == '复兴后' else 'PRE')

    # 执行编译
    Common.cmd_execute([
        '"%s" x86' % vcvarsall,
        'set CL=%s' % define_val, 'Devenv rAthena.sln /clean',
        'Devenv rAthena.sln /Rebuild "%s"' % scheme
    ], project_slndir, modetag, slndir(compile_logfile))

    # 编译完成后, 判断编译是否成功
    result, succ, faild, _skip = get_compile_result()
    if not result:
        Message.ShowError('无法获取 %s 的编译结果' % name)
        return False

    # 若成功, 则进行符号文件的存储
    if result and int(succ) > 1 and int(faild) == 0:
        return True
    else:
        Message.ShowWarning('%s: 存在编译失败的工程, 请进行检查...' % modetag)
        return False
Пример #12
0
def compile_renewal(version):
    '''
    编译复兴后版本
    '''
    time.sleep(3)
    print('')
    
    define_options = {}

    if os.getenv("DEFINE_CRASHRPT_APPID"):
        define_options["CRASHRPT_APPID"] = '\\"%s\\"' % os.getenv("DEFINE_CRASHRPT_APPID")
    if os.getenv("DEFINE_CRASHRPT_PUBLICKEY"):
        define_options["CRASHRPT_PUBLICKEY"] = '\\"%s\\"' % os.getenv("DEFINE_CRASHRPT_PUBLICKEY")

    define_options["GIT_BRANCH"] = '\\"%s\\"' % Common.get_pandas_branch(project_slndir)
    define_options["GIT_HASH"] = '\\"%s\\"' % Common.get_pandas_hash(project_slndir)

    define_values = define_builder(define_options)
    
    if not compile_sub(define_values, '复兴后', version):
        Message.ShowError('编译复兴前版本时发生了一些错误, 请检查...')
        Common.exit_with_pause(-1)
    
    # 将之前 compile_prere 中临时重命名的复兴前产物全部改回正常的文件名
    shutil.move(slndir('login-server-pre-t.exe'), slndir('login-server-pre.exe'))
    shutil.move(slndir('login-server-pre-t.pdb'), slndir('login-server-pre.pdb'))
    shutil.move(slndir('char-server-pre-t.exe'), slndir('char-server-pre.exe'))
    shutil.move(slndir('char-server-pre-t.pdb'), slndir('char-server-pre.pdb'))
    shutil.move(slndir('map-server-pre-t.exe'), slndir('map-server-pre.exe'))
    shutil.move(slndir('map-server-pre-t.pdb'), slndir('map-server-pre.pdb'))
    
    print('')
Пример #13
0
def process(project_dir, lang='zh-cn', silent=False):
    try:
        for v in configures:
            operate_params = v['operate_params']
            operate_params['lang'] = lang
            operate_params['project_dir'] = project_dir
            operate_params['silent'] = silent
            operate = globals()[v['operate']](**operate_params)

            if 'filepath' in v:
                for path in v['filepath']:
                    fullpath = os.path.abspath(project_dir + path)
                    operate.execute(fullpath)

            if 'globpath' in v:
                for path in v['globpath']:
                    files = glob.glob(os.path.abspath(project_dir + path),
                                      recursive=True)
                    for x in files:
                        relpath = os.path.relpath(x, project_dir).replace(
                            '\\', '/')
                        is_exclude = False
                        if 'globexclude' in v:
                            for e in v['globexclude']:
                                if e in relpath:
                                    is_exclude = True
                                    break
                        if not is_exclude:
                            operate.execute(x)
    except Exception as _err:
        Message.ShowError(str(_err))
        Common.exit_with_pause(-1)
Пример #14
0
 def __encoding_check(self, text, encoding, line):
     try:
         for i, element in enumerate(text):
             element.encode(encoding)
     except Exception as _err:
         Message.ShowError(
             '%s 第 %-5d 行中的 "%s" 字符不存在于 "%s" 编码中, 此错误必须被消除' %
             (os.path.relpath(self.__filename), line, element, encoding))
Пример #15
0
 def requireInt(self, options):
     print('-' * 70)
     Message.ShowSelect(options['tips'] + ':')
     result = input(options['prefix']) if 'prefix' in options else input()
     if not result:
         if not ('allow_empty' in options and options['allow_empty']):
             Message.ShowError('请至少输入一个数字. 程序终止')
             print('-' * 70)
             Common.exit_with_pause(-1)
         result = '0'
     if not result.isdigit():
         Message.ShowError('请输入一个数字而不是字符串. 程序终止')
         print('-' * 70)
         Common.exit_with_pause(-1)
     Message.ShowInfo('您输入的是: ' + result)
     print('-' * 70)
     print('')
     return int(result)
Пример #16
0
    def __init__(self, options):
        self.__options__ = options
        self.mark_dict = {}

        if not self.detect(self.__options__['source_dirs']):
            Message.ShowError('无法成功定位所有需要的代码注入点, 程序终止!')
            Common.exit_with_pause(-1)
        else:
            Message.ShowStatus('已成功定位所有代码注入点.\n')
Пример #17
0
    def versionFormat(self, version, vmode):
        ver_fields = []
        if '.' in version:
            ver_fields = version.split('.')
        elif ',' in version:
            ver_fields = version.split(',')
        else:
            Message.ShowError('您传入的版本号格式不正确: %s' % version)
            Common.exit_with_pause(-1)

        if vmode == '.':
            return '.'.join(ver_fields)
        elif vmode == ',':
            return ','.join(ver_fields)
        elif vmode == 'fmt':
            return 'v%s.%s.%s%s' % (ver_fields[0], ver_fields[1],
                                    ver_fields[2],
                                    '-dev' if ver_fields[3] == '1' else '')
        else:
            Message.ShowError('您传入的 vmode 版本号格式不正确: %s' % vmode)
            Common.exit_with_pause(-1)

        return version
Пример #18
0
 def requireText(self, options):
     print('-' * 70)
     Message.ShowSelect(options['tips'] + ':')
     result = input(options['prefix'])
     if not result:
         Message.ShowError('请至少输入一个字符. 程序终止')
         print('-' * 70)
         Common.exitWithPause(-1)
     result = options['prefix'] + result
     if options['upper']:
         result = result.upper()
     Message.ShowInfo('您输入的是: ' + result)
     print('-' * 70)
     print('\n')
     return result
Пример #19
0
    def requireSelect(self, options):
        print('-' * 70)
        prompt = options['prompt']
        option_name = options['option_name']
        select_data = options['data']
        Message.ShowSelect('请选择%s, 可选值为 [0~%d], 分别代表:' %
                           (prompt, len(select_data) - 1))
        print('')
        for select in select_data:
            Message.ShowMenu('%s' % select['desc'])
        print('')
        Message.ShowSelect('请选择%s [0~%d]:' % (prompt, len(select_data) - 1),
                           end="")
        user_select = input()

        if not user_select or not user_select.isnumeric():
            Message.ShowError(
                '您选择了无效的%s, 程序终止' %
                (option_name if option_name is not None else '选项'))
            print('-' * 70)
            Common.exit_with_pause(-1)

        user_select = int(user_select)

        if user_select < 0 or user_select >= len(select_data):
            Message.ShowError(
                '您选择了无效的%s, 程序终止' %
                (option_name if option_name is not None else '选项'))
            print('-' * 70)
            Common.exit_with_pause(-1)

        print('')
        Message.ShowInfo('您选择的是: %s' % select_data[user_select]['name'])
        print('-' * 70)
        print('')
        return user_select
Пример #20
0
 def requireText(self, options):
     print('-' * 70)
     Message.ShowSelect(options['tips'] + ':')
     prefix_val = options['prefix'] if 'prefix' in options else ''
     result = input(prefix_val)
     if not result:
         if 'default' in options and options['default']:
             result = options['default']
         if not result and not ('allow_empty' in options
                                and options['allow_empty']):
             Message.ShowError('请至少输入一个字符. 程序终止')
             print('-' * 70)
             Common.exit_with_pause(-1)
     result = prefix_val + result
     if 'upper' in options and options['upper']:
         result = result.upper()
     if 'lower' in options and options['lower']:
         result = result.lower()
     Message.ShowInfo('您输入的是: ' + result)
     print('-' * 70)
     print('')
     return result
Пример #21
0
def main():
    '''
    主入口函数
    '''
    # 显示欢迎信息
    Common.welcome('打包流程辅助脚本')
    print('')

    pandas_ver = Common.get_pandas_ver(os.path.abspath(project_slndir))
    Message.ShowInfo('当前模拟器的主版本是 %s' % pandas_ver)

    # 检查是否已经完成了编译
    if not Common.is_compiled(project_slndir):
        Message.ShowWarning('检测到打包需要的编译产物不完整, 请重新编译. 程序终止.')
        print('')
        Common.exit_with_pause(-1)

    # 导出当前仓库, 变成一个归档压缩文件
    Message.ShowInfo('正在将当前分支的 HEAD 内容导出成归档文件...')
    export_file = export()
    if not export_file:
        Message.ShowError('很抱歉, 导出归档文件失败, 程序终止.')
        Common.exit_with_pause(-1)
    Message.ShowInfo('归档文件导出完成, 此文件将在程序结束时被删除.') 

    # 基于归档压缩文件, 进行打包处理
    process(export_file, renewal=True)
    process(export_file, renewal=False)

    # 执行一些清理工作
    clean(export_file)

    print('')
    Message.ShowInfo('已经成功打包相关文件, 请进行人工核验.')

    # 友好退出, 主要是在 Windows 环境里给予暂停
    Common.exit_with_pause()
Пример #22
0
def compile_prere(version):
    '''
    编译复兴前版本
    '''
    time.sleep(3)
    print('')

    define_options = {"PRERE": ""}

    if os.getenv("DEFINE_CRASHRPT_APPID"):
        define_options["CRASHRPT_APPID"] = '\\"%s\\"' % os.getenv(
            "DEFINE_CRASHRPT_APPID")
    if os.getenv("DEFINE_CRASHRPT_PUBLICKEY"):
        define_options["CRASHRPT_PUBLICKEY"] = '\\"%s\\"' % os.getenv(
            "DEFINE_CRASHRPT_PUBLICKEY")

    define_options["GIT_BRANCH"] = '\\"%s\\"' % Common.get_pandas_branch(
        project_slndir)
    define_options["GIT_HASH"] = '\\"%s\\"' % Common.get_pandas_hash(
        project_slndir)

    define_values = define_builder(define_options)

    if not compile_sub(define_values, '复兴前', version):
        Message.ShowError('编译复兴前版本时发生了一些错误, 请检查...')
        Common.exit_with_pause(-1)

    # 将复兴前版本的编译产物重命名一下, 避免编译复兴后版本时被覆盖

# 因 ab7a827 的修改每次清理工程时, 也会同时清理复兴前的编译产物, 所以这里需要临时重命名
    if 're' in os.getenv('DEFINE_COMPILE_MODE').split(','):
        move_product_files('', '-pre-t')
    else:
        move_product_files('', '-pre')

    print('')
Пример #23
0
def main():
    '''
    主入口函数
    '''
    # 加载 .env 中的配置信息
    load_dotenv(dotenv_path='.config.env', encoding='UTF-8')

    # 若无配置信息则自动复制一份文件出来
    if not Common.is_file_exists('.config.env'):
        shutil.copyfile('.config.env.sample', '.config.env')

    # 显示欢迎信息
    Common.welcome('编译流程辅助脚本')

    # 只能在 Windows 环境运行
    if platform.system() != 'Windows':
        Message.ShowError('很抱歉, 此脚本只能在 Windows 环境上运行')
        Common.exit_with_pause(-1)

    # 判断本机是否安装了支持的 Visual Studio
    detected_vs, vs_name = detect_vs()
    if not detected_vs:
        Message.ShowError('无法检测到合适的 Visual Studio 版本 (2015 或 2017)')
        Common.exit_with_pause(-1)
    else:
        Message.ShowStatus('检测到已安装: %s 应可正常编译' % vs_name)

    print('')

    # 读取当前的 Pandas 主程序版本号
    pandas_ver = Common.get_pandas_ver(os.path.abspath(project_slndir))
    Message.ShowInfo('当前模拟器的主版本是 %s' % pandas_ver)

    # 判断是否已经写入了对应的更新日志, 若没有则要给予提示再继续
    if (has_changelog(pandas_ver)):
        Message.ShowStatus('已经在更新日志中找到了 %s 的版本信息.' % pandas_ver)
    else:
        Message.ShowWarning('没有在更新日志中找到 %s 版本的信息, 请注意完善!' % pandas_ver)

    # 判断当前 git 工作区是否干净, 若工作区不干净要给予提示
    if git.Repo(project_slndir).is_dirty():
        if not Inputer().requireBool({
                'tips': '当前模拟器代码仓库的工作区不干净, 要继续编译吗?',
                'default': False
        }):
            Message.ShowStatus('您主动放弃了继续操作')
            Common.exit_with_pause(-1)
    else:
        Message.ShowStatus('当前模拟器代码仓库的工作区是干净的.')

    # 检查 Crashrpt 使用的信息是否都设置好了, 若没有且企图编译正式版, 则给与提示
    if Common.is_pandas_release(os.path.abspath(project_slndir)):
        if not os.getenv("DEFINE_CRASHRPT_APPID"):
            Message.ShowWarning('当前并未设置 AppID, 且企图编译正式版.')
            Common.exit_with_pause(-1)
        if Common.md5(os.getenv("DEFINE_CRASHRPT_APPID")
                      ) != '952648de2d8f063a07331ae3827bc406':
            Message.ShowWarning('当前已设置了 AppID, 但并非正式版使用的 AppID.')
            Common.exit_with_pause(-1)
        if not os.getenv("DEFINE_CRASHRPT_PUBLICKEY"):
            Message.ShowWarning('当前并未设置 PublicKey, 且企图编译正式版.')
            Common.exit_with_pause(-1)

    Message.ShowStatus('即将开始编译, 编译速度取决于电脑性能, 请耐心...')

    # 清理目前的工作目录, 把一些可明确移除的删掉
    clean_environment()

    # 编译 Pandas 的复兴前版本
    compile_prere(pandas_ver)

    # 编译 Pandas 的复兴后版本
    compile_renewal(pandas_ver)

    Message.ShowStatus('编译工作已经全部结束, 请归档符号并执行打包流程.')

    # 友好退出, 主要是在 Windows 环境里给予暂停
    Common.exit_with_pause()
Пример #24
0
def main():
    '''
    主入口函数
    '''
    # 加载 .env 中的配置信息
    load_dotenv(dotenv_path='.config.env', encoding='UTF-8')

    # 若无配置信息则自动复制一份文件出来
    if not Common.is_file_exists('.config.env'):
        shutil.copyfile('.config.env.sample', '.config.env')

    # 显示欢迎信息
    Common.welcome('打包流程辅助脚本')
    print('')

    pandas_ver = Common.get_pandas_ver(os.path.abspath(project_slndir))
    Message.ShowInfo('当前模拟器的主版本是 %s' % pandas_ver)

    # 若环境变量为空则设置个默认值
    if not os.getenv('DEFINE_PROJECT_NAME'):
        os.environ["DEFINE_PROJECT_NAME"] = "Pandas"

    if not os.getenv('DEFINE_COMPILE_MODE'):
        os.environ["DEFINE_COMPILE_MODE"] = "re,pre"

    Message.ShowInfo('当前输出的项目名称为: %s' % os.getenv('DEFINE_PROJECT_NAME'))

    # 检查是否已经完成了编译
    if 're' in os.getenv('DEFINE_COMPILE_MODE').split(','):
        if not Common.is_compiled(project_slndir, checkmodel='re'):
            Message.ShowWarning('检测到打包需要的编译产物不完整, 请重新编译. 程序终止.')
            print('')
            Common.exit_with_pause(-1)

    if 'pre' in os.getenv('DEFINE_COMPILE_MODE').split(','):
        if not Common.is_compiled(project_slndir, checkmodel='pre'):
            Message.ShowWarning('检测到打包需要的编译产物不完整, 请重新编译. 程序终止.')
            print('')
            Common.exit_with_pause(-1)

    # 导出当前仓库, 变成一个归档压缩文件
    Message.ShowInfo('正在将当前分支的 HEAD 内容导出成归档文件...')
    export_file = export()
    if not export_file:
        Message.ShowError('很抱歉, 导出归档文件失败, 程序终止.')
        Common.exit_with_pause(-1)
    Message.ShowInfo('归档文件导出完成, 此文件将在程序结束时被删除.')

    # 基于归档压缩文件, 进行打包处理
    if 're' in os.getenv('DEFINE_COMPILE_MODE').split(','):
        process(export_file, renewal=True)

    if 'pre' in os.getenv('DEFINE_COMPILE_MODE').split(','):
        process(export_file, renewal=False)

    # 执行一些清理工作
    clean(export_file)

    print('')
    Message.ShowInfo('已经成功打包相关文件, 请进行人工核验.')

    # 友好退出, 主要是在 Windows 环境里给予暂停
    Common.exit_with_pause()
Пример #25
0
def guide(inject):

    define = Inputer().requireText({
        'tips' : '请输入该战斗配置选项的宏定义开关名称 (Pandas_BattleConfig_的末尾部分)',
        'prefix' : 'Pandas_BattleConfig_'
    })
    
    # --------
    
    option_name = Inputer().requireText({
        'tips' : '请输入该战斗配置选项的选项名称'
    })
    
    # --------
    
    var_name = Inputer().requireText({
        'tips' : '请输入该战斗配置选项的变量名称 (不填默认与选项名称一致)',
        'default' : option_name.replace('.', '_')
    })
    
    # --------
    
    def_val = Inputer().requireInt({
        'tips' : '请输入默认值 (不填则默认为 0)',
		'allow_empty' : True
    })
    
    # --------
    
    min_val = Inputer().requireInt({
        'tips' : '请输入允许设置的最小值 (不填则默认为 0)',
		'allow_empty' : True
    })
    
    # --------
    
    max_val = Inputer().requireInt({
        'tips' : '请输入允许设置的最大值 (不填则默认为 INT_MAX)',
		'allow_empty' : True
    })
    
    if max_val == 0:
        max_val = 2147483647
    
    if max_val <= min_val:
        Message.ShowError('最大值比最小值还要小, 这不合理...')
        Common.exit_with_pause(-1)
    
    def_val = str(def_val)
    min_val = str(min_val)
    max_val = 'INT_MAX' if max_val == 2147483647 else str(max_val)
    
    # --------
    
    print('-' * 70)
    Message.ShowInfo('请确认建立的信息, 确认后将开始修改代码.')
    print('-' * 70)
    Message.ShowInfo('开关名称 : %s' % define)
    Message.ShowInfo('选项名称 : %s' % option_name)
    Message.ShowInfo('变量名称 : %s' % var_name)
    print('')
    Message.ShowInfo('选项默认值 : %s' % def_val)
    Message.ShowInfo('选项最小值 : %s' % min_val)
    Message.ShowInfo('选项最大值 : %s' % max_val)
    print('-' * 70)
    print('\n')

    nextstep = Inputer().requireBool({
        'tips' : '请仔细阅读上述信息, 确认要开始写入操作么?',
        'default' : False
    })

    if not nextstep:
        Message.ShowStatus('终止写入操作, 程序终止')
        Common.exit_with_pause(-1)
    
    # --------
    
    Message.ShowStatus('开始将战斗配置选项写入到源代码...')
    
    options = {
        'define' : define,
        'option_name' : option_name,
        'var_name' : var_name,
        'def_val' : def_val,
        'min_val' : min_val,
        'max_val' : max_val
    }
    
    insert_battle_config(inject, options)
    
    Message.ShowStatus('已经成功写入到源代码, 请检查并完善必要的注释.')
    print('')
    print('=' * 70)
    print('')
    print('感谢您的使用, 战斗配置选项添加助手已经执行完毕'.center(50))
    print('')
    print('=' * 70)
Пример #26
0
def guide(inject):
    eventlist = [{
        'name': 'Event 类型的标准事件',
        'desc': '0 - Event  类型的标准事件, 不能被 processhalt 指令打断'
    }, {
        'name': 'Filter 类型的过滤事件',
        'desc': '1 - Filter 类型的过滤事件, 可以被 processhalt 指令打断'
    }]

    # 0 为 Event 类型的事件 | 1 为 Filter 类型的事件
    eventtype = InputController().requireSelect({
        'name': '想创建的 NPC 事件类型',
        'data': eventlist
    })

    # --------

    constant_prefix = 'NPCE_' if eventtype == 0 else 'NPCF_'
    constant = InputController().requireText({
        'tips':
        '请输入该 NPC 事件的 {prefix} 常量名称 (自动大写, {prefix}的末尾部分)'.format(
            prefix=constant_prefix),
        'prefix':
        constant_prefix,
        'upper':
        True
    })

    if eventtype == 0:
        define = 'rAthenaCN_NpcEvent_' + constant.replace(constant_prefix, '')
        eventvar = constant.replace(constant_prefix,
                                    '').lower() + '_event_name'
    elif eventtype == 1:
        define = 'rAthenaCN_NpcFilter_' + constant.replace(constant_prefix, '')
        eventvar = constant.replace(constant_prefix,
                                    '').lower() + '_filter_name'
    else:
        Message.ShowError('发现无效的事件类型, 请确认..')
        Common.exitWithPause(-1)

    # --------

    eventname = InputController().requireText({
        'tips': '请输入该 NPC 事件的名称 (以 On 开头, 末尾应为 Event 或 Filter)',
        'prefix': ''
    })

    if not eventname.startswith('On'):
        Message.ShowError('无论是什么类型的事件, 事件名称必须以 On 开头 (严格区分大小写)')
        Common.exitWithPause(-1)

    if eventtype == 0:
        if not eventname.endswith('Event'):
            Message.ShowError('Event 类型的事件, 事件名称必须以 Event 结尾 (严格区分大小写)')
            Common.exitWithPause(-1)

    if eventtype == 1:
        if not eventname.endswith('Filter'):
            Message.ShowError('Filter 类型的事件, 事件名称必须以 Filter 结尾 (严格区分大小写)')
            Common.exitWithPause(-1)

    # --------

    eventdesc = InputController().requireText({
        'tips': '请输入该 NPC 事件的简短说明 (如: 当玩家杀死 MVP 魔物时触发事件)',
        'prefix': ''
    })

    # --------

    print('-' * 70)
    Message.ShowInfo('请确认建立的信息, 确认后将开始修改代码.')
    print('-' * 70)
    Message.ShowInfo('事件类型 : %s' % eventlist[eventtype]['name'])
    Message.ShowInfo('常量名称 : %s' % constant)
    Message.ShowInfo('事件名称 : %s' % eventname)
    Message.ShowInfo('事件说明 : %s' % eventdesc)
    print('')
    Message.ShowInfo('开关名称 : %s' % define)
    Message.ShowInfo('变量名称 : %s' % eventvar)
    print('-' * 70)
    print('\n')

    nextstep = InputController().requireBool({
        'tips': '请仔细阅读上述信息, 确认要开始写入操作么?',
        'default': False
    })

    if not nextstep:
        Message.ShowStatus('终止写入操作, 程序终止')
        Common.exitWithPause(-1)

    # --------

    Message.ShowStatus('开始将 NPC 事件写入到源代码...')

    options = {
        'define': define,
        'constant': constant,
        'eventname': eventname,
        'eventvar': eventvar,
        'eventdesc': eventdesc
    }

    if eventtype == 0:
        insert_for_normal_npcevent(inject, options)
    elif eventtype == 1:
        insert_for_filter_npcevent(inject, options)

    Message.ShowStatus('已经成功写入到源代码, 请检查并完善必要的注释.')
    print('')
    print('=' * 70)
    print('')
    print('感谢您的使用, NPC 事件添加助手已经执行完毕'.center(48))
    print('')
    print('=' * 70)
Пример #27
0
def main():
    '''
    主入口函数
    '''
    # 加载 .env 中的配置信息
    load_dotenv(dotenv_path='pyhelp.conf', encoding='UTF-8-SIG')
    
    # 若无配置信息则自动复制一份文件出来
    if not Common.is_file_exists('pyhelp.conf'):
        shutil.copyfile('pyhelp.conf.sample', 'pyhelp.conf')
    
    # 显示欢迎信息
    Common.welcome('编译流程辅助脚本')

    # 只能在 Windows 环境运行
    if platform.system() != 'Windows':
        Message.ShowError('很抱歉, 此脚本只能在 Windows 环境上运行')
        Common.exit_with_pause(-1)

    # 判断本机是否安装了支持的 Visual Studio
    detected_vs, vs_name = detect_vs()
    if not detected_vs:
        Message.ShowError('无法检测到合适的 Visual Studio 版本 (2015 或 2017)')
        Common.exit_with_pause(-1)
    else:
        Message.ShowStatus('检测到已安装: %s 应可正常编译' % vs_name)

    print('')

    # 读取当前的 Pandas 主程序版本号
    pandas_ver = get_pandas_ver()
    Message.ShowInfo('当前模拟器的主版本是 %s' % pandas_ver)

    # 判断是否已经写入了对应的更新日志, 若没有则要给予提示再继续
    if (has_changelog(pandas_ver)):
        Message.ShowStatus('已经在更新日志中找到了 %s 的版本信息.' % pandas_ver)
    else:
        Message.ShowWarning('没有在更新日志中找到 %s 版本的信息, 请注意完善!' % pandas_ver)

    # 检查创建并尝试更新符号仓库
    update_symstore()

    # 判断当前 git 工作区是否干净, 若工作区不干净要给予提示
    if git.Repo(project_slndir).is_dirty():
        if not Inputer().requireBool({
            'tips' : '当前模拟器代码仓库的工作区不干净, 要继续编译吗?',
            'default' : False
        }):
            Message.ShowStatus('您主动放弃了继续操作')
            Common.exit_with_pause(-1)
    else:
        Message.ShowStatus('当前模拟器代码仓库的工作区是干净的.')
    Message.ShowStatus('即将开始编译, 编译速度取决于电脑性能, 请耐心...')

    # 清理目前的工作目录, 把一些可明确移除的删掉
    clean_environment()

    # 编译 Pandas 的复兴前版本
    compile_prere(pandas_ver)

    # 将复兴前版本的编译产物重命名一下, 避免编译复兴后版本时被覆盖
    shutil.move(slndir('login-server.exe'), slndir('login-server-pre.exe'))
    shutil.move(slndir('login-server.pdb'), slndir('login-server-pre.pdb'))
    shutil.move(slndir('char-server.exe'), slndir('char-server-pre.exe'))
    shutil.move(slndir('char-server.pdb'), slndir('char-server-pre.pdb'))
    shutil.move(slndir('map-server.exe'), slndir('map-server-pre.exe'))
    shutil.move(slndir('map-server.pdb'), slndir('map-server-pre.pdb'))

    # 编译 Pandas 的复兴后版本
    print('')
    compile_renewal(pandas_ver)

    print('')
    Message.ShowStatus('编译工作已经全部结束.')
    Message.ShowStatus('编译时产生的符号文件已存储, 记得提交符号文件.\n')

    # 友好退出, 主要是在 Windows 环境里给予暂停
    Common.exit_with_pause(0)