param() $ErrorActionPreference = "SilentlyContinue" $script:RunStopwatch = [System.Diagnostics.Stopwatch]::StartNew() $script:PrimaryColor = "Red" $script:AccentColor = "Cyan" $script:MutedColor = "DarkGray" $script:SuccessColor = "Green" $script:WarnColor = "Yellow" $Host.UI.RawUI.BackgroundColor = "Black" Clear-Host function Write-Line($text = "") { Write-Host $text } function Write-Brand($text) { Write-Host $text -ForegroundColor $script:PrimaryColor -BackgroundColor Black } function Write-Accent($text) { Write-Host $text -ForegroundColor $script:AccentColor -BackgroundColor Black } function Write-Muted($text) { Write-Host $text -ForegroundColor $script:MutedColor -BackgroundColor Black } function Write-Success($text) { Write-Host $text -ForegroundColor $script:SuccessColor -BackgroundColor Black } function Write-Warn($text) { Write-Host $text -ForegroundColor $script:WarnColor -BackgroundColor Black } function Write-Header($text) { Write-Host "[ $text ]" -ForegroundColor $script:AccentColor -BackgroundColor Black } function Write-Action($text) { Write-Host " > $text" -ForegroundColor Gray -BackgroundColor Black } function Write-Banner { Write-Brand "██╗ ██████╗ █████╗ ██████╗ ███████╗████████╗██████╗ ██╗███╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗" Write-Brand "██║ ██╔═══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██║████╗ ██║██╔════╝ ██╔══██╗██╔══██╗██╔═══██╗" Write-Brand "██║ ██║ ██║███████║██║ ██║███████╗ ██║ ██████╔╝██║██╔██╗ ██║██║ ███╗ ██████╔╝██████╔╝██║ ██║" Write-Brand "██║ ██║ ██║██╔══██║██║ ██║╚════██║ ██║ ██╔══██╗██║██║╚██╗██║██║ ██║ ██╔═══╝ ██╔══██╗██║ ██║" Write-Brand "███████╗╚██████╔╝██║ ██║██████╔╝███████║ ██║ ██║ ██║██║██║ ╚████║╚██████╔╝ ██║ ██║ ██║╚██████╔╝" Write-Brand "╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ " Write-Line Write-Accent " -- Roblox Live Channel Patcher" Write-Muted " local-only restore flow, no upload, no external data backup" Write-Line } function Read-Choice($promptText) { Write-Host $promptText -ForegroundColor White -BackgroundColor Black -NoNewline return (Read-Host).Trim() } function Confirm-Step($promptText, $automaticMode) { if ($automaticMode) { Write-Host $promptText -ForegroundColor White -BackgroundColor Black -NoNewline Write-Host "Y [auto]" -ForegroundColor $script:MutedColor -BackgroundColor Black return $true } $choice = Read-Choice $promptText return ($choice -match "^(?i)y(?:es)?$") } function Select-RunMode { Write-Header "Run mode" Write-Accent " [1] Automatic patch" Write-Muted " Runs the full patch flow with auto-confirmed steps." Write-Accent " [2] Manual patch" Write-Muted " Prompts for Y confirmation before each destructive or launch step." Write-Line while ($true) { $choice = Read-Choice "Select mode [1/2]: " switch -Regex ($choice) { "^(1|a|auto|automatic)$" { return "automatic" } "^(2|m|manual)$" { return "manual" } default { Write-Warn " Invalid selection. Enter 1 for Automatic or 2 for Manual." } } } } function Backup-Item($sourcePath, $destinationPath, $label) { if (-not (Test-Path $sourcePath)) { return $false } $parentDir = Split-Path -Parent $destinationPath if ($parentDir) { New-Item -ItemType Directory -Path $parentDir -Force | Out-Null } Copy-Item -Path $sourcePath -Destination $destinationPath -Recurse -Force if (Test-Path $destinationPath) { Write-Action "Backed up $label" return $true } return $false } function Restore-Item($sourcePath, $destinationPath, $label) { if (-not (Test-Path $sourcePath)) { return $false } $parentDir = Split-Path -Parent $destinationPath if ($parentDir) { New-Item -ItemType Directory -Path $parentDir -Force | Out-Null } Copy-Item -Path $sourcePath -Destination $destinationPath -Recurse -Force if (Test-Path $destinationPath) { Write-Action "Restored $label" return $true } return $false } function Stop-ProcessIfRunning($processName, $label) { $running = Get-Process -Name $processName if ($running) { Stop-Process -Name $processName -Force Start-Sleep -Milliseconds 900 Write-Action "Stopped $label" return $true } return $false } function Get-LatestRobloxPlayerPath($versionsDir) { if (-not (Test-Path $versionsDir)) { return $null } return Get-ChildItem -Path $versionsDir -Filter "RobloxPlayerBeta.exe" -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 1 } function Format-Elapsed($stopwatch) { $elapsed = $stopwatch.Elapsed if ($elapsed.TotalMinutes -ge 1) { return "{0:mm\:ss\.ff}" -f $elapsed } return "{0:ss\.ff}s" -f $elapsed } Write-Banner $mode = Select-RunMode $automaticMode = $mode -eq "automatic" Write-Line Write-Header "Session" Write-Action "Mode: $mode" Write-Action "Started: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")" Write-Action "Data handling: everything stays on this PC; nothing is uploaded or preserved remotely" Write-Line $processName = "RobloxPlayerBeta" $launcherProcessName = "RobloxPlayerLauncher" $downloadUrl = "https://www.roblox.com/download/client?token=666" $robloxAppData = Join-Path $env:LOCALAPPDATA "Roblox" $robloxLocalStorage = Join-Path $robloxAppData "LocalStorage" $cookieFile = Join-Path $robloxLocalStorage "RobloxCookies.dat" $globalBasicSettingsFile = Join-Path $robloxAppData "GlobalBasicSettings_13.xml" $globalBasicSettingsLegacyFile = Join-Path $robloxAppData "GlobalBasicSettings.xml" $versionsDir = Join-Path $env:LOCALAPPDATA "Roblox\Versions" $installerPath = Join-Path $env:TEMP "RobloxPlayerLauncher.exe" $backupDir = Join-Path $env:USERPROFILE ".roblox_live_channel_backup" $backupCookieFile = Join-Path $backupDir "RobloxCookies.dat" $backupSettingsDir = Join-Path $backupDir "settings" $backupGlobalBasicSettingsFile = Join-Path $backupSettingsDir "GlobalBasicSettings_13.xml" $backupGlobalBasicSettingsLegacyFile = Join-Path $backupSettingsDir "GlobalBasicSettings.xml" $backupLocalStorageDir = Join-Path $backupSettingsDir "LocalStorage" $hasBackupCookie = $false $settingsBackedUp = $false $installCompleted = $false $restoreCompleted = $false $launchCompleted = $false $hadBackupSettings = $false Write-Header "Step 1 - Process guard" if (Get-Process -Name $processName) { Write-Warn " RobloxPlayerBeta.exe is currently running." if (-not (Confirm-Step " Kill Roblox before patching? [Y/N]: " $automaticMode)) { Write-Warn " Patch flow aborted before any file changes were made." $script:RunStopwatch.Stop() Write-Line Write-Header "Result" Write-Action "Completed in $(Format-Elapsed $script:RunStopwatch)" exit } Stop-ProcessIfRunning $processName "RobloxPlayerBeta.exe" | Out-Null } else { Write-Action "RobloxPlayerBeta.exe is not running" } if (Get-Process -Name $launcherProcessName) { Stop-ProcessIfRunning $launcherProcessName "RobloxPlayerLauncher.exe" | Out-Null } Write-Line Write-Header "Step 2 - Backup current session" if (-not (Test-Path $backupDir)) { New-Item -ItemType Directory -Path $backupDir -Force | Out-Null } if (Test-Path $cookieFile) { Write-Action "Saving Roblox auth cookie" Copy-Item -Path $cookieFile -Destination $backupCookieFile -Force $hasBackupCookie = Test-Path $backupCookieFile if ($hasBackupCookie) { Write-Success " Auth cookie captured" } } else { Write-Muted " No Roblox cookie found" } Write-Action "Saving Roblox settings" if (Backup-Item $globalBasicSettingsFile $backupGlobalBasicSettingsFile "GlobalBasicSettings_13.xml") { $settingsBackedUp = $true } if (Backup-Item $globalBasicSettingsLegacyFile $backupGlobalBasicSettingsLegacyFile "GlobalBasicSettings.xml") { $settingsBackedUp = $true } if (Test-Path $robloxLocalStorage) { New-Item -ItemType Directory -Path $backupLocalStorageDir -Force | Out-Null Get-ChildItem -Path $robloxLocalStorage -Force | Where-Object { $_.Name -ne "RobloxCookies.dat" } | ForEach-Object { $destinationPath = Join-Path $backupLocalStorageDir $_.Name if (Backup-Item $_.FullName $destinationPath "LocalStorage/$($_.Name)") { $settingsBackedUp = $true } } } if (-not $settingsBackedUp) { Write-Muted " No additional settings files were found" } $hadBackupSettings = $settingsBackedUp -or (Test-Path $backupSettingsDir) Write-Line Write-Header "Step 3 - Purge local install" if (Test-Path $robloxAppData) { if (Confirm-Step " Delete Roblox AppData to prepare a clean patch? [Y/N]: " $automaticMode) { Remove-Item -Path "$robloxAppData\*" -Recurse -Force Remove-Item -Path $robloxAppData -Force Write-Success " Roblox AppData removed" } else { Write-Muted " Skipped Roblox AppData deletion" } } else { Write-Muted " Roblox AppData folder was not present" } Write-Line Write-Header "Step 4 - Temp cleanup" if (Confirm-Step " Clear TEMP files before reinstall? [Y/N]: " $automaticMode) { Remove-Item -Path "$($env:TEMP)\*" -Recurse -Force Write-Success " TEMP directory cleaned" } else { Write-Muted " TEMP cleanup skipped" } Write-Line Write-Header "Step 5 - Install latest channel" if (Confirm-Step " Download and patch to the latest live Roblox channel now? [Y/N]: " $automaticMode) { Write-Action "Downloading latest Roblox launcher" try { Invoke-WebRequest -Uri $downloadUrl -OutFile $installerPath Write-Success " Launcher download complete" Write-Action "Starting Roblox installer" Start-Process -FilePath $installerPath Write-Action "Waiting for RobloxPlayerBeta.exe to auto-launch" $timeoutSeconds = 120 $elapsedSeconds = 0 while (-not (Get-Process -Name $processName) -and $elapsedSeconds -lt $timeoutSeconds) { Start-Sleep -Seconds 2 $elapsedSeconds += 2 } if (Get-Process -Name $processName) { Write-Action "Intercepting RobloxPlayerBeta.exe" Stop-ProcessIfRunning $processName "RobloxPlayerBeta.exe" | Out-Null if (Get-Process -Name $launcherProcessName) { Write-Action "Stopping RobloxPlayerLauncher.exe" Stop-ProcessIfRunning $launcherProcessName "RobloxPlayerLauncher.exe" | Out-Null } $installCompleted = $true Write-Success " Latest live channel install completed" } else { Write-Warn " Timed out waiting for Roblox to auto-launch" } } catch { Write-Warn " Failed to download or execute the Roblox installer" } } else { Write-Muted " Latest-channel install skipped" } Write-Line Write-Header "Step 6 - Restore profile data" if (($hasBackupCookie -or $hadBackupSettings) -and (Confirm-Step " Restore saved Roblox login and settings? [Y/N]: " $automaticMode)) { if (-not (Test-Path $robloxLocalStorage)) { New-Item -ItemType Directory -Path $robloxLocalStorage -Force | Out-Null } if ($hasBackupCookie) { Copy-Item -Path $backupCookieFile -Destination $robloxLocalStorage -Force Write-Success " Login cookie restored" } if ($hadBackupSettings) { Write-Action "Restoring Roblox settings" Restore-Item $backupGlobalBasicSettingsFile $globalBasicSettingsFile "GlobalBasicSettings_13.xml" | Out-Null Restore-Item $backupGlobalBasicSettingsLegacyFile $globalBasicSettingsLegacyFile "GlobalBasicSettings.xml" | Out-Null if (Test-Path $backupLocalStorageDir) { Get-ChildItem -Path $backupLocalStorageDir -Force | ForEach-Object { $destinationPath = Join-Path $robloxLocalStorage $_.Name Restore-Item $_.FullName $destinationPath "LocalStorage/$($_.Name)" | Out-Null } } } $restoreCompleted = $true } else { Write-Muted " Restore step skipped" } Write-Line Write-Header "Step 7 - Launch latest build" if (Confirm-Step " Launch the latest installed Roblox build now? [Y/N]: " $automaticMode) { $robloxExe = Get-LatestRobloxPlayerPath $versionsDir if ($robloxExe) { Write-Action "Launching $($robloxExe.Directory.Name)" Start-Process -FilePath $robloxExe.FullName $launchCompleted = $true Write-Success " Latest Roblox build started" } else { Write-Warn " Could not locate RobloxPlayerBeta.exe inside Versions" } } else { Write-Muted " Final launch skipped" } if (Test-Path $backupDir) { Remove-Item -Path $backupDir -Recurse -Force } $script:RunStopwatch.Stop() Write-Line Write-Header "Result" if ($installCompleted) { Write-Success " Live channel patch flow completed" } else { Write-Warn " Live channel patch flow finished without a confirmed install interception" } Write-Action "Cookie backup: $(if ($hasBackupCookie) { 'yes' } else { 'no' })" Write-Action "Settings backup: $(if ($hadBackupSettings) { 'yes' } else { 'no' })" Write-Action "Restore applied: $(if ($restoreCompleted) { 'yes' } else { 'no' })" Write-Action "Latest build launched: $(if ($launchCompleted) { 'yes' } else { 'no' })" Write-Accent " Total runtime: $(Format-Elapsed $script:RunStopwatch)" Write-Line Write-Host "Press Enter to close..." -ForegroundColor White -BackgroundColor Black -NoNewline Read-Host | Out-Null