Resteamer.psm1
function Invoke-RedeemSteamKeys { #Disables Monocle logging $monoclePath = Get-Item -Path (Get-Module -Name Monocle | Select-Object -ExpandProperty Path) | Select-Object -ExpandProperty DirectoryName $monocleToolPath = Join-Path -Path $monoclePath -ChildPath 'Private/Tools.ps1' $monocleTool = Get-Content $monocleToolPath Set-Content -Path $monocleToolPath -Value ($monocleTool -replace '#?write-host', '#write-host') function Update-BrowserDriver { param( [ValidateSet('win', 'mac', 'linux')] $systemType ) switch ($systemType) { "win" { $chromeDriverFileName = 'chromedriver.exe' $dlPlatform = "win32" } "mac" { $chromeDriverFileName = 'chromedriver' $dlPlatform = 'mac-x64' } "linux" { $chromeDriverFileName = 'chromedriver' $dlPlatform = 'mac-x64' } Default {} } $chromeDriverPath = "$monoclePath\lib\Browsers\$systemType\$chromeDriverFileName" $chromeDriverVersion = & $chromeDriverPath --version $currentChromeDriverMetadata = (Invoke-RestMethod -Method Get -Uri 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json').channels.stable $currentChromedriverversion = $currentChromeDriverMetadata.version if ($chromeDriverVersion -notLike "ChromeDriver $currentChromedriverversion*") { Write-Host "ChromeDriver is out of date, updating..." -ForegroundColor Green $dlUrl = $currentChromeDriverMetadata.downloads.chromedriver | Where-Object Platform -eq $dlPlatform | Select-Object -ExpandProperty url $chromeDriverFolder = (Get-Item $chromeDriverPath).DirectoryName $chromeDriverTempFolder = "$chromedriverFolder\temp" $chromeDriverZipFile = "$chromeDriverTempFolder\chromedriver.zip" $null = New-Item -Path $chromeDriverTempFolder -ItemType Directory Invoke-WebRequest -Uri $dlUrl -OutFile $chromeDriverZipFile Expand-Archive -Path $chromeDriverZipFile -DestinationPath $chromeDriverTempFolder Remove-Item $chromeDriverPath Move-Item "$chromeDriverTempFolder\*\$chromeDriverFileName" "$chromeDriverFolder\$chromeDriverFileName" Remove-Item -Path $chromeDriverTempFolder -Recurse } } function Get-Platform { if ($IsWindows -or $PSVersionTable.psversion.Major -le 5 ) { return "win" } if ($IsMacOS) { return "mac" } if ($IsLinux) { return "linux" } } $platform = Get-Platform try { Update-BrowserDriver -systemType $platform } catch { Write-Host "Could not update ChromeDriver: $($_.Exception.Message)" } if ($platform -eq 'win') { Add-Type -AssemblyName System.Windows.Forms $filePicker = New-Object System.Windows.Forms.OpenFileDialog -Property @{ InitialDirectory = [System.Environment]::GetFolderPath('Desktop') Filter = 'Allowed Files (*.txt;*.csv)|*.txt;*.csv|Textfile (*.txt)|*.txt|CSV (*.csv)|*.csv' } $file = $filePicker.ShowDialog() if ($file -eq 'Cancel') { return Write-Host "A file is required" -ForegroundColor Red } $file = $filePicker.FileName $monocleType = 'Chrome' } else { while (-not ($file)) { $file = Read-Host "Full path to the file containing keys (.csv or .txt)" if (-not (Test-Path -Path $file -PathType Leaf)) { $file = $null Write-Host 'Invalid file, try again' -ForegroundColor Yellow } } $monocleType = 'Firefox' } switch ((Get-Item $file).Extension) { '.txt' { $keyData = (Get-Content -Path $file) | Where-Object { $_ -match '.{5}-.{5}-.{5}' } | ForEach-Object { if ($_ -match '.{5}-.{5}-.{5}-.{5}-.{5}') { $_ -replace '.*(.{5}-.{5}-.{5}-.{5}-.{5}).*', '$1' } else { $_ -replace '.*(.{5}-.{5}-.{5}).*', '$1' } } } '.csv' { $keyHeader = Read-Host "Input the key header (The title of the column, example: Key)" $keyDelimiter = Read-Host "Input the delimiter (Usually a comma ',' or a semicolon ';')" $keyData = (Import-Csv -Delimiter $keyDelimiter -Path $file).$keyHeader $errExt = ' and header' } '' { $keyData = Get-Content -Path $file } default { Write-Host "Invalid file, if the format is correct please rename the extention to either '.csv' or '.txt'" return } } $logName = "$(Get-Date -Format 'yyyy-MM-dd')_steam.log" $LogFolderPath = Join-Path -path ([Environment]::GetFolderPath('MyDocuments')) -ChildPath "Resteamer" $LogPath = Join-Path -Path $LogFolderPath -ChildPath $logName if (-not (Test-Path -Path $LogPath -PathType Leaf)) { New-Item -Path $LogPath -ItemType File -Force | Out-Null } Write-Host "Writing logs to: '$LogPath'" function New-JS_Toast { param ( [ValidateSet('info', 'error')] $type = "info", [Parameter(Mandatory)] [string]$message, [switch]$closeable, [int]$timeout, [ValidateSet('top', 'bottom')] $positionY = 'top', [ValidateSet('left', 'right')] $positionX = 'left' ) $background = switch ($type) { "info" { "linear-gradient(rgb(51, 136, 51), rgb(17, 119, 17))" } "error" { "linear-gradient(rgb(155 0 0), rgb(215 0 0))" } } $toastStyle = "position:absolute;$($positionY):1rem;$($positionX):1rem;padding: 1em 2em; background: $background; color: white; font-size: 1.05rem;z-index:9999" if ($timeout) { $js__timeout = @" setTimeout(() => container.remove(), $timeout) "@ } if ($closeable) { $js__closebtn = @" const close_btn = document.createElement('button') close_btn.style = "position:absolute;top:.5rem;right:.5rem;font-size:.6rem;background:red;color:white;padding:.3rem;border:none;line-height:1" close_btn.textContent = "✖" close_btn.addEventListener('click', () => container.remove()) container.append(close_btn) "@ } $js__toast = @" const container = document.createElement('div') container.style = "$toastStyle" container.id = "resteamer-toast" container.textContent = "$message" document.querySelector("body").insertAdjacentElement("afterbegin", container) $js__timeout $js__closebtn "@ Invoke-MonocleJavaScript -Script $js__toast } $browser = New-MonocleBrowser -Type $monocleType Start-MonocleFlow -Name 'Load Steam' -Browser $browser -ScriptBlock { Set-MonocleUrl -Url 'https://store.steampowered.com/login/' New-JS_Toast -type info -message "Log in to continue" while ($true) { try { Wait-MonocleUrlDifferent -FromUrl 'https://store.steampowered.com/login/' if (-not $browser.url) { try { $browser.quit() } catch {} return } break } catch {} } } function Write-Log { param ( $message, [ValidateSet('info', 'warning', 'error', 'debug')] $logType = 'info' ) $color = switch ($logType) { 'info' { [System.ConsoleColor]::Green } 'warning' { [System.ConsoleColor]::Yellow } 'error' { [System.ConsoleColor]::Red } default { [System.ConsoleColor]::White } } Write-Host $(Get-Date -Format 'HH:MM:ss') -NoNewline -ForegroundColor Magenta Write-Host ' | ' -NoNewline Write-Host "[$logtype] " -ForegroundColor $color -NoNewline Write-Host $message Write-Host "$(Get-Date -Format 'HH:MM:ss') [$logtype] $message" -ForegroundColor $color "$(Get-Date -Format 'HH:MM:ss') | [$logType] $message" | Out-File -FilePath $LogPath -Append -Force } function Invoke-RedeemKey { param($key) Start-MonocleFlow -Name 'Redeem Key' -Browser $browser -ScriptBlock { Set-MonocleUrl -Url "https://store.steampowered.com/account/registerkey?key=$key" -Force Get-MonocleElement -Id 'accept_ssa' | Set-MonocleElementAttribute -Name "checked" -Value 'true' Get-MonocleElement -Id 'register_btn' | Invoke-MonocleElementClick try { switch ((Get-MonocleElement -Id 'error_display').Text) { { $_ -like "$key | The product code you've entered is not valid or is not a product code.*" } { Write-Log -message "$key | Invalid key" -logType error return } { $_ -like "$key | The product code you've entered has already been activated by a different Steam account.*" } { Write-Log -message "$key | Already activated" -logType error return } { $_ -like "$key | This Steam account already owns the product(s) contained in this offer.*" } { Write-Log "$key | Already Owned" -logType warning return } { $_ -like "$key | The product code you've entered requires ownership of another product before activation.*" } { Write-Log "$key | Needs another product to activate" -logType warning return } ($_ -like "$key | There have been too many recent activation attempts from this account or Internet address.*") { Write-Log "$key | Too many activation attempts, the script will now wait 60 minutes" -logType warning for ($i = 0; $i -le 60; $i++) { Write-Progress -Activity "Waiting for cooldown" -PercentComplete ((($i) / 60) * 100) -status "($(60 - $i) minutes remaining)" Start-Sleep -Seconds 1 } Write-Progress -Completed Write-Log -message "$key | Retrying activation..." Invoke-RedeemKey -key $key } } } catch { if ($_.FullyQualifiedErrorId -ne [OpenQA.Selenium.StaleElementReferenceException].Name) { Write-Log -message "Something went wrong, please try again" -logType error } } } } if (-not $keyData) { return Write-Host "No keys found, check the file ($errExt) selected" -ForegroundColor Red } foreach ($key in $keyData) { Invoke-RedeemKey -key $key } } |