From ea9b5b173fb0d582c88159cf74191a1a34b7f53c Mon Sep 17 00:00:00 2001 From: "Jonny_Bro (Nikita)" Date: Sat, 20 Jul 2024 01:15:04 +0500 Subject: [PATCH] clean up installation script, remove unnecessary big VDF parser --- static/install | 408 +++++++++---------------------------------------- 1 file changed, 76 insertions(+), 332 deletions(-) diff --git a/static/install b/static/install index dfe4bab..291d976 100644 --- a/static/install +++ b/static/install @@ -1,345 +1,89 @@ -# VDF Deserializer +# Function to query the registry +function Get-RegistryValue { + param ( + [string]$path, + [string]$value + ) -Enum State -{ - Start = 0; - Property = 1; - Object = 2; - Conditional = 3; - Finished = 4; - Closed = 5 -}; - -Class VdfDeserializer -{ - [PSCustomObject] Deserialize([string]$vdfContent) - { - if([string]::IsNullOrWhiteSpace($vdfContent)) { - throw 'Mandatory argument $vdfContent must be a non-empty, non-whitespace object of type [string]'; - } - - [System.IO.TextReader]$reader = [System.IO.StringReader]::new($vdfContent); - return $this.Deserialize($reader); - } - - [PSCustomObject] Deserialize([System.IO.TextReader]$txtReader) - { - if( !$txtReader ){ - throw 'Mandatory arguments $textReader missing.'; - } - - $vdfReader = [VdfTextReader]::new($txtReader); - $result = [PSCustomObject]@{ }; - - try - { - if (!$vdfReader.ReadToken()) - { - throw "Incomplete VDF data."; - } - - $prop = $this.ReadProperty($vdfReader); - Add-Member -InputObject $result -MemberType NoteProperty -Name $prop.Key -Value $prop.Value; - } - finally - { - if($vdfReader) - { - $vdfReader.Close(); - } - } - return $result; - } - - [hashtable] ReadProperty([VdfTextReader]$vdfReader) - { - $key=$vdfReader.Value; - - if (!$vdfReader.ReadToken()) - { - throw "Incomplete VDF data."; - } - - if ($vdfReader.CurrentState -eq [State]::Property) - { - $result = @{ - Key = $key; - Value = $vdfReader.Value; - } - } - else - { - $result = @{ - Key = $key; - Value = $this.ReadObject($vdfReader); - } - } - return $result; - } - - [PSCustomObject] ReadObject([VdfTextReader]$vdfReader) - { - $result = [PSCustomObject]@{ }; - - if (!$vdfReader.ReadToken()) - { - throw "Incomplete VDF data."; - } - - while ( ($vdfReader.CurrentState -ne [State]::Object) -or ($vdfReader.Value -ne "}")) - { - [hashtable]$prop = $this.ReadProperty($vdfReader); - - Add-Member -InputObject $result -MemberType NoteProperty -Name $prop.Key -Value $prop.Value; - - if (!$vdfReader.ReadToken()) - { - throw "Incomplete VDF data."; - } - } - - return $result; + try { + $result = Get-ItemProperty -Path $path -ErrorAction Stop + return $result.$value + } catch { + return $null } } -Class VdfTextReader -{ - [string]$Value; - [State]$CurrentState; +# Get Steam installation path from registry +$steam_dir = Get-RegistryValue "HKLM:\SOFTWARE\Valve\Steam" "InstallPath" - hidden [ValidateNotNull()][System.IO.TextReader]$_reader; +if (-not $steam_dir) { + $steam_dir = Get-RegistryValue "HKLM:\SOFTWARE\WOW6432Node\Valve\Steam" "InstallPath" +} - hidden [ValidateNotNull()][char[]]$_charBuffer=; - hidden [ValidateNotNull()][char[]]$_tokenBuffer=; +if (-not $steam_dir) { + Write-Host "Steam installation path not found" + Read-Host "Press Enter to exit" + exit +} - hidden [int32]$_charPos; - hidden [int32]$_charsLen; - hidden [int32]$_tokensize; - hidden [bool]$_isQuoted; +# Check for Garry's Mod installation +$gmod_dir = Join-Path $steam_dir "steamapps\common\GarrysMod" +if (-not (Test-Path (Join-Path $steam_dir "steamapps\appmanifest_4000.acf"))) { + $library_folders_path = Join-Path $steam_dir "steamapps\libraryfolders.vdf" - VdfTextReader([System.IO.TextReader]$txtReader) - { - if( !$txtReader ){ - throw "Mandatory arguments `$textReader missing."; - } - - $this._reader = $txtReader; - - $this._charBuffer=[char[]]::new(1024); - $this._tokenBuffer=[char[]]::new(4096); - - $this._charPos=0; - $this._charsLen=0; - $this._tokensize=0; - $this._isQuoted=$false; - - $this.Value=""; - $this.CurrentState=[State]::Start; - } - - [bool] ReadToken() - { - if (!$this.SeekToken()) - { - return $false; - } - - $this._tokenSize = 0; - - while($this.EnsureBuffer()) - { - [char]$curChar = $this._charBuffer[$this._charPos]; - - #No special treatment for escape characters - - #region Quote - if ($curChar -eq '"' -or (!$this._isQuoted -and [Char]::IsWhiteSpace($curChar))) - { - $this.Value = [string]::new($this._tokenBuffer, 0, $this._tokenSize); - $this.CurrentState = [State]::Property; - $this._charPos++; - return $true; - } - #endregion Quote - - #region Object Start/End - if (($curChar -eq '{') -or ($curChar -eq '}')) - { - if ($this._isQuoted) - { - $this._tokenBuffer[$this._tokenSize++] = $curChar; - $this._charPos++; - continue; - } - elseif ($this._tokenSize -ne 0) - { - $this.Value = [string]::new($this._tokenBuffer, 0, $this._tokenSize); - $this.CurrentState = [State]::Property; - return $true; - } - else - { - $this.Value = $curChar.ToString(); - $this.CurrentState = [State]::Object; - $this._charPos++; - return $true; + if (Test-Path $library_folders_path) { + $lines = Get-Content $library_folders_path + foreach ($line in $lines) { + if ($line -match '^\s*"\d+"\s+"(.+)"$') { + $library_path = $matches[1] + if (Test-Path (Join-Path $library_path "steamapps\appmanifest_4000.acf")) { + $gmod_dir = Join-Path $library_path "steamapps\common\GarrysMod" + break } } - #endregion Object Start/End - - #region Long Token - $this._tokenBuffer[$this._tokenSize++] = $curChar; - $this._charPos++; - #endregion Long Token - } - - return $false; - } - - [void] Close() - { - $this.CurrentState = [State]::Closed; - } - - hidden [bool] SeekToken() - { - while($this.EnsureBuffer()) - { - # Skip Whitespace - if( [char]::IsWhiteSpace($this._charBuffer[$this._charPos]) ) - { - $this._charPos++; - continue; - } - - # Token - if ($this._charBuffer[$this._charPos] -eq '"') - { - $this._isQuoted = $true; - $this._charPos++; - return $true; - } - - # Comment - if ($this._charBuffer[$this._charPos] -eq '/') - { - $this.SeekNewLine(); - $this._charPos++; - continue; - } - - $this._isQuoted = $false; - return $true; - } - - return $false; - } - - hidden [bool] SeekNewLine() - { - while ($this.EnsureBuffer()) - { - if ($this._charBuffer[++$this._charPos] == '\n') - { - return $true; - } - } - return $false; - } - - hidden [bool]EnsureBuffer() - { - if($this._charPos -lt $this._charsLen -1) - { - return $true; - } - - [int32] $remainingChars = $this._charsLen - $this._charPos; - $this._charBuffer[0] = $this._charBuffer[($this._charsLen - 1) * $remainingChars]; #A bit of mathgic to improve performance by avoiding a conditional.; - $this._charsLen = $this._reader.Read($this._charBuffer, $remainingChars, 1024 - $remainingChars) + $remainingChars; - $this._charPos = 0; - - return ($this._charsLen -ne 0); - } -} - -function GetCount($thing) { - $aux = $($thing | Get-Member -MemberType NoteProperty); - $count = 0; - if ($null -eq $aux) { - $count = 0; - } elseif ( $aux -is [PSCustomObject] ) { - $count = 1; - } else { - $count = $aux.Count; - } - - return $count; -} - -$VDF = [VdfDeserializer]::new(); - -# Main Script - -$SteamPath = Get-ItemProperty -Path HKLM:/SOFTWARE/WOW6432Node/Valve/Steam; -$SteamPath = $SteamPath.InstallPath; -$SteamPath = $SteamPath.ToString(); - -Write-Host Looking for Steam libraries...; - -$LibraryFoldersVDF = $SteamPath + "/steamapps/libraryfolders.vdf"; -$LibrariesRaw = Get-Content $LibraryFoldersVDF; -$LibrariesVDF = $VDF.Deserialize($LibrariesRaw); - -Write-Host Found!; - -$libcount = GetCount($LibrariesVDF.libraryfolders); -for ($i = 0; $i -lt $libcount; $i++) { - $Install = $LibrariesVDF.libraryfolders.$i; - $GMODInstalled = $Install.apps.4000; - if ($GMODInstalled) { - $GMODPath = $Install.path + "\\steamapps\\common\\GarrysMod"; - $AddonsPath = $GMODPath + "\\garrysmod\\addons"; - - $_text = "Do you want to install in this path? It will completely wipe the previous Beatrun install if you had one! `n" + $GMODPath.replace("\\", "\") + " (y/n)"; - $GMODConfirmation = Read-Host $_text; - - if ($GMODConfirmation -eq "y") { - $TempPath = $GMODPath + "\\temp\\"; - $ZIPPath = $TempPath + "beatrun.zip"; - $FolderPath = $TempPath + "beatrun"; - $FolderMainPath = $TempPath + "beatrun-main"; - - (New-Item -ItemType Directory -Path $TempPath) | out-null; - - Write-Host Downloading the archive...; - - (New-Object Net.WebClient).DownloadFile("https://github.com/JonnyBro/beatrun/archive/refs/heads/main.zip", $ZIPPath); - Write-Host Downloaded! Unpacking...; - - Expand-Archive $ZIPPath $TempPath -Force; - Write-Host Unpacked successfully!; - - Rename-Item $FolderMainPath $FolderPath; - Remove-Item $ZIPPath; - - $confirmation = Read-Host "Do you want to install modules? (Discord + Steam Presence) (y/n)"; - if ($confirmation -eq "y") { - $ModulesPath = $FolderPath + "\\lua\\*"; - $NewModulesPath = $GMODPath + "\\garrysmod\\lua\\"; - Copy-Item -Path $ModulesPath -Destination $NewModulesPath -Force -Recurse; - } - - $AddonPath = $FolderPath + "\\beatrun"; - $NewAddonPath = $AddonsPath + "\\beatrun"; - if ((Test-Path $NewAddonPath) -eq $true) { - Remove-Item $NewAddonPath -Force -Recurse; - } - Move-Item -Path $AddonPath -Destination $NewAddonPath; - - Remove-Item $TempPath -Force -Recurse; - - Write-Host Beatrun Installed!; } } } + +if (-not (Test-Path $gmod_dir)) { + Write-Host "GMod installation path not found" + Read-Host "Press Enter to exit" + exit +} + +Write-Host "GMod installation path: $gmod_dir" + +# Confirm Garry's Mod installation path +$GMODPath = Join-Path $gmod_dir "garrysmod" +$AddonsPath = Join-Path $GMODPath "addons" +$_text = "Do you want to install in this path? It will completely wipe the previous Beatrun install if you had one!`n$GMODPath (y/n)" +$GMODConfirmation = Read-Host $_text + +if ($GMODConfirmation -eq "y") { + $TempPath = Join-Path $GMODPath "temp" + $ZIPPath = Join-Path $TempPath "beatrun.zip" + $FolderPath = Join-Path $TempPath "beatrun" + $FolderMainPath = Join-Path $TempPath "beatrun-main" + New-Item -ItemType Directory -Path $TempPath -Force | Out-Null + Write-Host "Downloading the archive..." + (New-Object Net.WebClient).DownloadFile("https://github.com/JonnyBro/beatrun/archive/refs/heads/main.zip", $ZIPPath) + Write-Host "Downloaded! Unpacking..." + Expand-Archive $ZIPPath $TempPath -Force + Write-Host "Unpacked successfully!" + Rename-Item $FolderMainPath $FolderPath + Remove-Item $ZIPPath + $confirmation = Read-Host "Do you want to install modules? (Discord + Steam Presence) (y/n)" + if ($confirmation -eq "y") { + $ModulesPath = Join-Path $FolderPath "lua\*" + $NewModulesPath = Join-Path $GMODPath "lua" + Copy-Item -Path $ModulesPath -Destination $NewModulesPath -Force -Recurse + } + $AddonPath = Join-Path $FolderPath "beatrun" + $NewAddonPath = Join-Path $AddonsPath "beatrun" + if (Test-Path $NewAddonPath) { + Remove-Item $NewAddonPath -Force -Recurse + } + Move-Item -Path $AddonPath -Destination $NewAddonPath + Remove-Item $TempPath -Force -Recurse + Write-Host "Beatrun Installed!" +}