@echo off
chcp 936 >nul 2>&1
setlocal enabledelayedexpansion
title 源声AI直播智能体 · 一键安装
color 0B

rem 安装包固定入口：服务端 源声AI_手动部署包.zip 永远指向最新版，重打新包不用改脚本
set "ZIP_URL=https://download.tb1688.top/%E6%BA%90%E5%A3%B0AI_%E6%89%8B%E5%8A%A8%E9%83%A8%E7%BD%B2%E5%8C%85.zip"
set "VER_URL=https://download.tb1688.top/version.txt"
set "PY_URL=https://download.tb1688.top/python-3.12.8-amd64.exe"
set "SITE=https://download.tb1688.top/"

echo.
echo   ==========================================================
echo     源声AI直播智能体 · 一键安装
echo     自动下载 -^- 解压 -^- 补环境 -^- 建桌面图标 -^- 启动
echo   ==========================================================
echo.

set "INSTALL_DIR=%RUNHE_INSTALL_DIR%"
if not defined INSTALL_DIR (
  if exist "D:\" (set "INSTALL_DIR=D:\源声AI直播智能体") else (set "INSTALL_DIR=%USERPROFILE%\源声AI直播智能体")
)
set "APP_DIR=%INSTALL_DIR%\app"
set "ZIP_FILE=%INSTALL_DIR%\源声AI_手动部署包.zip"

echo   安装位置：%INSTALL_DIR%
echo.
echo   现在开始安装，约 1-3 分钟...
ping -n 4 127.0.0.1 >nul
echo.

if not exist "%INSTALL_DIR%" mkdir "%INSTALL_DIR%" 2>nul
if not exist "%INSTALL_DIR%" (
  echo   [错误] 创建安装目录失败，请换一个位置，或右键"以管理员身份运行"。
  goto :end_pause
)

rem ================= 1/5 检查是否需要更新 =================
rem 旧逻辑只看本地 version.txt，版本号没变就永远不更新 —— 导致修好的包装不上。
rem 现在三道判据，任一命中就重装：
rem   ① 服务端版本号 != 本地版本号
rem   ② 服务端主程序不存在
rem   ③ 目录布局是旧的（缺 _工具\ 或 _说明\）
set "CURVER="
if exist "%APP_DIR%\version.txt" (
  for /f "usebackq delims=" %%v in ("%APP_DIR%\version.txt") do set "CURVER=%%v"
)
set "SRVVER="
if exist "%INSTALL_DIR%\version.txt" del /f /q "%INSTALL_DIR%\version.txt" >nul 2>&1
powershell -NoProfile -Command "try{ (Invoke-WebRequest -Uri '%VER_URL%' -UseBasicParsing -TimeoutSec 60).Content.Trim() | Out-File -Encoding ascii -FilePath '%INSTALL_DIR%\version.txt' }catch{ exit 1 }" >nul 2>&1
if exist "%INSTALL_DIR%\version.txt" (
  for /f "usebackq delims=" %%v in ("%INSTALL_DIR%\version.txt") do if not defined SRVVER set "SRVVER=%%v"
)

set "NEED=1"
if not defined SRVVER (
  echo   [1/5] 取不到服务端版本号，按最新版处理。
) else (
  if "!CURVER!"=="!SRVVER!" (
    if exist "%APP_DIR%\server\danmaku_server.py" (
      if exist "%APP_DIR%\_工具\一键启动.bat" (
        set "NEED=0"
      )
    )
  )
)

if "!NEED!"=="0" (
  echo   [1/5] 已是最新版 v!SRVVER!，跳过下载。
  goto :check_python
)
if defined CURVER (
  echo   [1/5] 检测到已装 v!CURVER!，正在更新到 v!SRVVER!（授权与数据都会保留）...
) else (
  echo   [1/5] 正在下载安装包（约 410 KB）...
)
powershell -NoProfile -Command "try{Invoke-WebRequest -Uri '%ZIP_URL%' -OutFile '%ZIP_FILE%' -UseBasicParsing -TimeoutSec 300}catch{exit 1}"
if not exist "%ZIP_FILE%" (
  echo   [错误] 下载失败，请检查网络，或到 %SITE% 手动下载。
  goto :end_pause
)

rem 说明：原本这里做 MD5 校验，但「安装包重打」和「脚本更新」会互相牵扯，
rem 一漏就 100%% 误报"校验不通过"，反而卡住客户（2026-09-17 踩过）。
rem 现在改成体积校验：小于 100 KB 说明下到了 404 页/错误文件；zip 本身 CRC 会在解压时兜住。
for %%a in ("%ZIP_FILE%") do set "ZSIZE=%%~za"
if not defined ZSIZE set "ZSIZE=0"
if !ZSIZE! LSS 100000 (
  echo   [错误] 下载的文件不完整或网络中断，请重新运行一次。
  del /f /q "%ZIP_FILE%" 2>nul
  goto :end_pause
)
echo         下载完成。

rem ================= 2/5 解压 =================
echo   [2/5] 正在解压...
if exist "%INSTALL_DIR%\_x" rmdir /s /q "%INSTALL_DIR%\_x" 2>nul
powershell -NoProfile -Command "try{Expand-Archive -LiteralPath '%ZIP_FILE%' -DestinationPath '%INSTALL_DIR%\_x' -Force}catch{exit 1}"
set "PKGDIR="
for /d %%d in ("%INSTALL_DIR%\_x\*") do if not defined PKGDIR set "PKGDIR=%%d"
if not exist "!PKGDIR!\server\danmaku_server.py" (
  echo   [错误] 解压失败或包内容不对，请再运行一次；仍失败就到 %SITE% 手动下载。
  goto :end_pause
)
rem ---- 升级前先停掉正在运行的本机服务，防止文件被占用 ----
for /f "tokens=5" %%p in ('netstat -ano -p tcp ^| findstr LISTENING ^| findstr :8901') do (
  taskkill /f /pid %%p >nul 2>&1
)
rem 多等一秒给文件句柄释放（SQLite 的 wal 文件经常要一秒）
ping -n 3 127.0.0.1 >nul
rem ---- 覆盖式更新，不删目录、不动 data ----
rem 说明：早先的写法是「先删掉整个 app 目录，再把新包搬进去」，有两个硬伤：
rem   1) 服务还在跑时目录删不干净，删不掉就让后面的 move 失败，客户直接卡死；
rem   2) data 目录（授权、积分、账号）会被一起删掉，客户得重新申请开通。
rem 所以改成原址覆盖，只动程序文件，绝不影响 data。
xcopy "!PKGDIR!\*" "%APP_DIR%\" /s /e /y /i >nul 2>&1
rmdir /s /q "%INSTALL_DIR%\_x" 2>nul
if not exist "%APP_DIR%\server\danmaku_server.py" (
  echo   [错误] 文件复制失败，请确认磁盘空间足够后重试。
  goto :end_pause
)
rem 旧布局残留清理（P30 起改成 _工具\ 与 _说明\，老版本的散文件留着会让客户点错）
del /f /q "%APP_DIR%\一键启动.bat" >nul 2>&1
del /f /q "%APP_DIR%\打开面板.bat" >nul 2>&1
del /f /q "%APP_DIR%\0_先看我_安装说明.html" >nul 2>&1
if defined SRVVER (echo !SRVVER!>"%APP_DIR%\version.txt") else (echo 1.6.4>"%APP_DIR%\version.txt")
echo         解压完成，当前版本 v!SRVVER!。

rem ================= 3/5 补 Python 环境 =================
:check_python
echo   [3/5] 正在补环境（Python）...
rem 注意：where 能查到 python 不等于能用。Windows 自带的应用执行别名
rem 在 ...\WindowsApps\python.exe，那个是空壳，where 出来一执行就闪退，
rem 以前客户那边报错"我明明装了 Python 它却说没有"就是踩的这里。
rem 所以过滤掉 WindowsApps，并且必须实际跑一次才算数。
set "HASPY="
for /f "delims=" %%p in ('where python 2^>nul') do (
  if not defined HASPY (
    echo %%p | findstr /i "WindowsApps" >nul || set "HASPY=%%p"
  )
)
if not defined HASPY (
  for /f "delims=" %%p in ('where py 2^>nul') do (
    if not defined HASPY (
      echo %%p | findstr /i "WindowsApps" >nul || set "HASPY=%%p"
    )
  )
)
rem 实际确认：能跑起来才算数
if defined HASPY (
  "!HASPY!" -c "import sys" >nul 2>&1 || set "HASPY="
)
if defined HASPY (
  echo         已检测到 Python，直接使用。
  goto :step_link
)

echo         本机没有 Python，正在自动安装（约 27 MB，1-3 分钟）...
set "PY_FILE=%INSTALL_DIR%\python-3.12.8-amd64.exe"
if not exist "%PY_FILE%" (
  powershell -NoProfile -Command "try{Invoke-WebRequest -Uri '%PY_URL%' -OutFile '%PY_FILE%' -UseBasicParsing -TimeoutSec 900}catch{exit 1}"
)
if not exist "%PY_FILE%" (
  echo   [提示] Python 安装包没下下来，已帮你打开 %SITE% 点「Python 环境包」手动安装，
  echo          安装时请勾选 "Add python.exe to PATH"，装完再双击本脚本一次。
  start "" "%SITE%"
  goto :end_pause
)

echo         正在静默安装（只装当前用户，不污染系统）...
start /wait "" "%PY_FILE%" /quiet InstallAllUsers=0 PrependPath=1 Include_launcher=1
set "PATH=%PATH%;%LOCALAPPDATA%\Programs\Python\Python312\;%LOCALAPPDATA%\Programs\Python\Python312\Scripts\"
rem 装完直接沿用刚装好的绝对路径，避免又踩到 WindowsApps 空壳
set "HASPY="
if exist "%LOCALAPPDATA%\Programs\Python\Python312\python.exe" set "HASPY=%LOCALAPPDATA%\Programs\Python\Python312\python.exe"
if not defined HASPY (
  for /f "delims=" %%p in ('where python 2^>nul') do (
    if not defined HASPY (
      echo %%p | findstr /i "WindowsApps" >nul || set "HASPY=%%p"
    )
  )
)
if not defined HASPY (
  for /f "delims=" %%p in ('where py 2^>nul') do (
    if not defined HASPY (
      echo %%p | findstr /i "WindowsApps" >nul || set "HASPY=%%p"
    )
  )
)
if defined HASPY (
  "!HASPY!" -c "import sys" >nul 2>&1 || set "HASPY="
)
if not defined HASPY (
  echo   [提示] 自动安装没成功（可能被安全软件拦了）。
  echo          已打开 %SITE% 请手动安装 Python 3.12，勾选 "Add python.exe to PATH"，装完再双击本脚本一次。
  start "" "%SITE%"
  goto :end_pause
)
echo         Python 装好了。

rem ================= 4/5 桌面图标 =================
:step_link
set "ICO=%SystemRoot%\System32\shell32.dll,25"
if exist "%APP_DIR%\源声AI直播智能体.ico" set "ICO=%APP_DIR%\源声AI直播智能体.ico"
echo   [4/5] 正在创建桌面图标...
set "LNKRES="
for /f "delims=" %%r in ('powershell -NoProfile -Command "$d=[Environment]::GetFolderPath('Desktop'); try{ if(-not $d){exit 1}; $p=Join-Path $d '源声AI直播智能体.lnk'; $s=(New-Object -ComObject WScript.Shell).CreateShortcut($p); $s.TargetPath='%APP_DIR%\源声AI直播智能体.vbs'; $s.WorkingDirectory='%APP_DIR%'; $s.IconLocation='%ICO%'; $s.Description='源声AI直播智能体 · 一键启动'; $s.Save(); if(Test-Path $p){'OK'}else{'FAIL'} }catch{'FAIL'}"') do set "LNKRES=%%r"
if /i "!LNKRES!"=="OK" (
  echo         桌面图标已创建，以后双击它就能用（无黑窗口）。
) else (
  echo         [提示] 桌面图标没建成，不影响使用，手动双击 %APP_DIR%\源声AI直播智能体.vbs 即可。
)

rem ================= 5/5 开机自启 + 启动 =================
rem 注意开机自启给客户装的是带 /silent 的（只起服务、不弹面板）。
rem 双击桌面图标走的就是这里，装完的这次启动不带 /silent，会直接把面板打开。
echo   [5/5] 正在注册开机自启...
rem 注意：cmd 的 ^ 和双引号在嵌套里转义很麻烦，交给 PowerShell 处理更稳。
rem 一律加 -ErrorAction SilentlyContinue，不用 | Out-Null。
powershell -NoProfile -Command "$q=[char]34; $k='HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'; New-Item -Path $k -Force -ErrorAction SilentlyContinue; $v='wscript.exe '+$q+'%APP_DIR%\源声AI直播智能体.vbs'+$q+' /silent'; Set-ItemProperty -Path $k -Name 'RunheDanmaku' -Value $v -ErrorAction SilentlyContinue" >nul 2>&1
set "AUTORES="
for /f "tokens=2,*" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v RunheDanmaku 2^>nul ^| findstr /i RunheDanmaku') do set "AUTORES=%%b"
if defined AUTORES (
  echo         已设置开机自动后台启动（无窗口）。
) else (
  echo         [提示] 开机自启没注册上，不影响使用，双击桌面图标一样能开。
)
echo         正在后台启动...
start "" wscript.exe "%APP_DIR%\源声AI直播智能体.vbs"

echo.
echo   ==========================================================
echo     装好了，马上为你打开操作面板...
echo     · 以后每天开机：双击桌面「源声AI直播智能体」图标
echo     · 出问题排查：双击 %APP_DIR%\_工具\一键启动.bat（带窗口，看得到日志）
echo     · 首次生成的本地口令写在：%APP_DIR%\data\api_token.txt
echo     · 浏览器扩展在里面：integration\extension
echo     · 扩展也能单独下：%SITE% 里的 源声AI_采集扩展.zip
echo     · 想先看图文说明：%APP_DIR%\_说明\0_先看我_安装说明.html
echo     · 下载站：%SITE%
echo   ==========================================================
echo.
echo   窗口 10 秒后自动关闭。
ping -n 11 127.0.0.1 >nul
exit /b 0

:end_pause
echo.
pause
exit /b 1
