param( [string]$DataDirectory = (Join-Path $env:LOCALAPPDATA 'BankSlotBorders'), [switch]$PrepareOnly ) $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $sourceCommit = '03ac7fa5864429f5e8719097f41cb7e2eebfc5a4' $sourceHash = 'b90def96d4b337cd6463336e21aa3b0750180c9f0a9d5ac090c25158bb058c84' $sourceUrl = "https://codeload.github.com/11jfreeman11/OSRS-Bank-Slot-Borders/zip/$sourceCommit" $javaUrl = 'https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.32.1%2B1/OpenJDK11U-jdk_x64_windows_hotspot_11.0.32.1_1.zip' $javaHash = 'd5008f02174c1ad21c10407cbf104815cb390ec4c263d53946e8d0507d7a77f9' function Get-VerifiedDownload([string]$Url, [string]$Destination, [string]$ExpectedHash) { if (Test-Path -LiteralPath $Destination) { if ((Get-FileHash -LiteralPath $Destination -Algorithm SHA256).Hash -eq $ExpectedHash) { return } throw "The cached download failed verification: $Destination. Rename that file and try again." } $partial = "$Destination.part" Invoke-WebRequest -UseBasicParsing -Uri $Url -OutFile $partial if ((Get-FileHash -LiteralPath $partial -Algorithm SHA256).Hash -ne $ExpectedHash) { throw 'A download failed its SHA-256 check. Nothing from that download was executed.' } Move-Item -LiteralPath $partial -Destination $Destination -Force } function Expand-PluginSource([string]$Archive, [string]$Destination) { # Strip GitHub's long enclosing folder so Java source paths stay short. Add-Type -AssemblyName System.IO.Compression.FileSystem $root = [IO.Path]::GetFullPath($Destination).TrimEnd('\') + '\' $zip = [IO.Compression.ZipFile]::OpenRead($Archive) try { foreach ($entry in $zip.Entries) { $slash = $entry.FullName.IndexOf('/') if ($slash -lt 0 -or $entry.FullName.EndsWith('/')) { continue } $relative = $entry.FullName.Substring($slash + 1).Replace('/', '\') if (-not $relative) { continue } $target = [IO.Path]::GetFullPath((Join-Path $root $relative)) if (-not $target.StartsWith($root, [StringComparison]::OrdinalIgnoreCase)) { throw 'The source archive contains an unsafe path.' } New-Item -ItemType Directory -Path ([IO.Path]::GetDirectoryName($target)) -Force | Out-Null [IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $target, $true) } } finally { $zip.Dispose() } } try { if (-not [Environment]::Is64BitOperatingSystem) { throw 'This launcher requires 64-bit Windows.' } if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64' -or $env:PROCESSOR_ARCHITEW6432 -eq 'ARM64') { throw 'This launcher is for Windows Intel/AMD x64. Windows ARM is not supported by this package.' } $DataDirectory = [IO.Path]::GetFullPath($DataDirectory) New-Item -ItemType Directory -Path $DataDirectory -Force | Out-Null $cache = Join-Path $DataDirectory 'downloads' $runtime = Join-Path $DataDirectory 'temurin-11.0.32.1' $source = Join-Path $DataDirectory ('src-' + $sourceCommit.Substring(0,8)) New-Item -ItemType Directory -Path $cache,$runtime,$source -Force | Out-Null Write-Host '' Write-Host 'BANK SLOT BORDERS - community test client' -ForegroundColor Yellow Write-Host "Plugin source: $sourceCommit" Write-Host 'First start downloads portable Java, source, Gradle and RuneLite dependencies.' Write-Host 'Future starts reuse these files. Keep this window open while playing.' Write-Host '' $javaArchive = Join-Path $cache 'temurin11.zip' $sourceArchive = Join-Path $cache "$sourceCommit.zip" Write-Host '[1/3] Checking portable Java (about 200 MB on the first start)...' Get-VerifiedDownload $javaUrl $javaArchive $javaHash $javaHome = Join-Path $runtime 'jdk-11.0.32.1+1' if (-not (Test-Path -LiteralPath (Join-Path $runtime 'ready.txt'))) { Expand-Archive -LiteralPath $javaArchive -DestinationPath $runtime -Force if (-not (Test-Path -LiteralPath (Join-Path $javaHome 'bin/java.exe'))) { throw 'Portable Java did not extract correctly.' } Set-Content -LiteralPath (Join-Path $runtime 'ready.txt') -Value $javaHash } if (-not (Test-Path -LiteralPath (Join-Path $javaHome 'bin/java.exe'))) { throw 'Portable Java is missing. Remove ready.txt in the Java folder and retry.' } Write-Host '[2/3] Checking the published plugin source...' Get-VerifiedDownload $sourceUrl $sourceArchive $sourceHash $project = $source if (-not (Test-Path -LiteralPath (Join-Path $source 'ready.txt'))) { Expand-PluginSource $sourceArchive $source if (-not (Test-Path -LiteralPath (Join-Path $project 'gradlew.bat'))) { throw 'Plugin source did not extract correctly.' } Set-Content -LiteralPath (Join-Path $source 'ready.txt') -Value $sourceCommit } if (-not (Test-Path -LiteralPath (Join-Path $project 'gradlew.bat'))) { throw 'The plugin project is missing. Remove ready.txt in the source folder and retry.' } $env:JAVA_HOME = $javaHome $env:GRADLE_USER_HOME = Join-Path $DataDirectory 'gradle' if ($PrepareOnly) { Write-Host 'Preparation complete. RuneLite was not launched.' exit 0 } Write-Host '[3/3] Building and opening RuneLite...' Write-Host 'Once open: enable Bank Slot Borders in plugin settings.' Write-Host 'Jagex accounts: open the Jagex auth sidebar, add your account, select your character, then Play Now.' Push-Location -LiteralPath $project try { & (Join-Path $project 'gradlew.bat') run --no-daemon if ($LASTEXITCODE -ne 0) { throw "RuneLite build or launch failed (exit $LASTEXITCODE). See the messages above." } } finally { Pop-Location } } catch { Write-Host '' Write-Host $_.Exception.Message -ForegroundColor Red Write-Host "Files are kept in: $DataDirectory" Write-Host 'Share the error text with the plugin author; never share login codes or account tokens.' exit 1 }