# MAGICIS INSTALL - Terminal Type Selector # Runs C:\magicis\agent.bat, adjusts C:\magicis\config.json, then enables kiosk mode and restarts. # Kiosk mode: AutoAdminLogon (user=magicis / pass=magicis123) + Shell = c:\magicis\agent\agent.exe # With resilient logging (C:\magicis\install.log -> C:\ProgramData\magicis\install.log -> %TEMP%\magicis_install.log) $ErrorActionPreference = 'Stop' # ---- Elevation check ---- if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( [Security.Principal.WindowsBuiltInRole] "Administrator")) { $self = if ($PSCommandPath) { $PSCommandPath } else { $MyInvocation.MyCommand.Path } Start-Process -FilePath "powershell.exe" -Verb RunAs -ArgumentList $self exit } # ---- Paths/Constants ---- $ConfigDir = 'C:\magicis' $ConfigPath = Join-Path $ConfigDir 'config.json' $AgentBat = Join-Path $ConfigDir 'agent.bat' $ShellPath = 'cmd.exe /c c:\magicis\launcher.bat' $KioskUser = 'magicis' $KioskPass = '124578Magicis' # ---- Logging (resilient) ---- $Global:LogPath = $null function Initialize-Log { $candidates = @( 'C:\magicis\install.log', 'C:\ProgramData\magicis\install.log', (Join-Path $env:TEMP 'magicis_install.log') ) foreach ($p in $candidates) { try { $dir = Split-Path $p -Parent if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } "----- LOG START $(Get-Date -Format s) -----" | Out-File -FilePath $p -Encoding UTF8 -Append $Global:LogPath = $p break } catch { } } } function Write-Log([string]$Message) { try { if (-not $Global:LogPath) { Initialize-Log } $line = "[{0}] {1}" -f (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Message if ($Global:LogPath) { Add-Content -Path $Global:LogPath -Value $line -Encoding UTF8 } } catch { } } Initialize-Log Write-Log "Script started." # ---- Helpers ---- function Get-ConfigObject { try { $raw = Get-Content -Path $ConfigPath -Raw -ErrorAction Stop Write-Log "Read config.json ($($raw.Length) chars)." return ($raw | ConvertFrom-Json -ErrorAction Stop) } catch { Write-Log "ERROR reading/parsing config.json: $($_.Exception.Message)" Write-Host "Failed to read or parse $ConfigPath." -ForegroundColor Red return $null } } function Save-ConfigObject($obj) { try { $json = $obj | ConvertTo-Json -Depth 5 $json | Set-Content -Path $ConfigPath -Encoding UTF8 -Force Write-Log "config.json saved successfully." } catch { Write-Log "ERROR saving config.json: $($_.Exception.Message)" Write-Host "Failed to save ${ConfigPath}: $($_.Exception.Message)" -ForegroundColor Red } } function Set-InstallationType($typeString) { if (-not (Test-Path -Path $ConfigPath)) { Write-Log "config.json not found. installationType not changed." Write-Host "Config not found at $ConfigPath. Nothing changed." -ForegroundColor Yellow return } $cfg = Get-ConfigObject if ($null -eq $cfg) { return } $prev = $cfg.installationType $cfg.installationType = $typeString Save-ConfigObject -obj $cfg Write-Log "installationType changed: '$prev' -> '$typeString'." Write-Host "installationType: '$prev' -> '$typeString' ($ConfigPath)" -ForegroundColor Green } function Run-Agent { if (-not (Test-Path -Path $ConfigDir)) { Write-Log "Directory $ConfigDir not found." Write-Host "Directory $ConfigDir was not found." -ForegroundColor Yellow return $false } if (-not (Test-Path -Path $AgentBat)) { Write-Log "agent.bat not found at $AgentBat." Write-Host "agent.bat not found at $AgentBat" -ForegroundColor Red return $false } try { Start-Process -FilePath "cmd.exe" -ArgumentList "/c","agent.bat" -WorkingDirectory $ConfigDir -WindowStyle Hidden | Out-Null Write-Log "agent.bat started." Write-Host "agent.bat started..." -ForegroundColor Cyan return $true } catch { Write-Log "ERROR starting agent.bat: $($_.Exception.Message)" Write-Host "Failed to start agent.bat: $($_.Exception.Message)" -ForegroundColor Red return $false } } function Stop-InteractiveProcesses { Write-Log "Stopping processes: java/javaw/godot..." $names = @('java','javaw','godot','openjdk') foreach ($n in $names) { try { Stop-Process -Name $n -Force -ErrorAction SilentlyContinue } catch {} } try { $procs = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object { $_.Name -match '(?i)java|godot' -or $_.Description -match '(?i)OpenJDK Platform Binary|Godot' } foreach ($p in $procs) { try { Stop-Process -Id $p.ProcessId -Force -ErrorAction SilentlyContinue } catch {} } } catch {} Write-Log "Process stop routine completed." Write-Host "Requested processes terminated (java/javaw/Godot if running)." -ForegroundColor DarkCyan } function Wait-ForConfig([int]$TimeoutSec = 30) { Write-Log "Waiting for config.json (timeout ${TimeoutSec}s)..." $elapsed = 0 while ($elapsed -lt $TimeoutSec) { if (Test-Path -Path $ConfigPath) { Write-Log "config.json detected after ${elapsed}s." return $true } Start-Sleep -Seconds 1 $elapsed++ } Write-Log "config.json NOT detected within timeout." return $false } # ---- Kiosk Mode ---- function Ensure-LocalAdminUser([string]$User, [string]$Pass) { try { $secure = ConvertTo-SecureString $Pass -AsPlainText -Force $existing = Get-LocalUser -Name $User -ErrorAction SilentlyContinue if ($null -eq $existing) { New-LocalUser -Name $User -Password $secure -PasswordNeverExpires -AccountNeverExpires -FullName $User -Description "Kiosk AutoLogon user" | Out-Null Write-Log "Created local user '$User'." } else { if ($existing.Enabled -eq $false) { Enable-LocalUser -Name $User } $existing | Set-LocalUser -Password $secure Set-LocalUser -Name $User -PasswordNeverExpires $true Write-Log "Updated local user '$User' (enabled & password set)." } $admins = Get-LocalGroupMember -Group 'Administrators' -ErrorAction SilentlyContinue $inGroup = $admins | Where-Object { $_.Name -match ("(?i)\\$User$") } if (-not $inGroup) { Add-LocalGroupMember -Group 'Administrators' -Member $User -ErrorAction Stop Write-Log "Added '$User' to Administrators." } else { Write-Log "User '$User' already in Administrators." } } catch { Write-Log "ERROR ensuring local user '$User': $($_.Exception.Message)" Write-Host "Failed to ensure local user '$User': $($_.Exception.Message)" -ForegroundColor Red throw } } function Enable-AutoAdminLogon([string]$User, [string]$Pass) { $key = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' try { #New-Item -Path $key -Force | Out-Null Set-ItemProperty -Path $key -Name 'AutoAdminLogon' -Value '1' -Type String Set-ItemProperty -Path $key -Name 'ForceAutoLogon' -Value '1' -Type String Set-ItemProperty -Path $key -Name 'DefaultUserName' -Value $User -Type String Set-ItemProperty -Path $key -Name 'DefaultDomainName' -Value '.' -Type String Set-ItemProperty -Path $key -Name 'DefaultPassword' -Value $Pass -Type String Set-ItemProperty -Path $key -Name 'DisableCAD' -Value 1 -Type DWord Write-Log "AutoAdminLogon configured for user '$User'." } catch { Write-Log "ERROR setting AutoAdminLogon: $($_.Exception.Message)" Write-Host "Failed to set AutoAdminLogon registry: $($_.Exception.Message)" -ForegroundColor Red throw } } function Set-KioskShell([string]$ShellExe) { $key = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' try { Set-ItemProperty -Path $key -Name 'Shell' -Value $ShellExe -Type String Write-Log "Kiosk shell set to '$ShellExe'." } catch { Write-Log "ERROR setting kiosk shell: $($_.Exception.Message)" Write-Host "Failed to set kiosk shell: $($_.Exception.Message)" -ForegroundColor Red throw } } function Enable-KioskMode([string]$SelectedType) { Write-Host "Enabling kiosk mode and restarting $SelectedType..." -ForegroundColor Cyan Write-Log "Enabling kiosk mode for '$SelectedType'..." Ensure-LocalAdminUser -User $KioskUser -Pass $KioskPass Enable-AutoAdminLogon -User $KioskUser -Pass $KioskPass Set-KioskShell -ShellExe $ShellPath Write-Log "Kiosk mode configured. Rebooting in 5 seconds." Write-Host "Kiosk mode configured: AutoAdminLogon=user '$KioskUser', Shell='$ShellPath'." -ForegroundColor Green Write-Host "Rebooting in 5 seconds..." -ForegroundColor Yellow Start-Sleep -Seconds 5 Restart-Computer -Force } # ---- Proper Exit (closes window) ---- function Exit-Script { Write-Log "Exit chosen by user. Terminating host..." try { if ($Host.Name -match 'ConsoleHost|Windows PowerShell ISE Host') { Stop-Process -Id $PID -Force } else { exit 0 } } catch { exit 0 } } function Show-Menu { Clear-Host Write-Host "==============================" -ForegroundColor Cyan Write-Host " MAGICIS INSTALL (choose terminal type) " -ForegroundColor Cyan Write-Host "==============================" -ForegroundColor Cyan Write-Host "1 - GAME TERMINAL" Write-Host "2 - POS" Write-Host "3 - LOADER" Write-Host "4 - Exit" Write-Host "" } # ---- Main loop ---- while ($true) { Show-Menu $choice = Read-Host "Enter an option (1-4)" Write-Log "Menu choice: $choice" switch ($choice) { '1' { if (Run-Agent) { Start-Sleep -Seconds 10 Write-Log "Option 1: waited 10s, stopping processes..." Stop-InteractiveProcesses if (Wait-ForConfig -TimeoutSec 30) { Set-InstallationType -typeString 'GAME_TERMINAL' } else { Write-Host "config.json did not appear within 30s." -ForegroundColor Yellow Write-Log "config.json not found within 30s (option 1)." } } Write-Host "Enabling kiosk mode and restarting GAME TERMINAL..." -ForegroundColor Cyan Enable-KioskMode -SelectedType 'GAME TERMINAL' } '2' { if (Run-Agent) { Start-Sleep -Seconds 10 Write-Log "Option 2: waited 10s, stopping processes..." Stop-InteractiveProcesses if (Wait-ForConfig -TimeoutSec 30) { Set-InstallationType -typeString 'POS' } else { Write-Host "config.json did not appear within 30s." -ForegroundColor Yellow Write-Log "config.json not found within 30s (option 2)." } } Write-Host "Enabling kiosk mode and restarting POS..." -ForegroundColor Cyan Enable-KioskMode -SelectedType 'POS' } '3' { if (Run-Agent) { Start-Sleep -Seconds 10 Write-Log "Option 3: waited 10s, stopping processes..." Stop-InteractiveProcesses if (Wait-ForConfig -TimeoutSec 30) { Set-InstallationType -typeString 'LOADER' } else { Write-Host "config.json did not appear within 30s." -ForegroundColor Yellow Write-Log "config.json not found within 30s (option 3)." } } Write-Host "Enabling kiosk mode and restarting LOADER..." -ForegroundColor Cyan Enable-KioskMode -SelectedType 'LOADER' } '4' { Write-Host "Exiting..." -ForegroundColor Cyan Exit-Script } default { Write-Log "Invalid choice: $choice" Write-Host "Invalid option. Please choose 1, 2, 3, or 4." -ForegroundColor Yellow Start-Sleep -Milliseconds 900 } } }