autool-dispatcher/scripts/recover_mumu.cmd
2026-06-17 19:50:39 +08:00

239 lines
7.6 KiB
Batchfile

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "BACKUP_FULL_PATH=%~1"
set "LOCAL_IMPORT_DIR=%~2"
set "MUMU_MANAGER_PATH=%~3"
set "VM_ID=%~4"
set "DEFAULT_NET_BRIDGE_CARD=%~5"
set "AHK_EXE=%~6"
set "BRIDGE_IP_OFFSET=%~7"
set "GATEWAY_RULES=%~8"
if not defined BACKUP_FULL_PATH call :fail "BACKUP_FULL_PATH argument is required"
if not defined LOCAL_IMPORT_DIR set "LOCAL_IMPORT_DIR=D:\mumu_backups"
if not defined MUMU_MANAGER_PATH set "MUMU_MANAGER_PATH=C:\Program Files\Netease\MuMu\nx_main\MuMuManager.exe"
if not defined VM_ID set "VM_ID=2"
if not defined DEFAULT_NET_BRIDGE_CARD set "DEFAULT_NET_BRIDGE_CARD=Realtek PCIe GbE Family Controller"
if not defined AHK_EXE call :fail "AHK_EXE argument is required"
if not defined BRIDGE_IP_OFFSET set "BRIDGE_IP_OFFSET=100"
if not defined GATEWAY_RULES call :fail "GATEWAY_RULES argument is required, format: 192.168.1=192.168.1.1;192.168.2=192.168.2.1"
set "SUBNET_MASK=255.255.255.0"
set "DNS1=8.8.8.8"
set "DNS2=1.1.1.1"
set "POLL_MAX=300"
for %%I in ("%BACKUP_FULL_PATH%") do (
set "BACKUP_DIR=%%~dpI"
set "BACKUP_FILENAME=%%~nxI"
)
if "!BACKUP_DIR:~-1!"=="\" set "BACKUP_DIR=!BACKUP_DIR:~0,-1!"
set "IMPORT_FILE=%LOCAL_IMPORT_DIR%\%BACKUP_FILENAME%"
set "RESULT_FILE=%LOCAL_IMPORT_DIR%\result.txt"
set "AHK_BAT=%LOCAL_IMPORT_DIR%\_run_ahk.bat"
echo ==================================================
echo Recover MuMu image started
echo ==================================================
echo [INFO] Backup source: %BACKUP_FULL_PATH%
echo [INFO] Local import dir: %LOCAL_IMPORT_DIR%
echo [INFO] MuMu manager: %MUMU_MANAGER_PATH%
echo [INFO] VM index: %VM_ID%
echo [INFO] AHK executable: %AHK_EXE%
if not exist "%MUMU_MANAGER_PATH%" call :fail "MuMuManager.exe not found: %MUMU_MANAGER_PATH%"
if not exist "%BACKUP_FULL_PATH%" call :fail "Remote backup not found: %BACKUP_FULL_PATH%"
if not exist "%LOCAL_IMPORT_DIR%" (
mkdir "%LOCAL_IMPORT_DIR%"
if errorlevel 1 call :fail "Failed to create local import dir: %LOCAL_IMPORT_DIR%"
)
call :sync_backup
if errorlevel 1 exit /b 1
call :run_restore
if errorlevel 1 exit /b 1
call :configure_network
if errorlevel 1 exit /b 1
echo ==================================================
echo MuMu restore and network config completed successfully.
echo ==================================================
exit /b 0
:sync_backup
echo [Phase 1] Check and synchronize backup image
set "NEED_COPY_BACKUP=1"
set "REMOTE_BACKUP_TIME="
set "LOCAL_BACKUP_TIME="
for %%I in ("%BACKUP_FULL_PATH%") do set "REMOTE_BACKUP_TIME=%%~tI"
echo [INFO] Remote backup time = !REMOTE_BACKUP_TIME!
if exist "%IMPORT_FILE%" (
for %%I in ("%IMPORT_FILE%") do set "LOCAL_BACKUP_TIME=%%~tI"
echo [INFO] Local backup time = !LOCAL_BACKUP_TIME!
if /i "!REMOTE_BACKUP_TIME!"=="!LOCAL_BACKUP_TIME!" (
echo [INFO] Backup timestamps match. Skip copying backup file.
set "NEED_COPY_BACKUP=0"
)
) else (
echo [INFO] Local backup file not found. A fresh copy is required.
)
if "!NEED_COPY_BACKUP!"=="1" (
echo [INFO] Copying backup file from %BACKUP_DIR% to %LOCAL_IMPORT_DIR% ...
robocopy "%BACKUP_DIR%" "%LOCAL_IMPORT_DIR%" "%BACKUP_FILENAME%" /R:2 /W:2 /COPY:DAT /DCOPY:T /NFL /NDL /NJH /NJS /NP >nul
if !errorlevel! gtr 7 call :fail "Failed to copy backup file to %IMPORT_FILE%"
)
exit /b 0
:run_restore
echo [Phase 2] Run MuMu restore through RunAHK scheduled task
echo [INFO] Shutting down MuMu emulator...
"%MUMU_MANAGER_PATH%" control -v %VM_ID% shutdown
call :sleep 15
echo [INFO] Killing MuMu-related processes if they are running...
call :kill_mumu_processes
call :sleep 5
del /f /q "%RESULT_FILE%" >nul 2>&1
(
echo @echo off
echo "%AHK_EXE%" "%IMPORT_FILE%" %VM_ID% "%RESULT_FILE%"
) > "%AHK_BAT%"
if errorlevel 1 call :fail "Failed to write AHK runner: %AHK_BAT%"
schtasks /delete /tn "RunAHK" /f >nul 2>&1
schtasks /create /tn "RunAHK" /tr "%AHK_BAT%" /sc ONCE /st 00:00 /rl HIGHEST /it /f >nul
if errorlevel 1 call :fail "Failed to create RunAHK task"
schtasks /run /tn "RunAHK" >nul
if errorlevel 1 call :fail "Failed to start RunAHK task"
echo [INFO] Waiting for restore result file: %RESULT_FILE%
for /l %%I in (1,1,%POLL_MAX%) do (
if exist "%RESULT_FILE%" goto :check_restore_result
call :sleep 2
)
call :fail "AHK restore timed out"
:check_restore_result
call :sleep 3
set "RESTORE_RESULT="
set /p RESTORE_RESULT=<"%RESULT_FILE%"
echo [INFO] AHK result: !RESTORE_RESULT!
echo !RESTORE_RESULT! | findstr /i /c:"OK" >nul
if errorlevel 1 call :fail "AHK restore failed: !RESTORE_RESULT!"
exit /b 0
:configure_network
echo [Phase 3] Configure MuMu network
call :detect_network_adapter
if errorlevel 1 exit /b 1
call :detect_bridge_network
if errorlevel 1 exit /b 1
call :set_mumu_setting net_bridge_card "!NetAdapterName!"
if errorlevel 1 exit /b 1
call :set_mumu_setting net_bridge_ip_mode static
if errorlevel 1 exit /b 1
call :set_mumu_setting net_bridge_ip_addr "!BRIDGE_IP!"
if errorlevel 1 exit /b 1
call :set_mumu_setting net_bridge_gateway "!GATEWAY!"
if errorlevel 1 exit /b 1
call :set_mumu_setting net_bridge_subnet_mask %SUBNET_MASK%
if errorlevel 1 exit /b 1
call :set_mumu_setting net_bridge_dns1 %DNS1%
if errorlevel 1 exit /b 1
call :set_mumu_setting net_bridge_dns2 %DNS2%
if errorlevel 1 exit /b 1
echo [INFO] Network configuration completed successfully.
exit /b 0
:kill_mumu_processes
for %%P in (MuMuPlayer.exe MuMuNxDevice.exe MuMuNxMain.exe MuMuManager.exe) do (
taskkill /F /IM %%P >nul 2>&1
)
exit /b 0
:detect_network_adapter
set "NetAdapterName="
for /f "tokens=* skip=1" %%a in ('wmic nic where "NetConnectionStatus=2" get Name /value 2^>nul') do (
if "!NetAdapterName!"=="" (
for /f "tokens=2 delims==" %%b in ("%%a") do set "NetAdapterName=%%b"
)
)
if not "!NetAdapterName!"=="" (
for /f "tokens=*" %%a in ("!NetAdapterName!") do set "NetAdapterName=%%a"
)
if "!NetAdapterName!"=="" set "NetAdapterName=%DEFAULT_NET_BRIDGE_CARD%"
echo [INFO] net_bridge_card = !NetAdapterName!
exit /b 0
:detect_bridge_network
set "LOCAL_IP="
set "LOCAL_PREFIX="
for /f "tokens=2 delims=:" %%a in ('ipconfig ^| findstr /r /c:"[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*"') do (
if not defined LOCAL_IP (
set "CANDIDATE_IP=%%a"
set "CANDIDATE_IP=!CANDIDATE_IP: =!"
for /f "tokens=1-4 delims=." %%b in ("!CANDIDATE_IP!") do (
call :find_gateway "%%b.%%c.%%d"
if defined GATEWAY (
set "LOCAL_IP=!CANDIDATE_IP!"
set "LOCAL_PREFIX=%%b.%%c.%%d"
)
)
)
)
if not defined LOCAL_IP call :fail "Failed to detect local IPv4 address matching GATEWAY_RULES: %GATEWAY_RULES%"
echo [INFO] Local IP: !LOCAL_IP!
set "BRIDGE_IP="
for /f "tokens=1-4 delims=." %%a in ("!LOCAL_IP!") do (
set /a LAST_OCTET=%%d + %BRIDGE_IP_OFFSET%
if !LAST_OCTET! gtr 254 call :fail "Local IP last octet is too large for bridge IP derivation"
set "BRIDGE_IP=%%a.%%b.%%c.!LAST_OCTET!"
)
echo [INFO] net_bridge_ip_addr = !BRIDGE_IP!
echo [INFO] net_bridge_gateway = !GATEWAY!
exit /b 0
:find_gateway
set "GATEWAY="
set "TARGET_PREFIX=%~1"
for %%R in ("%GATEWAY_RULES:;=" "%") do (
for /f "tokens=1,* delims==" %%K in ("%%~R") do (
if "%%K"=="!TARGET_PREFIX!" set "GATEWAY=%%L"
)
)
exit /b 0
:set_mumu_setting
set "SETTING_KEY=%~1"
set "SETTING_VALUE=%~2"
echo [INFO] !SETTING_KEY! = !SETTING_VALUE!
"%MUMU_MANAGER_PATH%" setting -v %VM_ID% -k "!SETTING_KEY!" -val "!SETTING_VALUE!"
if errorlevel 1 call :fail "Failed to set !SETTING_KEY!"
exit /b 0
:sleep
set /a SLEEP_COUNT=%~1 + 1
ping -n !SLEEP_COUNT! 127.0.0.1 >nul
exit /b 0
:fail
echo.
echo [ERROR] %~1 1>&2
echo Recover MuMu aborted. 1>&2
exit 1