View Raw
# 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