Skip to content

Commit

Permalink
Auto find game install (#37)
Browse files Browse the repository at this point in the history
* Added registry bypass to allow sfse to be launched within game folder

Added additional tests

Updated CLI to grab game path automatically and make registry bypass the default in Auto install

Additional fixes and refacoring

* Revert test setup

* Improved path check

Added tests

Misc changes

* SFSE can now be launched via the normal winstore shortcut, when enabled in the script

* Clean up

* Update README
  • Loading branch information
gazzamc authored Nov 22, 2024
1 parent 928562c commit 7d0ac85
Show file tree
Hide file tree
Showing 8 changed files with 925 additions and 113 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
Write-host $PSVersionTable.PSVersion.Major $PSVersionTable.PSRemotingProtocolVersion.Minor
Set-PSRepository psgallery -InstallationPolicy trusted
Install-Module -Name Pester -RequiredVersion 5.6.1 -confirm:$false -Force
Install-Module -Name Assert
Invoke-Pester -Path ./
shell: pwsh

Expand All @@ -36,6 +37,7 @@ jobs:
Write-host $PSVersionTable.PSVersion.Major $PSVersionTable.PSRemotingProtocolVersion.Minor
Set-PSRepository psgallery -InstallationPolicy trusted
Install-Module -Name Pester -RequiredVersion 5.6.1 -Confirm:$false -Force
Install-Module -Name Assert
Invoke-Pester -Path ./
if ($Error[0].Fullyqualifiederrorid -eq 'PesterAssertionFailed') {exit 1}
shell: powershell
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ python/
logs/
vswhere.exe
config.json
__cmake_systeminformation
__cmake_systeminformation
reg/
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ Be vigilant of the hex table name `hex_table_{game_version}_{commit_id}.json`, i

* As of `v1.5.10`, when setting the newGamePath, the permissions will be checked to ensure there's less issues when moving the Starfield executable.

* As of `v1.6.0`:
- The script will now auto find the game install path and update the config
- SFSE can now be launched via winstore shortcut without the need to move files/exe to bypass permissions
- This option can be enabled/disabled in the script options, if you want to revert to vanilla

### Misc

* Added a script to auto generate the hex table using the Address Libraries
4 changes: 2 additions & 2 deletions docs/compatibility/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Any SFSE Mod utilizing the Address Library should work on this version of SFSE.

If the mods has updated for Starfield `v1.14.70` then it should be good,
If the mods has updated for Starfield `v1.14.74` then it should be good,
otherwise get in contact with me and I'll add it to the incompatible list below.

**NOTE**
Expand All @@ -18,7 +18,7 @@

#

### Updated as of Starfield `v1.14.70`
### Updated as of Starfield `v1.14.74`

Incompatible Info:

Expand Down
34 changes: 32 additions & 2 deletions src/cli/cli.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,21 @@ Do {
switch ($moveGameFilesOption) {
1 {
Clear-Host

$choice = getConfigProperty "hardlinkOrCopy"
$newGamePath = getConfigProperty "newGamePath"

if (!$choice -and !$newGamePath) {
setFilesChoice
setGamePath
}
elseif (!$choice) {
setFilesChoice
}
elseif (!$newGamePath) {
setGamePath
}

moveGameFiles
break
}
Expand Down Expand Up @@ -105,7 +120,7 @@ Do {
switch ($setConfigOption) {
1 {
Clear-Host
setGamePaths
setGamePath
break
}
2 {
Expand Down Expand Up @@ -133,6 +148,16 @@ Do {
refresh
break
}
7 {
Clear-Host
if (sfseRegistryExists) {
removeSFSERegistry
}
else {
setSFSERegistry
}
break
}
Default {
}
}
Expand All @@ -141,6 +166,8 @@ Do {
Clear-Host
Write-Host "`n`t Config"
Write-Host "`t---------"
Write-Host "`tSFSE Enabled: $(sfseRegistryExists)"
Write-Host "`t"
Write-Host "`tGame Path: $(getConfigProperty "gamePath")"
Write-Host "`t"
Write-Host "`tCopied/Hardlinked Path: $(getConfigProperty "newGamePath" )"
Expand All @@ -157,9 +184,12 @@ Do {
1. Set Paths
2. Set Bypass Choice
3. Set Python Choice
4. Set Game File Choice
4. Set Game Transfer Choice
5. Uninstall Dependencies (Choco Packages only)
6. Refresh Environment (If Choco Packages are not detected)
7. $(if (-Not (sfseRegistryExists)) {"Enable SFSE"} else {"Disable SFSE"})
q. Return
"
$setConfigOption = Read-Host "Choose an option"
Expand Down
138 changes: 49 additions & 89 deletions src/cli/functions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ $python = "https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-amd64.zi

$progsToInstall = New-Object System.Collections.Generic.List[System.Object]
$powershellVersion = $host.Version.Major
$version = "1.5.22"
$version = "1.6.0"

# Paths
$rootPath = getRootPath
Expand Down Expand Up @@ -368,7 +368,12 @@ function moveSFSEFiles() {
Clear-Host
Set-Location $rootPath

$gamePath = getConfigProperty "newGamePath"
if (sfseRegistryExists) {
$gamePath = getConfigProperty "gamePath"
}
else {
$gamePath = getConfigProperty "newGamePath"
}

# Remove any existing sfse files before copying
$sfseItems = Get-ChildItem -Path $gamePath | Where-Object { $_.extension -in @(".dll", ".exe") -and ( $_.Name -match 'sfse') }
Expand Down Expand Up @@ -610,19 +615,10 @@ function moveGameFiles() {

$choice = getConfigProperty "hardlinkOrCopy"

if ($null -ne $choice) {
if ($choice) {
$type = $choice
}
else {
$type = Read-Host -Prompt "
1. Copy Files
2. Hardlink Files (Does not work across drives)
q. Return

Choose the type of operation"
}

Clear-Host

# Get path of game install and new location for files
$gamePath = getConfigProperty "gamePath"
Expand Down Expand Up @@ -693,84 +689,50 @@ function autoInstall() {
cloneRepo
patchFiles
buildRepo
moveGameFiles
setSFSERegistry
moveSFSEFiles
moveGameEXE

Clear-Host
writeToConsole "`n`tYou're ready to start using SFSE mods!"
writeToConsole "`n`t`tCheck out the list of compatible mods here:
`n`t`thttps://github.com/gazzamc/starfield_hex_updater/blob/main/docs/compatibility"
Pause
}
function setGamePaths() {
function setGamePath() {
Clear-Host
$pathNames = "`n`tGamePath", "`n`tNewGamePath"
$noPathMsg = "`n`tPath inputted does not exist, please check that it exists! [q to exit]"
$noPermissionMsg = "`n`tYou do not have the correct permissions for the path inputted, please use another! [q to exit]"
$samePathMsg = "`n`tThe Gamepath and NewGamePath cannot be the same! [q to exit]"

function isSamePath() {
param (
[string]$path
)
$continue = $true;
$inputMsg = "`n`tNewGamePath"

$gamePath = (getConfigProperty "gamePath")
# Get initial input
$inputtedPath = Read-Host $inputMsg;
$inputtedPathTrimmed = $inputtedPath.trim()

if ($path -eq $gamePath) {
return $true
while ($continue) {
if (!$inputtedPathTrimmed -or !(fileExists $inputtedPathTrimmed)) {
if ($inputtedPathTrimmed -eq 'q') { exit }
writeToConsole $noPathMsg
}

if ((Join-Path $path "Content") -eq $gamePath) {
return $true
elseif ((isSamePath $inputtedPathTrimmed)) {
if ($inputtedPathTrimmed -eq 'q') { exit }
writeToConsole $samePathMsg
}
# check if user has full control permissions in newgamepath
elseif (!(hasPermissions $inputtedPathTrimmed)) {
if ($inputtedPathTrimmed -eq 'q') { exit }
writeToConsole $noPermissionMsg
}
else {
setConfigProperty "newGamePath" $inputtedPathTrimmed
break
}

return $false
}

foreach ($pathName in $pathNames) {
$continue = $true;

# Get initial input
$inputtedPath = Read-Host $pathName;
# Get new inputs after message
$inputtedPath = Read-Host $inputMsg
$inputtedPathTrimmed = $inputtedPath.trim()

while ($continue) {
if (!$inputtedPathTrimmed -or !(fileExists $inputtedPathTrimmed)) {
if ($inputtedPathTrimmed -eq 'q') { exit }
writeToConsole $noPathMsg
}
elseif ($pathName -eq $pathNames[1] -and (isSamePath $inputtedPathTrimmed)) {
if ($inputtedPathTrimmed -eq 'q') { exit }
writeToConsole $samePathMsg
}
# check if user has full control permissions in newgamepath
elseif ($pathName -eq $pathNames[1] -and !(hasPermissions $inputtedPathTrimmed)) {
if ($inputtedPathTrimmed -eq 'q') { exit }
writeToConsole $noPermissionMsg
}
else {
if ($pathName -eq $pathNames[0]) {
# Add a check for the content folder, add it if not present
$splitPath = $inputtedPathTrimmed.split('\')

if ($splitPath[$splitPath.Length - 1].ToLower() -ne "content") {
$inputtedPath = Join-Path $inputtedPathTrimmed "Content"
}

setConfigProperty "gamePath" $inputtedPath
}
else {
setConfigProperty "newGamePath" $inputtedPathTrimmed
}

break
}

# Get new inputs after message
$inputtedPath = Read-Host $pathName
$inputtedPathTrimmed = $inputtedPath.trim()
}
}
}

Expand Down Expand Up @@ -831,27 +793,21 @@ function welcomeScreen() {
$title = (Get-Content -Raw "header.txt").Replace('x.x.x', $version).Replace('[at]', '@')

writeToConsole $title
writeToConsole "`n`tIn order to make the auto-install process as smooth as possible we'll set the path now, `n`tThis can be changed from the options menu." -type -color yellow -bgcolor black
writeToConsole "`n`tOnce the path is set, you won't see this screen again on start-up." -type -color yellow -bgcolor black
writeToConsole "`n`tIn order to make the auto-install process as smooth as possible we'll set some options now, `n`tthis can be changed from the options menu." -type -color yellow -bgcolor black
writeToConsole "`n`tOnce these are set, you won't see this screen again on start-up." -type -color yellow -bgcolor black

writeToConsole "`n`n`tGamePath:
`n`tThe original location installed by xbox app eg. C:\XboxGames\Starfield,
`n`tIf you have not set the install folder in 'Options > Install Options' within the Xbox app, `n`tplease do so now and restart the script."
writeToConsole "`n`tCopying the game files, executable to bypass permissions is no longer required to launch SFSE as of v1.6.0," -type -color yellow -bgcolor black
writeToConsole "`tAs is setting the game install path manually, this will be automatically set for you." -type -color yellow -bgcolor black

writeToConsole "`n`n`tNewGamePath:
`n`tThe new path that we will copy/hardlink the game files to in order to use SFSE,
`n`tThis can be anywhere you choose but Hardlinking cannot be done across drives.
writeToConsole "`n`tSFSE will be enabled by default when using the 'auto' option," -type -color yellow -bgcolor black
writeToConsole "`tthis will allow you to launch SFSE via the winstore shortcut directly." -type -color yellow -bgcolor black

`tOptions:
`n`t`t Hardlinking: `n`n`t`t`tSaves space but will be modified when game updates (or deleted)
`n`t`t Copying: `n`n`t`t`tRequires more space but will avoid issues after game updates,
`n`t`t`thas continued to work after updates so far.`n"
writeToConsole "`n`tYou can enable/disable this option via the options menu, when you want to play vanilla." -type -color green -bgcolor black
writeToConsole "`n"

Pause
setGamePaths
setPythonChoice
setBypassChoice
setFilesChoice
}


Expand All @@ -860,18 +816,22 @@ if (![System.Convert]::ToBoolean((getConfigProperty "debug"))) {
$ErrorActionPreference = "Stop"
}

# Display start message/ set paths if missing/invalid
# Display start message/ set path if missing/invalid
$pathsExistAndValid = $True

if (!(testPath (getConfigPath))) {
$pathsExistAndValid = $False
}
elseif (getConfigProperty "gamePath" -and getConfigProperty "newGamePath") {
if (!(testPath (getConfigProperty "gamePath")) -or !(testPath (getConfigProperty "newGamePath"))) {
$pathsExistAndValid = $False
else {
$gamePathConfig = getConfigProperty "gamePath"
$gamePathReg = getStarfieldPath

if ($gamePathReg -ne $gamePathConfig) {
setSFSEPath
}
}

if (!$pathsExistAndValid) {
welcomeScreen
setSFSEPath
}
Loading

0 comments on commit 7d0ac85

Please sign in to comment.