@echo off
REM ==============================================================
REM 名称: repair_ydisk_dns.bat
REM 说明: 检测 ydisk.cn 访问状态，必要时临时更新DNS并验证；
REM       若仍异常则自动还原原DNS配置。
REM 使用: 需管理员权限运行；默认DNS为 114.114.114.114/8.8.8.8
REM 备注: 首次运行会在 %TEMP%\dns_backup_ydisk.json 备份DNS。
REM ==============================================================
net session >nul 2>&1
if %errorlevel% neq 0 (
  powershell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
  exit /b
)
chcp 936 >nul
setlocal enabledelayedexpansion

REM Set DNS servers for active Ethernet and Wi-Fi adapters
set DNS1=114.114.114.114
set DNS2=8.8.8.8
set BACKUP=%TEMP%\dns_backup_ydisk.json

REM Args
set FORCE=0
if /i "%~1"=="-h" goto :help
if /i "%~1"=="--help" goto :help
if /i "%~1"=="/?" goto :help
if /i "%~1"=="-r" goto :restore
if /i "%~1"=="--restore" goto :restore
if /i "%~1"=="-s" goto :show
if /i "%~1"=="--show" goto :show
if /i "%~1"=="-f" set FORCE=1
if /i "%~1"=="--force" set FORCE=1

if %FORCE% equ 0 (
  call :check_ydisk
  if %errorlevel% equ 0 (
    echo 域名ydisk.cn 访问正常，无需更新DNS。
    endlocal
    exit /b 0
  )
) else (
  echo 已启用强制模式，跳过 ydisk.cn 检查。
)

echo ydisk.cn 访问异常，尝试更新DNS为：%DNS1%、%DNS2%
powershell -NoProfile -ExecutionPolicy Bypass -Command "& { $dns=@('%DNS1%','%DNS2%'); $candidates=@(); foreach ($a in Get-NetAdapter) { if ($a.Status -eq 'Up' -and ($a.Name -notmatch 'OpenVPN|TAP|Wintun|Loopback|Virtual')) { $candidates += $a } }; $adapters=@(); foreach ($a in $candidates) { if ($a.Name -match '以太网|Ethernet|WLAN|Wi-?Fi|无线' -or $a.InterfaceDescription -match 'Ethernet|Wireless|Wi-?Fi') { $adapters += $a } }; if (-not $adapters -and $candidates.Count -gt 0) { $adapters = $candidates }; if (-not $adapters) { Write-Host '未找到活动的以太网/无线网卡。'; exit 1 }; if (-not (Test-Path '%BACKUP%')) { $backup=@(); foreach ($a in $adapters) { $addr=(Get-DnsClientServerAddress -InterfaceIndex $a.ifIndex -AddressFamily IPv4).ServerAddresses; $backup += [pscustomobject]@{ ifIndex=$a.ifIndex; Name=$a.Name; ServerAddresses=$addr } }; $json=ConvertTo-Json -InputObject $backup; Set-Content -Encoding UTF8 -Path '%BACKUP%' -Value $json; Write-Host '已备份原始DNS。' } foreach ($a in $adapters) { try { Set-DnsClientServerAddress -InterfaceIndex $a.ifIndex -ServerAddresses $dns -ErrorAction Stop; Write-Host ('已设置DNS：{0}' -f $a.Name) } catch { Write-Host ('设置失败：{0} -> {1}' -f $a.Name, $_.Exception.Message) } } }"
if %errorlevel% neq 0 (
  echo DNS设置失败或未找到活动网卡！
  echo 按任意键退出...
  pause >nul
  endlocal
  exit /b 1
)

ipconfig /flushdns >nul
if %errorlevel% equ 0 (
  echo DNS缓存已刷新。
) else (
  echo DNS缓存刷新失败。
)

call :check_ydisk
if %errorlevel% equ 0 (
  echo 域名 ydisk.cn 已访问正常。
  endlocal
  exit /b 0
)

echo 域名 ydisk.cn 访问仍异常，还原DNS...
powershell -NoProfile -ExecutionPolicy Bypass -Command "& { if (Test-Path '%BACKUP%') { $content=Get-Content -Raw '%BACKUP%'; $backup=ConvertFrom-Json -InputObject $content; foreach ($item in $backup) { try { Set-DnsClientServerAddress -InterfaceIndex $item.ifIndex -ServerAddresses $item.ServerAddresses -ErrorAction Stop; Write-Host ('已还原DNS：{0}' -f $item.Name) } catch { Write-Host ('还原失败：{0} -> {1}' -f $item.Name, $_.Exception.Message) } } } else { Write-Host '未找到备份文件，无法还原。' } }"

ipconfig /flushdns >nul
if %errorlevel% equ 0 (
  echo DNS缓存已刷新。
) else (
  echo DNS缓存刷新失败。
)

endlocal
exit /b 1

:restore
powershell -NoProfile -ExecutionPolicy Bypass -Command "& { if (Test-Path '%BACKUP%') { $content=Get-Content -Raw '%BACKUP%'; $backup=ConvertFrom-Json -InputObject $content; foreach ($item in $backup) { try { Set-DnsClientServerAddress -InterfaceIndex $item.ifIndex -ServerAddresses $item.ServerAddresses -ErrorAction Stop; Write-Host ('已还原DNS：{0}' -f $item.Name) } catch { Write-Host ('还原失败：{0} -> {1}' -f $item.Name, $_.Exception.Message) } } } else { Write-Host '未找到备份文件，无法还原。' ; exit 1 } }"
ipconfig /flushdns >nul
if %errorlevel% equ 0 (
  echo DNS缓存已刷新。
) else (
  echo DNS缓存刷新失败。
)
endlocal
exit /b 0

:help
echo.
echo 用法: %~nx0 [选项]
echo.
echo 选项:
echo   -h, --help       显示帮助
echo   -r, --restore    从备份恢复DNS并退出
echo   -s, --show       显示当前DNS并退出
echo   -f, --force      不检查 ydisk.cn，直接修改DNS
echo.
echo 说明:
echo   - 首次运行会自动备份当前DNS到 %BACKUP%
echo   - 后续运行不会覆盖已有备份
echo   - 仅当访问 ydisk.cn 异常时才会更新DNS
endlocal
exit /b 0

:show
powershell -NoProfile -ExecutionPolicy Bypass -Command "& { $adapters=Get-NetAdapter | Where-Object { $_.Status -eq 'Up' -and ($_.Name -notmatch 'OpenVPN|TAP|Wintun|Loopback|Virtual') }; if (-not $adapters) { Write-Host '未找到活动网卡。'; exit 1 }; foreach ($a in $adapters) { $dns=(Get-DnsClientServerAddress -InterfaceIndex $a.ifIndex -AddressFamily IPv4).ServerAddresses; Write-Host ('{0}: {1}' -f $a.Name, ($dns -join ', ')) } }"
endlocal
exit /b %errorlevel%

:check_ydisk
powershell -NoProfile -ExecutionPolicy Bypass -Command "$ok=$false; try { $null=Resolve-DnsName ydisk.cn -ErrorAction Stop; $ok=Test-NetConnection -ComputerName ydisk.cn -CommonTCPPort HTTP -InformationLevel Quiet } catch { $ok=$false }; if ($ok) { exit 0 } else { exit 1 }"
exit /b %errorlevel%

:check_internet
powershell -NoProfile -ExecutionPolicy Bypass -Command "$ok=$false; try { $r=Invoke-WebRequest -Uri 'http://baidu.com' -UseBasicParsing -TimeoutSec 5; if ($r.StatusCode -ge 200 -and $r.StatusCode -lt 400) { $ok=$true } } catch { $ok=$false }; if (-not $ok) { try { $r=Invoke-WebRequest -Uri 'http://bing.com' -UseBasicParsing -TimeoutSec 5; if ($r.StatusCode -ge 200 -and $r.StatusCode -lt 400) { $ok=$true } } catch { $ok=$false } }; if (-not $ok) { try { $null=Resolve-DnsName baidu.com -ErrorAction Stop; $ok=$true } catch { $ok=$false } }; if ($ok) { exit 0 } else { exit 1 }"
exit /b %errorlevel%
