Option Explicit

Const GAME_ID = "892970"
Const VPLUS_URL = "https://vh.cybrp.com/WindowsClient.zip"
Const MODPACK_URL = "https://vh.cybrp.com/VALHEIM_CLIENT_MODPACK_20260616.zip"
Const MODPACK_LOCAL_NAME = "VALHEIM_CLIENT_MODPACK_20260616.zip"
Const WAIT_INSTALL_SECONDS = 3600   ' 1 ??? ???????? ????????? ????

Dim fso, sh
Set fso = CreateObject("Scripting.FileSystemObject")
Set sh = CreateObject("WScript.Shell")

' --- UAC auto-elevate ---
If Not IsElevated() Then
    CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """", "", "runas", 1
    WScript.Quit 0
End If
' ------------------------

Dim steamPath, valheimPath, desktopPath
Dim zipPath, modpackZipPath, vanillaCmdPath, plusCmdPath, scriptDir

If MsgBox("Скрипт выполнит полную настройку:" & vbCrLf & _
          "- проверит/установит Valheim" & vbCrLf & _
          "- установит Valheim Plus" & vbCrLf & _
          "- установит клиентский модпак" & vbCrLf & _
          "- создаст 2 ярлыка (Valheim / Valheim Plus)" & vbCrLf & vbCrLf & _
          "Перед началом закрой Steam и Valheim.", _
          vbOKCancel + vbInformation, "Valheim Setup") <> vbOK Then
    WScript.Quit 0
End If

steamPath = GetSteamPath()
scriptDir = GetScriptDir()
If steamPath = "" Then
    MsgBox "Steam не найден в реестре HKCU\Software\Valve\Steam\SteamPath", vbCritical, "Ошибка"
    WScript.Quit 1
End If

valheimPath = DetectValheimPath(steamPath)

If valheimPath = "" Then
    MsgBox "Valheim не найден. Сейчас открою установку игры в Steam." & vbCrLf & _
           "Дождись завершения установки в Steam.", vbInformation, "Установка Valheim"
    sh.Run "steam://install/" & GAME_ID, 1, False

    valheimPath = WaitForValheimInstalled(steamPath, WAIT_INSTALL_SECONDS)
    If valheimPath = "" Then
        MsgBox "Не дождался установки Valheim." & vbCrLf & _
               "Установи игру в Steam и запусти скрипт снова.", vbCritical, "Ошибка"
        WScript.Quit 1
    End If
End If

If Not fso.FileExists(valheimPath & "\valheim.exe") Then
    MsgBox "valheim.exe не найден: " & valheimPath, vbCritical, "Ошибка"
    WScript.Quit 1
End If

ShowStep "Шаг 1/4: Скачиваю Valheim Plus..."
zipPath = sh.ExpandEnvironmentStrings("%TEMP%") & "\ValheimPlus_WindowsClient.zip"
If Not DownloadFilePS(VPLUS_URL, zipPath) Then
    MsgBox "Не удалось скачать архив Valheim Plus с GitHub.", vbCritical, "Ошибка загрузки"
    WScript.Quit 1
End If

ShowStep "Шаг 2/4: Распаковываю Valheim Plus..."
If Not ExtractZipPS(zipPath, valheimPath) Then
    MsgBox "Ошибка распаковки архива в папку игры: " & valheimPath, vbCritical, "Ошибка распаковки"
    WScript.Quit 1
End If

If Not fso.FileExists(valheimPath & "\BepInEx\plugins\ValheimPlus.dll") Then
    MsgBox "ValheimPlus.dll не найден после установки.", vbCritical, "Ошибка установки"
    WScript.Quit 1
End If

' Установка клиентского модпака (скачивание по URL или локальный zip рядом со скриптом)
modpackZipPath = sh.ExpandEnvironmentStrings("%TEMP%") & "\" & MODPACK_LOCAL_NAME
If Trim(MODPACK_URL) <> "" Then
    ShowStep "Шаг 3/4: Скачиваю клиентский модпак..."
    If Not DownloadFilePS(MODPACK_URL, modpackZipPath) Then
        MsgBox "Не удалось скачать клиентский модпак: " & MODPACK_URL, vbCritical, "Ошибка загрузки"
        WScript.Quit 1
    End If
Else
    If fso.FileExists(scriptDir & "\" & MODPACK_LOCAL_NAME) Then
        modpackZipPath = scriptDir & "\" & MODPACK_LOCAL_NAME
    Else
        MsgBox "Не найден клиентский модпак." & vbCrLf & _
               "Положи файл рядом со скриптом: " & MODPACK_LOCAL_NAME & vbCrLf & _
               "или укажи MODPACK_URL в начале скрипта.", vbCritical, "Ошибка модпака"
        WScript.Quit 1
    End If
End If

ShowStep "Шаг 4/4: Распаковываю модпак..."
If Not ExtractZipPS(modpackZipPath, valheimPath) Then
    MsgBox "Ошибка распаковки клиентского модпака в папку игры: " & valheimPath, vbCritical, "Ошибка распаковки"
    WScript.Quit 1
End If

' Базовая проверка ключевых модов после установки модпака
If Not fso.FileExists(valheimPath & "\BepInEx\plugins\TeleportEverything.dll") Then
    MsgBox "Не найден TeleportEverything.dll после установки модпака.", vbCritical, "Ошибка установки"
    WScript.Quit 1
End If
If Not fso.FileExists(valheimPath & "\BepInEx\plugins\PlanBuild\PlanBuild.dll") Then
    MsgBox "Не найден PlanBuild.dll после установки модпака.", vbCritical, "Ошибка установки"
    WScript.Quit 1
End If
If Not fso.FileExists(valheimPath & "\BepInEx\plugins\XPortal\XPortal.dll") Then
    MsgBox "Не найден XPortal.dll после установки модпака.", vbCritical, "Ошибка установки"
    WScript.Quit 1
End If
If Not fso.FileExists(valheimPath & "\BepInEx\plugins\ServerDevcommands.dll") Then
    MsgBox "Не найден ServerDevcommands.dll после установки модпака.", vbCritical, "Ошибка установки"
    WScript.Quit 1
End If
If Not fso.FileExists(valheimPath & "\BepInEx\plugins\ExtraSlots.dll") Then
    MsgBox "Не найден ExtraSlots.dll после установки модпака.", vbCritical, "Ошибка установки"
    WScript.Quit 1
End If
If Not fso.FileExists(valheimPath & "\BepInEx\plugins\YamlDotNet.dll") Then
    MsgBox "Не найден YamlDotNet.dll после установки модпака.", vbCritical, "Ошибка установки"
    WScript.Quit 1
End If
If Not fso.FileExists(valheimPath & "\BepInEx\plugins\YamlDotNetDetector.dll") Then
    MsgBox "Не найден YamlDotNetDetector.dll после установки модпака.", vbCritical, "Ошибка установки"
    WScript.Quit 1
End If

' Создаем launcher-cmd в папке игры
vanillaCmdPath = valheimPath & "\launch_valheim_vanilla.cmd"
plusCmdPath = valheimPath & "\launch_valheim_plus.cmd"

WriteVanillaCmd vanillaCmdPath, valheimPath
WritePlusCmd plusCmdPath, valheimPath

' Ярлыки на рабочем столе
desktopPath = sh.SpecialFolders("Desktop")
CreateShortcut desktopPath & "\Valheim.lnk", vanillaCmdPath, valheimPath, "Valheim Vanilla"
CreateShortcut desktopPath & "\Valheim Plus.lnk", plusCmdPath, valheimPath, "Valheim Plus"

MsgBox "Готово!" & vbCrLf & vbCrLf & _
       "Игра: " & valheimPath & vbCrLf & _
       "Valheim Plus и модпак установлены." & vbCrLf & _
       "Созданы ярлыки:" & vbCrLf & _
       "- Valheim" & vbCrLf & _
       "- Valheim Plus", vbInformation, "Установка завершена"

WScript.Quit 0


' ===== Helpers =====

Function IsElevated()
    On Error Resume Next
    Dim exec, out
    Set exec = sh.Exec("cmd /c whoami /groups | find ""S-1-16-12288""")
    out = exec.StdOut.ReadAll
    IsElevated = (Len(out) > 0)
End Function

Function GetSteamPath()
    On Error Resume Next
    GetSteamPath = sh.RegRead("HKCU\Software\Valve\Steam\SteamPath")
    If Err.Number <> 0 Then
        GetSteamPath = ""
        Err.Clear
    End If
End Function

Function GetScriptDir()
    GetScriptDir = fso.GetParentFolderName(WScript.ScriptFullName)
End Function

Function DetectValheimPath(steamRoot)
    Dim p, libs, i, candidate
    p = steamRoot & "\steamapps\common\Valheim"
    If fso.FileExists(p & "\valheim.exe") Then
        DetectValheimPath = p
        Exit Function
    End If

    libs = GetSteamLibraries(steamRoot)
    For i = 0 To UBound(libs)
        If libs(i) <> "" Then
            candidate = libs(i) & "\steamapps\common\Valheim"
            If fso.FileExists(candidate & "\valheim.exe") Then
                DetectValheimPath = candidate
                Exit Function
            End If
        End If
    Next

    DetectValheimPath = ""
End Function

Function WaitForValheimInstalled(steamRoot, timeoutSeconds)
    Dim i, p
    For i = 1 To timeoutSeconds
        p = DetectValheimPath(steamRoot)
        If p <> "" Then
            WaitForValheimInstalled = p
            Exit Function
        End If
        WScript.Sleep 1000
    Next
    WaitForValheimInstalled = ""
End Function

Function GetSteamLibraries(steamRoot)
    Dim arr(), count, vdf, ts, txt, re, matches, m, pathVal
    ReDim arr(0)
    arr(0) = ""
    count = -1

    vdf = steamRoot & "\steamapps\libraryfolders.vdf"
    If Not fso.FileExists(vdf) Then
        GetSteamLibraries = arr
        Exit Function
    End If

    Set ts = fso.OpenTextFile(vdf, 1, False)
    txt = ts.ReadAll
    ts.Close

    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = """path""\s+""([^""]+)"""
    re.Global = True
    re.IgnoreCase = True

    Set matches = re.Execute(txt)
    For Each m In matches
        pathVal = m.SubMatches(0)
        pathVal = Replace(pathVal, "\\", "\")
        If pathVal <> "" Then
            count = count + 1
            ReDim Preserve arr(count)
            arr(count) = pathVal
        End If
    Next

    If count = -1 Then
        ReDim arr(0)
        arr(0) = ""
    End If

    GetSteamLibraries = arr
End Function

Function DownloadFilePS(url, outFile)
    Dim cmd, rc
    cmd = "powershell -NoProfile -ExecutionPolicy Bypass -Command " & _
          """try { " & _
          "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; " & _
          "$ProgressPreference='Continue'; " & _
          "Write-Host 'Downloading: " & url & "'; " & _
          "Invoke-WebRequest -UseBasicParsing -Headers @{ 'User-Agent'='Mozilla/5.0' } -Uri '" & url & "' -OutFile '" & Replace(outFile, "'", "''") & "'; " & _
          "Write-Host 'Download completed.'; " & _
          "exit 0 } catch { exit 1 }"""
    rc = sh.Run(cmd, 1, True)
    DownloadFilePS = (rc = 0 And fso.FileExists(outFile))
End Function

Function ExtractZipPS(zipFile, destFolder)
    Dim cmd, rc
    cmd = "powershell -NoProfile -ExecutionPolicy Bypass -Command " & _
          """try { " & _
          "$ProgressPreference='Continue'; " & _
          "Write-Host 'Extracting: " & Replace(zipFile, "'", "''") & "'; " & _
          "Expand-Archive -LiteralPath '" & Replace(zipFile, "'", "''") & "' -DestinationPath '" & Replace(destFolder, "'", "''") & "' -Force; " & _
          "Write-Host 'Extraction completed.'; " & _
          "exit 0 } catch { exit 1 }"""
    rc = sh.Run(cmd, 1, True)
    ExtractZipPS = (rc = 0)
End Function

Sub ShowStep(msg)
    On Error Resume Next
    sh.Popup msg, 2, "CYBRP Valheim Setup", 64
End Sub

Sub WriteVanillaCmd(path, gameDir)
    Dim txt
    txt = "@echo off" & vbCrLf & _
          "cd /d """ & gameDir & """" & vbCrLf & _
          "if exist ""winhttp.dll"" (" & vbCrLf & _
          "  if not exist ""winhttp.dll.off"" ren ""winhttp.dll"" ""winhttp.dll.off""" & vbCrLf & _
          ")" & vbCrLf & _
          "start """" ""steam://rungameid/" & GAME_ID & """" & vbCrLf & _
          "exit /b 0" & vbCrLf
    WriteAll path, txt
End Sub

Sub WritePlusCmd(path, gameDir)
    Dim txt
    txt = "@echo off" & vbCrLf & _
          "cd /d """ & gameDir & """" & vbCrLf & _
          "if exist ""winhttp.dll.off"" (" & vbCrLf & _
          "  if not exist ""winhttp.dll"" ren ""winhttp.dll.off"" ""winhttp.dll""" & vbCrLf & _
          ")" & vbCrLf & _
          "if not exist ""winhttp.dll"" (" & vbCrLf & _
          "  echo [ERROR] winhttp.dll not found. Valheim Plus not installed correctly." & vbCrLf & _
          "  pause" & vbCrLf & _
          "  exit /b 1" & vbCrLf & _
          ")" & vbCrLf & _
          "start """" ""steam://rungameid/" & GAME_ID & """" & vbCrLf & _
          "exit /b 0" & vbCrLf
    WriteAll path, txt
End Sub

Sub CreateShortcut(linkPath, targetPath, workDir, desc)
    Dim lnk
    Set lnk = sh.CreateShortcut(linkPath)
    lnk.TargetPath = targetPath
    lnk.WorkingDirectory = workDir
    lnk.Description = desc
    lnk.IconLocation = workDir & "\valheim.exe,0"
    lnk.Save
End Sub

Sub WriteAll(path, content)
    Dim ts
    Set ts = fso.OpenTextFile(path, 2, True)
    ts.Write content
    ts.Close
End Sub