@echo off
rem Instalador y actualizador del Mundo de Nova (Fabric + mods + servidor en la lista). Baja la version mas nueva del
rem instalador desde el servidor y la corre: vuelve a abrir este mismo archivo cuando haya mods nuevos.
rem Lo que hace se puede leer en http://212.56.34.168:8080/instalar.ps1
rem Si PowerShell esta bloqueado en el PC ("Access is denied"), instala igual con cmd + curl + certutil (modo simple).
chcp 65001 >nul
title Mundo de Nova
setlocal
echo.
echo   Si te sale "Access is denied" / "Acceso denegado": DESACTIVA EL ANTIVIRUS 10 minutos y vuelve a abrir esto.
echo.
set "LOG=%TEMP%\mundo-nova-instalador.log"
set "SRV=http://212.56.34.168:8080"

rem 1) Abierto desde dentro de un .zip: Windows no deja que el instalador guarde nada.
echo "%~dp0" | findstr /i /c:".zip\\" >nul
if not errorlevel 1 goto :desde_zip

rem 2) PowerShell: si Windows o el antivirus no lo deja abrir, cmd escribe "Access is denied" / "Acceso denegado".
where powershell >nul 2>&1
if errorlevel 1 goto :sin_powershell
powershell -NoProfile -ExecutionPolicy Bypass -Command "exit 7" >nul 2>&1
if not "%errorlevel%"=="7" goto :sin_powershell

rem 3) Normal: el instalador completo (lee el codigo de abajo, desde la linea INICIO_PS).
powershell -NoProfile -ExecutionPolicy Bypass -Command "$t = [IO.File]::ReadAllText('%~f0', [Text.Encoding]::UTF8); Invoke-Expression ($t.Substring($t.LastIndexOf('#INICIO_PS#') + 11))"
goto :fin

:desde_zip
echo.
echo   [X] Estas abriendo el instalador desde DENTRO de un .zip.
echo       Sacalo primero: clic derecho al .zip, "Extraer todo", y abre el instalador desde la carpeta extraida.
goto :fin

:sin_powershell
echo %date% %time% PowerShell bloqueado (salida %errorlevel%) >> "%LOG%"
echo.
echo   [!] Windows no deja abrir PowerShell en este PC ^(por eso salia "Access is denied" / "Acceso denegado"^).
echo       Casi siempre es EL ANTIVIRUS: desactivalo 10 minutos y vuelve a abrir el instalador ^(instalacion completa^).
echo       Mientras tanto instalo en MODO SIMPLE, sin PowerShell ^(sin el perfil del launcher oficial^).
echo.
goto :modo_simple

rem ================================================================================================================
rem MODO SIMPLE: solo cmd + curl.exe + certutil + setx (vienen con Windows 10 y 11). Compara cada archivo con
rem pack/manifest.txt (sha1) y baja solo lo que falta o cambio, igual que el instalador normal.
rem ================================================================================================================
:modo_simple
set "MC=%APPDATA%\.minecraft"
set "JUEGO=%APPDATA%\.minecraft-mundo-nova"
set "MAN=%TEMP%\mundo-nova-manifest.txt"
set /a NUEVOS=0, FALLOS=0, QUITADOS=0
where curl >nul 2>&1
if errorlevel 1 goto :sin_curl
curl -fsS --retry 2 -o "%MAN%" "%SRV%/pack/manifest.txt"
if errorlevel 1 goto :sin_servidor
for /f "usebackq tokens=1-4 delims=|" %%a in ("%MAN%") do if "%%a"=="#version" (set "PVER=%%b" & set "MCV=%%c" & set "FABV=%%d")
set "VER=fabric-loader-%FABV%-%MCV%"
echo   Mundo de Nova · Minecraft %MCV% · Fabric %FABV% · pack %PVER%

call :cerrar_juego

echo.
echo   ^>^> Fabric
mkdir "%MC%\versions\%VER%" 2>nul
curl -fsS --retry 2 -o "%MC%\versions\%VER%\%VER%.json" "https://meta.fabricmc.net/v2/versions/loader/%MCV%/%FABV%/profile/json"
if errorlevel 1 echo      no pude bajar Fabric ^(revisa internet^) & set /a FALLOS+=1
if not exist "%MC%\versions\%VER%\%VER%.jar" type nul > "%MC%\versions\%VER%\%VER%.jar"

set "TL="
if exist "%APPDATA%\.tlauncher" set "TL=1"
if exist "%MC%\TlauncherProfiles.json" set "TL=1"
if exist "%MC%\tlauncher-2.0.properties" set "TL=1"
if defined TL echo   TLauncher detectado: tambien dejo los mods en .minecraft.
if not defined TL if not exist "%JUEGO%\manifest-anterior.txt" (
  choice /c sn /m "  ¿Juegas con TLauncher o SKlauncher? (s = si, n = no)"
)
if not defined TL if not exist "%JUEGO%\manifest-anterior.txt" if not errorlevel 2 set "TL=1"
if not defined TL if exist "%JUEGO%\usa-minecraft.txt" set "TL=1"
mkdir "%JUEGO%" 2>nul
if defined TL ((echo si)> "%JUEGO%\usa-minecraft.txt") else (del "%JUEGO%\usa-minecraft.txt" 2>nul)

rem Primera vez con TLauncher: los mods que ya tenia en .minecraft\mods se guardan aparte.
if defined TL if not exist "%JUEGO%\manifest-anterior.txt" call :respaldar_mods

echo.
echo   ^>^> Revisando el perfil Mundo de Nova
call :sincronizar "%JUEGO%"
if defined TL echo.
if defined TL echo   ^>^> Revisando .minecraft ^(TLauncher/SKlauncher^)
if defined TL call :sincronizar "%MC%"

rem Mods que ya no estan en el pack: en su carpeta, todos; en .minecraft, solo los que puso el instalador.
for %%f in ("%JUEGO%\mods\*.jar") do call :quitar_si_sobra "%%f" "%%~nxf"
if defined TL if exist "%JUEGO%\manifest-anterior.txt" for /f "usebackq tokens=2 delims=|" %%r in ("%JUEGO%\manifest-anterior.txt") do call :quitar_viejo_mc "%%r"
copy /y "%MAN%" "%JUEGO%\manifest-anterior.txt" >nul

echo.
echo   ^>^> Conexion ^(IPv4^) para cualquier launcher
echo %JAVA_TOOL_OPTIONS% | findstr /c:"preferIPv4Stack" >nul
if errorlevel 1 if defined JAVA_TOOL_OPTIONS setx JAVA_TOOL_OPTIONS "%JAVA_TOOL_OPTIONS% -Djava.net.preferIPv4Stack=true" >nul
if errorlevel 1 if not defined JAVA_TOOL_OPTIONS setx JAVA_TOOL_OPTIONS "-Djava.net.preferIPv4Stack=true" >nul
echo      listo

echo.
echo %date% %time% modo simple: %NUEVOS% nuevos, %QUITADOS% quitados, %FALLOS% fallos >> "%LOG%"
if %FALLOS% GTR 0 (
  echo   [!] Quedaron %FALLOS% cosas sin hacer. Cierra Minecraft y el launcher y vuelve a abrir el instalador.
  echo       Si sigue, el antivirus puede estar bloqueando la carpeta: agregala a excepciones. ^(detalle: %LOG%^)
) else (
  echo   [OK] Listo: %NUEVOS% archivos nuevos o cambiados, %QUITADOS% quitados.
)
echo   1. CIERRA el launcher del todo y vuelve a abrirlo.
echo   2. TLauncher/SKlauncher: version %VER%.  Launcher oficial: Instalaciones, Nueva, version %VER%,
echo      carpeta del juego %JUEGO%
echo   3. Multijugador: Mundo de Nova ^(212.56.34.168^).  Primera vez: /register tuClave tuClave  luego: /login tuClave
goto :fin

:cerrar_juego
tasklist /v /fi "imagename eq javaw.exe" 2>nul | findstr /i "minecraft tlauncher" >nul
if not errorlevel 1 goto :hay_juego
tasklist /fi "imagename eq Minecraft.exe" 2>nul | findstr /i "Minecraft.exe" >nul
if not errorlevel 1 goto :hay_juego
tasklist /fi "imagename eq TLauncher.exe" 2>nul | findstr /i "TLauncher.exe" >nul
if not errorlevel 1 goto :hay_juego
exit /b
:hay_juego
echo   [!] Tienes Minecraft o el launcher abiertos: cierralos y presiona una tecla.
pause >nul
exit /b

:respaldar_mods
set "RESP=%MC%\mods-respaldo-%RANDOM%%RANDOM%"
for %%f in ("%MC%\mods\*.jar") do call :respaldar_uno "%%f" "%%~nxf"
exit /b
:respaldar_uno
findstr /l /c:"|mods/%~2|" "%MAN%" >nul
if not errorlevel 1 exit /b
mkdir "%RESP%" 2>nul
move /y "%~1" "%RESP%\" >nul && echo      tu mod %~2 quedo en %RESP%
exit /b

:sincronizar
rem La URL va por variable y no como argumento: `call` vuelve a expandir los % y dañaría el %20 de los espacios.
for /f "usebackq tokens=1-3 delims=|" %%a in ("%MAN%") do if not "%%a"=="#version" (
  set "URL=%%c"
  call :archivo "%~1" "%%a" "%%b"
)
exit /b

:archivo
set "SHA=%~2"
set "RUTA=%~3"
set "LOCAL=%~1\%RUTA:/=\%"
if /i "%RUTA%"=="servers.dat" if exist "%LOCAL%" exit /b
set "H="
if exist "%LOCAL%" call :hash "%LOCAL%"
if /i "%H%"=="%SHA%" exit /b
echo      %RUTA%
for %%d in ("%LOCAL%") do mkdir "%%~dpd" 2>nul
curl -fsS --retry 2 -o "%LOCAL%.descargando" "%SRV%/pack/%URL%"
if errorlevel 1 goto :archivo_fallo
call :hash "%LOCAL%.descargando"
if /i not "%H%"=="%SHA%" goto :archivo_fallo
attrib -r "%LOCAL%" >nul 2>&1
move /y "%LOCAL%.descargando" "%LOCAL%" >nul 2>&1
if errorlevel 1 goto :archivo_fallo
set /a NUEVOS+=1
exit /b
:archivo_fallo
del /f /q "%LOCAL%.descargando" >nul 2>&1
set /a FALLOS+=1
echo      no se pudo: %RUTA% ^(en uso por Minecraft/launcher, sin internet o antivirus^)
echo %date% %time% fallo %RUTA% >> "%LOG%"
exit /b

:hash
set "H="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%~1" SHA1') do if not defined H set "H=%%h"
set "H=%H: =%"
exit /b

:quitar_si_sobra
findstr /l /c:"|mods/%~2|" "%MAN%" >nul
if not errorlevel 1 exit /b
del /f /q "%~1" >nul 2>&1 && echo      quitado: %~2 && set /a QUITADOS+=1
exit /b

:quitar_viejo_mc
set "R=%~1"
if /i not "%R:~0,5%"=="mods/" exit /b
findstr /l /c:"|%R%|" "%MAN%" >nul
if not errorlevel 1 exit /b
set "F=%MC%\%R:/=\%"
if exist "%F%" del /f /q "%F%" >nul 2>&1 && echo      quitado: %R% && set /a QUITADOS+=1
exit /b

:sin_curl
echo   [X] Este Windows no trae curl ^(Windows 7/8 o muy viejo^). Usa el pack para Prism Launcher o Modrinth App de la pagina.
goto :fin

:sin_servidor
echo   [X] No pude conectar con el servidor del Mundo de Nova.
echo       Revisa internet; si tienes antivirus con "escudo web" o firewall, que deje 212.56.34.168; si usas VPN, apagala.
goto :fin

:fin
echo.
pause
exit /b

#INICIO_PS#
$registro = Join-Path $env:TEMP 'mundo-nova-instalador.log'
function Anotar($t) { try { Add-Content -LiteralPath $registro -Value "$(Get-Date -Format s) [bat] $t" -Encoding UTF8 } catch { } }
function Fallo($titulo, [string[]]$que) {
  Write-Host ''
  Write-Host "  [X] $titulo" -ForegroundColor Red
  $que | ForEach-Object { Write-Host "      $_" -ForegroundColor Yellow }
  Write-Host "      (detalle en $registro)"
  Anotar "$titulo :: $($que -join ' | ')"
}
if ($ExecutionContext.SessionState.LanguageMode -ne 'FullLanguage') {
  Fallo 'Este PC tiene PowerShell en modo restringido.' @('Es una política del administrador (PC de colegio o trabajo) o de un antivirus.', 'Cierra esta ventana: vuelve a abrir el instalador y, si sigue, usa el pack para Prism Launcher o Modrinth App de la página.')
  exit 1
}
$w = New-Object Net.WebClient
$w.Encoding = [Text.Encoding]::UTF8
try {
  $s = $w.DownloadString('http://212.56.34.168:8080/instalar.ps1')
} catch {
  $m = $_.Exception.Message
  if ($_.Exception.InnerException) { $m += ' / ' + $_.Exception.InnerException.Message }
  Fallo 'No pude conectar con el servidor del Mundo de Nova.' @(
    "Error: $m",
    'Revisa que tengas internet.',
    'Si tienes antivirus con «escudo web» o firewall, puede estar bloqueando 212.56.34.168: agrégalo a excepciones.',
    'Si usas VPN, apágala un momento.')
  exit 1
}
try {
  Invoke-Expression $s
} catch {
  $m = $_.Exception.Message
  if ($m -match 'malicious|malware|antivirus|ScriptContainedMaliciousContent|virus') {
    Fallo 'Tu antivirus bloqueó el instalador.' @("Error: $m", 'El instalador solo baja Fabric y los mods del servidor (puedes leerlo en http://212.56.34.168:8080/instalar.ps1).', 'Agrégalo a excepciones del antivirus o desactívalo 10 minutos y vuelve a abrirlo.')
  } elseif ($m -match 'denied|denegado|UnauthorizedAccess') {
    Fallo 'Windows negó el acceso.' @("Error: $m", 'Cierra Minecraft y el launcher, y vuelve a abrir el instalador.', 'Si sigue: el antivirus (protección de carpetas / ransomware) puede estar bloqueando; agrégalo a excepciones.')
  } else {
    Fallo 'El instalador se detuvo.' @("Error: $m", 'Vuelve a abrirlo. Si sigue, mándale una foto de esta ventana a Isa.')
  }
}
