mirror of
https://github.com/SpotX-Official/SpotX.git
synced 2026-04-20 10:44:35 +10:00
Compare commits
6 Commits
main
...
dl-diag-sc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bdfec03a8 | ||
|
|
2783cbe0c1 | ||
|
|
f4279fb962 | ||
|
|
ee5881572c | ||
|
|
4f0706b010 | ||
|
|
4106903513 |
22
scripts/DL_Diag.bat
Normal file
22
scripts/DL_Diag.bat
Normal file
@@ -0,0 +1,22 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
set "script_name=DL_Diag.ps1"
|
||||
set "branch_name=dl-diag-scripts"
|
||||
set "script_dir=%~dp0"
|
||||
set "local_script=%script_dir%%script_name%"
|
||||
set "branch_url=https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/%branch_name%/scripts/%script_name%"
|
||||
set "main_url=https://raw.githubusercontent.com/SpotX-Official/SpotX/refs/heads/main/scripts/%script_name%"
|
||||
set "temp_script=%TEMP%\SpotX-%script_name%"
|
||||
set "ps=%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe"
|
||||
|
||||
if exist "%local_script%" (
|
||||
%ps% -NoProfile -ExecutionPolicy Bypass -File "%local_script%"
|
||||
) else (
|
||||
%ps% -NoProfile -ExecutionPolicy Bypass ^
|
||||
-Command "[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12; $out='%temp_script%'; $urls=@('%branch_url%','%main_url%'); $downloaded=$false; foreach ($url in $urls) { try { Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile $out -ErrorAction Stop; $downloaded=$true; break } catch {} }; if (-not $downloaded) { throw 'Failed to download diagnostic script' }; & $out"
|
||||
)
|
||||
|
||||
pause
|
||||
endlocal
|
||||
exit /b
|
||||
388
scripts/DL_Diag.ps1
Normal file
388
scripts/DL_Diag.ps1
Normal file
@@ -0,0 +1,388 @@
|
||||
$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]'
|
||||
$sensitivePatterns = New-Object 'System.Collections.Generic.List[object]'
|
||||
|
||||
function Add-SensitivePattern {
|
||||
param(
|
||||
[string]$Pattern,
|
||||
[string]$Replacement = '[redacted]'
|
||||
)
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($Pattern)) {
|
||||
$script:sensitivePatterns.Add([PSCustomObject]@{
|
||||
Pattern = $Pattern
|
||||
Replacement = $Replacement
|
||||
}) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
function Protect-DiagnosticText {
|
||||
param(
|
||||
[AllowNull()]
|
||||
[string]$Text
|
||||
)
|
||||
|
||||
if ($null -eq $Text) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$value = [string]$Text
|
||||
|
||||
foreach ($item in $script:sensitivePatterns) {
|
||||
$value = [regex]::Replace($value, $item.Pattern, $item.Replacement)
|
||||
}
|
||||
|
||||
$value
|
||||
}
|
||||
|
||||
function Add-ReportLine {
|
||||
param(
|
||||
[AllowEmptyString()]
|
||||
[string]$Line = ''
|
||||
)
|
||||
|
||||
[void]$script:reportLines.Add((Protect-DiagnosticText -Text $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 Invoke-WebClientStep {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Title,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Uri
|
||||
)
|
||||
|
||||
Invoke-PowerShellStep -Title $Title -Action {
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$stream = $null
|
||||
|
||||
try {
|
||||
$stream = $wc.OpenRead($Uri)
|
||||
$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 $Uri)) | 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Copy-TextToClipboard {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Text
|
||||
)
|
||||
|
||||
try {
|
||||
if (Get-Command Set-Clipboard -ErrorAction SilentlyContinue) {
|
||||
Set-Clipboard -Value $Text -ErrorAction Stop
|
||||
return $true
|
||||
}
|
||||
|
||||
if (Get-Command clip.exe -ErrorAction SilentlyContinue) {
|
||||
$Text | clip.exe
|
||||
return ($LASTEXITCODE -eq 0)
|
||||
}
|
||||
}
|
||||
catch {
|
||||
return $false
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
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' }
|
||||
}
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:COMPUTERNAME)) {
|
||||
Add-SensitivePattern -Pattern ([regex]::Escape($env:COMPUTERNAME)) -Replacement '[redacted-host]'
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:USERNAME)) {
|
||||
Add-SensitivePattern -Pattern ([regex]::Escape($env:USERNAME)) -Replacement '[redacted-user]'
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($env:USERPROFILE)) {
|
||||
Add-SensitivePattern -Pattern ([regex]::Escape($env:USERPROFILE)) -Replacement '[redacted-profile]'
|
||||
}
|
||||
|
||||
Add-SensitivePattern -Pattern '(?<![\d.])(?:\d{1,3}\.){3}\d{1,3}(?![\d.])' -Replacement '[redacted-ipv4]'
|
||||
Add-SensitivePattern -Pattern '(?i)(?<![0-9a-f:])((?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}|(?:[0-9a-f]{1,4}:){1,7}:|(?:[0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}|(?:[0-9a-f]{1,4}:){1,5}(?::[0-9a-f]{1,4}){1,2}|(?:[0-9a-f]{1,4}:){1,4}(?::[0-9a-f]{1,4}){1,3}|(?:[0-9a-f]{1,4}:){1,3}(?::[0-9a-f]{1,4}){1,4}|(?:[0-9a-f]{1,4}:){1,2}(?::[0-9a-f]{1,4}){1,5}|[0-9a-f]{1,4}:(?:(?::[0-9a-f]{1,4}){1,6})|:(?:(?::[0-9a-f]{1,4}){1,7}|:))(?![0-9a-f:])' -Replacement '[redacted-ipv6]'
|
||||
|
||||
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 '-sS' @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 ("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 'HEAD direct stable' -Arguments @('-I', '-L', '-k', '--ssl-no-revoke', $directUrl)
|
||||
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)
|
||||
|
||||
if ($tempUrl) {
|
||||
Invoke-WebClientStep -Title 'WebClient temp' -Uri $tempUrl
|
||||
}
|
||||
else {
|
||||
Add-ReportSection -Title 'WebClient temp'
|
||||
Add-ReportLine 'Skipped because temporary route is only used for x64 latest build'
|
||||
}
|
||||
|
||||
Invoke-WebClientStep -Title 'WebClient direct stable' -Uri $directUrl
|
||||
|
||||
$finalOutputLines = New-Object 'System.Collections.Generic.List[string]'
|
||||
$finalOutputLines.Add('----- BEGIN DIAGNOSTICS -----') | Out-Null
|
||||
|
||||
foreach ($line in $reportLines) {
|
||||
$finalOutputLines.Add($line) | Out-Null
|
||||
}
|
||||
|
||||
$finalOutputLines.Add('----- END DIAGNOSTICS -----') | Out-Null
|
||||
$finalOutputText = [string]::Join([Environment]::NewLine, $finalOutputLines)
|
||||
$clipboardCopied = Copy-TextToClipboard -Text $finalOutputText
|
||||
|
||||
Write-Host
|
||||
Write-Host '----- BEGIN DIAGNOSTICS -----' -ForegroundColor Cyan
|
||||
|
||||
foreach ($line in $reportLines) {
|
||||
Write-Output $line
|
||||
}
|
||||
|
||||
Write-Host '----- END DIAGNOSTICS -----' -ForegroundColor Cyan
|
||||
|
||||
if ($clipboardCopied) {
|
||||
Write-Host
|
||||
Write-Host 'Diagnostics copied to clipboard' -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
Write-Host
|
||||
Write-Host 'Clipboard copy failed, copy the text above manually' -ForegroundColor Yellow
|
||||
}
|
||||
Reference in New Issue
Block a user