diff --git a/scripts/DL_Diag.bat b/scripts/DL_Diag.bat new file mode 100644 index 0000000..5d61836 --- /dev/null +++ b/scripts/DL_Diag.bat @@ -0,0 +1,15 @@ +@echo off +setlocal + +set "script_name=DL_Diag.ps1" +set "raw_url=https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/scripts/%script_name%" +set "mirror_url=https://spotx-official.github.io/SpotX/scripts/%script_name%" +set "temp_script=%TEMP%\%script_name%" +set "ps=%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe" + +%ps% -NoProfile -ExecutionPolicy Bypass ^ +-Command "[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12; $raw='%raw_url%'; $mirror='%mirror_url%'; $out='%temp_script%'; try { Invoke-WebRequest -UseBasicParsing -Uri $raw -OutFile $out -ErrorAction Stop } catch { Invoke-WebRequest -UseBasicParsing -Uri $mirror -OutFile $out -ErrorAction Stop }; & $out" + +pause +endlocal +exit /b diff --git a/scripts/DL_Diag.ps1 b/scripts/DL_Diag.ps1 new file mode 100644 index 0000000..0ac6334 --- /dev/null +++ b/scripts/DL_Diag.ps1 @@ -0,0 +1,279 @@ +$rawScriptUrl = 'https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/run.ps1' +$mirrorScriptUrl = 'https://spotx-official.github.io/SpotX/run.ps1' +$downloadHost = 'loadspot.amd64fox1.workers.dev' +$defaultLatestFull = '1.2.86.502.g8cd7fb22' +$stableFull = '1.2.13.661.ga588f749' + +$reportLines = New-Object 'System.Collections.Generic.List[string]' + +function Add-ReportLine { + param( + [AllowEmptyString()] + [string]$Line = '' + ) + + [void]$script:reportLines.Add($Line) +} + +function Add-ReportSection { + param( + [Parameter(Mandatory = $true)] + [string]$Title + ) + + if ($script:reportLines.Count -gt 0) { + Add-ReportLine + } + + Add-ReportLine ("== {0} ==" -f $Title) +} + +function Add-CommandOutput { + param( + [string[]]$Lines + ) + + foreach ($line in $Lines) { + Add-ReportLine ([string]$line) + } +} + +function Invoke-WebRequestCompat { + param( + [Parameter(Mandatory = $true)] + [string]$Uri + ) + + $params = @{ + Uri = $Uri + ErrorAction = 'Stop' + } + + if ($PSVersionTable.PSVersion.Major -lt 6) { + $params.UseBasicParsing = $true + } + + Invoke-WebRequest @params +} + +function Get-DiagnosticArchitecture { + $arch = $env:PROCESSOR_ARCHITEW6432 + if ([string]::IsNullOrWhiteSpace($arch)) { + $arch = $env:PROCESSOR_ARCHITECTURE + } + + switch -Regex ($arch) { + 'ARM64' { return 'arm64' } + '64' { return 'x64' } + default { return 'x86' } + } +} + +function Format-ExceptionDetails { + param( + [Parameter(Mandatory = $true)] + [System.Exception]$Exception + ) + + $details = New-Object 'System.Collections.Generic.List[string]' + $current = $Exception + + while ($null -ne $current) { + [void]$details.Add($current.Message) + $current = $current.InnerException + } + + $details +} + +function Invoke-CurlStep { + param( + [Parameter(Mandatory = $true)] + [string]$Title, + [Parameter(Mandatory = $true)] + [string[]]$Arguments + ) + + Add-ReportSection -Title $Title + + if (-not (Get-Command curl.exe -ErrorAction SilentlyContinue)) { + Add-ReportLine 'curl.exe not found' + return + } + + try { + $output = & curl.exe @Arguments 2>&1 + Add-CommandOutput -Lines ($output | ForEach-Object { [string]$_ }) + Add-ReportLine ("ExitCode: {0}" -f $LASTEXITCODE) + } + catch { + Add-CommandOutput -Lines (Format-ExceptionDetails -Exception $_.Exception) + } +} + +function Invoke-PowerShellStep { + param( + [Parameter(Mandatory = $true)] + [string]$Title, + [Parameter(Mandatory = $true)] + [scriptblock]$Action + ) + + Add-ReportSection -Title $Title + + try { + $result = & $Action + + if ($null -eq $result) { + Add-ReportLine + return + } + + if ($result -is [System.Array]) { + Add-CommandOutput -Lines ($result | ForEach-Object { [string]$_ }) + return + } + + Add-ReportLine ([string]$result) + } + catch { + Add-CommandOutput -Lines (Format-ExceptionDetails -Exception $_.Exception) + } +} + +$architecture = Get-DiagnosticArchitecture +$latestFull = $defaultLatestFull +$bootstrapResults = New-Object 'System.Collections.Generic.List[object]' + +foreach ($source in @( + [PSCustomObject]@{ Name = 'raw'; Url = $rawScriptUrl }, + [PSCustomObject]@{ Name = 'mirror'; Url = $mirrorScriptUrl } +)) { + try { + $response = Invoke-WebRequestCompat -Uri $source.Url + $content = [string]$response.Content + + if ($latestFull -eq $defaultLatestFull) { + $match = [regex]::Match($content, '\[string\]\$latest_full\s*=\s*"([^"]+)"') + if ($match.Success) { + $latestFull = $match.Groups[1].Value + } + } + + $bootstrapResults.Add([PSCustomObject]@{ + Name = $source.Name + Url = $source.Url + Success = $true + StatusCode = [int]$response.StatusCode + Length = $content.Length + }) | Out-Null + } + catch { + $bootstrapResults.Add([PSCustomObject]@{ + Name = $source.Name + Url = $source.Url + Success = $false + StatusCode = $null + Length = $null + Error = $_.Exception.Message + }) | Out-Null + } +} + +$tempUrl = if ($architecture -eq 'x64') { + 'https://{0}/temporary-download/spotify_installer-{1}-x64.exe' -f $downloadHost, $latestFull +} +else { + $null +} + +$directUrl = 'https://{0}/download/spotify_installer-{1}-{2}.exe' -f $downloadHost, $stableFull, $architecture + +Add-ReportSection -Title 'Environment' +Add-ReportLine ("Date: {0}" -f (Get-Date).ToString('yyyy-MM-dd HH:mm:ss zzz')) +Add-ReportLine ("ComputerName: {0}" -f $env:COMPUTERNAME) +Add-ReportLine ("UserName: {0}" -f $env:USERNAME) +Add-ReportLine ("PowerShell: {0}" -f $PSVersionTable.PSVersion) +Add-ReportLine ("Architecture: {0}" -f $architecture) +Add-ReportLine ("LatestFull: {0}" -f $latestFull) +Add-ReportLine ("StableFull: {0}" -f $stableFull) +Add-ReportLine ("TempUrl: {0}" -f $(if ($tempUrl) { $tempUrl } else { 'skipped for non-x64 system' })) +Add-ReportLine ("DirectUrl: {0}" -f $directUrl) + +Add-ReportSection -Title 'Bootstrap check' +foreach ($item in $bootstrapResults) { + Add-ReportLine ("Source: {0}" -f $item.Name) + Add-ReportLine ("Url: {0}" -f $item.Url) + Add-ReportLine ("Success: {0}" -f $item.Success) + + if ($item.Success) { + Add-ReportLine ("StatusCode: {0}" -f $item.StatusCode) + Add-ReportLine ("ContentLength: {0}" -f $item.Length) + } + else { + Add-ReportLine ("Error: {0}" -f $item.Error) + } + + Add-ReportLine +} + +Invoke-CurlStep -Title 'curl version' -Arguments @('-V') + +Invoke-PowerShellStep -Title 'DNS' -Action { + Resolve-DnsName $downloadHost | Format-Table -AutoSize | Out-String -Width 4096 +} + +if ($tempUrl) { + Invoke-CurlStep -Title 'HEAD temp' -Arguments @('-I', '-L', '-k', '--ssl-no-revoke', $tempUrl) + Invoke-CurlStep -Title '1MB temp' -Arguments @('-L', '-k', '--ssl-no-revoke', '--fail-with-body', '--connect-timeout', '15', '-r', '0-1048575', '-o', 'NUL', '-D', '-', '-w', "`nHTTP_STATUS:%{http_code}`n", $tempUrl) +} +else { + Add-ReportSection -Title 'HEAD temp' + Add-ReportLine 'Skipped because temporary route is only used for x64 latest build' + + Add-ReportSection -Title '1MB temp' + Add-ReportLine 'Skipped because temporary route is only used for x64 latest build' +} + +Invoke-CurlStep -Title '1MB direct stable' -Arguments @('-L', '-k', '--ssl-no-revoke', '--fail-with-body', '--connect-timeout', '15', '-r', '0-1048575', '-o', 'NUL', '-D', '-', '-w', "`nHTTP_STATUS:%{http_code}`n", $directUrl) + +Invoke-PowerShellStep -Title 'WebClient test' -Action { + $webClientUrl = if ($tempUrl) { $tempUrl } else { $directUrl } + $wc = New-Object System.Net.WebClient + $stream = $null + + try { + $stream = $wc.OpenRead($webClientUrl) + $buffer = New-Object byte[] 1 + [void]$stream.Read($buffer, 0, 1) + + $lines = New-Object 'System.Collections.Generic.List[string]' + $lines.Add('WEBCLIENT_OK') | Out-Null + $lines.Add(("Url: {0}" -f $webClientUrl)) | Out-Null + + if ($wc.ResponseHeaders) { + foreach ($headerName in $wc.ResponseHeaders.AllKeys) { + $lines.Add(("{0}: {1}" -f $headerName, $wc.ResponseHeaders[$headerName])) | Out-Null + } + } + + $lines + } + finally { + if ($stream) { + $stream.Dispose() + } + + $wc.Dispose() + } +} + +Write-Host +Write-Host 'Copy everything between the markers below and send it to SpotX support' -ForegroundColor Yellow +Write-Host '----- BEGIN DIAGNOSTICS -----' -ForegroundColor Cyan + +foreach ($line in $reportLines) { + Write-Output $line +} + +Write-Host '----- END DIAGNOSTICS -----' -ForegroundColor Cyan