# CCLS Games CLI Tool # Updated Version with Setup functionality # Configuration $baseUrl = "https://games.ccls.icu" $cliApiUrl = "$baseUrl/CLI" $settingsFolder = ".\settings" $credentialsFile = "$settingsFolder\credentials.dat" $settingsFile = "$settingsFolder\settings.json" # Using JSON instead of INI for simplicity # Ensure settings directory exists if (-not (Test-Path $settingsFolder)) { New-Item -Path $settingsFolder -ItemType Directory | Out-Null } # Initialize or load settings function Initialize-Settings { if (-not (Test-Path $settingsFile)) { # Create default settings file $defaultSettings = @{ RememberLogin = $false DownloadPath = ".\downloads" TempDownloadPath = ".\tmp" HasCompletedSetup = $false } $defaultSettings | ConvertTo-Json | Set-Content -Path $settingsFile } # Load settings $settings = Get-Content -Path $settingsFile | ConvertFrom-Json return $settings } # Save settings function Save-Settings($settings) { $settings | ConvertTo-Json | Set-Content -Path $settingsFile } # Store credentials securely function Save-Credentials($username, $password) { $credentials = @{ Username = $username Password = $password } | ConvertTo-Json # Simple encryption (replace with more secure method if needed) $securePassword = ConvertTo-SecureString -String $credentials -AsPlainText -Force $encryptedText = ConvertFrom-SecureString -SecureString $securePassword # Save to file $encryptedText | Set-Content -Path $credentialsFile } # Load stored credentials function Get-StoredCredentials { if (Test-Path $credentialsFile) { try { $encryptedText = Get-Content -Path $credentialsFile $securePassword = ConvertTo-SecureString -String $encryptedText $credentials = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword) ) return $credentials | ConvertFrom-Json } catch { Write-Host "Error reading credentials: $($_.Exception.Message)" -ForegroundColor Red return $null } } return $null } # Validate username against server function Test-Username($username) { $params = @{ Uri = "$cliApiUrl/username_check.php" Method = "POST" Headers = @{ "User-Agent" = "CCLS-CLI/1.0" } Body = @{ username = $username } } try { $response = Invoke-RestMethod @params return $response.exists } catch { Write-Host "Error connecting to the server: $($_.Exception.Message)" -ForegroundColor Red return $false } } # Validate password against server function Test-Password($username, $password) { $params = @{ Uri = "$cliApiUrl/password_check.php" Method = "POST" Headers = @{ "User-Agent" = "CCLS-CLI/1.0" } Body = @{ username = $username password = $password } } try { $response = Invoke-RestMethod @params return $response.success } catch { Write-Host "Error connecting to the server: $($_.Exception.Message)" -ForegroundColor Red return $false } } # Run setup process function Start-Setup { Clear-Host Write-Host "CCLS Games CLI Setup" -ForegroundColor Green Write-Host "=====================" -ForegroundColor Green Write-Host "Please configure the following settings:`n" -ForegroundColor Cyan $settings = Initialize-Settings # Get game installation directory $validPath = $false while (-not $validPath) { Write-Host "Set your games default installation directory: " -ForegroundColor Yellow -NoNewline $downloadPath = Read-Host if ([string]::IsNullOrWhiteSpace($downloadPath)) { Write-Host "Please enter a valid directory path." -ForegroundColor Red } else { # Create directory if it doesn't exist if (-not (Test-Path $downloadPath)) { try { New-Item -ItemType Directory -Path $downloadPath -Force | Out-Null $validPath = $true } catch { Write-Host "Error creating directory: $($_.Exception.Message)" -ForegroundColor Red } } else { $validPath = $true } } } # Get temporary download directory $validTempPath = $false while (-not $validTempPath) { Write-Host "Set the temporary directory of downloading files before they have finished downloading: " -ForegroundColor Yellow -NoNewline $tempDownloadPath = Read-Host if ([string]::IsNullOrWhiteSpace($tempDownloadPath)) { Write-Host "Please enter a valid directory path." -ForegroundColor Red } else { # Create directory if it doesn't exist if (-not (Test-Path $tempDownloadPath)) { try { New-Item -ItemType Directory -Path $tempDownloadPath -Force | Out-Null $validTempPath = $true } catch { Write-Host "Error creating directory: $($_.Exception.Message)" -ForegroundColor Red } } else { $validTempPath = $true } } } # Update settings $settings.DownloadPath = $downloadPath $settings.TempDownloadPath = $tempDownloadPath $settings.HasCompletedSetup = $true Save-Settings -settings $settings Clear-Host Write-Host "Great, you have now completed the setup. Type 'help' for a list of commands to get you started." -ForegroundColor Green } # Try auto-login with stored credentials function Start-AutoLogin { $credentials = Get-StoredCredentials if ($credentials -ne $null) { Write-Host "Attempting to login with stored credentials..." -ForegroundColor Gray if (Test-Password -username $credentials.Username -password $credentials.Password) { Write-Host "Auto-login successful!" -ForegroundColor Green return @{ Success = $true Username = $credentials.Username } } else { Write-Host "Stored credentials are no longer valid." -ForegroundColor Yellow # Remove invalid credentials if (Test-Path $credentialsFile) { Remove-Item -Path $credentialsFile -Force } } } return @{ Success = $false } } # Manual login process function Start-ManualLogin { $maxAttempts = 3 $attempts = 0 while ($attempts -lt $maxAttempts) { Write-Host "`nUsername: " -ForegroundColor Cyan -NoNewline $username = Read-Host # Check if username exists Write-Host "Checking username..." -ForegroundColor Gray if (Test-Username -username $username) { Write-Host "Username found!" -ForegroundColor Green Write-Host "Password: " -ForegroundColor Cyan -NoNewline $password = Read-Host -AsSecureString $passwordPlain = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password) ) Write-Host "Validating password..." -ForegroundColor Gray if (Test-Password -username $username -password $passwordPlain) { Write-Host "Login successful!" -ForegroundColor Green # Ask if user wants to save credentials Write-Host "`nDo you want to remember your login info for next time? (Y/N)" -ForegroundColor Yellow $rememberLogin = Read-Host if ($rememberLogin.ToLower() -eq "y") { Save-Credentials -username $username -password $passwordPlain $settings = Initialize-Settings $settings.RememberLogin = $true Save-Settings -settings $settings Write-Host "Login information saved." -ForegroundColor Green } return @{ Success = $true Username = $username } } else { Write-Host "Incorrect password, please try again." -ForegroundColor Red $attempts++ } } else { Write-Host "Username not found, please try again." -ForegroundColor Red $attempts++ } } Write-Host "Too many failed login attempts. Please try again later." -ForegroundColor Red return @{ Success = $false } } # Search for game information by CG number function Search-Game($cgNumber) { # Validate CG number format if ($cgNumber -notmatch "^cg\d{4}$") { Write-Host "Invalid CG number format. Please use format 'cg0000'." -ForegroundColor Red return } try { # Construct the URL for the game JSON file $gameJsonUrl = "$cliApiUrl/search.php?id=$cgNumber" # Attempt to fetch the game information $params = @{ Uri = $gameJsonUrl Method = "GET" Headers = @{ "User-Agent" = "CCLS-CLI/1.0" } } Write-Host "Searching for game information..." -ForegroundColor Gray # Fetch game data from server try { $response = Invoke-RestMethod @params # Check if the request was successful if (-not $response.success) { Write-Host "Error: $($response.message)" -ForegroundColor Red return } $gameInfo = $response } catch { Write-Host "Error fetching game information: $($_.Exception.Message)" -ForegroundColor Red return } # Display game information in a formatted way Clear-Host Write-Host "Game Information for $($gameInfo.name) ($($gameInfo.id))" -ForegroundColor Green Write-Host "=======================================================" -ForegroundColor Green Write-Host "`nDescription:" -ForegroundColor Cyan Write-Host $gameInfo.description if ($gameInfo.safety_score -or $gameInfo.safety_level) { Write-Host "`nSafety:" -ForegroundColor Cyan if ($gameInfo.safety_score) { Write-Host "Score: $($gameInfo.safety_score)" } if ($gameInfo.safety_level) { Write-Host "Level: $($gameInfo.safety_level)" } } Write-Host "`nDetails:" -ForegroundColor Cyan if ($gameInfo.size) { Write-Host "Size: $($gameInfo.size)" } if ($gameInfo.version -and $gameInfo.version -ne "") { Write-Host "Version: $($gameInfo.version)" } if (($gameInfo.online -and $gameInfo.online -ne "") -or ($gameInfo.steam -and $gameInfo.steam -ne "") -or ($gameInfo.epic -and $gameInfo.epic -ne "")) { Write-Host "`nAvailability:" -ForegroundColor Cyan if ($gameInfo.online -and $gameInfo.online -ne "") { Write-Host "Online: $($gameInfo.online)" } if ($gameInfo.steam -and $gameInfo.steam -ne "") { Write-Host "Steam: $($gameInfo.steam)" } if ($gameInfo.epic -and $gameInfo.epic -ne "") { Write-Host "Epic: $($gameInfo.epic)" } } if ($gameInfo.false_av -and $gameInfo.false_av -ne "") { Write-Host "`nNote: " -ForegroundColor Yellow -NoNewline Write-Host "This game may trigger false antivirus alerts: $($gameInfo.false_av)" } if ($gameInfo.system_requirements) { Write-Host "`nSystem Requirements:" -ForegroundColor Cyan if ($gameInfo.system_requirements.minimum) { Write-Host "Minimum:" -ForegroundColor Yellow foreach ($prop in $gameInfo.system_requirements.minimum.PSObject.Properties) { Write-Host " $($prop.Name): $($prop.Value)" } } if ($gameInfo.system_requirements.recommended) { Write-Host "`nRecommended:" -ForegroundColor Yellow foreach ($prop in $gameInfo.system_requirements.recommended.PSObject.Properties) { Write-Host " $($prop.Name): $($prop.Value)" } } } Write-Host "`nPress any key to return to the main menu..." -ForegroundColor Gray $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } catch { Write-Host "An error occurred while processing game information: $($_.Exception.Message)" -ForegroundColor Red Write-Host "Press any key to return to the main menu..." -ForegroundColor Gray $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } } # Main CLI interface function Start-MainInterface($username) { Clear-Host Write-Host "Welcome to CCLS Games CLI Tool, $username!" -ForegroundColor Green # Load settings to check setup status $settings = Initialize-Settings # Show appropriate message based on setup status if ($settings.HasCompletedSetup) { Write-Host "Type 'help' for a list of available commands.`n" -ForegroundColor Cyan } else { Write-Host "ALERT, type command 'setup' to set critical values before downloading." -ForegroundColor Red } $running = $true while ($running) { Write-Host "CCLS>" -ForegroundColor Yellow -NoNewline $command = Read-Host switch -Regex ($command.ToLower()) { "^exit|^quit" { $running = $false Write-Host "Thank you for using the CCLS Games CLI Tool. Goodbye!" -ForegroundColor Cyan } "^help" { Write-Host "`nAvailable Commands:" -ForegroundColor Green Write-Host " help - Show this help message" Write-Host " setup - Configure download directories" Write-Host " search - Search for game information by CG number" Write-Host " exit, quit - Exit the application" Write-Host " logout - Log out and exit" Write-Host " forget - Remove stored credentials" Write-Host "" } "^setup" { Start-Setup } "^search$" { Clear-Host Write-Host "To use the search command please provide a valid CG number in this format 'search cg0000'" -ForegroundColor Cyan Write-Host "To get the CG number of a game, go to the main games page and click on any game, then check" -ForegroundColor Cyan Write-Host "the URL 'https://games.ccls.icu/game.php?id=cg0000' and the 'cg0000' part in URL is the CG number" -ForegroundColor Cyan } "^search\s+(cg\d{4})$" { $cgNumber = $matches[1] Search-Game -cgNumber $cgNumber } "^logout" { $running = $false Write-Host "Logging out..." -ForegroundColor Cyan # Clear the current session but keep credentials if they exist } "^forget" { if (Test-Path $credentialsFile) { Remove-Item -Path $credentialsFile -Force $settings = Initialize-Settings $settings.RememberLogin = $false Save-Settings -settings $settings Write-Host "Stored credentials have been removed." -ForegroundColor Green } else { Write-Host "No stored credentials found." -ForegroundColor Yellow } } default { Write-Host "Unknown command. Type 'help' for a list of available commands." -ForegroundColor Red } } } } # Main application flow function Start-CclsCliTool { Clear-Host Write-Host "Hello and welcome to the CCLS Games CLI Tool" -ForegroundColor Green Write-Host "Before proceeding to using this software you will need to sign in." Write-Host "If you do not have an account already please go to $baseUrl/login.php?signup to register a new account.`n" -ForegroundColor Cyan $settings = Initialize-Settings # Try auto-login if remember login is enabled $loginResult = @{ Success = $false } if ($settings.RememberLogin) { $loginResult = Start-AutoLogin } # If auto-login failed or is disabled, do manual login if (-not $loginResult.Success) { $loginResult = Start-ManualLogin } # If login succeeded, show main interface if ($loginResult.Success) { Start-MainInterface -username $loginResult.Username } else { Write-Host "Login failed. Press any key to exit..." -ForegroundColor Red $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") } } # Start the application Start-CclsCliTool