Skip to content

Commit 5e42622

Browse files
committed
merge changes from SunshineScriptInstaller for Apollo support
1 parent 4a514b2 commit 5e42622

3 files changed

Lines changed: 218 additions & 107 deletions

File tree

Helpers.ps1

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,24 +217,59 @@ function Update-JsonProperty {
217217
# Read the file as a single string.
218218
$content = Get-Content -Path $FilePath -Raw
219219

220+
# Remove comments (both // and /* */ style) and trailing commas
221+
$strippedContent = $content -replace '//.*?(\r?\n|$)', '$1' # Remove single line comments
222+
$strippedContent = $strippedContent -replace '/\*[\s\S]*?\*/', '' # Remove multi-line comments
223+
$strippedContent = $strippedContent -replace ',(\s*[\]}])', '$1' # Remove trailing commas
224+
225+
# Format the new value properly
220226
if ($NewValue -is [string]) {
221227
# Convert the string to a JSON-compliant string.
222-
# ConvertTo-Json will take care of escaping characters properly.
223228
$formattedValue = (ConvertTo-Json $NewValue -Compress)
224-
}
225-
else {
226-
$formattedValue = $NewValue.ToString()
229+
} else {
230+
$formattedValue = $NewValue.ToString().ToLower()
227231
}
228232

229233
# Build a regex pattern for matching the property.
230234
$escapedProperty = [regex]::Escape($Property)
231235
$pattern = '"' + $escapedProperty + '"\s*:\s*[^,}\r\n]+'
232236

233-
# Build the replacement string.
234-
$replacement = '"' + $Property + '": ' + $formattedValue
235-
236-
# Replace the matching part in the content.
237-
$updatedContent = [regex]::Replace($content, $pattern, { param($match) $replacement })
237+
# Check if the property exists in the stripped content
238+
if ($strippedContent -match $pattern) {
239+
# Property exists, just update its value in the original content
240+
$replacement = '"' + $Property + '": ' + $formattedValue
241+
$updatedContent = [regex]::Replace($content, $pattern, $replacement)
242+
} else {
243+
# Property doesn't exist, need to add it
244+
# Find the last property in the JSON object
245+
$lastPropPattern = ',?\s*"([^"]+)"\s*:\s*[^,}\r\n]+'
246+
247+
if ($content -match '}\s*$') {
248+
# Find the last occurrence of a property
249+
$lastMatch = [regex]::Matches($content, $lastPropPattern)[-1]
250+
$lastPropIndex = $lastMatch.Index + $lastMatch.Length
251+
252+
# Check if the last property ends with a comma
253+
$endsWithComma = $content.Substring($lastPropIndex).TrimStart() -match '^\s*,'
254+
255+
# Prepare the new property string
256+
$newPropString = ""
257+
if (!$endsWithComma) {
258+
$newPropString += ","
259+
}
260+
$newPropString += "`n `"$Property`": $formattedValue"
261+
262+
# Insert the new property before the closing brace
263+
$closingBraceIndex = $content.LastIndexOf('}')
264+
$updatedContent = $content.Substring(0, $closingBraceIndex).TrimEnd() +
265+
$newPropString +
266+
"`n}" +
267+
$content.Substring($closingBraceIndex + 1)
268+
} else {
269+
Write-Error "Unable to find a proper location to insert the new property. JSON file may be malformed."
270+
return
271+
}
272+
}
238273

239274
# Write the updated content back.
240275
Set-Content -Path $FilePath -Value $updatedContent

Installer.ps1

Lines changed: 93 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@ $scriptPath = "$scriptRoot\StreamMonitor.ps1"
1414
. .\Helpers.ps1 -n $scriptName
1515
$settings = Get-Settings
1616

17-
# This script modifies the global_prep_cmd setting in the Sunshine configuration file
17+
# This script modifies the global_prep_cmd setting in the Sunshine/Apollo configuration files
1818

1919
function Test-UACEnabled {
2020
$key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
2121
$uacEnabled = Get-ItemProperty -Path $key -Name 'EnableLUA'
2222
return [bool]$uacEnabled.EnableLUA
2323
}
2424

25-
2625
$isAdmin = [bool]([System.Security.Principal.WindowsIdentity]::GetCurrent().Groups -match 'S-1-5-32-544')
2726

2827
# If the user is not an administrator and UAC is enabled, re-launch the script with elevated privileges
@@ -31,58 +30,80 @@ if (-not $isAdmin -and (Test-UACEnabled)) {
3130
exit
3231
}
3332

34-
function Test-AndRequest-SunshineConfig {
35-
param(
36-
[string]$InitialPath
37-
)
38-
39-
# Check if the initial path exists
40-
if (Test-Path $InitialPath) {
41-
Write-Host "File found at: $InitialPath"
42-
return $InitialPath
33+
function Find-ConfigurationFiles {
34+
$sunshineDefaultPath = "C:\Program Files\Sunshine\config\sunshine.conf"
35+
$apolloDefaultPath = "C:\Program Files\Apollo\config\sunshine.conf"
36+
37+
$sunshineFound = Test-Path $sunshineDefaultPath
38+
$apolloFound = Test-Path $apolloDefaultPath
39+
$configPaths = @{}
40+
41+
# If either one is found, use their default paths
42+
if ($sunshineFound) {
43+
$configPaths["Sunshine"] = $sunshineDefaultPath
44+
Write-Host "Sunshine config found at: $sunshineDefaultPath"
4345
}
44-
else {
46+
47+
if ($apolloFound) {
48+
$configPaths["Apollo"] = $apolloDefaultPath
49+
Write-Host "Apollo config found at: $apolloDefaultPath"
50+
}
51+
52+
# Only prompt if neither is found
53+
if (-not $sunshineFound -and -not $apolloFound) {
4554
# Show error message dialog
4655
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
47-
[System.Windows.Forms.MessageBox]::Show("Sunshine configuration could not be found. Please locate it.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) | Out-Null
56+
[System.Windows.Forms.MessageBox]::Show("Neither Sunshine nor Apollo configuration could be found. Please locate a configuration file.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) | Out-Null
4857

4958
# Open file dialog
5059
$fileDialog = New-Object System.Windows.Forms.OpenFileDialog
5160
$fileDialog.Title = "Open sunshine.conf"
5261
$fileDialog.Filter = "Configuration files (*.conf)|*.conf"
53-
$fileDialog.InitialDirectory = [System.IO.Path]::GetDirectoryName($InitialPath)
54-
62+
5563
if ($fileDialog.ShowDialog() -eq "OK") {
5664
$selectedPath = $fileDialog.FileName
5765
# Check if the selected path is valid
5866
if (Test-Path $selectedPath) {
5967
Write-Host "File selected: $selectedPath"
60-
return $selectedPath
68+
if ($selectedPath -like "*Apollo*") {
69+
$configPaths["Apollo"] = $selectedPath
70+
} else {
71+
$configPaths["Sunshine"] = $selectedPath
72+
}
6173
}
6274
else {
6375
Write-Error "Invalid file path selected."
76+
exit 1
6477
}
65-
6678
}
6779
else {
68-
Write-Error "Sunshine Configuiration file dialog was canceled or no valid file was selected."
80+
Write-Error "Configuration file dialog was canceled or no valid file was selected."
6981
exit 1
7082
}
7183
}
84+
85+
return $configPaths
7286
}
73-
74-
# Define the path to the Sunshine configuration file
75-
$confPath = Test-AndRequest-SunshineConfig -InitialPath "C:\Program Files\Sunshine\config\sunshine.conf"
76-
Update-JsonProperty -FilePath "./settings.json" -Property "sunshineConfigPath" -NewValue $confPath
77-
$scriptRoot = Split-Path $scriptPath -Parent
7887

88+
# Find configuration files
89+
$configPaths = Find-ConfigurationFiles
7990

91+
# Save paths to settings
92+
if ($configPaths.ContainsKey("Sunshine")) {
93+
Update-JsonProperty -FilePath "./settings.json" -Property "sunshineConfigPath" -NewValue $configPaths["Sunshine"]
94+
}
95+
if ($configPaths.ContainsKey("Apollo")) {
96+
Update-JsonProperty -FilePath "./settings.json" -Property "apolloConfigPath" -NewValue $configPaths["Apollo"]
97+
}
8098

8199
# Get the current value of global_prep_cmd from the configuration file
82100
function Get-GlobalPrepCommand {
101+
param (
102+
[string]$ConfigPath
103+
)
83104

84105
# Read the contents of the configuration file into an array of strings
85-
$config = Get-Content -Path $confPath
106+
$config = Get-Content -Path $ConfigPath
86107

87108
# Find the line that contains the global_prep_cmd setting
88109
$globalPrepCmdLine = $config | Where-Object { $_ -match '^global_prep_cmd\s*=' }
@@ -99,8 +120,12 @@ function Get-GlobalPrepCommand {
99120

100121
# Remove any existing commands that contain the scripts name from the global_prep_cmd value
101122
function Remove-Command {
123+
param (
124+
[string]$ConfigPath
125+
)
126+
102127
# Get the current value of global_prep_cmd as a JSON string
103-
$globalPrepCmdJson = Get-GlobalPrepCommand -ConfigPath $confPath
128+
$globalPrepCmdJson = Get-GlobalPrepCommand -ConfigPath $ConfigPath
104129

105130
# Convert the JSON string to an array of objects
106131
$globalPrepCmdArray = $globalPrepCmdJson | ConvertFrom-Json
@@ -119,7 +144,7 @@ function Remove-Command {
119144
# Set a new value for global_prep_cmd in the configuration file
120145
function Set-GlobalPrepCommand {
121146
param (
122-
147+
[string]$ConfigPath,
123148
# The new value for global_prep_cmd as an array of objects
124149
[object[]]$Value
125150
)
@@ -128,15 +153,17 @@ function Set-GlobalPrepCommand {
128153
$Value = [object[]]@()
129154
}
130155

131-
132156
# Read the contents of the configuration file into an array of strings
133-
$config = Get-Content -Path $confPath
157+
$config = Get-Content -Path $ConfigPath
134158

135159
# Get the current value of global_prep_cmd as a JSON string
136-
$currentValueJson = Get-GlobalPrepCommand -ConfigPath $confPath
160+
$currentValueJson = Get-GlobalPrepCommand -ConfigPath $ConfigPath
137161

138-
# Convert the new value to a JSON string
139-
$newValueJson = ConvertTo-Json -InputObject $Value -Compress
162+
# Convert the new value to a JSON string - ensure proper JSON types
163+
$newValueJson = ConvertTo-Json -InputObject $Value -Compress -Depth 10
164+
# Fix boolean values to be JSON compliant
165+
$newValueJson = $newValueJson -replace '"elevated"\s*:\s*"true"', '"elevated": true'
166+
$newValueJson = $newValueJson -replace '"elevated"\s*:\s*"false"', '"elevated": false'
140167

141168
# Replace the current value with the new value in the config array
142169
try {
@@ -153,12 +180,10 @@ function Set-GlobalPrepCommand {
153180
[object[]]$config += "global_prep_cmd = $($newValueJson)"
154181
}
155182
}
156-
157-
158-
159183
# Write the modified config array back to the file
160-
$config | Set-Content -Path $confPath -Force
184+
$config | Set-Content -Path $ConfigPath -Force
161185
}
186+
162187
function OrderCommands($commands, $scriptNames) {
163188
$orderedCommands = New-Object System.Collections.ArrayList
164189

@@ -197,23 +222,23 @@ function OrderCommands($commands, $scriptNames) {
197222
if ($null -ne $afterIndex -and ($afterIndex -lt $beforeIndex)) {
198223
$orderedCommands.RemoveAt($afterIndex)
199224
$orderedCommands.Insert($beforeIndex, $afterCommand)
200-
201225
}
202-
203226
}
204227

205228
$orderedCommands
206-
207229
}
208230

209231
function Add-Command {
232+
param (
233+
[string]$ConfigPath
234+
)
210235

211236
# Remove any existing commands that contain the scripts name from the global_prep_cmd value
212-
$globalPrepCmdArray = Remove-Command -ConfigPath $confPath
237+
$globalPrepCmdArray = Remove-Command -ConfigPath $ConfigPath
213238

214239
$command = [PSCustomObject]@{
215240
do = "powershell.exe -executionpolicy bypass -file `"$($scriptPath)`" -n $scriptName"
216-
elevated = "false"
241+
elevated = $false
217242
undo = "powershell.exe -executionpolicy bypass -file `"$($scriptRoot)\UndoScript.ps1`" -n $scriptName"
218243
}
219244

@@ -222,22 +247,35 @@ function Add-Command {
222247

223248
return [object[]]$globalPrepCmdArray
224249
}
225-
$commands = @()
226-
if ($install -eq 1) {
227-
$commands = Add-Command
228-
}
229-
else {
230-
$commands = Remove-Command
231-
}
232250

233-
if ($settings.installationOrderPreferences.enabled) {
234-
$commands = OrderCommands $commands $settings.installationOrderPreferences.scriptNames
235-
}
251+
# Process each found configuration file
252+
foreach ($key in $configPaths.Keys) {
253+
$configPath = $configPaths[$key]
254+
255+
$commands = @()
256+
if ($install -eq 1) {
257+
$commands = Add-Command -ConfigPath $configPath
258+
}
259+
else {
260+
$commands = Remove-Command -ConfigPath $configPath
261+
}
236262

237-
Set-GlobalPrepCommand $commands
263+
if ($settings.installationOrderPreferences.enabled) {
264+
$commands = OrderCommands $commands $settings.installationOrderPreferences.scriptNames
265+
}
238266

239-
$sunshineService = Get-Service -ErrorAction Ignore | Where-Object { $_.Name -eq 'sunshinesvc' -or $_.Name -eq 'SunshineService' }
240-
# In order for the commands to apply we have to restart the service
241-
$sunshineService | Restart-Service -WarningAction SilentlyContinue
242-
Write-Host "If you didn't see any errors, that means the script installed without issues! You can close this window."
267+
Set-GlobalPrepCommand -ConfigPath $configPath -Value $commands
268+
269+
if ($key -eq "Sunshine") {
270+
$service = Get-Service -ErrorAction Ignore | Where-Object { $_.Name -eq 'sunshinesvc' -or $_.Name -eq 'SunshineService' }
271+
$service | Restart-Service -WarningAction SilentlyContinue
272+
Write-Host "Sunshine configuration updated successfully!"
273+
} elseif ($key -eq "Apollo") {
274+
$service = Get-Service -ErrorAction Ignore | Where-Object { $_.Name -eq 'Apollo Service' }
275+
# Uncomment the line below if you want to automatically restart the service
276+
$service | Restart-Service -WarningAction SilentlyContinue
277+
Write-Host "Apollo configuration updated successfully!"
278+
}
279+
}
243280

281+
Write-Host "If you didn't see any errors, that means the script installed without issues! You can close this window."

0 commit comments

Comments
 (0)