源战役
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

542 lines
19 KiB

@echo off
rem ------------------------------
rem huangyongxing@yeah.net
rem 项目编译及启停控制工具
rem ------------------------------
cd %~dp0/../
set DIR_ERL=%cd%
cd ../
set DIR_MAIN=%cd%
rem 注意设置SRV_ID、HOST、PORT,
rem 一般HOST用自己的IP,SRV_ID推荐使用自己的工号数字【保证唯一】
rem 同时,需要在下方指定对应版本的erl安装路径
set SRV_ID=1
set HOST=
set COOKIE=mrzj_%SRV_ID%
set PORT=9110
set NODE_NAME_PREFIX=mrzj_dev_
set NODE_NAME=%NODE_NAME_PREFIX%%SRV_ID%@%HOST%
set CENTER_NODE_NAME=mrzj_dev_center@%HOST%
set CENTER_COOKIE=mrzj_dev_center
set CENTER_PORT=9111
title 明日战纪源码管理(%NODE_NAME%, %PORT%)
rem 协议生成工具
set PROTO_TOOL=%DIR_MAIN%\doc\proto_auto\ProtoBuilder.exe
if not exist %PROTO_TOOL% set PROTO_TOOL=
rem 指定erl路径,会自动计算对应的werl和escript路径
rem 使用otp 18.3示例
rem set ERL=D:\Program Files\erl7.3\bin\erl.exe
rem 使用otp 19.3示例
rem set ERL=D:\Program Files\erl8.3\bin\erl
rem 使用otp 23.3示例
set ERL=D:\Program Files\erl-23.3.4.4\bin\erl
rem 使用环境变量中的erl
rem set ERL=erl
rem 设置游戏服使用的config,便于在本地配置多个服测试
set GS_CONFIG=gsrv.config
rem 客户端路径
set CLIENT=%DIR_MAIN%\code\u3d\app\localTest\ClientApp.exe
if "%HOST%"=="" (
call :fun_error HOST未配置
goto :EOF
)
rem 客户端目录
set CLIENT_DIR=%DIR_MAIN%\code
rem 服务端目录
set SERV_DIR=%DIR_ERL%
rem svn程序目录(视实际安装目录而异)
set SVN_EXE=C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
rem 调用初始化脚本执行环境的接口
call :fun_init_calc
rem dialyzer相关配置
rem plt file
set PLTFILE=%DIR_ERL%\script\.dialyzer_plt_v%OTP_VER%
rem dialyzer 分析日志输出文件名前缀
set DIALYZER_OUTFILE_PREFIX=dialyzer_v%OTP_VER%
echo.
rem --------- 开始主循环: 等待指令->输入指令->执行指令->等待指令 ---------
:fun_main
echo erts version: %ERTS_VER%
echo otp version: %OTP_VER%
echo werl.exe : %WERL%
echo server root : %DIR_ERL%
set inp=
echo ---------------------------------------------------------------------------
echo make^|m 编译 ^| dialyzer^|dlz 运行dialyzer静态分析
echo mmm 快速编译(powershell) ^| mm 编译与版本库差异文件
echo start 启动游戏服及跨服 ^| stop 关闭游戏服及跨服
echo restart 重启服务器及跨服 ^| hot 热更服务器及跨服
echo hot_master 热更游戏服 ^| hot_center 热更跨服
echo master 启动游戏服 ^| stop_master 关闭游戏服
echo center 启动跨服服务器 ^| stop_center 关闭跨服服务器
echo werl 开启一个werl窗口 ^| kill^|k 强行结束所有werl.exe
echo dir 打开server目录 ^| clean_logs^|cl 清理本地游戏服日志
echo client^|c 开户PC版客户端 ^| attr 重新生成attr_conv模块
if "%PROTO_TOOL%" NEQ "" echo pt 协议生成工具 ^| su ^| cu svn更新 服务端^|客户端
echo clear^|cls 清屏 ^| quit^|q 退出
echo ---------------------------------------------------------------------------
set /p inp=请输入指令:
cd %DIR_ERL%
goto fun_routing
:fun_routing
if "%inp%"=="make" call :fun_make
if "%inp%"=="m" call :fun_make
if "%inp%"=="mm" call :fun_mm
if "%inp%"=="mmm" call :fun_mmm
if "%inp%"=="start" call :fun_start
if "%inp%"=="stop" call :fun_stop
if "%inp%"=="master" call :fun_start_master
if "%inp%"=="stop_master" call :fun_stop_master
if "%inp%"=="hot" call :fun_hot
if "%inp%"=="hot_master" call :fun_hot_master
if "%inp%"=="hot_center" call :fun_hot_center
if "%inp%"=="restart" call :fun_restart
if "%inp%"=="center" call :fun_start_center
if "%inp%"=="stop_center" call :fun_stop_center
if "%inp%"=="kill" call :fun_kill
if "%inp%"=="k" call :fun_kill
if "%inp%"=="clean_logs" call :fun_clean_logs
if "%inp%"=="cl" call :fun_clean_logs
if "%inp%"=="werl" call :fun_start_werl
if "%inp%"=="client" call :fun_start_client
if "%inp%"=="c" call :fun_start_client
if "%inp%"=="pt" call :fun_proto_tool
if "%inp%"=="attr" call :fun_create_attr_conv
if "%inp%"=="dir" call :fun_dir_server
if "%inp%"=="su" call :server_svn_update
if "%inp%"=="cu" call :client_svn_update
if "%inp%"=="dlz" call :fun_run_dialyzer
if "%inp%"=="dialyzer" call :fun_run_dialyzer
if "%inp%"=="cls" cls
if "%inp%"=="clear" cls
if "%inp%"=="quit" goto :EOF
if "%inp%"=="q" goto :EOF
echo.
goto fun_main
rem --------- 后面为相关指令操作接口封装 ---------
rem 初始化计算脚本一些工具路径和设置一些全局变量
rem 包括以下变量值:
rem ERL、WERL、ESCRIPT、ERTS_VER、ERTS_VER_MAIN
rem ERL_OPT_NORMAL
rem ERL_OPT_S_SINGLE
:fun_init_calc
rem 如果%erl%等于erl说明有设置环境变量,理论上escript也找得到
if "%ERL%"=="erl" set envTrue=1
if "%ERL%"=="erl.exe" set envTrue=1
setlocal enabledelayedexpansion
if "!envTrue!"=="1" (
for /f "delims=" %%i in ('where erl') do (set ERL=%%i)
)
rem 给文件补上后缀,便于判断是否存在
if "!ERL:~-4!" NEQ ".exe" set ERL=!ERL!.exe
if NOT EXIST !ERL! (
echo "文件不存在"!ERL!
goto :EOF
) ELSE (
set ERL_BIN_ROOT=!ERL:erl.exe=!
set ESCRIPT=!ERL_BIN_ROOT!escript.exe
set WERL=!ERL_BIN_ROOT!werl.exe
set DIALYZER=!ERL_BIN_ROOT!dialyzer.exe
rem 避免自动计算的路径用'\',手写的可能用'/',所以两类都先尝试去除
set ERL_INST_TMP=!ERL_BIN_ROOT:bin\=!
set ERL_INST=!ERL_INST_TMP:bin/=!
)
rem 取得erts version
call :fun_calc_erts_ver ERTS_VER ERTS_VER_MAIN "!ERL!"
rem call :fun_calc_otp_ver OTP_VER "!ERL!" "!ERL_INST!"
call :fun_calc_otp_ver_simple OTP_VER "!ERL_INST!"
endlocal & (
rem 如果是作为全局变量,需要在这里set(否则仍是局部变量)
rem set ERL_BIN_ROOT=%ERL_BIN_ROOT%
set ERL=%ERL%
set WERL=%WERL%
set ESCRIPT=%ESCRIPT%
set DIALYZER=%DIALYZER%
set ERTS_VER=%ERTS_VER%
set ERTS_VER_MAIN=%ERTS_VER_MAIN%
set OTP_VER=%OTP_VER%
set ERL_INST=%ERL_INST%
rem echo erlang root: %ERL_BIN_ROOT%
echo erl.exe : %ERL%
echo werl.exe : %WERL%
echo escript.exe : %ESCRIPT%
rem 设置一些执行参数
if %ERTS_VER_MAIN% LEQ 8 (
set ERL_OPT_NORMAL=+P 204800 +K true +A 100 +spp true -smp enable -hidden +sbwt none
set ERL_OPT_S_SINGLE=+P 204800 +K true +A 100 +spp true -smp disable -hidden +sbwt none
) ELSE (
set ERL_OPT_NORMAL=+P 204800 +K true +A 100 +spp true +S 0 -hidden +sbwt none
set ERL_OPT_S_SINGLE=+P 204800 +K true +A 100 +spp true +S 1 -hidden +sbwt none
)
) & goto :EOF
:fun_make
cd %DIR_ERL%
set startTime=%time%
call :get_localtime startTimeStr
echo [%startTimeStr%] start make
echo.
rem xcopy /d 只更新比目标新的源文件
xcopy "dep\ebin\*.beam" "ebin\" /h /r /k /q /y /d
rem 判断编译参数,决定真实使用的文件(目前windows版都使用release版,需要其他版本的手工拷贝文件)
setlocal enabledelayedexpansion
set needCopy=FALSE
if NOT EXIST "ebin\game_logger.beam" (
SET needCopy=TRUE
) ELSE (
rem SET fileCmpRet=
rem FOR /F %%i IN ('comp /M dep\ebin\debug\game_logger.beam ebin\game_logger.beam') DO set fileCmpRet=%%i
rem if "!fileCmpRet!"=="文件的大小不同。" SET needCopy=TRUE
call :calc_md5 "dep\ebin\release\game_logger.beam" "fMD51"
call :calc_md5 "ebin\game_logger.beam" "fMD52"
if "!fMD51!" NEQ "!fMD52!" SET needCopy=TRUE
)
if "!needCopy!"=="TRUE" xcopy "dep\ebin\release\*.beam" "ebin\" /e /h /r /k /q /y
endlocal
rem 在编译、热更等简单操作中可直接使用halt(0)直接退出erlangVM,比c:q()优雅中止服务的速度更快
rem set makeOptions=[{d, 'DEV_SERVER'}],
rem 通常可增加的选项 {d,'DEV_SERVER'}, {d,'CP_VER',"TW"}, ...
set makeOptions=[]
"%ERL%" -noinput -pa ./ebin -eval "mmake:all(2, %makeOptions%),halt(0)"
call :calc_time_diff "%startTime%" "%time%" "runTime"
call :get_localtime EndTimeStr
echo.
echo cost time: %runTime%
echo.
echo [%EndTimeStr%] finish make
echo "%EndTimeStr%" > %DIR_ERL%/script/timefile
goto :EOF
:fun_mm
cd %DIR_ERL%
set startTime=%time%
call :get_localtime startTimeStr
echo [%startTimeStr%] start mm
echo.
svn status "./src" > "./svn_status.log"
cd %DIR_ERL%
"%ERL%" -noinput -pa ./ebin -eval "make_file:make_file(),halt(0)"
call :calc_time_diff "%startTime%" "%time%" "runTime"
call :get_localtime EndTimeStr
echo.
echo cost time: %runTime%
echo.
echo [%EndTimeStr%] finish make
goto :EOF
:fun_start
call :fun_start_center & call :fun_start_master
goto :EOF
:fun_stop
call :fun_stop_master & call :fun_stop_center
goto :EOF
:fun_mmm
cd %DIR_ERL%
set startTime=%time%
call :get_localtime startTimeStr
echo [%startTimeStr%] start mmm
echo.
cd script
echo %cd%
PowerShell.exe -file mm.ps1
call :calc_time_diff "%startTime%" "%time%" "runTime"
call :get_localtime EndTimeStr
echo.
echo cost time: %runTime%
echo.
echo [%EndTimeStr%] finish make
goto :EOF
:fun_start_master
cd %DIR_ERL%\config
rem start cmd /C ""%ERL%" %ERL_OPT_NORMAL% -name %NODE_NAME% -setcookie %COOKIE% -boot start_sasl -config %GS_CONFIG% -pa ../ebin -s main start -extra %HOST% %PORT% & pause"
start "" "%WERL%" %ERL_OPT_NORMAL% -name %NODE_NAME% -setcookie %COOKIE% -boot start_sasl -config %GS_CONFIG% -pa ../ebin -s main start -extra %HOST% %PORT%
goto :EOF
:fun_stop_master
cd %DIR_ERL%\config
set STOP_NODE_NAME=%NODE_NAME_PREFIX%%SRV_ID%_stop_%RANDOM%@%HOST%
"%ERL%" -hidden -name %STOP_NODE_NAME% -setcookie %COOKIE% -pa ../ebin -s main stop_server -extra %NODE_NAME%
rem start "" "%WERL%" -hidden -name %STOP_NODE_NAME% -setcookie %COOKIE% -pa ../ebin -s main stop_server -extra %NODE_NAME%
goto :EOF
:fun_hot
call :fun_hot_master & call :fun_hot_center
goto :EOF
:fun_hot_master
cd %DIR_ERL%\config
set hotNodeName=%NODE_NAME_PREFIX%%SRV_ID%_hot_%RANDOM%@%HOST%
"%ERL%" -hidden -name %hotNodeName% -setcookie %COOKIE% -pa ../ebin -eval "rpc:call('%NODE_NAME%', u, u, []), halt(0)"
rem start "" "%WERL%" -hidden -name %hotNodeName% -setcookie %COOKIE% -pa ../ebin -eval "rpc:call('%NODE_NAME%', u, u, []), halt(0)"
goto :EOF
:fun_hot_center
cd %DIR_ERL%\config
set hotNodeName=%NODE_NAME_PREFIX%center_hot_%RANDOM%@%HOST%
"%ERL%" -hidden -name %hotNodeName% -setcookie %CENTER_COOKIE% -pa ../ebin -eval "rpc:call('%CENTER_NODE_NAME%', u, u, []), halt(0)"
rem start "" "%WERL%" -hidden -name %hotNodeName% -setcookie %CENTER_COOKIE% -pa ../ebin -eval "rpc:call('%CENTER_NODE_NAME%', u, u, []), halt(0)"
goto :EOF
:fun_restart
call :fun_stop
choice /t 2 /d y /n >nul
call :fun_start
goto :EOF
:fun_start_center
cd %DIR_ERL%\config
rem start cmd /C ""%ERL%" %ERL_OPT_NORMAL% -name %CENTER_NODE_NAME% -setcookie %CENTER_COOKIE% -boot start_sasl -config cls.config -pa ../ebin -s main start -extra %HOST% %CENTER_PORT% & pause"
start "" "%WERL%" %ERL_OPT_NORMAL% -name %CENTER_NODE_NAME% -setcookie %CENTER_COOKIE% -boot start_sasl -config cls.config -pa ../ebin -s main start -extra %HOST% %CENTER_PORT%
goto :EOF
:fun_stop_center
cd %DIR_ERL%\config
set STOP_NODE_NAME=center_stop_%RANDOM%@%HOST%
"%ERL%" -hidden -name %STOP_NODE_NAME% -setcookie %CENTER_COOKIE% -pa ../ebin -s main stop_server -extra %CENTER_NODE_NAME%
rem start "" "%WERL%" -hidden -name %STOP_NODE_NAME% -setcookie %CENTER_COOKIE% -pa ../ebin -s main stop_server -extra %CENTER_NODE_NAME%
goto :EOF
rem 强制关闭werl进程(在异常崩溃的情况下,windows中会残留werl进程)
:fun_kill
taskkill /F /IM werl.exe
goto :EOF
rem 清理本地游戏服日志
:fun_clean_logs
cd %DIR_ERL%\logs
DEL /Q *.*
goto :EOF
rem 随机节点名的werl
:fun_start_werl
cd %DIR_ERL%\config
if %time:~0,2% leq 9 (set hour=0%time:~1,1%) else (set hour=%time:~0,2%)
set randomNode=werl_%hour%%time:~3,2%%time:~6,2%_%RANDOM%@%HOST%
if not exist gsrv.config (
start "" "%WERL%" -hidden -name %randomNode% -setcookie %COOKIE% -pa ../ebin
) else (
start "" "%WERL%" -hidden -name %randomNode% -setcookie %COOKIE% -pa ../ebin -config gsrv.config
)
goto :EOF
rem dialyzer静态分析工具 初始化持久查询表文件plt file
:fun_init_plt
echo [init] build plt file
"%DIALYZER%" --build_plt --apps erts kernel stdlib sasl compiler mnesia crypto inets ssl public_key eunit tools --output_plt "%PLTFILE%"
goto :EOF
rem dialyzer静态分析工具 执行分析
:fun_analyse_code
call :get_datetime_str dt
set outfile=%DIR_ERL%\script\%DIALYZER_OUTFILE_PREFIX%_%dt%.txt
set erlLib=%ERL_INST%\lib
set serverDir=%DIR_ERL%
echo 正在执行dialyzer分析
echo 输出分析日志文件:%outfile%
rem "D:/Program Files/erl-23.2.5/bin/dialyzer.exe" -I server/include --src server/src -r server/src -pa "D:/Program Files/erl-23.2.5/lib" --plt ./.dialyzer_plt_mrzj > dialyzer_%dt%.txt
"%DIALYZER%" -I %serverDir%\include --src %serverDir%\src -r %serverDir%\src -pa "%erlLib%" --plt "%PLTFILE%" > "%outfile%"
goto :EOF
rem dialyzer静态分析工具调用
:fun_run_dialyzer
if NOT EXIST "%PLTFILE%" call :fun_init_plt
call :fun_analyse_code
goto :EOF
rem 协议生成工具
:fun_proto_tool
rem 需要开启变量延迟,否则else括号块首次执行时变量解析有问题
setlocal enabledelayedexpansion
if "!PROTO_TOOL!"=="" (
call :fun_error 未配置协议生成工具
) else (
for /f "delims=" %%t in ('echo !PROTO_TOOL!') do (set dirProtoTool=%%~dpt)
echo ---------------------------------
echo change to directory: [!dirProtoTool!]
cd !dirProtoTool!
"!PROTO_TOOL!"
)
endlocal
goto :EOF
rem 开户客户端
:fun_start_client
if NOT EXIST %CLIENT% (
call :fun_error 没有找到客户端可执行文件[%CLIENT%]
goto :EOF
)
setlocal enabledelayedexpansion
for /f "delims=" %%t in ('echo !CLIENT!') do (set dirClient=%%~dpt)
rem 客户端从某个版本开始,似乎用了绝对路径来查找资源,必须在exe所在目录启动才行
cd /d "!dirClient!"
start "" cmd /C "%CLIENT%"
endlocal
goto :EOF
rem 生成attr_conv模块
:fun_create_attr_conv
if NOT EXIST src\tool\attr_tool.erl (
echo "未找到attr_tool.erl文件"
) ELSE (
"%ESCRIPT%" src\tool\attr_tool.erl
)
goto :EOF
rem 打开服务端工作目录 %DIR_ERL%
:fun_dir_server
start "" explorer "%DIR_ERL%"
goto :EOF
rem 服务端更新
:server_svn_update
start "" "%SVN_EXE%" /command:update /path:"%SERV_DIR%" /closeonend:0
goto :EOF
rem 客户端更新
:client_svn_update
start "" "%SVN_EXE%" /command:update /path:"%CLIENT_DIR%" /closeonend:0
goto :EOF
rem node name split
rem call :node_name_split "%node%" "nodePrefix" "nodeHost"
:node_name_split
set input=%~1
set sep=@
set nPre=
set nHost=
setlocal enabledelayedexpansion
for /F "delims=%sep% tokens=1-2" %%a in ("%input%") do (
set nPre=%%a
set nHost=%%b
)
endlocal & set "%~2=%nPre%" & set "%~3=%nHost%" & goto :EOF
rem 计算两个时间差值
rem 调用示例:
rem set startTime=%time%
rem echo do something
rem call :calc_time_diff "%startTime%" "%time%" "runTime"
rem echo cost time %runTime%
:calc_time_diff
setlocal
set /a n=0
for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
set /a n-=1%%a*3600000+1%%b*60000+1%%c*1000+1%%d*10
set /a n+=1%%e*3600000+1%%f*60000+1%%g*1000+1%%h*10
)
set /a s=n/3600000,n=n%%3600000,f=n/60000,n=n%%60000,m=n/1000,n=n%%1000
set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
endlocal & set "%~3=%ok%" & goto :EOF
rem 获取本地时间
:get_localtime
setlocal
if %time:~0,2% leq 9 (set hour=0%time:~1,1%) else (set hour=%time:~0,2%)
set lt=%date:~0,4%-%date:~5,2%-%date:~8,2% %hour%:%time:~3,2%:%time:~6,2%
endlocal & set "%~1=%lt%" & goto :EOF
rem 获取日期
rem call :get_datetime_str var
:get_datetime_str
setlocal
if %time:~0,2% leq 9 (set hour=0%time:~1,1%) else (set hour=%time:~0,2%)
set dt=%date:~0,4%%date:~5,2%%date:~8,2%_%hour%%time:~3,2%%time:~6,2%
endlocal & set "%~1=%dt%" & goto :EOF
rem 计算文件md5
rem call :calc_md5 "filePath" "fMD5"
rem echo %fMD5%
:calc_md5
setlocal
FOR /F %%i IN ('certutil -hashfile "%~1" MD5 ^| findstr /V 哈希 ^| findstr /V 完成') DO set fMD5=%%i
endlocal & set "%~2=%fMD5%" & goto :EOF
rem 计算erts版本
rem call :fun_calc_erts_ver "ERTS_VER" "ERTS_VER_MAIN" "%ERL%"
:fun_calc_erts_ver
rem 注意,pattern最后面本身有空格需要保留(bat语法奇葩,两侧加引号又会出问题)
rem 但是为防止不小心格式化代码时去掉了空格,
rem 所以改为无空格,并在替换后,多进行一次替换空格操作
set pattern=Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version
set replace=
set erlbin=%3
setlocal enabledelayedexpansion
for /f "usebackq delims=" %%i in (`"%erlbin%" +V 2^>^&1`) do (set allstr=%%i)
set "ertsVer=!allstr:%pattern%=%replace%!"
set "ertsVer=!ertsVer: =!"
for /f "usebackq delims=." %%i in (`echo !ertsVer!`) do (
if defined ertsVerMain goto break_calc_erts_ver
set ertsVerMain=%%i
)
:break_calc_erts_ver
endlocal & set "%~1=%ertsVer%" & set "%~2=%ertsVerMain%" & goto :EOF
rem 查找otp version【调用erl获取主版本号,再定位版本号文件】
rem call :fun_calc_otp_ver OTP_VER "%ERL%" "%ERL_INST%"
:fun_calc_otp_ver
rem erlang:system_info(otp_release) 在OTP 17之后,只能获取主版本号
rem Win和Linux通行的方案是通过 os:find_executable("erl") 找到erl.exe,
rem 然后读取这个文件 ../../release/MainOTPVerion/OTP_VERSION
rem 在Win上可以简化为安装路径下的 releases/MainOTPVerion/OTP_VERSION
set erlbin=%2
set erlInst=%3
setlocal enabledelayedexpansion
for /f "usebackq delims=" %%i in (`"%erlbin% -noshell -eval ""io:fwrite(""""^~s"""",[erlang:system_info(otp_release)]),halt(0)"""`) do (
set otpMainVer=%%i
)
set releaseFile=%erlInst%\releases\%otpMainVer%\OTP_VERSION
for /f "usebackq delims=" %%i in (`type %releaseFile%`) do (
set otpVer=%%i
)
endlocal & set "%~1=%otpVer%" & goto :EOF
rem 查找otp version【不调用erl获取主版本号,依赖文件系统下仅存一个版本号目录来定位文件】
:fun_calc_otp_ver_simple OTP_VER "%ERL_INST%"
set erlInst=%2
set releaseDir=%erlInst%\releases
setlocal enabledelayedexpansion
cd /d %releaseDir%
for /f "usebackq delims=" %%i in (`dir /AD /B`) do (
set releaseFile=%releaseDir%\%%i\OTP_VERSION
)
for /f "usebackq delims=" %%i in (`type %releaseFile%`) do (
set otpVer=%%i
)
endlocal & set "%~1=%otpVer%" & goto :EOF
:fun_error
echo ---------------------
if "%1"=="" (
echo 出错了!
) ELSE (
echo %1
)
echo ---------------------
echo.
pause
goto :EOF