# Install-MCE2.ps1 - Installe le modpack MCE2 cote client (Forge + mods + profil du launcher). param([switch]$Force) $ErrorActionPreference = 'Stop' # ======================= A CONFIGURER ======================= $ManifestUrl = 'https://minecraftapi.sayzx.fr/pack.json' # URL du pack.json heberge $PackName = 'MCE2' $McVersion = '1.20.1' $ForgeVersion = '47.4.2' # ============================================================ $ForgeFull = "$McVersion-$ForgeVersion" $ForgeUrl = "https://maven.minecraftforge.net/net/minecraftforge/forge/$ForgeFull/forge-$ForgeFull-installer.jar" $VersionId = "$McVersion-forge-$ForgeVersion" $mc = Join-Path $env:APPDATA '.minecraft' $inst = Join-Path $mc "instances\$PackName" $tmp = Join-Path $env:TEMP "$PackName-install" $ProgressPreference = 'SilentlyContinue' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Add-Type -AssemblyName System.IO.Compression.FileSystem function Step($m) { Write-Host "`n==> $m" -ForegroundColor Cyan } function Get-JavaMajor($exe) { $prev = $ErrorActionPreference; $ErrorActionPreference = 'Continue' try { $out = (& $exe -version 2>&1 | Out-String) } catch { return 0 } finally { $ErrorActionPreference = $prev } if ($out -match 'version "(\d+)(\.(\d+))?') { if ($Matches[1] -eq '1') { return [int]$Matches[3] } else { return [int]$Matches[1] } } return 0 } function Find-Java17 { $cands = @() $c = Get-Command java.exe -ErrorAction SilentlyContinue if ($c) { $cands += $c.Source } $cands += Get-ChildItem "$env:APPDATA\.minecraft\runtime\java-runtime-*\windows*\java-runtime-*\bin\java.exe" -ErrorAction SilentlyContinue | ForEach-Object FullName $cands += Get-ChildItem "$env:LOCALAPPDATA\Packages\Microsoft.4297127D64EC6_*\LocalCache\Local\runtime\java-runtime-*\windows-x64\java-runtime-*\bin\java.exe" -ErrorAction SilentlyContinue | ForEach-Object FullName foreach ($j in $cands) { if ((Get-JavaMajor $j) -eq 17) { return $j } } return $null } function Download($url, $dest) { $curl = Get-Command curl.exe -ErrorAction SilentlyContinue if ($curl) { & $curl.Source -L --fail --retry 5 -C - -o $dest $url if ($LASTEXITCODE -ne 0) { throw "Echec du telechargement : $url" } } else { Start-BitsTransfer -Source $url -Destination $dest } } New-Item -ItemType Directory -Force -Path $tmp | Out-Null # --- 1. Manifest ------------------------------------------------------- Step "Lecture des informations du pack" $manifest = Invoke-RestMethod -Uri $ManifestUrl Write-Host "Version du pack : $($manifest.version)" $verFile = Join-Path $inst '.pack-version' if (-not $Force -and (Test-Path $verFile) -and ((Get-Content $verFile -Raw).Trim() -eq "$($manifest.version)") -and (Test-Path (Join-Path $mc "versions\$VersionId"))) { Write-Host "Deja a jour. (relancez avec -Force pour reinstaller)" -ForegroundColor Green return } # --- 2. Launcher Minecraft -------------------------------------------- Step "Verification du dossier Minecraft" if (-not (Test-Path $mc)) { New-Item -ItemType Directory -Force -Path $mc | Out-Null } $profilesPath = Join-Path $mc 'launcher_profiles.json' if (-not (Test-Path $profilesPath)) { Write-Warning "Le launcher Minecraft n'a jamais ete lance. Creation d'un fichier de profils minimal." [System.IO.File]::WriteAllText($profilesPath, '{"profiles":{},"version":3}', (New-Object System.Text.UTF8Encoding($false))) } # --- 3. Java 17 -------------------------------------------------------- Step "Recherche de Java 17" $java = Find-Java17 if (-not $java) { Write-Host "Java 17 introuvable, telechargement d'une version portable..." $jz = Join-Path $tmp 'jre17.zip' Download 'https://api.adoptium.net/v3/binary/latest/17/ga/windows/x64/jre/hotspot/normal/eclipse' $jz $jd = Join-Path $tmp 'jre17' if (Test-Path $jd) { Remove-Item $jd -Recurse -Force } [System.IO.Compression.ZipFile]::ExtractToDirectory($jz, $jd) $java = (Get-ChildItem $jd -Recurse -Filter java.exe | Select-Object -First 1).FullName } Write-Host "Java : $java" # --- 4. Forge ---------------------------------------------------------- if (-not (Test-Path (Join-Path $mc "versions\$VersionId"))) { Step "Installation de Forge $ForgeFull" $fj = Join-Path $tmp "forge-$ForgeFull-installer.jar" Download $ForgeUrl $fj & $java -jar $fj --installClient $mc if ($LASTEXITCODE -ne 0) { throw "L'installeur Forge a echoue (code $LASTEXITCODE)." } } else { Write-Host "Forge $ForgeFull deja installe." } # --- 5. Pack (mods, config...) ---------------------------------------- Step "Telechargement du modpack ($($manifest.sizeMB) Mo)" $zipPath = Join-Path $tmp 'pack.zip' if ((Test-Path $zipPath) -and ((Get-FileHash $zipPath -Algorithm SHA256).Hash.ToLower() -eq $manifest.sha256)) { Write-Host "Archive deja telechargee." } else { Download $manifest.url $zipPath if ((Get-FileHash $zipPath -Algorithm SHA256).Hash.ToLower() -ne $manifest.sha256) { Remove-Item $zipPath -Force throw "Le fichier telecharge est corrompu (SHA256 different). Relancez le script." } } Step "Installation des mods et configs dans $inst" New-Item -ItemType Directory -Force -Path $inst | Out-Null foreach ($d in 'mods', 'kubejs', 'defaultconfigs') { $p = Join-Path $inst $d if (Test-Path $p) { Remove-Item $p -Recurse -Force } } $zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath) try { $n = $zip.Entries.Count; $i = 0 foreach ($e in $zip.Entries) { $i++ if ($e.FullName.EndsWith('/') -or $e.FullName.EndsWith('\')) { continue } $target = Join-Path $inst ($e.FullName -replace '/', '\') $dir = Split-Path $target -Parent if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Force -Path $dir | Out-Null } [System.IO.Compression.ZipFileExtensions]::ExtractToFile($e, $target, $true) if ($i % 100 -eq 0) { Write-Progress -Activity 'Extraction' -Status "$i / $n" -PercentComplete (100 * $i / $n) } } } finally { $zip.Dispose() } Write-Progress -Activity 'Extraction' -Completed # --- 6. Profil du launcher -------------------------------------------- Step "Creation du profil '$PackName' dans le launcher" Copy-Item $profilesPath "$profilesPath.bak" -Force $ramGB = [math]::Floor((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB) $xmx = [math]::Min(8, [math]::Max(4, [math]::Floor($ramGB / 2))) $json = Get-Content $profilesPath -Raw | ConvertFrom-Json if (-not $json.profiles) { $json | Add-Member -NotePropertyName profiles -NotePropertyValue ([pscustomobject]@{}) -Force } $now = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.000'Z'") $profile = [pscustomobject]@{ name = $PackName type = 'custom' created = $now lastUsed = $now icon = 'Furnace' lastVersionId = $VersionId gameDir = $inst javaArgs = "-Xmx${xmx}G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200" } $json.profiles | Add-Member -NotePropertyName $PackName -NotePropertyValue $profile -Force [System.IO.File]::WriteAllText($profilesPath, ($json | ConvertTo-Json -Depth 20), (New-Object System.Text.UTF8Encoding($false))) Set-Content -Path $verFile -Value "$($manifest.version)" Remove-Item $tmp -Recurse -Force -ErrorAction SilentlyContinue Write-Host "`nInstallation terminee ! ($xmx Go de RAM alloues)" -ForegroundColor Green Write-Host "Ouvrez le launcher Minecraft, choisissez le profil '$PackName' et cliquez sur Jouer."