mirror of
https://github.com/SpotX-Official/SpotX.git
synced 2026-08-09 09:31:09 +10:00
@@ -1613,6 +1613,92 @@ function injection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Extract-WebpackModules {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$InputFile
|
||||||
|
)
|
||||||
|
|
||||||
|
$scriptStart = Get-Date
|
||||||
|
Write-Debug "=== Script execution started ==="
|
||||||
|
Write-Debug "Input file: $InputFile"
|
||||||
|
|
||||||
|
function Encode-UTF16LE {
|
||||||
|
param([byte[]]$Bytes)
|
||||||
|
$str = [System.Text.Encoding]::UTF8.GetString($Bytes)
|
||||||
|
[System.Text.Encoding]::Unicode.GetBytes($str)
|
||||||
|
}
|
||||||
|
|
||||||
|
$StartMarker = [System.Text.Encoding]::UTF8.GetBytes("var __webpack_modules__={")
|
||||||
|
$EndMarker = [System.Text.Encoding]::UTF8.GetBytes("//# sourceMappingURL=xpui-modules.js.map")
|
||||||
|
|
||||||
|
[byte[]]$fileContent = [System.IO.File]::ReadAllBytes($InputFile)
|
||||||
|
|
||||||
|
$isUTF16LE = $false
|
||||||
|
if ($fileContent.Length -ge 2 -and $fileContent[0] -eq 0xFF -and $fileContent[1] -eq 0xFE) {
|
||||||
|
$isUTF16LE = $true
|
||||||
|
}
|
||||||
|
elseif ($fileContent.Length -gt 100 -and $fileContent[1] -eq 0x00) {
|
||||||
|
$isUTF16LE = $true
|
||||||
|
}
|
||||||
|
if (-not $isUTF16LE) {
|
||||||
|
Write-Error "File is not in UTF-16LE format: $InputFile"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$searchStartMarker = Encode-UTF16LE -Bytes $StartMarker
|
||||||
|
$searchEndMarker = Encode-UTF16LE -Bytes $EndMarker
|
||||||
|
|
||||||
|
function IndexOfBytes($haystack, $needle, [int]$startIndex = 0) {
|
||||||
|
if ($startIndex -lt 0) { $startIndex = 0 }
|
||||||
|
$haystackLength = $haystack.Length
|
||||||
|
$needleLength = $needle.Length
|
||||||
|
$searchLimit = $haystackLength - $needleLength
|
||||||
|
if ($searchLimit -lt $startIndex) { return -1 }
|
||||||
|
$firstNeedleByte = $needle[0]
|
||||||
|
for ($i = $startIndex; $i -le $searchLimit; $i++) {
|
||||||
|
if ($haystack[$i] -eq $firstNeedleByte) {
|
||||||
|
$found = $true
|
||||||
|
for ($j = 1; $j -lt $needleLength; $j++) {
|
||||||
|
if ($haystack[$i + $j] -ne $needle[$j]) {
|
||||||
|
$found = $false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($found) { return $i }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
$startIdx = IndexOfBytes $fileContent $searchStartMarker 2
|
||||||
|
if ($startIdx -eq -1) {
|
||||||
|
Write-Error "Start marker not found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Write-Debug "Start marker found at index $startIdx"
|
||||||
|
|
||||||
|
$endMarkerSearchOffset = $startIdx + $searchStartMarker.Length
|
||||||
|
$endIdx = IndexOfBytes $fileContent $searchEndMarker $endMarkerSearchOffset
|
||||||
|
if ($endIdx -eq -1) {
|
||||||
|
Write-Error "End marker not found after index $endMarkerSearchOffset"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Write-Debug "End marker found at absolute index $endIdx"
|
||||||
|
|
||||||
|
$endDataIdx = $endIdx + $searchEndMarker.Length
|
||||||
|
$length = $endDataIdx - $startIdx
|
||||||
|
|
||||||
|
Write-Debug "Decoding data from UTF-16LE..."
|
||||||
|
$decodedString = [System.Text.Encoding]::Unicode.GetString($fileContent, $startIdx, $length)
|
||||||
|
|
||||||
|
$scriptEnd = Get-Date
|
||||||
|
$duration = [math]::Round(($scriptEnd - $scriptStart).TotalSeconds, 1)
|
||||||
|
Write-Debug "=== Execution completed in $duration seconds ==="
|
||||||
|
|
||||||
|
return $decodedString
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Write-Host ($lang).ModSpoti`n
|
Write-Host ($lang).ModSpoti`n
|
||||||
|
|
||||||
@@ -1663,13 +1749,85 @@ if (!($test_js) -and !($test_spa)) {
|
|||||||
Exit
|
Exit
|
||||||
}
|
}
|
||||||
|
|
||||||
If ($test_spa) {
|
if ($test_spa) {
|
||||||
|
|
||||||
|
Add-Type -Assembly 'System.IO.Compression.FileSystem'
|
||||||
|
|
||||||
|
# Check for the presence of xpui.js in the xpui.spa archive
|
||||||
|
try {
|
||||||
|
$archive_spa = [System.IO.Compression.ZipFile]::OpenRead($xpui_spa_patch)
|
||||||
|
$xpuiJsEntry = $archive_spa.GetEntry('xpui.js')
|
||||||
|
$xpuiSnapshotEntry = $archive_spa.GetEntry('xpui-snapshot.js')
|
||||||
|
if (($null -eq $xpuiJsEntry) -and ($null -ne $xpuiSnapshotEntry)) {
|
||||||
|
|
||||||
|
$snapshot_x64 = Join-Path $spotifyDirectory 'v8_context_snapshot.bin'
|
||||||
|
$snapshot_arm64 = Join-Path $spotifyDirectory 'v8_context_snapshot.arm64.bin'
|
||||||
|
|
||||||
|
$v8_snapshot = switch ($true) {
|
||||||
|
{ Test-Path $snapshot_x64 } { $snapshot_x64; break }
|
||||||
|
{ Test-Path $snapshot_arm64 } { $snapshot_arm64; break }
|
||||||
|
default { $null }
|
||||||
|
}
|
||||||
|
if ($v8_snapshot) {
|
||||||
|
$modules = Extract-WebpackModules -InputFile $v8_snapshot
|
||||||
|
|
||||||
|
function Update-ZipEntry {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
$archive,
|
||||||
|
[Parameter(Mandatory)]
|
||||||
|
[string]$entryName,
|
||||||
|
[string]$newEntryName = $null,
|
||||||
|
[string]$prepend = $null,
|
||||||
|
[scriptblock]$contentTransform = $null
|
||||||
|
)
|
||||||
|
$entry = $archive.GetEntry($entryName)
|
||||||
|
if ($entry) {
|
||||||
|
$tmpFile = [System.IO.Path]::GetTempFileName()
|
||||||
|
$reader = New-Object IO.StreamReader($entry.Open())
|
||||||
|
$content = $reader.ReadToEnd()
|
||||||
|
$reader.Close()
|
||||||
|
$entry.Delete()
|
||||||
|
if ($prepend) { $content = "$prepend`n$content" }
|
||||||
|
if ($contentTransform) { $content = & $contentTransform $content }
|
||||||
|
[System.IO.File]::WriteAllText($tmpFile, $content)
|
||||||
|
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive, $tmpFile, $(if ($newEntryName) { $newEntryName } else { $entryName })) | Out-Null
|
||||||
|
Remove-Item $tmpFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$firstLine = ($modules -split "`r?`n")[0]
|
||||||
|
|
||||||
|
$archive_spa.Dispose()
|
||||||
|
$archive_spa = [System.IO.Compression.ZipFile]::Open($xpui_spa_patch, [System.IO.Compression.ZipArchiveMode]::Update)
|
||||||
|
|
||||||
|
Update-ZipEntry -archive $archive_spa -entryName 'xpui-snapshot.js' -prepend $firstLine
|
||||||
|
Update-ZipEntry -archive $archive_spa -entryName 'xpui-snapshot.js' -newEntryName 'xpui.js'
|
||||||
|
Update-ZipEntry -archive $archive_spa -entryName 'xpui-snapshot.css' -newEntryName 'xpui.css'
|
||||||
|
Update-ZipEntry -archive $archive_spa -entryName 'index.html' -contentTransform {
|
||||||
|
param($c)
|
||||||
|
$c -replace 'xpui-snapshot.js', 'xpui.js' -replace 'xpui-snapshot.css', 'xpui.css'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Warning "v8_context_snapshot file not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Warning "Error: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if ($null -ne $archive_spa) {
|
||||||
|
$archive_spa.Dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$bak_spa = Join-Path (Join-Path $env:APPDATA 'Spotify\Apps') 'xpui.bak'
|
$bak_spa = Join-Path (Join-Path $env:APPDATA 'Spotify\Apps') 'xpui.bak'
|
||||||
$test_bak_spa = Test-Path -Path $bak_spa
|
$test_bak_spa = Test-Path -Path $bak_spa
|
||||||
|
|
||||||
# Make a backup copy of xpui.spa if it is original
|
# Make a backup copy of xpui.spa if it is original
|
||||||
Add-Type -Assembly 'System.IO.Compression.FileSystem'
|
|
||||||
$zip = [System.IO.Compression.ZipFile]::Open($xpui_spa_patch, 'update')
|
$zip = [System.IO.Compression.ZipFile]::Open($xpui_spa_patch, 'update')
|
||||||
$entry = $zip.GetEntry('xpui.js')
|
$entry = $zip.GetEntry('xpui.js')
|
||||||
$reader = New-Object System.IO.StreamReader($entry.Open())
|
$reader = New-Object System.IO.StreamReader($entry.Open())
|
||||||
@@ -1771,7 +1929,7 @@ If ($test_spa) {
|
|||||||
|
|
||||||
if ([version]$offline -ge [version]"1.2.28.581" -and [version]$offline -le [version]"1.2.57.463") {
|
if ([version]$offline -ge [version]"1.2.28.581" -and [version]$offline -le [version]"1.2.57.463") {
|
||||||
|
|
||||||
if ([version]$offline -ge [version]"1.2.45.454") { $typefile = "xpui.js"}
|
if ([version]$offline -ge [version]"1.2.45.454") { $typefile = "xpui.js" }
|
||||||
|
|
||||||
else { $typefile = "xpui-routes-search.js" }
|
else { $typefile = "xpui-routes-search.js" }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user