Param( [string]$Java = 'java', [switch]$NoDeploy ) Add-Type -AssemblyName System.Windows.Forms Add-type -AssemblyName System.Drawing $ProgressPreference = 'SilentlyContinue' $ErrorActionPreference = 'Stop' function execJava { $ErrorActionPreference = 'Continue' if ($args[0].getType().Name -ne "String") { & $Java $args[0] 2>&1 | ForEach-Object{ "$_" } } else { & $Java $args 2>&1 | ForEach-Object{ "$_" } } $ErrorActionPreference = 'Stop' } function renderForm([String[]]$items, [String]$label, [String]$title, [System.Windows.Forms.SelectionMode]$mode, [System.Collections.ArrayList]$selected) { # https://docs.microsoft.com/en-us/powershell/scripting/samples/multiple-selection-list-boxes?view=powershell-7.2 # https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.anchorstyles $form = New-Object System.Windows.Forms.Form $form.Text = $title $form.Size = New-Object System.Drawing.Size(300,200) $form.StartPosition = 'CenterScreen' $OKButton = New-Object System.Windows.Forms.Button $OKButton.Anchor = 2 $OKButton.Location = New-Object System.Drawing.Point(102,120) $OKButton.Size = New-Object System.Drawing.Size(75,23) $OKButton.Text = 'OK' $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $OKButton $form.Controls.Add($OKButton) $_label = New-Object System.Windows.Forms.Label $_label.Anchor = 1+4+8 $_label.Location = New-Object System.Drawing.Point(10,20) $_label.Size = New-Object System.Drawing.Size(280,20) $_label.Text = $label $form.Controls.Add($_label) $listBox = New-Object System.Windows.Forms.Listbox $listBox.Anchor = 15 $listBox.Location = New-Object System.Drawing.Point(10,40) $listBox.Size = New-Object System.Drawing.Size(260,20) $listBox.SelectionMode = $mode foreach ($entry in $items) { [void] $listBox.Items.Add($entry) } if ($null -ne $selected) { for($i = 0; ($i -lt $selected.Count) -and ($i -lt $items.Length); $i++) { if ($selected[$i]) {$listBox.SetSelected($i, $true) | Out-Null} } } $listBox.Height = 70 $form.Controls.Add($listBox) $form.Topmost = $true if ($form.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { return $listbox.selectedItems } return $false } function splitArray([String[]]$array, $splitter = $null, [int]$row = 0) { $returnVal = New-Object System.Collections.ArrayList if ($null -eq $splitter) { foreach ($i in $array) { $returnVal.Add(@($i.Split()[$row])) | Out-Null } } else { foreach ($i in $array) { $returnVal.Add(@($i.Split($splitter)[$row])) | Out-Null } } return $returnVal } class config { [String]$patches = "none" [String]$integrations = "none" [String]$cli = "none" [System.Collections.ArrayList]$excluded = (New-Object System.Collections.ArrayList) [void] load($Path) { $fileContent = ConvertFrom-Json ((Get-Content $Path) -Join ' ').ToString() $this.patches = $fileContent.patches $this.integrations = $fileContent.integrations $this.cli = $fileContent.cli $this.excluded = $fileContent.excluded } [void] save($Path) { Out-File $Path -InputObject (ConvertTo-Json $this) } } function main { $config = New-Object config # Get latest releases try { $patchesRelease = ConvertFrom-Json (Invoke-WebRequest https://api.github.com/repos/revanced/revanced-patches/releases/latest).Content $integrationsRelease = ConvertFrom-Json (Invoke-WebRequest https://api.github.com/repos/revanced/revanced-integrations/releases/latest).Content $cliRelease = ConvertFrom-Json (Invoke-WebRequest https://api.github.com/repos/revanced/revanced-cli/releases/latest).Content # Check versions [Bool[]]$install = $true, $true, $true try { $config.load(".\config.json") if ($config.patches -eq $patchesRelease.tag_name) {$install[0] = $false} if ($config.integrations -eq $integrationsRelease.tag_name) {$install[1] = $false} if ($config.cli -eq $cliRelease.tag_name) {$install[2] = $false} } catch [System.Management.Automation.ItemNotFoundException] { Write-Output "currentVersion.json not found, downloading everything" } # Download latest releases New-Item -type Directory -Path ".\app" -ErrorAction SilentlyContinue | Out-Null if ($install[0]) { Write-Output "Downloading Patches ($($config.patches) -> $($patchesRelease.tag_name)) changelog: $($patchesRelease.html_url)" Invoke-WebRequest $patchesRelease.assets[1].browser_download_url -OutFile ".\app\revanced-patches.jar" $config.patches = $patchesRelease.tag_name } else {Write-Output "Patches up to date $($config.patches)"} if ($install[1]) { Write-Output "Downloading Integrations ($($config.integrations) -> $($integrationsRelease.tag_name)) changelog: $($integrationsRelease.html_url)" Invoke-WebRequest $integrationsRelease.assets[0].browser_download_url -OutFile ".\app\app-release-unsigned.apk" $config.integrations = $integrationsRelease.tag_name } else {Write-Output "Integrations up to date $($config.integrations)"} if ($install[2]) { Write-Output "Downloading cli ($($config.cli) -> $($cliRelease.tag_name)) changelog: $($cliRelease.html_url)" Invoke-WebRequest $cliRelease.assets[0].browser_download_url -OutFile ".\app\revanced-cli.jar" $config.cli = $cliRelease.tag_name } else {Write-Output "cli up to date! $($config.cli)"} $config.save(".\config.json") } catch [System.Net.WebException] { Write-Output "Couldn't get newest files, using locals" } if ($NoDeploy) {return} # Select Youtube app $apks = (Get-ChildItem *.apk).Name [String]$selectedApk = '' if ($apks.Length -eq 0) {throw "No YouTube apk files found!"} elseif ($apks.getType().Name -eq 'String') {$selectedApk = $apks} else { $selectedApk = (renderForm -items $apks -label "Select apk file to patch" -title "Installer for ReVanced - apk selector" -mode One) if (-not $selectedApk) {throw "No apk selected!"} } # Get available integrations $integrationsList = New-Object System.Collections.ArrayList class Integration { [String] $id [String] $description Integration([String] $_id, [String] $_description) { $this.id = $_id $this.description = $_description } [String] ToString() { return "$($this.id) - $($this.description)" } } foreach ($i in (execJava -jar .\app\revanced-cli.jar -b .\app\revanced-patches.jar -l)) { $i = $i.ToString().substring(6).split("`t") [void] $integrationsList.Add([Integration]::new($i[0].TrimStart(), $i[1])) } # integrations selector $excludedIntegrations = New-Object System.Collections.ArrayList [System.Collections.ArrayList]$savedExclusions = New-Object System.Collections.ArrayList $savedExclusionsNames = $config.excluded foreach ($i in $integrationsList) { if (($savedExclusionsNames.Count -gt 1) -and $savedExclusionsNames.Contains($i.id)) { [void] $savedExclusions.Add($true) [void] $savedExclusionsNames.Remove($integrationID) } else { [void] $savedExclusions.Add($false) } } foreach ($i in (renderForm -items $integrationsList -label "Select integrations to exclude" -title "Installer for ReVanced - integrations" -mode MultiExtended -selected $savedExclusions)) { [void] $excludedIntegrations.Add($i.Split(' ')[0]) #FIXME: hacky way to do this, but it works } $config.excluded = $excludedIntegrations $config.save(".\config.json") # devices $devices = adb devices $devices = $devices[1..($devices.length-2)] [String]$selectedDevice = '' if ($devices.Length -eq 0) {throw "No devices found"} elseif ($devices.Length -eq 1) {$selectedDevice = (splitArray -array $devices)[0]} else { $selectedDevice = (renderForm -items (splitArray -array $devices) -label "Select deployment target" -title "Installer for ReVanced - target" -mode One) } # install to device $patcherArgs = "-jar", ".\app\revanced-cli.jar", "-a", ".\$selectedApk", "-c", "-d", "$selectedDevice", "-o", "$env:tmp\revanced.apk", "-m", ".\app\app-release-unsigned.apk", "-b", ".\app\revanced-patches.jar" # is microg patch excluded? if ($excludedIntegrations.Contains("microg-support")) { $patcherArgs += "--mount" } foreach ($i in $excludedIntegrations) { $patcherArgs += "-e" $patcherArgs += $i Write-Output "Excluded: $i" } Write-Output "Logs below are from the cli" execJava $patcherArgs } main