From 3fa78b577abf678e6964e4e12ef8c4ec3a4dab54 Mon Sep 17 00:00:00 2001 From: couleurm Date: Wed, 31 Jan 2024 18:10:07 +0000 Subject: [PATCH] Autobuild --- Manifests.json | 10 +- Master.ps1 | 3720 ++++++++++++++++++++++++------------------------ 2 files changed, 1865 insertions(+), 1865 deletions(-) diff --git a/Manifests.json b/Manifests.json index 9f43d80..618a509 100644 --- a/Manifests.json +++ b/Manifests.json @@ -2,8 +2,8 @@ { "Parameters": [ { - "Required": "false", "Type": "Array", + "Required": "false", "Name": "Settings", "KeyValues": { "Performance": "Turn off performance-hungry settings", @@ -29,9 +29,9 @@ ] } ], - "Path": "/modules/Game & Program tuners/Optimize-LunarClient.ps1", "Description": "Tunes a selected Lunar Client profile to your liking, it has some good defaults everyone should have (no numbers in scoreboard, modern keybind handling, no achievements, transparent texture packs section, borderless fullscreen..)", "Name": "Optimize-LunarClient", + "Path": "/modules/Game & Program tuners/Optimize-LunarClient.ps1", "Display Name": "Optimize Lunar Client", "Platform": [ "Linux", @@ -46,8 +46,8 @@ { "Parameters": [ { - "Required": "false", "Type": "String", + "Required": "false", "Name": "Encoder", "KeyValues": { "NVENC": "NVIDIA's Fastest encoder, it lets you record in hundreds of FPS easily", @@ -64,16 +64,16 @@ ] }, { - "Required": "false", "Type": "String", + "Required": "false", "Name": "OBS64Path", "KeyValues": {}, "Description": "If you've got a portable install or something, pass in the main OBS binary's path here" } ], - "Path": "/modules/Game & Program tuners/Optimize-OBS.ps1", "Description": "Tune your OBS for a specific usecase in the snap of a finger!", "Name": "Optimize-OBS", + "Path": "/modules/Game & Program tuners/Optimize-OBS.ps1", "Display Name": "Optimize OBS", "Platform": [ "Linux", diff --git a/Master.ps1 b/Master.ps1 index 2b0cb20..75c982d 100644 --- a/Master.ps1 +++ b/Master.ps1 @@ -3196,140 +3196,6 @@ tl ui opens the UI "@ } -function Remove-DesktopShortcuts { - param( - [Switch]$ConfirmEach - ) - - if($ConfirmEach){ - Get-ChildItem -Path "$HOME\Desktop" | Where-Object Extension -eq ".lnk" | Remove-Item -Confirm - }else{ - Get-ChildItem -Path "$HOME\Desktop" | Where-Object Extension -eq ".lnk" | Remove-Item - } -} - -<# - -List of commonly used Appx packages: - -Windows.PrintDialog -Microsoft.WindowsCalculator -Microsoft.ZuneVideo -Microsoft.Windows.Photos - -I did not add them, but you can opt in by calling the function, e.g: - - Remove-KnownAppxPackages -Add @('Windows.PrintDialog','Microsoft.WindowsCalculator') - -Don't forget to surround them by a ' so PowerShell considers them as a string - -#> - -function Remove-KnownAppxPackages ([array]$Add,[array]$Exclude) { - - $AppxPackages = @( - "Microsoft.Windows.NarratorQuickStart" - "Microsoft.Wallet" - "3DBuilder" - "Microsoft.Microsoft3DViewer" - "WindowsAlarms" - "BingSports" - "WindowsCommunicationsapps" - "WindowsCamera" - "Feedback" - "Microsoft.GetHelp" - "GetStarted" - "ZuneMusic" - "WindowsMaps" - "Microsoft.Messaging" - "Microsoft.MixedReality.Portal" - "Microsoft.OneConnect" - "BingFinance" - "Microsoft.MSPaint" - "People" - "WindowsPhone" - "Microsoft.YourPhone" - "Microsoft.Print3D" - "Microsoft.ScreenSketch" - "Microsoft.MicrosoftStickyNotes" - "SoundRecorder" - - ) | Where-Object { $_ -notin $Exclude } - - $AppxPackages += $Add # Appends the Appx packages given by the user (if any) - - if (-Not($KeepXboxPackages)){ - $AppxPackages += @( - "XboxApp" - "Microsoft.XboxGameOverlay" - "Microsoft.XboxGamingOverlay" - "Microsoft.XboxSpeechToTextOverlay" - "Microsoft.XboxIdentityProvider" - "Microsoft.XboxGameCallableUI" - ) - } - - - ForEach ($Package in $AppxPackages){ - - if ($PSVersionTable.PSEdition -eq 'Core'){ # Newer PowerShell versions don't have Appx cmdlets, manually calling PowerShell to - - powershell.exe -command "Get-AppxPackage `"*$Package*`" | Remove-AppxPackage" - - }else{ - Get-AppxPackage "*$Package*" | Remove-AppxPackage - } - - } - -} - - -function Remove-UselessFiles { - - @( - "$env:TEMP" - "$env:WINDIR\TEMP" - "$env:HOMEDRIVE\TEMP" - ) | ForEach-Object { Remove-Item (Convert-Path $_\*) -Force -ErrorAction SilentlyContinue } - -} -function Set-PowerPlan { - param ( - [string]$URL, - [switch]$Ultimate - ) - - if ($Ultimate){ - powercfg /duplicatescheme e9a42b02-d5df-448d-aa00-03f14749eb61 - powercfg /setactive e9a42b02-d5df-448d-aa00-03f14749eb61 - }elseif($URL){ - if ($URL -Like "http*://cdn.discordapp.com/attachments/*.pow"){ - $DotPow = "$env:TMP\{0}" -f (Split-Path $URL -Leaf) - }else{ - $DotPow = "$env:TMP\Powerplan $(Get-Random).pow" - } - Invoke-WebRequest -Uri $PowURL -OutFile $DotPow - powercfg -duplicatescheme $DotPow - powercfg /s $DotPow - } -} - -function Set-Win32PrioritySeparation { - param( - [int]$DWord - ) - - $Path = 'REGISTRY::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\PriorityControl' - $current = (Get-ItemProperty $Path).Win32PrioritySeparation - - Set-ItemProperty -Path ($Path).Win32PrioritySeparation -Value $Value -Type DWord -Force -ErrorAction Inquire - - Write-Verbose "Set-Win32ProritySeparation: Changed from $current to $((Get-ItemProperty $Path).Win32PrioritySeparation)" - -} - - function 4K-Notifier { param( [Parameter(Mandatory)] @@ -3453,6 +3319,18 @@ if %ERRORLEVEL% == 0 (exit) else (pause) return } +function Remove-DesktopShortcuts { + param( + [Switch]$ConfirmEach + ) + + if($ConfirmEach){ + Get-ChildItem -Path "$HOME\Desktop" | Where-Object Extension -eq ".lnk" | Remove-Item -Confirm + }else{ + Get-ChildItem -Path "$HOME\Desktop" | Where-Object Extension -eq ".lnk" | Remove-Item + } +} + function CB-CleanTaskbar { if (-Not(Get-Module -Name "Sophia Script (TL)" -Ea 0)){ Import-Sophia @@ -3466,2032 +3344,2154 @@ function CB-CleanTaskbar { # Remove "Meet now" from the taskbar, s/o privacy.sexy Set-ItemProperty -Path "Registry::HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "HideSCAMeetNow" -Value 1 } -function Optimize-Bedrock { - [alias('optmcbe')] - [CmdletBinding()] +function Get-GraalVM { param( - [ValidateScript({ - Test-Path $_ -PathType Leaf - })] - [String]$options = "$env:localappdata\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe\LocalState\games\com.mojang\minecraftpe\options.txt", + [Switch]$Reinstall + ) + + if ((Test-Path "$env:ProgramData\GraalVM") -and !$Reinstall){ + return "GraalVM is already installed, run with -Reinstall to force reinstallation" + } + if (-Not(Get-Command curl.exe -ErrorAction Ignore)){ + return "curl is not found (comes with windows per default?)" + } + Remove-Item "$env:ProgramData\GraalVM" -ErrorAction Ignore -Force -Recurse + $URL = 'https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.2.0/graalvm-ce-java16-windows-amd64-21.2.0.zip' + $SHA256 = 'DAE2511ABFF8EAD3EBC90CD9FC81A8E84B762FC91462B198C3EDDF28F81A937E' + $Zip = "$env:TMP\GraalVM.zip" - [ValidateSet('Low', 'High', 'ashanksupercool')] - $Preset = "High", - $Presets = @{ + if (-Not(Test-Path $Zip)){ + Write-Host "Downloading GraalVM ($(Get-HeaderSize $URL)`MB).." -ForegroundColor Green + curl.exe -# -L $URL -o"$Zip" + } - High = @{ - gfx_viewdistance = 256 - gfx_particleviewdistance = 1 - gfx_viewbobbing = 1 - gfx_fancygraphics = 1 - gfx_transparentleaves = 1 - gfx_smoothlighting = 1 - gfx_fancyskies = 1 - gfx_msaa = 4 - gfx_texel_aa_2 = 0 - gfx_multithreaded_renderer = 1 - gfx_vsync = 0 - } + if ((Get-FileHash $Zip).Hash -ne $SHA256){ + Remove-Item "$env:TMP\GraalVM.zip" + return "Failed to download GraalVM (SHA256 checksum mismatch, not the expected file)" - Low = @{ - gfx_viewdistance = 160 - gfx_particleviewdistance = 0 - gfx_viewbobbing = 0 - gfx_fancygraphics = 0 - gfx_transparentleaves = 0 - gfx_smoothlighting = 0 - gfx_fancyskies = 0 - gfx_msaa = 1 - gfx_texel_aa_2 = 0 - gfx_multithreaded_renderer = 1 - gfx_vsync = 0 - } - ashanksupercool = @{ - gfx_viewdistance = 256 - gfx_particleviewdistance = 1 - gfx_viewbobbing = 1 - gfx_fancygraphics = 0 - gfx_transparentleaves = 1 - gfx_vr_transparentleaves = 0 - gfx_smoothlighting = 1 - gfx_vr_smoothlighting = 0 - gfx_fancyskies = 0 - gfx_field_of_view = 81.2 - gfx_msaa = 1 - gfx_gamma = 1 - gfx_multithreaded_renderer = 1 - gfx_vsync = 0 - dev_file_watcher = 1 - audio_music = 0 - gfx_hidepaperdoll = 1 - dev_enable_texture_hot_reloader = 1 - do_not_show_multiplayer_online_safety_warning = 1 - only_show_trusted_skins = 0 - camera_shake = 0 - gfx_resizableui = 0 - gfx_hotbarScale = 1 - 'keyboard_type_0_key.pickItem' = 75 - 'keyboard_type_0_key.hotbar.1' = 49 - 'keyboard_type_0_key.hotbar.2' = 50 - 'keyboard_type_0_key.hotbar.3' = 51 - 'keyboard_type_0_key.hotbar.4' = 52 - 'keyboard_type_0_key.hotbar.5' = 82 - 'keyboard_type_0_key.hotbar.6' = 70 - 'keyboard_type_0_key.hotbar.7' = 86 - 'keyboard_type_0_key.hotbar.8' = 90 - 'keyboard_type_0_key.hotbar.9' = '- 97' - 'keyboard_type_0_key.inventory' = 69 - 'keyboard_type_0_key.togglePerspective' = 53 - 'keyboard_type_0_key.jump' = 32 - 'keyboard_type_0_key.sneak' = 16 - 'keyboard_type_0_key.sprint' = 17 - 'keyboard_type_0_key.left' = 65 - 'keyboard_type_0_key.right' = 68 - 'keyboard_type_0_key.back' = 83 - 'keyboard_type_0_key.forward' = 87 - 'keyboard_type_0_key.mobEffects' = 88 - 'keyboard_type_0_key.chat' = 13 - 'keyboard_type_0_key.emote' = 0 - } - } - ) + } - Write-Host "Optimize Minecraft bedrock with $Preset" + if (Get-Command 7z -ErrorAction Ignore){ - $optionsTable = (Get-Content $options) -Replace ':', '=' | ConvertFrom-StringData - Write-Verbose ($optionsTable | ConvertTo-Json -Depth 3) - - $optionsTable = Merge-Hashtables -Original $optionsTable -Patch $Presets.$Preset - Write-Verbose ($optionsTable | ConvertTo-Json -Depth 3) - - Set-Content $options -Value (ConvertTo-MCSetting $optionsTable) -Force + Invoke-Expression "& `"7z`" x -bso0 -bsp1 -bse1 -aoa `"$env:TMP\GraalVM.zip`" -o`"$env:ProgramData\GraalVM`"" + } else { + Expand-Archive -Path $Zip -Destination "$env:ProgramData\GraalVM" + } + Move-Item -Path "$env:ProgramData\GraalVM\graalvm-?e*\*" "C:\ProgramData\GraalVM" } - -function Optimize-LunarClient { - <# - .SYNOPSIS - Display Name: Optimize Lunar Client - Platform: Linux; Windows - Category: Optimizations - Depends: Write-Diff; Merge-HashTables - - .DESCRIPTION - Tunes a selected Lunar Client profile to your liking, it has some good defaults everyone should have (no numbers in scoreboard, modern keybind handling, no achievements, transparent texture packs section, borderless fullscreen..) - - .PARAMETER Settings - Specify which specific tweak you'd like applying on your profile - Performance: Turn off performance-hungry settings - NoCosmetics: Disable all emotes, cosmetics, wings, hats.. - MinimalViewBobbing: Keep item movement but disable walk bobbing - No16xSaturationOverlay: Remove the yellow 16x hunger bar overlay - HideToggleSprint: Hides the ToggleSprint status from HUD - ToggleSneak: Turns on ToggleSneak - DisableUHCMods: Disables ArmorHUD, DirectionHUD and Coordinates mods - FullBright: literally night vision - #> - [alias('optlc')] +function Get-TLShell { param( + [switch]$Offline, + [switch]$DontOpen + ) + + $WR = "$env:LOCALAPPDATA\Microsoft\WindowsApps" # I've had the habit of calling this folder WR + # because it's the only folder I know that is added to path + # that you don't need perms to access. - #//[HelpMessage("Set your lazy chunk load speed")] - [ValidateSet( - 'highest', - 'high', - 'medium', - 'low', - 'lowest', - 'off_van' - )] - [String]$LazyChunkLoadSpeed = 'low', +if ($Offline){ + + try { + $Master = Invoke-RestMethod -UseBasicParsing https://raw.githubusercontent.com/couleur-tweak-tips/TweakList/master/Master.ps1 + } catch { + Write-Host "Failed to get Master.ps1 from TweakList GitHub" -ForegroundColor DarkRed + Write-Output "Error: $($Error[0].ToString())" + return + } + Set-Content "$WR/TLSOff.cmd" -Value @' +<# : batch portion +@echo off +powershell.exe -noexit -noprofile -noexit -command "iex (${%~f0} | out-string)" +: end batch / begin powershell #> +Write-Host "TweakList Shell " -Foregroundcolor White -NoNewLine +Write-Host "(Offline)" -Foregroundcolor DarkGray -NoNewLine +Write-Host " - dsc.gg/CTT" -Foregroundcolor White -NoNewLine - [ValidateSet( - 'Performance', - 'NoCosmetics', - 'MinimalViewBobbing', - 'No16xSaturationOverlay', - 'HideToggleSprint', - 'ToggleSneak', - 'DisableUHCMods', - 'FullBright', - 'CouleursPreset' - )] - #// Gotta be put twice because mf cant handle variables in validate sets - [Array]$Settings = (Invoke-Checkbox -Title "Select tweaks to apply" -Items @( - 'Performance' - 'NoCosmetics' - 'MinimalViewBobbing' - 'No16xSaturationOverlay' - 'HideToggleSprint' - 'ToggleSneak' - 'DisableUHCMods' - 'FullBright' - 'CouleursPreset' - )), - - [String] - $LCDirectory = "$HOME\.lunarclient", +'@ + $Batch = Get-Item "$WR/TLSOff.cmd" + Add-Content $Batch -Value $Master + if (!$DontOpen){ + explorer.exe /select,`"$($Batch.FullName)`" + } + +}else{ - [Switch]$NoBetaWarning, - [Switch]$KeepLCOpen, - [Switch]$DryRun - #//TODO: [Array]$Misc HideFoliage, NoEntityShadow, LCNametags, Clearglass, NoBackground, NoHypixelMods - ) - if (-Not(Test-Path $LCDirectory)){ - Write-Host "Lunar Client's directory ($HOME\.lunarclient) does not exist (for the turbonerds reading this you can overwrite that with -LCDirectory" - } - if (!$NoBetaWarning){ - Write-Warning "This script may corrupt your Lunar Client profiles, continue at your own risk,`nyou're probably safer if you copy the folder located at $(Convert-Path $HOME\.lunarclient\settings\game)" - pause - } - if (!$KeepLCOpen){ - while ((Get-Process -Name java?).MainWindowTitle -Like "Lunar Client*"){ - Write-Host "You must quit Lunar Client before running these optimizations (LC will overwrite them when it exits)" -ForegroundColor Red - pause - } + if ($WR -NotIn $env:PATH.Split(';')){ + Write-Error "`"$env:LOCALAPPDATA\Microsoft\WindowsApps`" is not added to path, did you mess with Windows?" + return }else{ - Write-Warning "You disabled the script from not running if Lunar Client is running, here be dragons!" - Start-Sleep -Milliseconds 500 - } + $TLS = "$WR\TLS.CMD" + Set-Content -Path $TLS -Value @' +@echo off +title TweakList Shell +if /I "%1" == "wr" (explorer "%~dp0" & exit) +if /I "%1" == "so" (set sophiaflag=Write-Host 'Importing Sophia Script..' -NoNewLine -ForegroundColor DarkGray;Import-Sophia) - if (!$LazyChunkLoadSpeed -and ('Performance' -in $Settings)){$LazyChunkLoadSpeed = 'low'} +fltmc >nul 2>&1 || ( + echo Elevating to admin.. + PowerShell.exe -NoProfile Start-Process -Verb RunAs ' %0' 2> nul || ( + echo Failed to elevate to admin, launch CMD as Admin and type in "TL" + pause & exit 1 + ) + exit 0 +) - $Manager = Get-Content "$LCDirectory\settings\game\profile_manager.json" -ErrorAction Stop | ConvertFrom-Json - - $Profiles = @{} - ForEach($Profile in $Manager){ - $Profiles += @{ "$($Profile.DisplayName) ($($Profile.Name))" = $Profile} +powershell.exe -NoProfile -NoLogo -NoExit -Command ^ +"if ($PWD.Path -eq \"$env:WINDIR\system32\"){cd $HOME} ;^ +[System.Net.ServicePointManager]::SecurityProtocol='Tls12' ;^ +Write-Host 'Invoking TweakList.. ' -NoNewLine -ForegroundColor DarkGray;^ +iex(irm tl.ctt.cx);^ +%SOPHIAFLAG%;^ +Write-Host \"`rTweakList Shell - dsc.gg/CTT `n\" -Foregroundcolor White" +'@ -Force } + $ShortcutPath = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\TweakList Shell.lnk" + $WScriptShell = New-Object -ComObject WScript.Shell + $Shortcut = $WScriptShell.CreateShortcut($ShortcutPath) + $Shortcut.IconLocation = (Get-Command powershell.exe).Source + ",0" + $Shortcut.TargetPath = "$WR\TLS.CMD" + $Shortcut.Save() - Write-Host "Select a profile:" - $Selection = Menu @([Array[]]'Create a new profile' + [Array[]]$Profiles.Keys) - if ($Selection -in $Manager.name,$Manager.DisplayName){ - if ($VerbosePreference -eq 'Continue'){ - Write-Host "Error, Manager:`n`n" -ForegroundColor Red - Write-Host ($Manager | ConvertTo-Json) - return - - } - return "A profile with the same name already exists!" + # Got this from my old list of snippets, originally found this on StackOverflow, forgot link + $bytes = [System.IO.File]::ReadAllBytes($ShortCutPath) + $bytes[0x15] = $bytes[0x15] -bor 0x20 # Set byte 21 (0x15) bit 6 (0x20) ON + [System.IO.File]::WriteAllBytes($ShortcutPath, $bytes) + + Write-Host "You can now type 'TLS' in Run (Windows+R) to launch it, or from your start menu" + if (!$DontOpen){ + & explorer.exe /select,`"$("$WR\TLS.CMD")`" } + + +} +} - if ($Selection -eq 'Create a new profile'){ - - $ProfileName = Read-Host "Enter a name for the new profile" - New-Item -ItemType Directory -Path "$LCDirectory\settings\game\$ProfileName" -ErrorAction Stop | Out-Null - Push-Location "$LCDirectory\settings\game\$ProfileName" - ('general.json', 'mods.json', 'performance.json') | ForEach-Object { - if (-Not(Test-Path ./$_)){Add-Content ./$_ -Value '{}'} # Empty json file - } - Pop-Location - $Selection = [PSCustomObject]@{ +# This function centralizes most of what you can download/install on CTT +# Anything it doesn't find in that switch ($App){ statement is passed to scoop +$global:SendTo = [System.Environment]::GetFolderPath('SendTo') +function Get { + [alias('g')] # minimalism at it's finest + param( + [Parameter(ValueFromRemainingArguments = $true)] + [Array]$Apps, + [Switch]$DryRun + ) - name = $ProfileName - displayName = $ProfileName - active = $False - default = $False - iconName = 'crossed-swords' - server = '' - } - $Manager += $Selection # Overwriting the string "Create a new profile" with the fresh one - Set-Content -Path "$LCDirectory\settings\game\profile_manager.json" -Value ($Manager | ConvertTo-Json -Compress -Depth 99) - }else{ - $Selection = $Profiles.$Selection + $FailedToInstall = $null # Reset that variable for later + if ($Apps.Count -eq 1 -and (($Apps[0] -Split '\r?\n') -gt 1)){ + $Apps = $Apps[0] -Split '\r?\n' } - - $ProfileDir = "$LCDirectory\settings\game\$($Selection.name)" - ForEach($file in 'general','mods','performance'){ # Assigns $general, $mods and $performance variables - Set-Variable -Scope Global -Name $file -Value (Get-Content "$ProfileDir\$file.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop) - if ($DryRun){ - Write-Host $file -ForegroundColor Red - (Get-Variable -Name $file).Value | ConvertTo-Json + if ($DryRun){ + ForEach($App in $Apps){ + "Installing $app." } + return } - - $Presets = @{ - All = @{ - general = @{ - shift_effects_bl = $false - achievements_bl = $false - compact_menu_bl = $true - modernKeybindHandling_bl = $true - borderless_fullscreen_bl = $true - trans_res_pack_menu_bg_bl = $true + + ForEach($App in $Apps){ # Scoop exits when it throws + + switch ($App){ + 'nvddl'{Get-ScoopApp utils/nvddl} + {$_ -in 'Remux','Remuxer'}{ + Invoke-RestMethod https://github.com/couleurm/couleurstoolbox/raw/main/7%20FFmpeg/Old%20Toolbox%20scripts/Remux.bat -Verbose | + Out-File "$SendTo\Remux.bat" + } - mods = @{ - chat = @{ - options = @{ - chat_bg_opacity_nr = "0.0" - } - } - scoreboard = @{ - options = @{ - numbers_bl = $true - } - } - } - } - CouleursPreset = @{ - mods = @{ - scoreboard = @{ - seen = $True - x = 2 # Moves scoreboard 2 pixels to the right - } - potioneffects = @{ - seen = $True - position = 'bottom_left' - y = -246.5 # Middle left - } - saturation_hud_mod = @{ - seen = $True - saturation_hud_mod_enabled_bl = $True - position = 'bottom_right' # Just right to the last hunger bar - x = -289 - y = -37 - options = @{ - scale_nr = 1.5 # Yellow - text_clr_nr = @{value=-171} - background_clr_nr = @{value=0} - } - } - zoom = @{ - seen = $True - options = @{ - zoom_kblc = 'KEY_X' - } - } - bossbar = @{ - seen = $True - bossbar_enabled_bl = $False - } - } - } - Performance = @{ - general = @{ - friend_online_status_bl = $false - } - performance = @{ - lazy_chunk_loading = $LazyChunkLoadSpeed - ground_arrows_bl = $false - stuck_arrows_bl = $false - hide_skulls_bl = $true - hide_foliage_bl = $true - } - } - NoCosmetics = @{ - general = @{ - renderClothCloaks_bl = $false - render_cosmetic_particles_bl = $false - backpack_bl = $false - dragon_wings_bl = $false - pet_bl = $false - glasses_bl = $false - bandanna_bl = $false - mask_bl = $false - belts_bl = $false - neckwear_bl = $false - bodywear_bl = $false - hat_bl = $false - render_emotes_bl = $false - render_emote_particles_bl = $false - cloak_bl = $false - show_hat_above_helmet_bl = $false - show_over_chestplate_bl = $false - show_over_leggings_bl = $false - show_over_boots_bl = $false - scale_hat_with_skinlayer_bl = $false - } - } - MinimalViewBobbing = @{ - general = @{ - minimal_viewbobbing_bl = $true - } - } - No16xSaturationOverlay = @{ - mods = @{ - saturation_mod = @{ - options = @{ - show_saturation_overlay_bl=$False - } - } - } - } - HideToggleSprint = @{ - mods = @{ - toggleSneak = @{ - options = @{ - showHudText_bl = $false - } - } - } - } - ToggleSneak = @{ - mods = @{ - toggleSneak = @{ - options = @{ - toggle_sneak_bl = $true - } - } + {$_ -in 'RemuxAVI','AVIRemuxer'}{ + Invoke-RestMethod https://github.com/couleurm/couleurstoolbox/raw/main/7%20FFmpeg/Old%20Toolbox%20scripts/Remux.bat -Verbose | + Out-File "$SendTo\Remux - AVI.bat" + $Content = (Get-Content "$SendTo\Remux - AVI.bat") -replace 'set container=mp4','set container=avi' + Set-Content "$SendTo\Remux - AVI.bat" $Content } - } - DisableUHCMods = @{ - mods = @{ - waypoints = @{ - waypoints_enabled_bl = $false - } - directionhud = @{ - directionhud_enabled_bl = $false - } - coords = @{ - coords_enabled_bl = $false - } - armorstatus = @{ - armorstatus_enabled_bl = $false - } + {$_ -in 'Voukoder','vk'}{Install-Voukoder } + 'Upscaler'{ + + Install-FFmpeg + Invoke-RestMethod 'https://github.com/couleur-tweak-tips/utils/raw/main/Miscellaneous/CTT%20Upscaler.cmd' | + Out-File (Join-Path ([System.Environment]::GetFolderPath('SendTo')) 'CTT Upscaler.cmd') -Encoding ASCII -Force + Write-Host @" +CTT Upscaler has been installed! Find it in the options when right clicking a video file -> Send To -> CTT Upscaler.cmd +"@ -ForegroundColor Green + } - } - FullBright = @{ - mods = @{ - lighting = @{ - lighting_enabled_bl = $true - options = @{ - full_bright_bl = $true - } - } + {$_ -In 'QualityMuncher','qm'}{ + Install-FFmpeg + + Invoke-RestMethod 'https://raw.githubusercontent.com/Thqrn/qualitymuncher/main/Quality%20Muncher.bat' | + Out-File (Join-Path ([System.Environment]::GetFolderPath('SendTo')) 'Quality Muncher.bat') -Encoding ASCII -Force + + Invoke-RestMethod 'https://raw.githubusercontent.com/Thqrn/qualitymuncher/main/!!qualitymuncher%20multiqueue.bat' | + Out-File (Join-Path ([System.Environment]::GetFolderPath('SendTo')) '!!qualitymuncher multiqueue.bat') -Encoding ASCII -Force + } - } - } - # Whatever you do that's highly recommended :+1: - $general = Merge-Hashtables -Original $general -Patch $Presets.All.general - $mods = Merge-Hashtables -Original $mods -Patch $Presets.All.mods - Write-Diff "recommended settings (compact mods, fast chat).." -Positivity $True -Term "Setting up" + 'Scoop'{Install-Scoop } + {$_ -in 'ff','FFmpeg'}{Install-FFmpeg } - if ('Performance' -in $Settings){ - $general = Merge-Hashtables -Original $general -Patch $Presets.Performance.general - $performance = Merge-Hashtables -Original $performance -Patch $Presets.Performance.performance - Write-Diff -Message "notifications from LC friends getting on (causes massive FPS drop)" - Write-Diff -Positivity $True -Message "lazy chunk loading at speed $LazyChunkLoadSpeed" - Write-Diff -Message "ground arrows" - Write-Diff -Message "player/mob skulls" - Write-Diff -Message "foliage (normal/tall grass)" - } - if ('NoCosmetics' -in $Settings){ - $general = Merge-Hashtables -Original $general -Patch $Presets.NoCosmetics.general - ForEach($CosmeticRemoved in @( - "cloth cloaks" - "cosmetic particles" - "backpacks" - "pets" - "dragon wings" - "bandannas" - "masks" - "belts" - "neckwears" - "bodywears" - "hats" - "emotes rendering" - "emote particles rendering" - "cloaks" - )){ - Write-Diff -Message $CosmeticRemoved -Term "Disabled" + {$_ -in 'zl','ZetaLoader'}{Install-ZetaLoader} + {$_ -in 'CRU','custom-resolution-utility'}{Get-ScoopApp extras/cru} + {$_ -in 'wt','windowsterminal','windows-terminal'}{Get-ScoopApp extras/windows-terminal} + {$_ -in 'np++','Notepad++','notepadplusplus'}{Get-ScoopApp extras/notepadplusplus} + {$_ -in 'DDU','DisplayDriverUninstaller'}{Get-ScoopApp extras/ddu} + {$_ -in 'Afterburner','MSIAfterburner'}{Get-ScoopApp utils/msiafterburner} + {$_ -in 'Everything','Everything-Alpha','Everything-Beta'}{Get-ScoopApp extras/everything-alpha} + {$_ -In '7-Zip','7z','7Zip'}{Get-ScoopApp 7zip} + {$_ -In 'Smoothie','sm'}{Install-FFmpeg ;Get-ScoopApp utils/Smoothie} + {$_ -In 'OBS','OBSstudio','OBS-Studio'}{Get-ScoopApp extras/obs-studio} + {$_ -In 'UTVideo'}{Get-ScoopApp utils/utvideo} + {$_ -In 'Nmkoder'}{Get-ScoopApp utils/nmkoder} + {$_ -In 'Librewolf'}{Get-ScoopApp extras/librewolf} + {$_ -In 'ffmpeg-nightly'}{Get-ScoopApp versions/ffmpeg-nightly} + {$_ -In 'Graal','GraalVM'}{Get-ScoopApp utils/GraalVM} + {$_ -In 'DiscordCompressor','dc'}{Install-FFmpeg ;Get-ScoopApp utils/discordcompressor} + {$_ -In 'Moony','mn'}{if (-Not(Test-Path "$HOME\.lunarclient")){Write-Warning "You NEED Lunar Client to launch it with Moony"};Get-ScoopApp utils/Moony} + {$_ -In 'TLShell','TLS'}{Get-TLShell } + default{Get-ScoopApp $App} } + Write-Verbose "Finished installing $app" } - if ('MinimalViewBobbing' -in $Settings){ - $general = Merge-Hashtables -Original $general -Patch $Presets.MinimalViewBobbing.general - Write-Diff -Positivity $True -Message "minimal view bobbing" - } - if ('No16xSaturationOverlay' -in $Settings){ - $mods = Merge-Hashtables -Original $mods -Patch $Presets.No16xSaturationOverlay.mods - Write-Diff -Positivity $False -Message "16x saturation hunger bar overlay" - } - if ('HideToggleSprint' -in $Settings){ - $mods = Merge-Hashtables -Original $mods -Patch $Presets.HideToggleSprint.mods - Write-Diff -Positivity $False -Term "Hid" -Message "ToggleSprint HUD" - } - if ('ToggleSneak' -in $Settings){ - $mods = Merge-Hashtables -Original $mods $Presets.ToggleSneak.mods - Write-Diff -Positivity $True -Message "ToggleSneak" - } - if ('DisableUHCMods' -in $Settings){ - $mods = Merge-Hashtables -Original $mods -Patch $Presets.DisableUHCMods.mods - Write-Diff -Positivity $False -Term "Disabled" -Message "Waypoints mod" - Write-Diff -Positivity $False -Term "Disabled" -Message "DirectionHUD mod" - Write-Diff -Positivity $False -Term "Disabled" -Message "Coordinates mod" - Write-Diff -Positivity $False -Term "Disabled" -Message "ArmorStatus mod" + if ($FailedToInstall){ + + Write-Host "[!] The following apps failed to install (scroll up for details):" -ForegroundColor Red + $FailedToInstall } - if ('FullBright' -in $Settings){ - $mods = Merge-Hashtables -Original $mods -Patch $Presets.FullBright.mods - Write-Diff -Term "Added" -Positivity $true -Message "Fullbright (disable shaders before restarting)" +} +function Install-MPVProtocol { + param( + [ValidateScript({Test-Path -Path $_ -PathType Leaf})] + $VideoPlayerFilePath + ) + +if (!(Test-Admin)){ + "PowerShell NEEDS to run as Adminisrator in order to create the protocol handler" + return +} + + +if ((Get-Command mpv -Ea 0) -and (Get-Command mpvnet -Ea 0)){ + "Would you like mpv:// links to open with MPV or MPV.net?" + $Answer = Read-Host "Answer" + while ($answer -notin 'mpv','mpv.net','mpvnet','exit'){ + "Answer must be mpv / mpvnet, type exit to quit" } - if ('CouleursPreset' -in $Settings){ - $mods = Merge-Hashtables -Original $mods -Patch $Presets.CouleursPreset.mods + switch ($Answer) { + 'exit'{return} + {$_ -in 'mpvnet','mpv.net'}{$MPV = (Get-Command mpvnet.exe).Source} + 'mpv'{$MPV = (Get-Command mpv.exe).Source} } +}elseif(Get-Command mpv -Ea 0){ + "Using default MPV" + $MPV = (Get-Command mpv.exe).Source +}elseif(Get-Command mpvnet -Ea 0){ + Write-Warning "Using MPV.net since MPV was not found (not added to path?)" + $MPV = (Get-Command mpvnet.exe).Source +}else{ + return "MPV or MPV.net couldn't be found, please install MPV / MPV.net" +} - ForEach($file in 'general','mods','performance'){ # Assigns $general, $mods and $performance variables - if ($DryRun){ - Write-Host $file -ForegroundColor Red - (Get-Variable -Name $file).Value - }else{ - ConvertTo-Json -Depth 99 -Compress -InputObject (Get-Variable -Name $file).Value -ErrorAction Stop | Set-Content "$ProfileDir\$file.json" -ErrorAction Stop - } - } +New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT -ea SilentlyContinue | Out-Null +New-Item -Path "HKCR:" -Name "mpv" -Force | Out-Null +Set-ItemProperty -Path "HKCR:\mpv" -Name "(Default)" -Value '"URL:mpv Protocol"' | Out-Null +Set-ItemProperty -Path "HKCR:\mpv" -Name "URL Protocol" -Value '""' | Out-Null +New-Item -Path "HKCR:\mpv" -Name "shell" -Force | Out-Null +New-Item -Path "HKCR:\mpv\shell" -Name "open" -Force | Out-Null +New-Item -Path "HKCR:\mpv\shell\open" -Name "command" -Force | Out-Null +#Old command: "C:\ProgramData\CTT\mpv-protocol\mpv-protocol-wrapper.cmd" "%1" +$Command = "cmd /c title MPV && powershell -ep bypass -NoProfile `"& \`"$MPV\`" ('%1' -replace 'mpv://https//','https://')`"" +Set-ItemProperty -Path "HKCR:\mpv\shell\open\command" -Name "(Default)" -Value $Command | Out-Null + +Write-Output "Added the registry keys to handle mpv protocol and redirect to wrapper!" } -function Optimize-OBS { - <# - .SYNOPSIS - Display Name: Optimize OBS - Platform: Linux; Windows - Category: Optimizations +function Install-Voukoder { + [CmdletBinding()] + [alias('isvk')] + param( + [Switch]$GetTemplates + # Skip Voukoder installation and just get to the template selector + ) - .DESCRIPTION - Tune your OBS for a specific usecase in the snap of a finger! + function Get-VoukoderProgram ($Name){ + # Parses the registry manually instead of using PackageManagement's Get-Package - .PARAMETER Encoder - Which hardware type you wish to record with - NVENC: NVIDIA's Fastest encoder, it lets you record in hundreds of FPS easily - AMF: AMD GPUs/Integrated GPUs encoder, not as good as NVENC but can still get out ~240FPS at most - QuickSync: Intel's GPU encoder, worst out of the three, note this is H264, not the new fancy but slow AV1 - x264: Encoding using your CPU, slow but efficient, only use if necessary/you know what you're doing + $Programs = @( + 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' + 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' + 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' + 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' - .PARAMETER OBS64Path - If you've got a portable install or something, pass in the main OBS binary's path here + ) | Where-Object {Test-path $_} | - #> - [alias('optobs')] - param( - [ValidateSet('x264','NVENC','AMF','QuickSync')] - [String]$Encoder, + Get-ItemProperty | Where-Object Publisher -eq 'Daniel Stankewitz' | + Sort-Object DisplayName | + Select-Object -Property @{n='Name'; e='DisplayName' }, + @{n='Version'; e='DisplayVersion'}, + @{n='UninstallString'; e='UninstallString'} - [ValidateScript({Test-Path -Path $_ -PathType Leaf})] - [String]$OBS64Path, + return $Programs | Where-Object Name -Like $Name + } - [ValidateSet('HighPerformance')] - [String]$Preset = 'HighPerformance', + if (!$GetTemplates){ + + $LatestCore = (Invoke-RestMethod https://api.github.com/repos/Vouk/voukoder/releases/latest)[0] + # get the latest release manifest from GitHub's API - [ValidateSet( - 'EnableStatsDock', 'OldDarkTheme')] - [Array]$MiscTweaks = (Invoke-CheckBox -Title "Select misc tweaks to apply" -Items ( - 'EnableStatsDock', 'OldDarkTheme')), + if (($tag = $LatestCore.tag_name) -NotLike "*.*"){ + $tag += ".0" # E.g "12" will not convert to a version type, "12.0" will + } + [Version]$LatestCoreVersion = $tag + + $Core = Get-VoukoderProgram -Name "Voukoder*" -ErrorAction Ignore | # Find all programs starting with Voukoder + Where-Object Name -NotLike "*Connector*" # Exclude connectors + + if ($Core){ + + if ($Core.Length -gt 1){ + $Core + Write-Host "Multiple Voukoder Cores detected (or bad parsing?)" -ForegroundColor Red + return + } + + $CurrentVersion = [Version]$Core.Version + if ($LatestCoreVersion -gt $CurrentVersion){ # then an upgrade is needed + "Updating Voukoder Core from version $CurrentVersion to $LatestCoreVersion" + Start-Process -FilePath msiexec -ArgumentList "/qb /x {$($Core.TagId)}" -Wait -NoNewWindow + # Uses msiexec to uninstall the program + $Upgraded = $True + } + } + + if (!$Core -or $Upgraded){ + + $DriverVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{B2FE1952-0186-46C3-BAEC-A80AA35AC5B8}_Display.Driver" -ErrorAction Ignore).DisplayVersion + if ($DriverVersion -and $DriverVersion -lt 520.00){ # Oldest NVIDIA version capable + Write-Warning "Outdated NVIDIA Drivers detected ($DriverVersion), you may not be able to encode (render) using NVENC util you update them." + pause + } + + "Downloading and installing Voukoder Core.." + $CoreURL = $LatestCore[0].assets[0].browser_download_url + curl.exe -# -L $CoreURL -o"$env:TMP\Voukoder-Core.msi" + msiexec /i "$env:TMP\Voukoder-Core.msi" /passive + } + + filter ConnectorVer {$_.Trim('.msi').Trim('.zip').Split('-') | Select-Object -Last 1} + # .zip for Resolve's - [ValidateScript({ Test-Path -Path $_ -PathType Container })] - [String]$OBSProfile = $null - ) - if (!$Encoder){ - $Encoders = [Ordered]@{ - "NVENC (NVIDIA GPUs)" = "NVENC" - "AMF (AMD GPUs)" = "AMF" - "QuickSync (Intel iGPUs)" = "QuickSync" - "x264 (CPU)" = "x264" - } - Write-Host "Select what OBS will use to record (use arrow keys and press ENTER to confirm)" - $Key = Menu ([Collections.ArrayList]$Encoders.Keys) - $Encoder = $Encoders.$Key - } + # Following block generates a hashtable of all of the latest connectors - $OBSPatches = @{ - HighPerformance = @{ - NVENC = @{ - basic = @{ - AdvOut = @{ - RecEncoder = 'jim_nvenc' - } - } - recordEncoder = @{ - bf=0 - cqp=18 - multipass='disabled' - preset2='p2' - profile='main' - psycho_aq='false' - rate_control='CQP' + $Tree = (Invoke-RestMethod 'https://api.github.com/repos/Vouk/voukoder-connectors/git/trees/master?recursive=1').Tree + # Gets all files from the connectors repo, which contain all filepaths + $Connectors = [Ordered]@{} + ForEach($NLE in 'vegas','vegas18','vegas19','vegas20','aftereffects','premiere','resolve'){ + # 'vegas' is for older versions + switch ($NLE){ + vegas{ + $Pattern = "*vegas-connector-*" + break # needs to stop here, otherwise it would overwrite it the next match } - } - AMF = @{ - Basic = @{ - ADVOut = @{ - RecQuality='Small' - RecEncoder='h265_texture_amf' - FFOutputToFile='true' - } + {$_ -Like "vegas*"}{ + $Pattern = "*connector-$_*" } - recordEncoder = @{ - 'cqp' = 20 - preset = 'speed' - rate_control = 'CQP' - ffmpeg_opts = "MaxNumRefFrames=4 HighMotionQualityBoostEnable=1" + default { + $Pattern = "*$NLE-connector*" } } - QuickSync = @{ - basic = @{ - AdvOut = @{ - RecEncoder = 'obs_qsv11' - } - } - recordEncoder = @{ - enhancements = 'false' - target_usage = 'speed' - bframes = 0 - rate_control = 'ICQ' - bitrate = 16500 - icq_quality = 18 - keyint_sec = 2 - } - - } - x264 = @{ - basic = @{ - ADVOut = @{ - RecEncoder='obs_x264' - } - } - recordEncoder = @{ - crf=1 - keyint_sec=1 - preset='ultrafast' - profile='high' - rate_control='CRF' - x264opts='qpmin=15 qpmax=15 ref=0 merange=4 direct=none weightp=0 no-chroma-me' - } + $LCV = $Tree.path | # Short for LatestConnectorVersion + Where-Object {$_ -Like $Pattern} | # Find all versions of all matching connectors + ForEach-Object {[Version]($_ | ConnectorVer)} | # Parse it's version using the filter + Sort-Object -Descending | Select-Object -First 1 # Sort then select only the latest + + $Path = $Tree.path | Where-Object {$_ -Like "$Pattern*$LCV*.*"} # get the absolute path with the latest version + $Connectors += @{$NLE = "https://github.com/Vouk/voukoder-connectors/raw/master/$Path"} + Remove-Variable -Name NLE + } + + $Processes = @( + 'vegas*' + 'Adobe Premiere Pro' + 'AfterFX' + 'Resolve' + ) + + $Found = { Get-Process $Processes -ErrorAction Ignore } + + if (-not (. $Found)){ # If $Found scriptblock returns nothing + Write-Host "[!] Open your video editor" -ForegroundColor Red + Write-Host "Voukoder supports: VEGAS 12-20, Premiere, After Effects, DaVinci Resolve (ONLY PAID `"Studio `"VERSION)" -ForeGroundColor Green + Write-Host "Looking for processes: $($Processes -join ', ')" -ForegroundColor DarkGray + While(-not (. $Found)){ + Start-Sleep -Seconds 1 } } - } + Write-Host @( + "`nDetected the following video editor(s):`n`n" + $(. $Found | Select-Object MainWindowTitle, Path, FileVersion | Out-String) + ) - # Applies to all patches/presets - $Global = @{ - basic = @{ - Output = @{ - RecType='Standard' - Mode='Advanced' + function Get-Connector ($PackageName, $Key, $NLEDir, $InnoFlag){ + # Key is to get the right connector URL in $Connector hashtable + + function Install-Connector { + $msiPath = "$env:TMP\Voukoder Connector-$Key.msi" + curl.exe -# -L $Connectors.$Key -o"$msiPath" + Write-Verbose "Installing $msiPath at $InnoFlag=$NLEDir" -Verbose + msiexec /i "$msiPath" /qb "$InnoFlag=`"$NLEDir`"" } - AdvOut = @{ - RecRB='true' + + $CurrentConnector = (Get-VoukoderProgram -Name $PackageName) + if ($CurrentConnector){ + [Version]$CurrentConnectorVersion = $CurrentConnector.Version + [Version]$LatestConnector = $Connectors.$Key | ConnectorVer # Parse connector version + if ($LatestConnector -gt $CurrentConnectorVersion){ + + Write-Host "Upgrading $PackageName from $CurrentConnectorVersion to $LatestConnector" + Start-Process -FilePath msiexec -ArgumentList "/qb /x {$($CurrentConnector.TagId)}" -Wait -NoNewWindow + Install-Connector + } + } else { + + Install-Connector } } - } - $OBSPatches.$Preset.$Encoder = Merge-Hashtables $OBSPatches.$Preset.$Encoder $Global - # Merge with global, which will be added for all + $NLEs = Get-Process $Processes -ErrorAction Ignore + ForEach($NLE in $NLEs){ - if (!$OBSProfile){ - Remove-Variable -Name OBSProfile - if (-Not($OBS64Path)){ + switch ($NLE){ - $Parameters = @{ - Path = @("$env:APPDATA\Microsoft\Windows\Start Menu","$env:ProgramData\Microsoft\Windows\Start Menu") - Recurse = $True - Include = 'OBS Studio*.lnk' - } - $StartMenu = Get-ChildItem @Parameters - - if (!$StartMenu){ - if ((Get-Process obs64 -ErrorAction Ignore).Path){$OBS64Path = (Get-Process obs64).Path} # Won't work if OBS is ran as Admin - else{ - return @' -Your OBS installation could not be found, -please manually specify the path to your OBS64 executable, example: + {(Split-Path $_.Path -Leaf) -in 'vegas180.exe', 'vegas190.exe','vegas200.exe'} { + Write-Verbose "Using newer VEGAS" -Optimize-OBS -OBS64Path "D:\obs\bin\64bit\obs64.exe" + $VegVer = (Split-Path $_.Path -Leaf) -replace 'vegas' -replace '0\.exe' -You can find it this way: -Search OBS -> Right click it -Open file location in Explorer -> -Open file location again if it's a shortcut -> -Shift right click obs64.exe -> Copy as path -'@ + Get-Connector -PackageName "Voukoder connector for VEGAS Pro $VegVer" -Key "vegas$VegVer" -NLEDir (Split-Path $_.Path -Parent) -InnoFlag VEGASDIR + + continue # Needs to loop over the next switch, which would've matched and also thought it needed to install an older Version } - } - if ($StartMenu.Count -gt 1){ - $Shortcuts = $null - $StartMenu = Get-Item $StartMenu - ForEach($Lnk in $StartMenu){$Shortcuts += @{$Lnk.BaseName = $Lnk.FullName}} - "There are multiple OBS shortcuts in your Start Menu folder. Please select one." - $ShortcutName = menu ($Shortcuts.Keys -Split [System.Environment]::NewLine) - $StartMenu = $Shortcuts.$ShortcutName - $OBS64Path = Get-ShortcutTarget $StartMenu - }else{ - $OBS64Path = Get-ShortcutTarget $StartMenu - } - } + {(Split-Path $_.Path -Leaf) -Like 'vegas*.exe'}{ + Write-Host "/!\ Old-VEGAS connector installation may fail if you already have a connector for newer VEGAS versions" -ForegroundColor Red + Get-Connector -PackageName "Voukoder connector for VEGAS" -Key vegas -NLEDir (Split-Path $_.Path -Parent) -InnoFlag VEGASDIR + } - if (!$IsLinux -or !$IsMacOS){ - [Version]$CurVer = (Get-Item $OBS64Path).VersionInfo.ProductVersion - if ($CurVer -lt [Version]"28.1.0"){ - Write-Warning @" -It is strongly advised you update OBS before continuing (for compatibility with new NVENC/AMD settings) -Detected version: $CurVer -obs64.exe path: $OBS64Path -pause -"@ - } - } + {(Split-Path $_.Path -Leaf) -eq 'afterfx.exe'} { + Get-Connector -PackageName 'Voukoder Connector for Adobe After Effects' -Key aftereffects -NLEDir "$env:ProgramFiles\Adobe\Common\Plug-ins\7.0\MediaCore" -InnoFlag INSTALLDIR + } - Set-CompatibilitySettings $OBS64Path -RunAsAdmin - if (Resolve-Path "$OBS64Path\..\..\..\portable_mode.txt" -ErrorAction Ignore){ # "Portable Mode" makes OBS make the config in it's own folder, else it's in appdata + {(Split-Path $_.Path -Leaf) -eq 'Adobe Premiere Pro.exe'}{ + Get-Connector -PackageName 'Voukoder connector for Premiere' -Key premiere -NLEDir "$env:ProgramFiles\Adobe\Common\Plug-ins\7.0\MediaCore" -InnoFlag TGDir + } - $ProfilesDir = (Resolve-Path "$OBS64Path\..\..\..\config\obs-studio\basic\profiles" -ErrorAction Stop) - }else{ - $ProfilesDir = (Resolve-Path "$env:APPDATA\obs-studio\basic\profiles" -ErrorAction Stop) - } - $Profiles = Get-ChildItem $ProfilesDir - ForEach($OBSProfile in $Profiles){$ProfilesHash += @{$OBSProfile.Name = $OBSProfile.FullName}} + {(Split-Path $_.Path -Leaf) -eq 'Resolve.exe'}{ + Write-Warning "Voukoder's connector for Resolve is ONLY FOR IT'S PAID `"Studio`" VERSION" + pause + + $IOPlugins = "$env:ProgramData\Blackmagic Design\DaVinci Resolve\Support\IOPlugins" + $dvcpBundle = "$IOPlugins\voukoder_plugin.dvcp.bundle" - $ProfileNames = ($ProfilesHash.Keys -Split [System.Environment]::NewLine) + 'Create a new profile' - "Please select a profile (use arrow keys to navigate, ENTER to select)" - $OBSProfile = menu $ProfileNames + if (-Not(Test-Path $IOPlugins)){ + New-Item -ItemType Directory -Path $IOPlugins | Out-Null + } + elseif (Test-Path $dvcpBundle -PathType Container){ + if (-Not(Get-Boolean "Would you like to reinstall/update the Voukoder Resolve plugin? (Y/N)")){continue} + Remove-Item $dvcpBundle -Force -Recurse + } - if ($OBSProfile -eq 'Create a new profile'){ - $NewProfileName = Read-Host "Enter a name for the new profile" - $OBSProfile = Join-Path $ProfilesDir $NewProfileName - New-Item -ItemType Directory -Path $OBSProfile -ErrorAction Stop - $DefaultWidth, $DefaultHeight = ((Get-CimInstance Win32_VideoController).VideoModeDescription.Split(' x ') | Where-Object {$_ -ne ''} | Select-Object -First 2) - if (!$DefaultWidth -or !$DefaultHeight){ - $DefaultWidth = 1920 - $DefaultHeight = 1080 - } - Set-Content "$OBSProfile\basic.ini" -Value @" -[General] -Name=$NewProfileName + $Zip = "$env:TMP\Voukoder-Connector-Resolve.zip" + curl.exe -# -L $Connectors.Resolve -o"$Zip" + + $ExtractDir = "$env:TMP\Voukoder-Connector-Resolve" + Remove-Item $ExtractDir -Recurse -Force -ErrorAction Ignore + Expand-Archive $Zip -Destination $ExtractDir -[Video] -BaseCX=$DefaultWidth -BaseCY=$DefaultHeight -OutputCX=$DefaultWidth -OutputCY=$DefaultHeight -"@ - Write-Host "Created new profile '$NewProfileName' with default resolution of $DefaultWidth`x$DefaultHeight" -ForegroundColor DarkGray - }else{ - $OBSProfile = $ProfilesHash.$OBSProfile + Copy-Item "$ExtractDir\voukoder_plugin.dvcp.bundle" $IOPlugins -Recurse + + Write-Warning "If connection failed you should find instructions in $ExtractDir\README.txt" + } + } } + $NLEBin = $NLE.Path + }else{ + $AvailableNLETemplates = @{ + "Vegas Pro" = "vegas200.exe" + "Premiere Pro" = "Adobe Premiere Pro.exe" + "After Effects" = "AfterFX.exe" + } + $NLE = Menu -menuItems $AvailableNLETemplates.Keys + $NLEBin = $AvailableNLETemplates.$NLE } - if ('basic.ini' -notin ((Get-ChildItem $OBSProfile).Name)){ - return "FATAL: Profile $OBSProfile is incomplete (missing basic.ini)" - } - Write-Verbose "Tweaking profile $OBSProfile" - try { - $Basic = Get-IniContent "$OBSProfile\basic.ini" -ErrorAction Stop - } catch { - Write-Warning "Failed to get basic.ini from profile folder $OBSProfile" - $_ - return - } - if ($Basic.Video.FPSType -ne 2){ # then switch to fractional FPS - $FPS=$Basic.Video.FPSCommon - $Basic.Video.FPSType = 2 - $Basic.Video.FPSNum = 60 - $Basic.Video.FPSDen = 1 - Write-Warning "Your FPS is at the default (60), you can go in Settings -> Video to set it to a higher value" + # Converts + # https://cdn.discordapp.com/attachments/969870701798522901/972541638578667540/HEVC_NVENC_Upscale.sft2 + # To hashtable with key "HEVC NVENC + Upscale" and val the URL + + filter File2Display { + [IO.Path]::GetFileNameWithoutExtension($_) -replace '_',' ' -replace " Upscale", " + Upscale" -replace ' ',' ' } - $FPS = $Basic.Video.FPSNum/$Basic.Video.FPSDen - $Pixels = [int]$Basic.Video.BaseCX*[int]$Basic.Video.BaseCY + $VegasTemplates = @( - if (($Basic.AdvOut.RecTracks -NotIn '1','2') -And ($FPS -gt 120)){ - Write-Warning "Using multiple audio tracks while recording at a high FPS may cause OBS to fail to stop recording" + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039599904873517106/HEVC_NVENC_Upscale.sft2' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039599905175502929/HEVC_NVENC.sft2' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039599904609288255/HEVC_NVENC__Upscale.sft2' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039599904353419284/H264_NVENC.sft2' + 'https://cdn.discordapp.com/attachments/969870701798522901/972541639346225264/x265_Upscale.sft2' + 'https://cdn.discordapp.com/attachments/969870701798522901/972541639560163348/x265.sft2' + 'https://cdn.discordapp.com/attachments/969870701798522901/972541638943596574/x264_Upscale.sft2' + 'https://cdn.discordapp.com/attachments/969870701798522901/972541639128129576/x264.sft2' + # 'https://cdn.discordapp.com/attachments/969870701798522901/972541638578667540/HEVC_NVENC_Upscale.sft2' + # 'https://cdn.discordapp.com/attachments/969870701798522901/972541638733885470/HEVC_NVENC.sft2' + # 'https://cdn.discordapp.com/attachments/969870701798522901/972541639744688198/H264_NVENC_Upscale.sft2' + # 'https://cdn.discordapp.com/attachments/969870701798522901/972541638356389918/H264_NVENC.sft2' + ) | ForEach-Object { + [Ordered]@{($_ | File2Display) = $_} } - if (!$Basic.Hotkeys.ReplayBuffer){ - Write-Warning "Replay Buffer is enabled, but there's no hotkey to Save Replay, set it up in Settings -> Hotkeys" + $PremiereTemplates = @( + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609690025369690/HEVC_NVENC__Upscale.epr' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609690369298432/HEVC_NVENC.epr' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609691992498218/H264_NVENC__Upscale.epr' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609692277706902/H264_NVENC.epr' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609690688061490/x264__Upscale.epr' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609690964893706/x264.epr' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609691380125827/x265__Upscale.epr' + 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609691682111548/x265.epr' + ) | ForEach-Object { + [Ordered]@{($_ | File2Display) = $_} } - $Basic = Merge-Hashtables -Original $Basic -Patch $OBSPatches.$Preset.$Encoder.basic -ErrorAction Stop - Out-IniFile -FilePath "$OBSProfile\basic.ini" -InputObject $Basic -Pretty -Force - - if ($Basic.Video.BaseCX -and $Basic.Video.BaseCY -and $Basic.Video.OutputCX -and $Basic.Video.OutputCY){ + switch($NLEBin){ - $Base = "{0}x{1}" -f $Basic.Video.BaseCX,$Basic.Video.BaseCY - $Output = "{0}x{1}" -f $Basic.Video.OutputCX,$Basic.Video.OutputCY - if ($Base -Ne $Output){ - Write-Warning "Your Base/Canvas resolution ($Base) is not the same as the Output/Scaled resolution ($Output),`nthis means OBS is scaling your video. This is not recommended." - } - } - - $NoEncSettings = -Not(Test-Path "$OBSProfile\recordEncoder.json") - $EmptyEncSettings = (Get-Content "$OBSProfile\recordEncoder.json" -ErrorAction Ignore) -in '',$null + {($NLEBin | Split-Path -Leaf).StartsWith('vegas')}{ - if ($NoEncSettings -or $EmptyEncSettings){ - Set-Content -Path "$OBSProfile\recordEncoder.json" -Value '{}' -Force - } - $RecordEncoder = Get-Content "$OBSProfile\recordEncoder.json" | ConvertFrom-Json -ErrorAction Stop + $NLETerm = "Vegas" + $TemplatesFolder = "$env:APPDATA\VEGAS\Render Templates\voukoder" - if (($Basic.Video.FPSNum/$Basic.Video.FPSDen -gt 480) -And ($Pixels -ge 2073600)){ # Set profile to baseline if recording at a high FPS and if res +> 2MP - $RecordEncoder.Profile = 'baseline' - } - $RecordEncoder = Merge-Hashtables -Original $RecordEncoder -Patch $OBSPatches.$Preset.$Encoder.recordEncoder -ErrorAction Stop - if ($Verbose){ - ConvertTo-Yaml $Basic - ConvertTo-Yaml $RecordEncoder - } - Set-Content -Path "$OBSProfile\recordEncoder.json" -Value (ConvertTo-Json -InputObject $RecordEncoder -Depth 100) -Force + if (-Not(Test-Path $TemplatesFolder)){ + New-Item -ItemType Directory -Path $TemplatesFolder -Force | Out-Null + } - if ($True -in [bool]$MiscTweaks){ # If there is anything in $MiscTweaks - $global = Get-Item (Join-Path ($OBSProfile | Split-Path | Split-Path | Split-Path) -ChildPath 'global.ini') -ErrorAction Stop - $glob = Get-IniContent -FilePath $global + $SelectedTemplates = Invoke-Checkbox -Items $VegasTemplates.Keys -Title "Select VEGAS render templates to install" - if ('OldDarkTheme' -in $MiscTweaks){ - $glob.General.CurrentTheme3 = 'Dark' + ForEach ($Template in $SelectedTemplates){ + if (Test-Path ($TPPath = "$TemplatesFolder\$Template.sft2")){ + Remove-Item $TPPath -Force + } + curl.exe -# -sSL $VegasTemplates.$Template -o"$TPPath" + } } - if ('OldDarkTheme' -in $MiscTweaks){ - $glob.BasicWindow.geometry = 'AdnQywADAAAAAAe/////uwAADJ0AAAKCAAAHv////9oAAAydAAACggAAAAEAAAAACgAAAAe/////2gAADJ0AAAKC' - $glob.BasicWindow.DockState = 'AAAA/wAAAAD9AAAAAgAAAAAAAAJOAAABvPwCAAAAAfsAAAASAHMAdABhAHQAcwBEAG8AYwBrAQAAABYAAAG8AAAA5gD///8AAAADAAAE3wAAALr8AQAAAAX7AAAAFABzAGMAZQBuAGUAcwBEAG8AYwBrAQAAAAAAAAD4AAAAoAD////7AAAAFgBzAG8AdQByAGMAZQBzAEQAbwBjAGsBAAAA/AAAAPoAAACgAP////sAAAASAG0AaQB4AGUAcgBEAG8AYwBrAQAAAfoAAAFBAAAA3gD////7AAAAHgB0AHIAYQBuAHMAaQB0AGkAbwBuAHMARABvAGMAawEAAAM/AAAAtAAAAI4A////+wAAABgAYwBvAG4AdAByAG8AbABzAEQAbwBjAGsBAAAD9wAAAOgAAACeAP///wAAAo0AAAG8AAAABAAAAAQAAAAIAAAACPwAAAAA' - } - $glob | Out-IniFile -FilePath $global -Force - } - Write-Host "Finished patching OBS, yay! Please switch profiles or reload OBS to see changes" -ForegroundColor Green -} -function Optimize-OptiFine { - [alias('optof')] - param( - [ValidateSet('Smart','Lowest','CouleursPreset')] - [Parameter(Mandatory)] - $Preset, - [String]$CustomDirectory = (Join-path $env:APPDATA '.minecraft'), - [Switch]$MultiMC, - [Switch]$PolyMC, - [Switch]$GDLauncher - ) + {($NLEBin | Split-Path -Leaf).StartsWith('Adobe Premiere Pro.exe')}{ + + $NLETerm = 'Premiere Pro' + $TemplatesFolder = "$env:USERPROFILE\Documents\Adobe\Adobe Media Encoder\12.0\Presets" -if($MultiMC){ - $CustomDirectory = Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs" -Recurse | Where-Object Name -Like "MultiMC.lnk" - $CustomDirectory = Get-ShortcutPath $CustomDirectory - $Instances = Get-ChildItem (Join-Path (Split-Path $CustomDirectory) instances) - "Please select a MultiMC instance" - $CustomDirectory = menu (Get-ChildItem $Instances).Name - $CustomDirectory = Join-Path $Instances $CustomDirectory + if (-Not(Test-Path $TemplatesFolder)){ + New-Item -ItemType Directory -Path $TemplatesFolder -Force | Out-Null + } -}elseif($PolyMC){ - $Instances = Get-ChildItem "$env:APPDATA\PolyMC\instances" - "Please select a PolyMC instance" - $CustomDirectory = menu $Instances.Name - $CustomDirectory = Join-Path $Instances $CustomDirectory + $SelectedTemplates = Invoke-Checkbox -Items $PremiereTemplates.Keys -Title "Select render templates to install" -}elseif($GDLauncher){ - $Instances = Get-ChildItem "$env:APPDATA\gdlauncher_next\instances" - "Please select a GDLauncher instance" - $CustomDirectory = menu $Instances.Name - $CustomDirectory = Join-Path $Instances $CustomDirectory + ForEach ($Template in $SelectedTemplates){ + if (Test-Path ($TPPath = "$TemplatesFolder\$Template.epr")){ + Remove-Item $TPPath -Force + } + curl.exe -# -sSL $PremiereTemplates.$Template -o"$TPPath" + } + + } -} -$Presets = @{ - CouleursPresets = @{ - options = @{ - 'key_key.hotbar.5' = 19 - 'key_key.hotbar.6' = 20 - 'key_key.hotbar.7' = 33 - 'key_key.hotbar.8' = 34 - 'key_key.hotbar.9' = 0 - chatScale = 0.8 - chatWidth = 0.65 - guiScale = 3 - renderDistance = 7 - maxFps = 260 - chatOpacity = 0.25 - enableVsync = $False - pauseOnLostFocus = $False - } - } - Smart = @{ - options = @{ - renderDistance=5 - mipmapLevels=4 - ofAoLevel=1.0 - } - optionsof = @{ - ofMipmapType=3 - ofCustomSky=$true - } - } + {($NLEBin | Split-Path -Leaf).StartsWith('AfterFX.exe')}{ + $NLETerm = 'After Effects' - Lowest = @{ - options = @{ - gamma=1000000 # I've never tried anything else and this always worked - renderDistance=2 - particles=2 - fboEnable=$true - useVbo=$true - showInventoryAchievementHint=$false - } - optionsof = @{ - ofAaLevel=0 # Anti-Aliasing - ofDynamicLights=3 - ofChunkUpdates=1 - ofAoLevel=0.0 # Smooth lighting - ofOcclusionFancy=$false - ofSmoothWorld=$true - ofClouds=3 - ofTrees=1 - ofDroppedItems=0 - ofRain=3 - ofAnimatedWater=2 - ofAnimatedLava=2 - ofAnimatedFire=$true - ofAnimatedPortal=$false - ofAnimatedRedstone=$false - ofAnimatedExplosion=$false - ofAnimatedFlame=$true - ofAnimatedSmoke=$false - ofVoidParticles=$false - ofWaterParticles=$false - ofPortalParticles=$false - ofPotionParticles=$false - ofFireworkParticles=$false - ofDrippingWaterLava=$false - ofAnimatedTerrain=$false - ofAnimatedTextures=$false - ofRainSplash=$false - ofSky=$false - ofStars=$false - ofSunMoon=$false - ofVignette=1 - ofCustomSky=$false - ofShowCapes=$false - ofFastMath=$true - ofSmoothFps=$false - ofTranslucentBlocks=1 + "Opening a tutorial in your browser and downloading the AE templates file.." + Start-Sleep -Seconds 2 + if (-Not(Test-Path ($TPDir = "$env:TMP\AE_Templates"))){ + New-Item -ItemType Directory -Path $TPDir -Force | Out-Null + } + curl.exe -# -sSL https://cdn.discordapp.com/attachments/1039599872703213648/1039614649638858772/CTT_AE_VOUKODER_TEMPLATES.aom -o"$TPDir\CTT_AE_VOUKODER_TEMPLATES.aom" + + Start-Process -FilePath explorer.exe -ArgumentList "/select,`"$TPDir\CTT_AE_VOUKODER_TEMPLATES.aom`"" + $Tutorial = 'https://i.imgur.com/XCaJGoV.mp4' + try { + Start-Process $Tutorial + } catch { # If the user does not have any browser + "Tutorial URL: $Tutorial" + } } - } -} -$Global = @{ - optionsof = @{ - ofFastRender=$true - ofClouds=3 - ofAfLevel=1 # Anisotropic filtering - ofAaLevel=0 # Anti-aliasing - ofRainSplash=$false - } - options = @{ - showInventoryAchievementHint=$false - maxFps=260 - renderClouds=$false - useVbo=$true - } -} -$Presets.$Preset = Merge-Hashtables $Presets.$Preset $Global -function ConvertTo-MCSetting ($table){ - $file = @() - ForEach($setting in $table.keys){ - $file += [String]$($setting + ':' + ($table.$setting)) -replace'True','true' -replace 'False','false' - } - return $file -} -foreach ($file in 'options','optionsof'){ + default{ + Write-Host "Your video editor ($($NLEBin)) does not have any pre-made templates for me to propose you" -ForegroundColor Red + $NLETerm = "your video editor" + } + } + Write-Host "Installation script finished, follow instructions (if any)" + Write-Host "Then restart $NLETerm to make sure Voukoder render templates have loaded." -ForegroundColor Red - $Hash = (Get-Content "$CustomDirectory\$file.txt") -Replace ':','=' | ConvertFrom-StringData - $Hash = Merge-Hashtables -Original $Hash -Patch $Presets.$Preset.$file - Set-Content "$CustomDirectory\$file.txt" -Value (ConvertTo-MCSetting $Hash) -Force } -if (Test-Path "$CustomDirectory\optionsLC.txt"){ - $Hash = (Get-Content "$CustomDirectory\optionsLC.txt") -Replace ',"maxFps":"260"','' | ConvertFrom-Json -} -$Hash = Merge-Hashtables -Original $Hash -Patch $Presets.$Preset.optionsof -$Hash = Merge-Hashtables -Original $Hash -Patch $Presets.$Preset.options -$Hash.maxFPS = 260 -Set-Content "$CustomDirectory\optionsLC.txt" -Value (ConvertTo-Json $Hash) -Force -} -function Get-GraalVM { +function Invoke-SmoothiePost { param( - [Switch]$Reinstall + [String] + [ValidateScript({ + Test-Path -Path (Get-Item $_) -PathType Container -ErrorAction Stop + })] + $CustomDir ) - - if ((Test-Path "$env:ProgramData\GraalVM") -and !$Reinstall){ - return "GraalVM is already installed, run with -Reinstall to force reinstallation" + # DIR is the variable used by Scoop, hence why I'm using a separate name + if ($CustomDir -and !$DIR){ + if (!(Test-Path "$CustomDir\Smoothie") -And !(Test-Path "$CustomDir\VapourSynth")){ + Write-Host "The folder you gave needs to contain the folders 'Smoothie' and 'VapourSynth', try the right path" + }else{ + $DIR = (Get-Item $CustomDir).FullName + } } - if (-Not(Get-Command curl.exe -ErrorAction Ignore)){ - return "curl is not found (comes with windows per default?)" + if (!$DIR){return "This script is suppose to be ran by Scoop after it's intallation, not manually"} + + $rc = (Get-Content "$DIR\Smoothie\settings\recipe.yaml" -ErrorAction Stop) -replace ('H264 CPU',(Get-EncodingArgs -EzEncArgs)) + + if ($valid_args -like "H* CPU"){$rc = $rc -replace ('gpu: true','gpu: false')} + + Set-Content "$DIR\Smoothie\settings\recipe.ini" -Value $rc + + $term = Get-Path conhost.exe + + Get Scoop + + $SendTo = [System.Environment]::GetFolderPath('SendTo') + $Scoop = Get-Command Scoop | Split-Path | Split-Path + $SA = [System.IO.Path]::Combine([Environment]::GetFolderPath('StartMenu'), 'Programs', 'Scoop Apps') + + if (-Not(Test-Path $SA)){ # If not using Scoop + $SA = [System.IO.Path]::Combine([Environment]::GetFolderPath('StartMenu'), 'Programs') } - Remove-Item "$env:ProgramData\GraalVM" -ErrorAction Ignore -Force -Recurse - $URL = 'https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.2.0/graalvm-ce-java16-windows-amd64-21.2.0.zip' - $SHA256 = 'DAE2511ABFF8EAD3EBC90CD9FC81A8E84B762FC91462B198C3EDDF28F81A937E' - $Zip = "$env:TMP\GraalVM.zip" + Set-Content "$Scoop\shims\sm.shim" -Value @" +path = "$DIR\VapourSynth\python.exe" +args = "$DIR\Smoothie\src\main.py" +"@ + if (-Not(Test-Path "$Scoop\shims\sm.exe")){ + Copy-Item "$Scoop\shims\7z.exe" "$Scoop\shims\sm.exe" + } - if (-Not(Test-Path $Zip)){ - Write-Host "Downloading GraalVM ($(Get-HeaderSize $URL)`MB).." -ForegroundColor Green - curl.exe -# -L $URL -o"$Zip" + $Parameters = @{ + Overwrite = $True + LnkPath = "$Scoop\shims\rc.lnk" + TargetPath = "$DIR\Smoothie\settings\recipe.yaml" } + New-Shortcut @Parameters - if ((Get-FileHash $Zip).Hash -ne $SHA256){ - Remove-Item "$env:TMP\GraalVM.zip" - return "Failed to download GraalVM (SHA256 checksum mismatch, not the expected file)" - + + $Parameters = @{ + Overwrite = $True + LnkPath = "$SA\Smoothie Recipe.lnk" + TargetPath = "$DIR\Smoothie\settings\recipe.yaml" } + New-Shortcut @Parameters - if (Get-Command 7z -ErrorAction Ignore){ + $Parameters = @{ + Overwrite = $True + LnkPath = "$SA\Smoothie.lnk" + TargetPath = $term + Arguments = "`"$DIR\VapourSynth\python.exe`" `"$DIR\Smoothie\src\main.py`" -cui" + Icon = "$DIR\Smoothie\src\sm.ico" + } + New-Shortcut @Parameters + + $Parameters = @{ + Overwrite = $True + LnkPath = "$SendTo\Smoothie.lnk" + TargetPath = $term + Arguments = "`"$DIR\VapourSynth\python.exe`" `"$DIR\Smoothie\src\main.py`" -cui -input" + Icon = "$DIR\Smoothie\src\sm.ico" - Invoke-Expression "& `"7z`" x -bso0 -bsp1 -bse1 -aoa `"$env:TMP\GraalVM.zip`" -o`"$env:ProgramData\GraalVM`"" - } else { - Expand-Archive -Path $Zip -Destination "$env:ProgramData\GraalVM" } - Move-Item -Path "$env:ProgramData\GraalVM\graalvm-?e*\*" "C:\ProgramData\GraalVM" + New-Shortcut @Parameters + } -function Get-TLShell { + +# This does not install Smoothie, it simply creates shortcuts in the start menu, Send To and configures the recipe +function Invoke-SmoothieRsPost { param( - [switch]$Offline, - [switch]$DontOpen + + [ValidateScript({ + Test-Path -Path (Get-Item $_) -PathType Container -ErrorAction Stop + })] + [String]$DIR, + [Switch]$Scoop, + [Switch]$Uninstall + ) + + $ErrorActionPreference = 'Stop' + + <# + .SYNOPSIS + Merges recipes + + .NOTES + It returns void, it just applies all patches on what was passed to -Original + + .NOTES + Limitations: + - It cannot remove keys from $OG, most it can do is Patch containing a same key that is $null + + .PARAMETER Original + The original hashtable which will get modified + .PARAMETER Patches + Recursively merge with $Original + #> + function Merge-Recipe { + [CmdletBinding()] + param ( + $Original, + $Patch ) - - $WR = "$env:LOCALAPPDATA\Microsoft\WindowsApps" # I've had the habit of calling this folder WR - # because it's the only folder I know that is added to path - # that you don't need perms to access. + foreach ($category in $Patch.GetEnumerator()) { + + $key, $patch = $category.name, $category.value -if ($Offline){ + if ($Original.Contains($key) -and ($Original[$key] -is [Collections.Specialized.OrderedDictionary] -and $Patch -is [Collections.Specialized.OrderedDictionary])) { + Merge-Recipe -Original $Original[$key] -Patch $Patch + } + else { + $Original[$key] = $Patch + } + } + } - try { - $Master = Invoke-RestMethod -UseBasicParsing https://raw.githubusercontent.com/couleur-tweak-tips/TweakList/master/Master.ps1 - } catch { - Write-Host "Failed to get Master.ps1 from TweakList GitHub" -ForegroundColor DarkRed - Write-Output "Error: $($Error[0].ToString())" + $SendTo = [System.Environment]::GetFolderPath('SendTo') + $Start = [System.IO.Path]::Combine([Environment]::GetFolderPath('StartMenu'), 'Programs') + + if (!$SendTo -or !(Test-Path $SendTo)) { + return "FATAL: Send To folder [$SendTo] does not exist, did you/a script strip it?" + } + if (!$Start -or !(Test-Path $Start)) { + return "FATAL: Start Menu folder [$Start] does not exist, did you/a script strip it?" + } + + if ($Scoop){ + $shims = (Resolve-Path $DIR/../../../shims).Path + } + + if ($Uninstall) { + Remove-Item "$Sendto\Smoothie.lnk" + Remove-Item "$SA\Smoothie.lnk" + if ($Scoop) { + Remove-Item "$shims\rc.lnk" + } return } - Set-Content "$WR/TLSOff.cmd" -Value @' -<# : batch portion -@echo off -powershell.exe -noexit -noprofile -noexit -command "iex (${%~f0} | out-string)" -: end batch / begin powershell #> -Write-Host "TweakList Shell " -Foregroundcolor White -NoNewLine -Write-Host "(Offline)" -Foregroundcolor DarkGray -NoNewLine -Write-Host " - dsc.gg/CTT" -Foregroundcolor White -NoNewLine -'@ - $Batch = Get-Item "$WR/TLSOff.cmd" - Add-Content $Batch -Value $Master - if (!$DontOpen){ - explorer.exe /select,`"$($Batch.FullName)`" - } + if ($Scoop) { + $old_VERSIONS = Get-ChildItem $dir/.. -Directory -Exclude current, $version + $old_DIR = switch ($old_VERSIONS.Length) { + { $_ -in 0, $null } {} + 1 { $old_VERSIONS } + default { + $script:ret = "" + $script:mostRecentDate = [datetime]::MinValue + + $old_VERSIONS | ForEach-Object { + $string = $_.BaseName -replace "Nightly_" + $datetime = [datetime]::ParseExact($string, "yyyy.MM.dd_HH-mm", [CultureInfo]::InvariantCulture) + + if ($datetime -gt $script:mostRecentDate) { + $script:mostRecentDate = $datetime + $script:ret = $_ + } + } + + if ($script:mostRecentDate -eq [datetime]::MinValue) { + write-Warning "Failed to parse old versions:" + Write-Host $old_VERSIONS.FullName + } + + $script:ret + } + } -}else{ + if ($old_DIR -and (Test-Path $old_DIR)) { + [Collections.Specialized.OrderedDictionary]$old_MACROS = Get-IniContent $old_DIR/encoding_presets.ini -KeyValSeparator ':' + [Collections.Specialized.OrderedDictionary]$new_MACROS = Get-IniContent $DIR/encoding_presets.ini -KeyValSeparator ':' + + Merge-Recipe $new_MACROS $old_MACROS + $new_MACROS | Out-IniFile $DIR/encoding_presets.ini -Pretty -Force -Loose -KeyValSeparator ':' - - if ($WR -NotIn $env:PATH.Split(';')){ - Write-Error "`"$env:LOCALAPPDATA\Microsoft\WindowsApps`" is not added to path, did you mess with Windows?" - return - }else{ - $TLS = "$WR\TLS.CMD" - Set-Content -Path $TLS -Value @' -@echo off -title TweakList Shell -if /I "%1" == "wr" (explorer "%~dp0" & exit) -if /I "%1" == "so" (set sophiaflag=Write-Host 'Importing Sophia Script..' -NoNewLine -ForegroundColor DarkGray;Import-Sophia) + $old_RECIPES = Get-ChildItem $old_DIR -File -Filter *.ini | Where-Object BaseName -Notin 'defaults', 'encoding_presets' -fltmc >nul 2>&1 || ( - echo Elevating to admin.. - PowerShell.exe -NoProfile Start-Process -Verb RunAs ' %0' 2> nul || ( - echo Failed to elevate to admin, launch CMD as Admin and type in "TL" - pause & exit 1 - ) - exit 0 -) + $old_RECIPES | ForEach-Object { + [Collections.Specialized.OrderedDictionary]$old_RC = Get-IniContent $_.FullName -KeyValSeparator ':' + [Collections.Specialized.OrderedDictionary]$new_RC = Get-IniContent $DIR\recipe.ini -KeyValSeparator ':' + + Merge-Recipe $new_RC $old_RC + $new_RC | Out-IniFile $DIR/$($_.BaseName).ini -Pretty -Force -Loose -KeyValSeparator ':' + } + $old_files = Get-ChildItem $old_DIR | Where-Object Name -notin 'defaults.ini', 'encoding_presets.ini', 'jamba.vpy', 'bin', 'recipe.ini', 'launch.cmd', 'manifest.json', 'install.json' -powershell.exe -NoProfile -NoLogo -NoExit -Command ^ -"if ($PWD.Path -eq \"$env:WINDIR\system32\"){cd $HOME} ;^ -[System.Net.ServicePointManager]::SecurityProtocol='Tls12' ;^ -Write-Host 'Invoking TweakList.. ' -NoNewLine -ForegroundColor DarkGray;^ -iex(irm tl.ctt.cx);^ -%SOPHIAFLAG%;^ -Write-Host \"`rTweakList Shell - dsc.gg/CTT `n\" -Foregroundcolor White" -'@ -Force + $old_files | ForEach-Object { Move-Item $_.FullName $DIR -Verbose } + + } } - $ShortcutPath = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\TweakList Shell.lnk" - $WScriptShell = New-Object -ComObject WScript.Shell - $Shortcut = $WScriptShell.CreateShortcut($ShortcutPath) - $Shortcut.IconLocation = (Get-Command powershell.exe).Source + ",0" - $Shortcut.TargetPath = "$WR\TLS.CMD" - $Shortcut.Save() - # Got this from my old list of snippets, originally found this on StackOverflow, forgot link - $bytes = [System.IO.File]::ReadAllBytes($ShortCutPath) - $bytes[0x15] = $bytes[0x15] -bor 0x20 # Set byte 21 (0x15) bit 6 (0x20) ON - [System.IO.File]::WriteAllBytes($ShortcutPath, $bytes) + $SendTo = [System.Environment]::GetFolderPath('SendTo') + $Start = [System.IO.Path]::Combine([Environment]::GetFolderPath('StartMenu'), 'Programs') + . { # Shortcuts + if (!$SendTo -or !(Test-Path $SendTo)) { + return "FATAL: Send To folder [$SendTo] does not exist, did you/a script strip it?" + } + if (!$Start -or !(Test-Path $Start)) { + return "FATAL: Start Menu folder [$Start] does not exist, did you/a script strip it?" + } - Write-Host "You can now type 'TLS' in Run (Windows+R) to launch it, or from your start menu" - if (!$DontOpen){ - & explorer.exe /select,`"$("$WR\TLS.CMD")`" + # %APPDATA%\Microsoft\Windows\SendTo\Smoothie.lnk + $Parameters = @{ + Overwrite = $True + LnkPath = "$SendTo\&Smoothie.lnk" + TargetPath = "$DIR\bin\smoothie-rs.exe" + Arguments = "--tui -i" + } + New-Shortcut @Parameters + + if ($Scoop) { + + # %USERPROFILE%\scoop\shims\rc.lnk + $Parameters = @{ + Overwrite = $True + LnkPath = "$shims\rc.lnk" + TargetPath = "$dir\recipe.ini" + } + New-Shortcut @Parameters + } + else { + # %APPDATA%\Microsoft\Windows\Start Menu\Programs\Smoothie Recipe.lnk + $Parameters = @{ + Overwrite = $True + LnkPath = "$Start\Smoothie Recipe.lnk" + TargetPath = "$DIR\recipe.ini" + } + # %APPDATA%\Microsoft\Windows\Start Menu\Programs\Smoothie.lnk + New-Shortcut @Parameters + $Parameters = @{ + Overwrite = $True + LnkPath = "$Start\Smoothie.lnk" + TargetPath = "$DIR\bin\smoothie-rs.exe" + Arguments = "--tui -i" + } + New-Shortcut @Parameters + } } - - -} + } +function Launch{ + [alias('l')] + param( + [ValidateSet( + 'DisplayDriverUninstaller', + 'NVCleanstall', + 'NvidiaProfileInspector', + 'MSIUtilityV3', + 'Rufus', + 'AutoRuns', + 'Procmon', + 'CustomResolutionUtility', + 'NotepadReplacer', + 'privacy.sexy', + 'ReShade' + #! TODO: NVProfileInspector, MSIUtility, CRU, Notepadreplacer, BulkCrapUninstaller, https://www.bill2-software.com/processmanager/exe/BPM-Setup.exe + )] + [Array]$Apps, + [Switch]$DontLaunch, # Just keep them tidy in the Downloads folder)) + # This is the non hardcoded Downloads folder path s/o @farag2 + [String]$OutDir = (Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{374DE290-123F-4565-9164-39C4925E467B}") + ) -# This function centralizes most of what you can download/install on CTT -# Anything it doesn't find in that switch ($App){ statement is passed to scoop -$global:SendTo = [System.Environment]::GetFolderPath('SendTo') -function Get { - [alias('g')] # minimalism at it's finest - param( - [Parameter(ValueFromRemainingArguments = $true)] - [Array]$Apps, - [Switch]$DryRun - ) + Add-Type -AssemblyName System.IO.Compression.FileSystem - $FailedToInstall = $null # Reset that variable for later - if ($Apps.Count -eq 1 -and (($Apps[0] -Split '\r?\n') -gt 1)){ - $Apps = $Apps[0] -Split '\r?\n' - } - if ($DryRun){ - ForEach($App in $Apps){ - "Installing $app." - } - return - } + function Invoke-Download{ + param( + [String]$URL, # Parses mediafire + [String]$AppName, + [Switch]$Scoop, # Scoop 'bucket/manifest' name + [String]$PathToBinary, # In the zip + [String]$Checksum, + [String]$SelfExtracting7z # e.g for DDU + ) - ForEach($App in $Apps){ # Scoop exits when it throws + if (-Not(Test-Path $env:TMP)){ + throw "TMP environment variable not found [$env:TMP]" + } - switch ($App){ - 'nvddl'{Get-ScoopApp utils/nvddl} - {$_ -in 'Remux','Remuxer'}{ - Invoke-RestMethod https://github.com/couleurm/couleurstoolbox/raw/main/7%20FFmpeg/Old%20Toolbox%20scripts/Remux.bat -Verbose | - Out-File "$SendTo\Remux.bat" + if($Scoop){ + $Bucket, $Manifest = $URL -split '/' - } - {$_ -in 'RemuxAVI','AVIRemuxer'}{ - Invoke-RestMethod https://github.com/couleurm/couleurstoolbox/raw/main/7%20FFmpeg/Old%20Toolbox%20scripts/Remux.bat -Verbose | - Out-File "$SendTo\Remux - AVI.bat" - $Content = (Get-Content "$SendTo\Remux - AVI.bat") -replace 'set container=mp4','set container=avi' - Set-Content "$SendTo\Remux - AVI.bat" $Content - } - {$_ -in 'Voukoder','vk'}{Install-Voukoder } - 'Upscaler'{ + $Repos = @{ - Install-FFmpeg - Invoke-RestMethod 'https://github.com/couleur-tweak-tips/utils/raw/main/Miscellaneous/CTT%20Upscaler.cmd' | - Out-File (Join-Path ([System.Environment]::GetFolderPath('SendTo')) 'CTT Upscaler.cmd') -Encoding ASCII -Force - Write-Host @" -CTT Upscaler has been installed! Find it in the options when right clicking a video file -> Send To -> CTT Upscaler.cmd -"@ -ForegroundColor Green + main = @{org = 'ScoopInstaller';repo = 'main';branch = 'master'} + extras = @{org = 'ScoopInstaller';repo = 'extras';branch = 'master'} + utils = @{org = 'couleur-tweak-tips';repo = 'utils';branch = 'main'} + nirsoft = @{org = 'kodybrown';repo = 'scoop-nirsoft';branch = 'master'} + games = @{org = 'ScoopInstaller';repo = 'games';branch = 'master'} + 'nerd-fonts' = @{org = 'ScoopInstaller';repo = 'nerd-fonts';branch = 'master'} + versions = @{org = 'ScoopInstaller';repo = 'versions';branch = 'master'} + java = @{org = 'ScoopInstaller';repo = 'java';branch = 'master'} + } + $repo = $Repos.$Bucket + $URL = "https://raw.githubusercontent.com/$($repo.org)/$($repo.repo)/$($repo.branch)/bucket/$Manifest.json" + $URL, $Version = Invoke-RestMethod $URL | ForEach-Object {$PSItem.URL, $PSItem.Version} + }elseif($URL -Like "*mediafire.com*"){ + $URL = (Invoke-WebRequest -UseBasicParsing $URL).Links.href | Where-Object {$PSItem -Like "http*://download*.mediafire.com/*"} + } + + if ($AppName){ + $FileName = $AppName + }else{ + $FileName = $Manifest + } + + if ($Version){$FileName += " $Version"} + + $Extension = [io.path]::GetExtension((($URL -replace '#/dl.7z') | Split-Path -Leaf)) + + $OutFile = "$env:TMP\$FileName$Extension" + if (-Not(Test-Path $OutFile)){ + curl.exe -#L -A "Scoop" $URL -o"$OutFile" + } + + if($Checksum){ + $Parameters = @{ + Path = $OutFile + } + if ($Checksum -Like "*:*"){ # Contains a : + $Algo, $Checksum = $Checksum -Split ':' # To split hash and algo, eg md5:8424509737CEDBDE4BA9E9A780D5CE96 + $Parameters += @{ + Algorithm = $Algo + } + } + if ($Checksum -ne (Get-FileHash @Parameters).Hash){ + throw "Hash provided $Checksum does not match $OutFile" + } + } + + if ($Extension -eq '.zip'){ + $OutDir = "$env:TMP\$FileName\" + if (-Not(Test-Path $OutDir)){ + [System.IO.Compression.ZipFile]::ExtractToDirectory($OutFile, $OutDir) + } + + if ($PathToBinary){ + $OutDir = Join-Path $OutDir $PathToBinary + } + $OutFile = $OutDir # To not have to check for the following statement twice + }elseif($SelfExtracting7z){ + Start-Process -FilePath $OutFile -ArgumentList "-y" -Wait + $SelfExtracting7z = $SelfExtracting7z -replace "%VER%", $Version + if (-Not(Test-Path "$env:TMP\$SelfExtracting7z" -PathType Container)){ + throw "Self extracting 7-Zip got wrong path: $SelfExtracting7z" + } + $OutDir = $SelfExtracting7z + } - } - {$_ -In 'QualityMuncher','qm'}{ - Install-FFmpeg + if (-Not(Test-Path $OutFile)){ + throw "$OutFile could not be found" + } - Invoke-RestMethod 'https://raw.githubusercontent.com/Thqrn/qualitymuncher/main/Quality%20Muncher.bat' | - Out-File (Join-Path ([System.Environment]::GetFolderPath('SendTo')) 'Quality Muncher.bat') -Encoding ASCII -Force + return $OutFile - Invoke-RestMethod 'https://raw.githubusercontent.com/Thqrn/qualitymuncher/main/!!qualitymuncher%20multiqueue.bat' | - Out-File (Join-Path ([System.Environment]::GetFolderPath('SendTo')) '!!qualitymuncher multiqueue.bat') -Encoding ASCII -Force + } - } + $Paths = @() - 'Scoop'{Install-Scoop } - {$_ -in 'ff','FFmpeg'}{Install-FFmpeg } + $Apps | ForEach-Object { # Cycles through given apps + Write-Host "getting $PSItem" + $Paths += switch ($PSItem){ + DisplayDriverUninstaller{ Invoke-Download -URL extras/ddu -Scoop -PathToBinary "Display Driver Uninstaller.exe" -SelfExtracting7z "DDU v%VER%" -AppName DDU } + NVCleanstall{ Invoke-Download -URL extras/nvcleanstall -Scoop -AppName NVCleanstall -PathToBinary "NVCleanstall.exe" } + NvidiaProfileInspector{ Invoke-Download -URL extras/nvidia-profile-inspector -Scoop -AppName NvidiaProfileInspector -PathToBinary 'nvidiaProfileInspector.exe' } + MSIUtilityV3{ + Write-Warning "MSI mode is already applied by default on NVIDIA 1600/2000/3000 GPUs and AMD cards" + Invoke-Download -URL https://www.mediafire.com/file/ewpy1p0rr132thk/MSI_util_v3.zip/file -AppName "MSIUtilV3" -PathToBinary "MSI_util_v3.exe" -Checksum "md5:8424509737CEDBDE4BA9E9A780D5CE96" + } + Rufus{ Invoke-Download -URL extras/rufus -Scoop -AppName rufus} + AutoRuns{ Invoke-Download -URL https://download.sysinternals.com/files/Autoruns.zip -AppName AutoRuns -PathToBinary Autoruns64.exe } + Procmon{ Invoke-Download -URL https://download.sysinternals.com/files/ProcessMonitor.zip -AppName Procmon -PathToBinary Procmon64.exe } + CustomResolutionUtility { Invoke-Download -URL extras/cru -Scoop -AppName CRU -PathToBinary CRU.exe} + NotepadReplacer { Invoke-Download -URL utils/notepadreplacer -Scoop -AppName NotepadReplacer} + privacy.sexy { Invoke-Download -URL utils/privacysexy -Scoop -AppName privacysexy} + ReShade{ + $Website = "https://reshade.me/" + $DLLink = (Invoke-WebRequest "$Website#download").Links.Href | Where-Object {$_ -Like "*.exe"} | Where-Object {$_ -NotLike "*_Addon.exe"} + $URL = $Website + $DLLink + Invoke-Download -URL $URL -AppName ReShade + } + } + } + return $Paths +} +# Source: https://github.com/Aetopia/Install-NVCPL +function Install-NVCPL { + if (!(Test-Admin)) { + Write-Host "Install-NVCPL: This function needs Administrator priviledges" -ForegroundColor DarkRed + return + } - {$_ -in 'zl','ZetaLoader'}{Install-ZetaLoader} - {$_ -in 'CRU','custom-resolution-utility'}{Get-ScoopApp extras/cru} - {$_ -in 'wt','windowsterminal','windows-terminal'}{Get-ScoopApp extras/windows-terminal} - {$_ -in 'np++','Notepad++','notepadplusplus'}{Get-ScoopApp extras/notepadplusplus} - {$_ -in 'DDU','DisplayDriverUninstaller'}{Get-ScoopApp extras/ddu} - {$_ -in 'Afterburner','MSIAfterburner'}{Get-ScoopApp utils/msiafterburner} - {$_ -in 'Everything','Everything-Alpha','Everything-Beta'}{Get-ScoopApp extras/everything-alpha} - {$_ -In '7-Zip','7z','7Zip'}{Get-ScoopApp 7zip} - {$_ -In 'Smoothie','sm'}{Install-FFmpeg ;Get-ScoopApp utils/Smoothie} - {$_ -In 'OBS','OBSstudio','OBS-Studio'}{Get-ScoopApp extras/obs-studio} - {$_ -In 'UTVideo'}{Get-ScoopApp utils/utvideo} - {$_ -In 'Nmkoder'}{Get-ScoopApp utils/nmkoder} - {$_ -In 'Librewolf'}{Get-ScoopApp extras/librewolf} - {$_ -In 'ffmpeg-nightly'}{Get-ScoopApp versions/ffmpeg-nightly} - {$_ -In 'Graal','GraalVM'}{Get-ScoopApp utils/GraalVM} - {$_ -In 'DiscordCompressor','dc'}{Install-FFmpeg ;Get-ScoopApp utils/discordcompressor} - {$_ -In 'Moony','mn'}{if (-Not(Test-Path "$HOME\.lunarclient")){Write-Warning "You NEED Lunar Client to launch it with Moony"};Get-ScoopApp utils/Moony} - {$_ -In 'TLShell','TLS'}{Get-TLShell } - default{Get-ScoopApp $App} + choice.exe /C 12 /N /M "Install NVIDIA Control Panel as:`n1. Win32 App`n2. UWP App`n>" + + $NVCPL = "$ENV:TEMP\NVCPL.zip" + $InstallationDirectory = "$ENV:PROGRAMFILES\NVIDIA Corporation\Control Panel Client" + $ShortcutFile = "$ENV:PROGRAMDATA\Microsoft\Windows\Start Menu\Programs\NVIDIA Control Panel.lnk" + if ($LASTEXITCODE -eq 2) { $NVCPL = "$NVCPL.appx" } + + if ($null -eq (Get-CimInstance Win32_VideoController | + Where-Object { $_.Name -like "NVIDIA*" })) { + Write-Host "No NVIDIA GPU found." -ForegroundColor DarkRed + return } - Write-Verbose "Finished installing $app" - } - if ($FailedToInstall){ - Write-Host "[!] The following apps failed to install (scroll up for details):" -ForegroundColor Red - $FailedToInstall + # Disable Telemetry. + New-ItemProperty -Path "HKLM:\SOFTWARE\NVIDIA Corporation\NvControlPanel2\Client" -Name "OptInOrOutPreference" -Value 0 -PropertyType DWORD -Force -ErrorAction SilentlyContinue | Out-Null + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm\Global\Startup" -Name "SendTelemetryData" -Value 0 -PropertyType DWORD -Force -ErrorAction SilentlyContinue | Out-Null + + + # Using rg-adguard to fetch the latest version of the NVIDIA Control Panel. + $Body = @{ + type = 'url' + url = "https://apps.microsoft.com/store/detail/nvidia-control-panel/9NF8H0H7WMLT" + ring = 'RP' + lang = 'en-US' + } + Write-Output "Getting the latest version of the NVIDIA Control Panel from the Microsoft Store..." + $Link = ((Invoke-RestMethod -Method Post -Uri "https://store.rg-adguard.net/api/GetFiles" -ContentType "application/x-www-form-urlencoded" -Body $Body) -Split "`n" | + ForEach-Object { $_.Trim() } | + Where-Object { $_ -like ("*http://tlu.dl.delivery.mp.microsoft.com*") } | + ForEach-Object { ((($_ -split "", 2, "SimpleMatch")[1] -Split "rel=", 2, "SimpleMatch")[0] -Split " + [alias('optlc')] param( - [Switch]$GetTemplates - # Skip Voukoder installation and just get to the template selector + + #//[HelpMessage("Set your lazy chunk load speed")] + [ValidateSet( + 'highest', + 'high', + 'medium', + 'low', + 'lowest', + 'off_van' + )] + [String]$LazyChunkLoadSpeed = 'low', + + [ValidateSet( + 'Performance', + 'NoCosmetics', + 'MinimalViewBobbing', + 'No16xSaturationOverlay', + 'HideToggleSprint', + 'ToggleSneak', + 'DisableUHCMods', + 'FullBright', + 'CouleursPreset' + )] + #// Gotta be put twice because mf cant handle variables in validate sets + [Array]$Settings = (Invoke-Checkbox -Title "Select tweaks to apply" -Items @( + 'Performance' + 'NoCosmetics' + 'MinimalViewBobbing' + 'No16xSaturationOverlay' + 'HideToggleSprint' + 'ToggleSneak' + 'DisableUHCMods' + 'FullBright' + 'CouleursPreset' + )), + + [String] + $LCDirectory = "$HOME\.lunarclient", + + [Switch]$NoBetaWarning, + [Switch]$KeepLCOpen, + [Switch]$DryRun + + #//TODO: [Array]$Misc HideFoliage, NoEntityShadow, LCNametags, Clearglass, NoBackground, NoHypixelMods ) + + if (-Not(Test-Path $LCDirectory)){ + Write-Host "Lunar Client's directory ($HOME\.lunarclient) does not exist (for the turbonerds reading this you can overwrite that with -LCDirectory" + } + if (!$NoBetaWarning){ + Write-Warning "This script may corrupt your Lunar Client profiles, continue at your own risk,`nyou're probably safer if you copy the folder located at $(Convert-Path $HOME\.lunarclient\settings\game)" + pause + } + if (!$KeepLCOpen){ + while ((Get-Process -Name java?).MainWindowTitle -Like "Lunar Client*"){ + Write-Host "You must quit Lunar Client before running these optimizations (LC will overwrite them when it exits)" -ForegroundColor Red + pause + } + }else{ + Write-Warning "You disabled the script from not running if Lunar Client is running, here be dragons!" + Start-Sleep -Milliseconds 500 + } - function Get-VoukoderProgram ($Name){ - # Parses the registry manually instead of using PackageManagement's Get-Package + if (!$LazyChunkLoadSpeed -and ('Performance' -in $Settings)){$LazyChunkLoadSpeed = 'low'} - $Programs = @( - 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' - 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' - 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' - 'HKCU:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' + $Manager = Get-Content "$LCDirectory\settings\game\profile_manager.json" -ErrorAction Stop | ConvertFrom-Json + + $Profiles = @{} + ForEach($Profile in $Manager){ + $Profiles += @{ "$($Profile.DisplayName) ($($Profile.Name))" = $Profile} + } - ) | Where-Object {Test-path $_} | + Write-Host "Select a profile:" + $Selection = Menu @([Array[]]'Create a new profile' + [Array[]]$Profiles.Keys) + if ($Selection -in $Manager.name,$Manager.DisplayName){ + if ($VerbosePreference -eq 'Continue'){ + Write-Host "Error, Manager:`n`n" -ForegroundColor Red + Write-Host ($Manager | ConvertTo-Json) + return + + } + return "A profile with the same name already exists!" + } - Get-ItemProperty | Where-Object Publisher -eq 'Daniel Stankewitz' | - Sort-Object DisplayName | - Select-Object -Property @{n='Name'; e='DisplayName' }, - @{n='Version'; e='DisplayVersion'}, - @{n='UninstallString'; e='UninstallString'} + if ($Selection -eq 'Create a new profile'){ - return $Programs | Where-Object Name -Like $Name + $ProfileName = Read-Host "Enter a name for the new profile" + New-Item -ItemType Directory -Path "$LCDirectory\settings\game\$ProfileName" -ErrorAction Stop | Out-Null + Push-Location "$LCDirectory\settings\game\$ProfileName" + ('general.json', 'mods.json', 'performance.json') | ForEach-Object { + if (-Not(Test-Path ./$_)){Add-Content ./$_ -Value '{}'} # Empty json file + } + Pop-Location + $Selection = [PSCustomObject]@{ + + name = $ProfileName + displayName = $ProfileName + active = $False + default = $False + iconName = 'crossed-swords' + server = '' + } + $Manager += $Selection # Overwriting the string "Create a new profile" with the fresh one + Set-Content -Path "$LCDirectory\settings\game\profile_manager.json" -Value ($Manager | ConvertTo-Json -Compress -Depth 99) + }else{ + $Selection = $Profiles.$Selection } - if (!$GetTemplates){ + $ProfileDir = "$LCDirectory\settings\game\$($Selection.name)" + ForEach($file in 'general','mods','performance'){ # Assigns $general, $mods and $performance variables + Set-Variable -Scope Global -Name $file -Value (Get-Content "$ProfileDir\$file.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop) + if ($DryRun){ + Write-Host $file -ForegroundColor Red + (Get-Variable -Name $file).Value | ConvertTo-Json + } + } - $LatestCore = (Invoke-RestMethod https://api.github.com/repos/Vouk/voukoder/releases/latest)[0] - # get the latest release manifest from GitHub's API - - if (($tag = $LatestCore.tag_name) -NotLike "*.*"){ - $tag += ".0" # E.g "12" will not convert to a version type, "12.0" will + $Presets = @{ + All = @{ + general = @{ + shift_effects_bl = $false + achievements_bl = $false + compact_menu_bl = $true + modernKeybindHandling_bl = $true + borderless_fullscreen_bl = $true + trans_res_pack_menu_bg_bl = $true + } + mods = @{ + chat = @{ + options = @{ + chat_bg_opacity_nr = "0.0" + } + } + scoreboard = @{ + options = @{ + numbers_bl = $true + } + } + } + } + CouleursPreset = @{ + mods = @{ + scoreboard = @{ + seen = $True + x = 2 # Moves scoreboard 2 pixels to the right + } + potioneffects = @{ + seen = $True + position = 'bottom_left' + y = -246.5 # Middle left + } + saturation_hud_mod = @{ + seen = $True + saturation_hud_mod_enabled_bl = $True + position = 'bottom_right' # Just right to the last hunger bar + x = -289 + y = -37 + options = @{ + scale_nr = 1.5 # Yellow + text_clr_nr = @{value=-171} + background_clr_nr = @{value=0} + } + } + zoom = @{ + seen = $True + options = @{ + zoom_kblc = 'KEY_X' + } + } + bossbar = @{ + seen = $True + bossbar_enabled_bl = $False + } + } + } + Performance = @{ + general = @{ + friend_online_status_bl = $false + } + performance = @{ + lazy_chunk_loading = $LazyChunkLoadSpeed + ground_arrows_bl = $false + stuck_arrows_bl = $false + hide_skulls_bl = $true + hide_foliage_bl = $true + } + } + NoCosmetics = @{ + general = @{ + renderClothCloaks_bl = $false + render_cosmetic_particles_bl = $false + backpack_bl = $false + dragon_wings_bl = $false + pet_bl = $false + glasses_bl = $false + bandanna_bl = $false + mask_bl = $false + belts_bl = $false + neckwear_bl = $false + bodywear_bl = $false + hat_bl = $false + render_emotes_bl = $false + render_emote_particles_bl = $false + cloak_bl = $false + show_hat_above_helmet_bl = $false + show_over_chestplate_bl = $false + show_over_leggings_bl = $false + show_over_boots_bl = $false + scale_hat_with_skinlayer_bl = $false + } } - [Version]$LatestCoreVersion = $tag - - $Core = Get-VoukoderProgram -Name "Voukoder*" -ErrorAction Ignore | # Find all programs starting with Voukoder - Where-Object Name -NotLike "*Connector*" # Exclude connectors - - if ($Core){ - - if ($Core.Length -gt 1){ - $Core - Write-Host "Multiple Voukoder Cores detected (or bad parsing?)" -ForegroundColor Red - return + MinimalViewBobbing = @{ + general = @{ + minimal_viewbobbing_bl = $true } - - $CurrentVersion = [Version]$Core.Version - if ($LatestCoreVersion -gt $CurrentVersion){ # then an upgrade is needed - "Updating Voukoder Core from version $CurrentVersion to $LatestCoreVersion" - Start-Process -FilePath msiexec -ArgumentList "/qb /x {$($Core.TagId)}" -Wait -NoNewWindow - # Uses msiexec to uninstall the program - $Upgraded = $True + } + No16xSaturationOverlay = @{ + mods = @{ + saturation_mod = @{ + options = @{ + show_saturation_overlay_bl=$False + } + } } } - - if (!$Core -or $Upgraded){ - - $DriverVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{B2FE1952-0186-46C3-BAEC-A80AA35AC5B8}_Display.Driver" -ErrorAction Ignore).DisplayVersion - if ($DriverVersion -and $DriverVersion -lt 520.00){ # Oldest NVIDIA version capable - Write-Warning "Outdated NVIDIA Drivers detected ($DriverVersion), you may not be able to encode (render) using NVENC util you update them." - pause + HideToggleSprint = @{ + mods = @{ + toggleSneak = @{ + options = @{ + showHudText_bl = $false + } + } } - - "Downloading and installing Voukoder Core.." - $CoreURL = $LatestCore[0].assets[0].browser_download_url - curl.exe -# -L $CoreURL -o"$env:TMP\Voukoder-Core.msi" - msiexec /i "$env:TMP\Voukoder-Core.msi" /passive } - - filter ConnectorVer {$_.Trim('.msi').Trim('.zip').Split('-') | Select-Object -Last 1} - # .zip for Resolve's - - - # Following block generates a hashtable of all of the latest connectors - - $Tree = (Invoke-RestMethod 'https://api.github.com/repos/Vouk/voukoder-connectors/git/trees/master?recursive=1').Tree - # Gets all files from the connectors repo, which contain all filepaths - $Connectors = [Ordered]@{} - ForEach($NLE in 'vegas','vegas18','vegas19','vegas20','aftereffects','premiere','resolve'){ - # 'vegas' is for older versions - switch ($NLE){ - vegas{ - $Pattern = "*vegas-connector-*" - break # needs to stop here, otherwise it would overwrite it the next match + ToggleSneak = @{ + mods = @{ + toggleSneak = @{ + options = @{ + toggle_sneak_bl = $true + } } - {$_ -Like "vegas*"}{ - $Pattern = "*connector-$_*" + } + } + DisableUHCMods = @{ + mods = @{ + waypoints = @{ + waypoints_enabled_bl = $false } - default { - $Pattern = "*$NLE-connector*" + directionhud = @{ + directionhud_enabled_bl = $false + } + coords = @{ + coords_enabled_bl = $false + } + armorstatus = @{ + armorstatus_enabled_bl = $false + } + } + } + FullBright = @{ + mods = @{ + lighting = @{ + lighting_enabled_bl = $true + options = @{ + full_bright_bl = $true + } } } + } - $LCV = $Tree.path | # Short for LatestConnectorVersion - Where-Object {$_ -Like $Pattern} | # Find all versions of all matching connectors - ForEach-Object {[Version]($_ | ConnectorVer)} | # Parse it's version using the filter - Sort-Object -Descending | Select-Object -First 1 # Sort then select only the latest + } + # Whatever you do that's highly recommended :+1: + $general = Merge-Hashtables -Original $general -Patch $Presets.All.general + $mods = Merge-Hashtables -Original $mods -Patch $Presets.All.mods + Write-Diff "recommended settings (compact mods, fast chat).." -Positivity $True -Term "Setting up" - $Path = $Tree.path | Where-Object {$_ -Like "$Pattern*$LCV*.*"} # get the absolute path with the latest version - $Connectors += @{$NLE = "https://github.com/Vouk/voukoder-connectors/raw/master/$Path"} - Remove-Variable -Name NLE + if ('Performance' -in $Settings){ + $general = Merge-Hashtables -Original $general -Patch $Presets.Performance.general + $performance = Merge-Hashtables -Original $performance -Patch $Presets.Performance.performance + Write-Diff -Message "notifications from LC friends getting on (causes massive FPS drop)" + Write-Diff -Positivity $True -Message "lazy chunk loading at speed $LazyChunkLoadSpeed" + Write-Diff -Message "ground arrows" + Write-Diff -Message "player/mob skulls" + Write-Diff -Message "foliage (normal/tall grass)" + } + if ('NoCosmetics' -in $Settings){ + $general = Merge-Hashtables -Original $general -Patch $Presets.NoCosmetics.general + ForEach($CosmeticRemoved in @( + "cloth cloaks" + "cosmetic particles" + "backpacks" + "pets" + "dragon wings" + "bandannas" + "masks" + "belts" + "neckwears" + "bodywears" + "hats" + "emotes rendering" + "emote particles rendering" + "cloaks" + )){ + Write-Diff -Message $CosmeticRemoved -Term "Disabled" } - $Processes = @( - 'vegas*' - 'Adobe Premiere Pro' - 'AfterFX' - 'Resolve' - ) - - $Found = { Get-Process $Processes -ErrorAction Ignore } + } + if ('MinimalViewBobbing' -in $Settings){ + $general = Merge-Hashtables -Original $general -Patch $Presets.MinimalViewBobbing.general + Write-Diff -Positivity $True -Message "minimal view bobbing" + } + if ('No16xSaturationOverlay' -in $Settings){ + $mods = Merge-Hashtables -Original $mods -Patch $Presets.No16xSaturationOverlay.mods + Write-Diff -Positivity $False -Message "16x saturation hunger bar overlay" + } + if ('HideToggleSprint' -in $Settings){ + $mods = Merge-Hashtables -Original $mods -Patch $Presets.HideToggleSprint.mods + Write-Diff -Positivity $False -Term "Hid" -Message "ToggleSprint HUD" + } + if ('ToggleSneak' -in $Settings){ + $mods = Merge-Hashtables -Original $mods $Presets.ToggleSneak.mods + Write-Diff -Positivity $True -Message "ToggleSneak" + } + if ('DisableUHCMods' -in $Settings){ + $mods = Merge-Hashtables -Original $mods -Patch $Presets.DisableUHCMods.mods + Write-Diff -Positivity $False -Term "Disabled" -Message "Waypoints mod" + Write-Diff -Positivity $False -Term "Disabled" -Message "DirectionHUD mod" + Write-Diff -Positivity $False -Term "Disabled" -Message "Coordinates mod" + Write-Diff -Positivity $False -Term "Disabled" -Message "ArmorStatus mod" + } + if ('FullBright' -in $Settings){ + $mods = Merge-Hashtables -Original $mods -Patch $Presets.FullBright.mods + Write-Diff -Term "Added" -Positivity $true -Message "Fullbright (disable shaders before restarting)" + } + if ('CouleursPreset' -in $Settings){ + $mods = Merge-Hashtables -Original $mods -Patch $Presets.CouleursPreset.mods + } - if (-not (. $Found)){ # If $Found scriptblock returns nothing - Write-Host "[!] Open your video editor" -ForegroundColor Red - Write-Host "Voukoder supports: VEGAS 12-20, Premiere, After Effects, DaVinci Resolve (ONLY PAID `"Studio `"VERSION)" -ForeGroundColor Green - Write-Host "Looking for processes: $($Processes -join ', ')" -ForegroundColor DarkGray - While(-not (. $Found)){ - Start-Sleep -Seconds 1 - } + ForEach($file in 'general','mods','performance'){ # Assigns $general, $mods and $performance variables + if ($DryRun){ + Write-Host $file -ForegroundColor Red + (Get-Variable -Name $file).Value + }else{ + ConvertTo-Json -Depth 99 -Compress -InputObject (Get-Variable -Name $file).Value -ErrorAction Stop | Set-Content "$ProfileDir\$file.json" -ErrorAction Stop } - Write-Host @( - "`nDetected the following video editor(s):`n`n" - $(. $Found | Select-Object MainWindowTitle, Path, FileVersion | Out-String) - ) + } - function Get-Connector ($PackageName, $Key, $NLEDir, $InnoFlag){ - # Key is to get the right connector URL in $Connector hashtable - - function Install-Connector { - $msiPath = "$env:TMP\Voukoder Connector-$Key.msi" - curl.exe -# -L $Connectors.$Key -o"$msiPath" - Write-Verbose "Installing $msiPath at $InnoFlag=$NLEDir" -Verbose - msiexec /i "$msiPath" /qb "$InnoFlag=`"$NLEDir`"" - } +} +function Optimize-OBS { + <# + .SYNOPSIS + Display Name: Optimize OBS + Platform: Linux; Windows + Category: Optimizations - $CurrentConnector = (Get-VoukoderProgram -Name $PackageName) - if ($CurrentConnector){ - [Version]$CurrentConnectorVersion = $CurrentConnector.Version - [Version]$LatestConnector = $Connectors.$Key | ConnectorVer # Parse connector version - if ($LatestConnector -gt $CurrentConnectorVersion){ + .DESCRIPTION + Tune your OBS for a specific usecase in the snap of a finger! - Write-Host "Upgrading $PackageName from $CurrentConnectorVersion to $LatestConnector" - Start-Process -FilePath msiexec -ArgumentList "/qb /x {$($CurrentConnector.TagId)}" -Wait -NoNewWindow - Install-Connector - } - } else { + .PARAMETER Encoder + Which hardware type you wish to record with + NVENC: NVIDIA's Fastest encoder, it lets you record in hundreds of FPS easily + AMF: AMD GPUs/Integrated GPUs encoder, not as good as NVENC but can still get out ~240FPS at most + QuickSync: Intel's GPU encoder, worst out of the three, note this is H264, not the new fancy but slow AV1 + x264: Encoding using your CPU, slow but efficient, only use if necessary/you know what you're doing + + .PARAMETER OBS64Path + If you've got a portable install or something, pass in the main OBS binary's path here + + #> + [alias('optobs')] + param( + [ValidateSet('x264','NVENC','AMF','QuickSync')] + [String]$Encoder, + + [ValidateScript({Test-Path -Path $_ -PathType Leaf})] + [String]$OBS64Path, - Install-Connector - } - } - $NLEs = Get-Process $Processes -ErrorAction Ignore - ForEach($NLE in $NLEs){ + [ValidateSet('HighPerformance')] + [String]$Preset = 'HighPerformance', - switch ($NLE){ + [ValidateSet( + 'EnableStatsDock', 'OldDarkTheme')] + [Array]$MiscTweaks = (Invoke-CheckBox -Title "Select misc tweaks to apply" -Items ( + 'EnableStatsDock', 'OldDarkTheme')), - {(Split-Path $_.Path -Leaf) -in 'vegas180.exe', 'vegas190.exe','vegas200.exe'} { - Write-Verbose "Using newer VEGAS" + [ValidateScript({ Test-Path -Path $_ -PathType Container })] + [String]$OBSProfile = $null + ) - $VegVer = (Split-Path $_.Path -Leaf) -replace 'vegas' -replace '0\.exe' + if (!$Encoder){ + $Encoders = [Ordered]@{ + "NVENC (NVIDIA GPUs)" = "NVENC" + "AMF (AMD GPUs)" = "AMF" + "QuickSync (Intel iGPUs)" = "QuickSync" + "x264 (CPU)" = "x264" + } + Write-Host "Select what OBS will use to record (use arrow keys and press ENTER to confirm)" + $Key = Menu ([Collections.ArrayList]$Encoders.Keys) + $Encoder = $Encoders.$Key + } - Get-Connector -PackageName "Voukoder connector for VEGAS Pro $VegVer" -Key "vegas$VegVer" -NLEDir (Split-Path $_.Path -Parent) -InnoFlag VEGASDIR - - continue # Needs to loop over the next switch, which would've matched and also thought it needed to install an older Version + $OBSPatches = @{ + HighPerformance = @{ + NVENC = @{ + basic = @{ + AdvOut = @{ + RecEncoder = 'jim_nvenc' + } } - - - {(Split-Path $_.Path -Leaf) -Like 'vegas*.exe'}{ - Write-Host "/!\ Old-VEGAS connector installation may fail if you already have a connector for newer VEGAS versions" -ForegroundColor Red - Get-Connector -PackageName "Voukoder connector for VEGAS" -Key vegas -NLEDir (Split-Path $_.Path -Parent) -InnoFlag VEGASDIR + recordEncoder = @{ + bf=0 + cqp=18 + multipass='disabled' + preset2='p2' + profile='main' + psycho_aq='false' + rate_control='CQP' } - - - {(Split-Path $_.Path -Leaf) -eq 'afterfx.exe'} { - Get-Connector -PackageName 'Voukoder Connector for Adobe After Effects' -Key aftereffects -NLEDir "$env:ProgramFiles\Adobe\Common\Plug-ins\7.0\MediaCore" -InnoFlag INSTALLDIR + } + AMF = @{ + Basic = @{ + ADVOut = @{ + RecQuality='Small' + RecEncoder='h265_texture_amf' + FFOutputToFile='true' + } } - - - {(Split-Path $_.Path -Leaf) -eq 'Adobe Premiere Pro.exe'}{ - Get-Connector -PackageName 'Voukoder connector for Premiere' -Key premiere -NLEDir "$env:ProgramFiles\Adobe\Common\Plug-ins\7.0\MediaCore" -InnoFlag TGDir + recordEncoder = @{ + 'cqp' = 20 + preset = 'speed' + rate_control = 'CQP' + ffmpeg_opts = "MaxNumRefFrames=4 HighMotionQualityBoostEnable=1" } + } + QuickSync = @{ - - {(Split-Path $_.Path -Leaf) -eq 'Resolve.exe'}{ - Write-Warning "Voukoder's connector for Resolve is ONLY FOR IT'S PAID `"Studio`" VERSION" - pause - - $IOPlugins = "$env:ProgramData\Blackmagic Design\DaVinci Resolve\Support\IOPlugins" - $dvcpBundle = "$IOPlugins\voukoder_plugin.dvcp.bundle" - - if (-Not(Test-Path $IOPlugins)){ - New-Item -ItemType Directory -Path $IOPlugins + basic = @{ + AdvOut = @{ + RecEncoder = 'obs_qsv11' } - elseif (Test-Path $dvcpBundle){ - if (-Not(Get-Boolean "Would you like to reinstall/update the Voukoder Resolve plugin? (Y/N)")){continue} - Remove-Item $dvcpBundle -Force -Recurse + } + recordEncoder = @{ + enhancements = 'false' + target_usage = 'speed' + bframes = 0 + rate_control = 'ICQ' + bitrate = 16500 + icq_quality = 18 + keyint_sec = 2 + } + + } + x264 = @{ + basic = @{ + ADVOut = @{ + RecEncoder='obs_x264' } - - $Zip = "$env:TMP\Voukoder-Connector-Resolve.zip" - curl.exe -# -L $Connectors.Resolve -o"$Zip" - - $ExtractDir = "$env:TMP\Voukoder-Connector-Resolve" - Remove-Item $ExtractDir -Recurse -Force -ErrorAction Ignore - Expand-Archive $Zip -Destination $ExtractDir - - Copy-Item "$ExtractDir\voukoder_plugin.dvcp.bundle" $IOPlugins - - Write-Warning "If connection failed you should find instructions in $ExtractDir\README.txt" + } + recordEncoder = @{ + crf=1 + keyint_sec=1 + preset='ultrafast' + profile='high' + rate_control='CRF' + x264opts='qpmin=15 qpmax=15 ref=0 merange=4 direct=none weightp=0 no-chroma-me' } } } - $NLEBin = $NLE.Path - }else{ - $AvailableNLETemplates = @{ - "Vegas Pro" = "vegas200.exe" - "Premiere Pro" = "Adobe Premiere Pro.exe" - "After Effects" = "AfterFX.exe" - } - $NLE = Menu -menuItems $AvailableNLETemplates.Keys - $NLEBin = $AvailableNLETemplates.$NLE - } - - # Converts - # https://cdn.discordapp.com/attachments/969870701798522901/972541638578667540/HEVC_NVENC_Upscale.sft2 - # To hashtable with key "HEVC NVENC + Upscale" and val the URL - - filter File2Display { - [IO.Path]::GetFileNameWithoutExtension($_) -replace '_',' ' -replace " Upscale", " + Upscale" -replace ' ',' ' - } - - $VegasTemplates = @( - - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039599904873517106/HEVC_NVENC_Upscale.sft2' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039599905175502929/HEVC_NVENC.sft2' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039599904609288255/HEVC_NVENC__Upscale.sft2' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039599904353419284/H264_NVENC.sft2' - 'https://cdn.discordapp.com/attachments/969870701798522901/972541639346225264/x265_Upscale.sft2' - 'https://cdn.discordapp.com/attachments/969870701798522901/972541639560163348/x265.sft2' - 'https://cdn.discordapp.com/attachments/969870701798522901/972541638943596574/x264_Upscale.sft2' - 'https://cdn.discordapp.com/attachments/969870701798522901/972541639128129576/x264.sft2' - # 'https://cdn.discordapp.com/attachments/969870701798522901/972541638578667540/HEVC_NVENC_Upscale.sft2' - # 'https://cdn.discordapp.com/attachments/969870701798522901/972541638733885470/HEVC_NVENC.sft2' - # 'https://cdn.discordapp.com/attachments/969870701798522901/972541639744688198/H264_NVENC_Upscale.sft2' - # 'https://cdn.discordapp.com/attachments/969870701798522901/972541638356389918/H264_NVENC.sft2' - ) | ForEach-Object { - [Ordered]@{($_ | File2Display) = $_} } - $PremiereTemplates = @( - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609690025369690/HEVC_NVENC__Upscale.epr' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609690369298432/HEVC_NVENC.epr' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609691992498218/H264_NVENC__Upscale.epr' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609692277706902/H264_NVENC.epr' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609690688061490/x264__Upscale.epr' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609690964893706/x264.epr' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609691380125827/x265__Upscale.epr' - 'https://cdn.discordapp.com/attachments/1039599872703213648/1039609691682111548/x265.epr' - ) | ForEach-Object { - [Ordered]@{($_ | File2Display) = $_} - } - - switch($NLEBin){ - - {($NLEBin | Split-Path -Leaf).StartsWith('vegas')}{ - - $NLETerm = "Vegas" - $TemplatesFolder = "$env:APPDATA\VEGAS\Render Templates\voukoder" - - if (-Not(Test-Path $TemplatesFolder)){ - New-Item -ItemType Directory -Path $TemplatesFolder -Force | Out-Null + # Applies to all patches/presets + $Global = @{ + basic = @{ + Output = @{ + RecType='Standard' + Mode='Advanced' } - - $SelectedTemplates = Invoke-Checkbox -Items $VegasTemplates.Keys -Title "Select VEGAS render templates to install" - - ForEach ($Template in $SelectedTemplates){ - if (Test-Path ($TPPath = "$TemplatesFolder\$Template.sft2")){ - Remove-Item $TPPath -Force - } - curl.exe -# -sSL $VegasTemplates.$Template -o"$TPPath" + AdvOut = @{ + RecRB='true' } } + } + $OBSPatches.$Preset.$Encoder = Merge-Hashtables $OBSPatches.$Preset.$Encoder $Global + # Merge with global, which will be added for all + if (!$OBSProfile){ + Remove-Variable -Name OBSProfile + if (-Not($OBS64Path)){ - - {($NLEBin | Split-Path -Leaf).StartsWith('Adobe Premiere Pro.exe')}{ - - $NLETerm = 'Premiere Pro' - $TemplatesFolder = "$env:USERPROFILE\Documents\Adobe\Adobe Media Encoder\12.0\Presets" - - if (-Not(Test-Path $TemplatesFolder)){ - New-Item -ItemType Directory -Path $TemplatesFolder -Force | Out-Null + $Parameters = @{ + Path = @("$env:APPDATA\Microsoft\Windows\Start Menu","$env:ProgramData\Microsoft\Windows\Start Menu") + Recurse = $True + Include = 'OBS Studio*.lnk' } + $StartMenu = Get-ChildItem @Parameters + + if (!$StartMenu){ + if ((Get-Process obs64 -ErrorAction Ignore).Path){$OBS64Path = (Get-Process obs64).Path} # Won't work if OBS is ran as Admin + else{ + return @' +Your OBS installation could not be found, +please manually specify the path to your OBS64 executable, example: - $SelectedTemplates = Invoke-Checkbox -Items $PremiereTemplates.Keys -Title "Select render templates to install" +Optimize-OBS -OBS64Path "D:\obs\bin\64bit\obs64.exe" - ForEach ($Template in $SelectedTemplates){ - if (Test-Path ($TPPath = "$TemplatesFolder\$Template.epr")){ - Remove-Item $TPPath -Force +You can find it this way: +Search OBS -> Right click it +Open file location in Explorer -> +Open file location again if it's a shortcut -> +Shift right click obs64.exe -> Copy as path +'@ } - curl.exe -# -sSL $PremiereTemplates.$Template -o"$TPPath" } - - } - - - - - {($NLEBin | Split-Path -Leaf).StartsWith('AfterFX.exe')}{ - $NLETerm = 'After Effects' + if ($StartMenu.Count -gt 1){ - "Opening a tutorial in your browser and downloading the AE templates file.." - Start-Sleep -Seconds 2 - if (-Not(Test-Path ($TPDir = "$env:TMP\AE_Templates"))){ - New-Item -ItemType Directory -Path $TPDir -Force | Out-Null + $Shortcuts = $null + $StartMenu = Get-Item $StartMenu + ForEach($Lnk in $StartMenu){$Shortcuts += @{$Lnk.BaseName = $Lnk.FullName}} + "There are multiple OBS shortcuts in your Start Menu folder. Please select one." + $ShortcutName = menu ($Shortcuts.Keys -Split [System.Environment]::NewLine) + $StartMenu = $Shortcuts.$ShortcutName + $OBS64Path = Get-ShortcutTarget $StartMenu + }else{ + $OBS64Path = Get-ShortcutTarget $StartMenu } - curl.exe -# -sSL https://cdn.discordapp.com/attachments/1039599872703213648/1039614649638858772/CTT_AE_VOUKODER_TEMPLATES.aom -o"$TPDir\CTT_AE_VOUKODER_TEMPLATES.aom" - Start-Process -FilePath explorer.exe -ArgumentList "/select,`"$TPDir\CTT_AE_VOUKODER_TEMPLATES.aom`"" - $Tutorial = 'https://i.imgur.com/XCaJGoV.mp4' - try { - Start-Process $Tutorial - } catch { # If the user does not have any browser - "Tutorial URL: $Tutorial" - } } + if (!$IsLinux -or !$IsMacOS){ + [Version]$CurVer = (Get-Item $OBS64Path).VersionInfo.ProductVersion + if ($CurVer -lt [Version]"28.1.0"){ + Write-Warning @" +It is strongly advised you update OBS before continuing (for compatibility with new NVENC/AMD settings) - - default{ - Write-Host "Your video editor ($($NLEBin)) does not have any pre-made templates for me to propose you" -ForegroundColor Red - $NLETerm = "your video editor" +Detected version: $CurVer +obs64.exe path: $OBS64Path +pause +"@ + } } - } - Write-Host "Installation script finished, follow instructions (if any)" - Write-Host "Then restart $NLETerm to make sure Voukoder render templates have loaded." -ForegroundColor Red -} + Set-CompatibilitySettings $OBS64Path -RunAsAdmin -function Invoke-SmoothiePost { - param( - [String] - [ValidateScript({ - Test-Path -Path (Get-Item $_) -PathType Container -ErrorAction Stop - })] - $CustomDir - ) - # DIR is the variable used by Scoop, hence why I'm using a separate name - if ($CustomDir -and !$DIR){ - if (!(Test-Path "$CustomDir\Smoothie") -And !(Test-Path "$CustomDir\VapourSynth")){ - Write-Host "The folder you gave needs to contain the folders 'Smoothie' and 'VapourSynth', try the right path" + if (Resolve-Path "$OBS64Path\..\..\..\portable_mode.txt" -ErrorAction Ignore){ # "Portable Mode" makes OBS make the config in it's own folder, else it's in appdata + + $ProfilesDir = (Resolve-Path "$OBS64Path\..\..\..\config\obs-studio\basic\profiles" -ErrorAction Stop) }else{ - $DIR = (Get-Item $CustomDir).FullName + $ProfilesDir = (Resolve-Path "$env:APPDATA\obs-studio\basic\profiles" -ErrorAction Stop) } - } - if (!$DIR){return "This script is suppose to be ran by Scoop after it's intallation, not manually"} - - $rc = (Get-Content "$DIR\Smoothie\settings\recipe.yaml" -ErrorAction Stop) -replace ('H264 CPU',(Get-EncodingArgs -EzEncArgs)) - - if ($valid_args -like "H* CPU"){$rc = $rc -replace ('gpu: true','gpu: false')} - - Set-Content "$DIR\Smoothie\settings\recipe.ini" -Value $rc - - $term = Get-Path conhost.exe + $Profiles = Get-ChildItem $ProfilesDir - Get Scoop + ForEach($OBSProfile in $Profiles){$ProfilesHash += @{$OBSProfile.Name = $OBSProfile.FullName}} - $SendTo = [System.Environment]::GetFolderPath('SendTo') - $Scoop = Get-Command Scoop | Split-Path | Split-Path - $SA = [System.IO.Path]::Combine([Environment]::GetFolderPath('StartMenu'), 'Programs', 'Scoop Apps') + $ProfileNames = ($ProfilesHash.Keys -Split [System.Environment]::NewLine) + 'Create a new profile' + "Please select a profile (use arrow keys to navigate, ENTER to select)" + $OBSProfile = menu $ProfileNames - if (-Not(Test-Path $SA)){ # If not using Scoop - $SA = [System.IO.Path]::Combine([Environment]::GetFolderPath('StartMenu'), 'Programs') - } + if ($OBSProfile -eq 'Create a new profile'){ + $NewProfileName = Read-Host "Enter a name for the new profile" + $OBSProfile = Join-Path $ProfilesDir $NewProfileName + New-Item -ItemType Directory -Path $OBSProfile -ErrorAction Stop + $DefaultWidth, $DefaultHeight = ((Get-CimInstance Win32_VideoController).VideoModeDescription.Split(' x ') | Where-Object {$_ -ne ''} | Select-Object -First 2) + if (!$DefaultWidth -or !$DefaultHeight){ + $DefaultWidth = 1920 + $DefaultHeight = 1080 + } + Set-Content "$OBSProfile\basic.ini" -Value @" +[General] +Name=$NewProfileName - Set-Content "$Scoop\shims\sm.shim" -Value @" -path = "$DIR\VapourSynth\python.exe" -args = "$DIR\Smoothie\src\main.py" +[Video] +BaseCX=$DefaultWidth +BaseCY=$DefaultHeight +OutputCX=$DefaultWidth +OutputCY=$DefaultHeight "@ - if (-Not(Test-Path "$Scoop\shims\sm.exe")){ - Copy-Item "$Scoop\shims\7z.exe" "$Scoop\shims\sm.exe" - } - - - $Parameters = @{ - Overwrite = $True - LnkPath = "$Scoop\shims\rc.lnk" - TargetPath = "$DIR\Smoothie\settings\recipe.yaml" + Write-Host "Created new profile '$NewProfileName' with default resolution of $DefaultWidth`x$DefaultHeight" -ForegroundColor DarkGray + }else{ + $OBSProfile = $ProfilesHash.$OBSProfile + } } - New-Shortcut @Parameters - - - $Parameters = @{ - Overwrite = $True - LnkPath = "$SA\Smoothie Recipe.lnk" - TargetPath = "$DIR\Smoothie\settings\recipe.yaml" + if ('basic.ini' -notin ((Get-ChildItem $OBSProfile).Name)){ + return "FATAL: Profile $OBSProfile is incomplete (missing basic.ini)" } - New-Shortcut @Parameters - - $Parameters = @{ - Overwrite = $True - LnkPath = "$SA\Smoothie.lnk" - TargetPath = $term - Arguments = "`"$DIR\VapourSynth\python.exe`" `"$DIR\Smoothie\src\main.py`" -cui" - Icon = "$DIR\Smoothie\src\sm.ico" + Write-Verbose "Tweaking profile $OBSProfile" + try { + $Basic = Get-IniContent "$OBSProfile\basic.ini" -ErrorAction Stop + } catch { + Write-Warning "Failed to get basic.ini from profile folder $OBSProfile" + $_ + return } - New-Shortcut @Parameters - - $Parameters = @{ - Overwrite = $True - LnkPath = "$SendTo\Smoothie.lnk" - TargetPath = $term - Arguments = "`"$DIR\VapourSynth\python.exe`" `"$DIR\Smoothie\src\main.py`" -cui -input" - Icon = "$DIR\Smoothie\src\sm.ico" + if ($Basic.Video.FPSType -ne 2){ # then switch to fractional FPS + $FPS=$Basic.Video.FPSCommon + $Basic.Video.FPSType = 2 + $Basic.Video.FPSNum = 60 + $Basic.Video.FPSDen = 1 + Write-Warning "Your FPS is at the default (60), you can go in Settings -> Video to set it to a higher value" } - New-Shortcut @Parameters - -} - -# This does not install Smoothie, it simply creates shortcuts in the start menu, Send To and configures the recipe -function Invoke-SmoothieRsPost { - param( - - [ValidateScript({ - Test-Path -Path (Get-Item $_) -PathType Container -ErrorAction Stop - })] - [String]$DIR, - [Switch]$Scoop, - [Switch]$Uninstall - ) - $ErrorActionPreference = 'Stop' + $FPS = $Basic.Video.FPSNum/$Basic.Video.FPSDen + $Pixels = [int]$Basic.Video.BaseCX*[int]$Basic.Video.BaseCY - <# - .SYNOPSIS - Merges recipes + if (($Basic.AdvOut.RecTracks -NotIn '1','2') -And ($FPS -gt 120)){ + Write-Warning "Using multiple audio tracks while recording at a high FPS may cause OBS to fail to stop recording" + } - .NOTES - It returns void, it just applies all patches on what was passed to -Original + if (!$Basic.Hotkeys.ReplayBuffer){ + Write-Warning "Replay Buffer is enabled, but there's no hotkey to Save Replay, set it up in Settings -> Hotkeys" + } - .NOTES - Limitations: - - It cannot remove keys from $OG, most it can do is Patch containing a same key that is $null + $Basic = Merge-Hashtables -Original $Basic -Patch $OBSPatches.$Preset.$Encoder.basic -ErrorAction Stop + Out-IniFile -FilePath "$OBSProfile\basic.ini" -InputObject $Basic -Pretty -Force - .PARAMETER Original - The original hashtable which will get modified - .PARAMETER Patches - Recursively merge with $Original - #> - function Merge-Recipe { - [CmdletBinding()] - param ( - $Original, - $Patch - ) - foreach ($category in $Patch.GetEnumerator()) { - - $key, $patch = $category.name, $category.value + if ($Basic.Video.BaseCX -and $Basic.Video.BaseCY -and $Basic.Video.OutputCX -and $Basic.Video.OutputCY){ - if ($Original.Contains($key) -and ($Original[$key] -is [Collections.Specialized.OrderedDictionary] -and $Patch -is [Collections.Specialized.OrderedDictionary])) { - Merge-Recipe -Original $Original[$key] -Patch $Patch - } - else { - $Original[$key] = $Patch - } - } + $Base = "{0}x{1}" -f $Basic.Video.BaseCX,$Basic.Video.BaseCY + $Output = "{0}x{1}" -f $Basic.Video.OutputCX,$Basic.Video.OutputCY + if ($Base -Ne $Output){ + Write-Warning "Your Base/Canvas resolution ($Base) is not the same as the Output/Scaled resolution ($Output),`nthis means OBS is scaling your video. This is not recommended." + } } - $SendTo = [System.Environment]::GetFolderPath('SendTo') - $Start = [System.IO.Path]::Combine([Environment]::GetFolderPath('StartMenu'), 'Programs') + $NoEncSettings = -Not(Test-Path "$OBSProfile\recordEncoder.json") + $EmptyEncSettings = (Get-Content "$OBSProfile\recordEncoder.json" -ErrorAction Ignore) -in '',$null - if (!$SendTo -or !(Test-Path $SendTo)) { - return "FATAL: Send To folder [$SendTo] does not exist, did you/a script strip it?" - } - if (!$Start -or !(Test-Path $Start)) { - return "FATAL: Start Menu folder [$Start] does not exist, did you/a script strip it?" + if ($NoEncSettings -or $EmptyEncSettings){ + Set-Content -Path "$OBSProfile\recordEncoder.json" -Value '{}' -Force } + $RecordEncoder = Get-Content "$OBSProfile\recordEncoder.json" | ConvertFrom-Json -ErrorAction Stop - if ($Scoop){ - $shims = (Resolve-Path $DIR/../../../shims).Path + if (($Basic.Video.FPSNum/$Basic.Video.FPSDen -gt 480) -And ($Pixels -ge 2073600)){ # Set profile to baseline if recording at a high FPS and if res +> 2MP + $RecordEncoder.Profile = 'baseline' } - - if ($Uninstall) { - Remove-Item "$Sendto\Smoothie.lnk" - Remove-Item "$SA\Smoothie.lnk" - if ($Scoop) { - Remove-Item "$shims\rc.lnk" - } - return + $RecordEncoder = Merge-Hashtables -Original $RecordEncoder -Patch $OBSPatches.$Preset.$Encoder.recordEncoder -ErrorAction Stop + if ($Verbose){ + ConvertTo-Yaml $Basic + ConvertTo-Yaml $RecordEncoder } + Set-Content -Path "$OBSProfile\recordEncoder.json" -Value (ConvertTo-Json -InputObject $RecordEncoder -Depth 100) -Force - if ($Scoop) { - $old_VERSIONS = Get-ChildItem $dir/.. -Directory -Exclude current, $version - $old_DIR = switch ($old_VERSIONS.Length) { - { $_ -in 0, $null } {} - 1 { $old_VERSIONS } - default { - $script:ret = "" - $script:mostRecentDate = [datetime]::MinValue - - $old_VERSIONS | ForEach-Object { - $string = $_.BaseName -replace "Nightly_" - $datetime = [datetime]::ParseExact($string, "yyyy.MM.dd_HH-mm", [CultureInfo]::InvariantCulture) - - if ($datetime -gt $script:mostRecentDate) { - $script:mostRecentDate = $datetime - $script:ret = $_ - } - } + if ($True -in [bool]$MiscTweaks){ # If there is anything in $MiscTweaks + $global = Get-Item (Join-Path ($OBSProfile | Split-Path | Split-Path | Split-Path) -ChildPath 'global.ini') -ErrorAction Stop + $glob = Get-IniContent -FilePath $global - if ($script:mostRecentDate -eq [datetime]::MinValue) { - write-Warning "Failed to parse old versions:" - Write-Host $old_VERSIONS.FullName - } + if ('OldDarkTheme' -in $MiscTweaks){ + $glob.General.CurrentTheme3 = 'Dark' + } - $script:ret - } + if ('OldDarkTheme' -in $MiscTweaks){ + + $glob.BasicWindow.geometry = 'AdnQywADAAAAAAe/////uwAADJ0AAAKCAAAHv////9oAAAydAAACggAAAAEAAAAACgAAAAe/////2gAADJ0AAAKC' + $glob.BasicWindow.DockState = 'AAAA/wAAAAD9AAAAAgAAAAAAAAJOAAABvPwCAAAAAfsAAAASAHMAdABhAHQAcwBEAG8AYwBrAQAAABYAAAG8AAAA5gD///8AAAADAAAE3wAAALr8AQAAAAX7AAAAFABzAGMAZQBuAGUAcwBEAG8AYwBrAQAAAAAAAAD4AAAAoAD////7AAAAFgBzAG8AdQByAGMAZQBzAEQAbwBjAGsBAAAA/AAAAPoAAACgAP////sAAAASAG0AaQB4AGUAcgBEAG8AYwBrAQAAAfoAAAFBAAAA3gD////7AAAAHgB0AHIAYQBuAHMAaQB0AGkAbwBuAHMARABvAGMAawEAAAM/AAAAtAAAAI4A////+wAAABgAYwBvAG4AdAByAG8AbABzAEQAbwBjAGsBAAAD9wAAAOgAAACeAP///wAAAo0AAAG8AAAABAAAAAQAAAAIAAAACPwAAAAA' } - if ($old_DIR -and (Test-Path $old_DIR)) { + $glob | Out-IniFile -FilePath $global -Force + } + Write-Host "Finished patching OBS, yay! Please switch profiles or reload OBS to see changes" -ForegroundColor Green +} +function Optimize-OptiFine { + [alias('optof')] + param( + [ValidateSet('Smart','Lowest','CouleursPreset')] + [Parameter(Mandatory)] + $Preset, + [String]$CustomDirectory = (Join-path $env:APPDATA '.minecraft'), + [Switch]$MultiMC, + [Switch]$PolyMC, + [Switch]$GDLauncher + ) - [Collections.Specialized.OrderedDictionary]$old_MACROS = Get-IniContent $old_DIR/encoding_presets.ini -KeyValSeparator ':' - [Collections.Specialized.OrderedDictionary]$new_MACROS = Get-IniContent $DIR/encoding_presets.ini -KeyValSeparator ':' - - Merge-Recipe $new_MACROS $old_MACROS - $new_MACROS | Out-IniFile $DIR/encoding_presets.ini -Pretty -Force -Loose -KeyValSeparator ':' +if($MultiMC){ + $CustomDirectory = Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs" -Recurse | Where-Object Name -Like "MultiMC.lnk" + $CustomDirectory = Get-ShortcutPath $CustomDirectory + $Instances = Get-ChildItem (Join-Path (Split-Path $CustomDirectory) instances) + "Please select a MultiMC instance" + $CustomDirectory = menu (Get-ChildItem $Instances).Name + $CustomDirectory = Join-Path $Instances $CustomDirectory - $old_RECIPES = Get-ChildItem $old_DIR -File -Filter *.ini | Where-Object BaseName -Notin 'defaults', 'encoding_presets' +}elseif($PolyMC){ + $Instances = Get-ChildItem "$env:APPDATA\PolyMC\instances" + "Please select a PolyMC instance" + $CustomDirectory = menu $Instances.Name + $CustomDirectory = Join-Path $Instances $CustomDirectory - $old_RECIPES | ForEach-Object { - [Collections.Specialized.OrderedDictionary]$old_RC = Get-IniContent $_.FullName -KeyValSeparator ':' - [Collections.Specialized.OrderedDictionary]$new_RC = Get-IniContent $DIR\recipe.ini -KeyValSeparator ':' - - Merge-Recipe $new_RC $old_RC - $new_RC | Out-IniFile $DIR/$($_.BaseName).ini -Pretty -Force -Loose -KeyValSeparator ':' - } - $old_files = Get-ChildItem $old_DIR | Where-Object Name -notin 'defaults.ini', 'encoding_presets.ini', 'jamba.vpy', 'bin', 'recipe.ini', 'launch.cmd', 'manifest.json', 'install.json' +}elseif($GDLauncher){ + $Instances = Get-ChildItem "$env:APPDATA\gdlauncher_next\instances" + "Please select a GDLauncher instance" + $CustomDirectory = menu $Instances.Name + $CustomDirectory = Join-Path $Instances $CustomDirectory - $old_files | ForEach-Object { Move-Item $_.FullName $DIR -Verbose } +} +$Presets = @{ + + CouleursPresets = @{ + options = @{ + 'key_key.hotbar.5' = 19 + 'key_key.hotbar.6' = 20 + 'key_key.hotbar.7' = 33 + 'key_key.hotbar.8' = 34 + 'key_key.hotbar.9' = 0 + chatScale = 0.8 + chatWidth = 0.65 + guiScale = 3 + renderDistance = 7 + maxFps = 260 + chatOpacity = 0.25 + enableVsync = $False + pauseOnLostFocus = $False } } - $SendTo = [System.Environment]::GetFolderPath('SendTo') - $Start = [System.IO.Path]::Combine([Environment]::GetFolderPath('StartMenu'), 'Programs') - . { # Shortcuts - if (!$SendTo -or !(Test-Path $SendTo)) { - return "FATAL: Send To folder [$SendTo] does not exist, did you/a script strip it?" - } - if (!$Start -or !(Test-Path $Start)) { - return "FATAL: Start Menu folder [$Start] does not exist, did you/a script strip it?" + Smart = @{ + options = @{ + renderDistance=5 + mipmapLevels=4 + ofAoLevel=1.0 } - - # %APPDATA%\Microsoft\Windows\SendTo\Smoothie.lnk - $Parameters = @{ - Overwrite = $True - LnkPath = "$SendTo\&Smoothie.lnk" - TargetPath = "$DIR\bin\smoothie-rs.exe" - Arguments = "--tui -i" + optionsof = @{ + ofMipmapType=3 + ofCustomSky=$true } - New-Shortcut @Parameters + } - if ($Scoop) { - - # %USERPROFILE%\scoop\shims\rc.lnk - $Parameters = @{ - Overwrite = $True - LnkPath = "$shims\rc.lnk" - TargetPath = "$dir\recipe.ini" - } - New-Shortcut @Parameters + Lowest = @{ + options = @{ + gamma=1000000 # I've never tried anything else and this always worked + renderDistance=2 + particles=2 + fboEnable=$true + useVbo=$true + showInventoryAchievementHint=$false } - else { - # %APPDATA%\Microsoft\Windows\Start Menu\Programs\Smoothie Recipe.lnk - $Parameters = @{ - Overwrite = $True - LnkPath = "$Start\Smoothie Recipe.lnk" - TargetPath = "$DIR\recipe.ini" - } - # %APPDATA%\Microsoft\Windows\Start Menu\Programs\Smoothie.lnk - New-Shortcut @Parameters - $Parameters = @{ - Overwrite = $True - LnkPath = "$Start\Smoothie.lnk" - TargetPath = "$DIR\bin\smoothie-rs.exe" - Arguments = "--tui -i" - } - New-Shortcut @Parameters + optionsof = @{ + ofAaLevel=0 # Anti-Aliasing + ofDynamicLights=3 + ofChunkUpdates=1 + ofAoLevel=0.0 # Smooth lighting + ofOcclusionFancy=$false + ofSmoothWorld=$true + ofClouds=3 + ofTrees=1 + ofDroppedItems=0 + ofRain=3 + ofAnimatedWater=2 + ofAnimatedLava=2 + ofAnimatedFire=$true + ofAnimatedPortal=$false + ofAnimatedRedstone=$false + ofAnimatedExplosion=$false + ofAnimatedFlame=$true + ofAnimatedSmoke=$false + ofVoidParticles=$false + ofWaterParticles=$false + ofPortalParticles=$false + ofPotionParticles=$false + ofFireworkParticles=$false + ofDrippingWaterLava=$false + ofAnimatedTerrain=$false + ofAnimatedTextures=$false + ofRainSplash=$false + ofSky=$false + ofStars=$false + ofSunMoon=$false + ofVignette=1 + ofCustomSky=$false + ofShowCapes=$false + ofFastMath=$true + ofSmoothFps=$false + ofTranslucentBlocks=1 } } - } -function Launch{ - [alias('l')] - param( - [ValidateSet( - 'DisplayDriverUninstaller', - 'NVCleanstall', - 'NvidiaProfileInspector', - 'MSIUtilityV3', - 'Rufus', - 'AutoRuns', - 'Procmon', - 'CustomResolutionUtility', - 'NotepadReplacer', - 'privacy.sexy', - 'ReShade' - #! TODO: NVProfileInspector, MSIUtility, CRU, Notepadreplacer, BulkCrapUninstaller, https://www.bill2-software.com/processmanager/exe/BPM-Setup.exe - )] - [Array]$Apps, - [Switch]$DontLaunch, # Just keep them tidy in the Downloads folder)) - # This is the non hardcoded Downloads folder path s/o @farag2 - [String]$OutDir = (Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{374DE290-123F-4565-9164-39C4925E467B}") - ) - - Add-Type -AssemblyName System.IO.Compression.FileSystem - - function Invoke-Download{ - param( - [String]$URL, # Parses mediafire - [String]$AppName, - [Switch]$Scoop, # Scoop 'bucket/manifest' name - [String]$PathToBinary, # In the zip - [String]$Checksum, - [String]$SelfExtracting7z # e.g for DDU - ) - - if (-Not(Test-Path $env:TMP)){ - throw "TMP environment variable not found [$env:TMP]" - } - - if($Scoop){ - $Bucket, $Manifest = $URL -split '/' - - $Repos = @{ +$Global = @{ + optionsof = @{ + ofFastRender=$true + ofClouds=3 + ofAfLevel=1 # Anisotropic filtering + ofAaLevel=0 # Anti-aliasing + ofRainSplash=$false + } + options = @{ + showInventoryAchievementHint=$false + maxFps=260 + renderClouds=$false + useVbo=$true + } +} +$Presets.$Preset = Merge-Hashtables $Presets.$Preset $Global - main = @{org = 'ScoopInstaller';repo = 'main';branch = 'master'} - extras = @{org = 'ScoopInstaller';repo = 'extras';branch = 'master'} - utils = @{org = 'couleur-tweak-tips';repo = 'utils';branch = 'main'} - nirsoft = @{org = 'kodybrown';repo = 'scoop-nirsoft';branch = 'master'} - games = @{org = 'ScoopInstaller';repo = 'games';branch = 'master'} - 'nerd-fonts' = @{org = 'ScoopInstaller';repo = 'nerd-fonts';branch = 'master'} - versions = @{org = 'ScoopInstaller';repo = 'versions';branch = 'master'} - java = @{org = 'ScoopInstaller';repo = 'java';branch = 'master'} - } - $repo = $Repos.$Bucket - $URL = "https://raw.githubusercontent.com/$($repo.org)/$($repo.repo)/$($repo.branch)/bucket/$Manifest.json" - $URL, $Version = Invoke-RestMethod $URL | ForEach-Object {$PSItem.URL, $PSItem.Version} - }elseif($URL -Like "*mediafire.com*"){ - $URL = (Invoke-WebRequest -UseBasicParsing $URL).Links.href | Where-Object {$PSItem -Like "http*://download*.mediafire.com/*"} - } +function ConvertTo-MCSetting ($table){ - if ($AppName){ - $FileName = $AppName - }else{ - $FileName = $Manifest - } - - if ($Version){$FileName += " $Version"} + $file = @() + ForEach($setting in $table.keys){ + $file += [String]$($setting + ':' + ($table.$setting)) -replace'True','true' -replace 'False','false' + } + return $file +} - $Extension = [io.path]::GetExtension((($URL -replace '#/dl.7z') | Split-Path -Leaf)) +foreach ($file in 'options','optionsof'){ - $OutFile = "$env:TMP\$FileName$Extension" - if (-Not(Test-Path $OutFile)){ - curl.exe -#L -A "Scoop" $URL -o"$OutFile" - } + $Hash = (Get-Content "$CustomDirectory\$file.txt") -Replace ':','=' | ConvertFrom-StringData + $Hash = Merge-Hashtables -Original $Hash -Patch $Presets.$Preset.$file + Set-Content "$CustomDirectory\$file.txt" -Value (ConvertTo-MCSetting $Hash) -Force +} +if (Test-Path "$CustomDirectory\optionsLC.txt"){ + $Hash = (Get-Content "$CustomDirectory\optionsLC.txt") -Replace ',"maxFps":"260"','' | ConvertFrom-Json +} +$Hash = Merge-Hashtables -Original $Hash -Patch $Presets.$Preset.optionsof +$Hash = Merge-Hashtables -Original $Hash -Patch $Presets.$Preset.options +$Hash.maxFPS = 260 +Set-Content "$CustomDirectory\optionsLC.txt" -Value (ConvertTo-Json $Hash) -Force - if($Checksum){ - $Parameters = @{ - Path = $OutFile - } - if ($Checksum -Like "*:*"){ # Contains a : - $Algo, $Checksum = $Checksum -Split ':' # To split hash and algo, eg md5:8424509737CEDBDE4BA9E9A780D5CE96 - $Parameters += @{ - Algorithm = $Algo - } - } - if ($Checksum -ne (Get-FileHash @Parameters).Hash){ - throw "Hash provided $Checksum does not match $OutFile" - } - } +} +<# - if ($Extension -eq '.zip'){ - $OutDir = "$env:TMP\$FileName\" - if (-Not(Test-Path $OutDir)){ - [System.IO.Compression.ZipFile]::ExtractToDirectory($OutFile, $OutDir) - } +List of commonly used Appx packages: - if ($PathToBinary){ - $OutDir = Join-Path $OutDir $PathToBinary - } - $OutFile = $OutDir # To not have to check for the following statement twice - }elseif($SelfExtracting7z){ - Start-Process -FilePath $OutFile -ArgumentList "-y" -Wait - $SelfExtracting7z = $SelfExtracting7z -replace "%VER%", $Version - if (-Not(Test-Path "$env:TMP\$SelfExtracting7z" -PathType Container)){ - throw "Self extracting 7-Zip got wrong path: $SelfExtracting7z" - } - $OutDir = $SelfExtracting7z - } +Windows.PrintDialog +Microsoft.WindowsCalculator +Microsoft.ZuneVideo +Microsoft.Windows.Photos - if (-Not(Test-Path $OutFile)){ - throw "$OutFile could not be found" - } +I did not add them, but you can opt in by calling the function, e.g: - return $OutFile + Remove-KnownAppxPackages -Add @('Windows.PrintDialog','Microsoft.WindowsCalculator') - } +Don't forget to surround them by a ' so PowerShell considers them as a string - $Paths = @() +#> - $Apps | ForEach-Object { # Cycles through given apps - Write-Host "getting $PSItem" - $Paths += switch ($PSItem){ - DisplayDriverUninstaller{ Invoke-Download -URL extras/ddu -Scoop -PathToBinary "Display Driver Uninstaller.exe" -SelfExtracting7z "DDU v%VER%" -AppName DDU } - NVCleanstall{ Invoke-Download -URL extras/nvcleanstall -Scoop -AppName NVCleanstall -PathToBinary "NVCleanstall.exe" } - NvidiaProfileInspector{ Invoke-Download -URL extras/nvidia-profile-inspector -Scoop -AppName NvidiaProfileInspector -PathToBinary 'nvidiaProfileInspector.exe' } - MSIUtilityV3{ - Write-Warning "MSI mode is already applied by default on NVIDIA 1600/2000/3000 GPUs and AMD cards" - Invoke-Download -URL https://www.mediafire.com/file/ewpy1p0rr132thk/MSI_util_v3.zip/file -AppName "MSIUtilV3" -PathToBinary "MSI_util_v3.exe" -Checksum "md5:8424509737CEDBDE4BA9E9A780D5CE96" - } - Rufus{ Invoke-Download -URL extras/rufus -Scoop -AppName rufus} - AutoRuns{ Invoke-Download -URL https://download.sysinternals.com/files/Autoruns.zip -AppName AutoRuns -PathToBinary Autoruns64.exe } - Procmon{ Invoke-Download -URL https://download.sysinternals.com/files/ProcessMonitor.zip -AppName Procmon -PathToBinary Procmon64.exe } - CustomResolutionUtility { Invoke-Download -URL extras/cru -Scoop -AppName CRU -PathToBinary CRU.exe} - NotepadReplacer { Invoke-Download -URL utils/notepadreplacer -Scoop -AppName NotepadReplacer} - privacy.sexy { Invoke-Download -URL utils/privacysexy -Scoop -AppName privacysexy} - ReShade{ - $Website = "https://reshade.me/" - $DLLink = (Invoke-WebRequest "$Website#download").Links.Href | Where-Object {$_ -Like "*.exe"} | Where-Object {$_ -NotLike "*_Addon.exe"} - $URL = $Website + $DLLink - Invoke-Download -URL $URL -AppName ReShade - } - } - } - return $Paths -} -# Source: https://github.com/Aetopia/Install-NVCPL -function Install-NVCPL { - if (!(Test-Admin)) { - Write-Host "Install-NVCPL: This function needs Administrator priviledges" -ForegroundColor DarkRed - return - } +function Remove-KnownAppxPackages ([array]$Add,[array]$Exclude) { - choice.exe /C 12 /N /M "Install NVIDIA Control Panel as:`n1. Win32 App`n2. UWP App`n>" - - $NVCPL = "$ENV:TEMP\NVCPL.zip" - $InstallationDirectory = "$ENV:PROGRAMFILES\NVIDIA Corporation\Control Panel Client" - $ShortcutFile = "$ENV:PROGRAMDATA\Microsoft\Windows\Start Menu\Programs\NVIDIA Control Panel.lnk" - if ($LASTEXITCODE -eq 2) { $NVCPL = "$NVCPL.appx" } + $AppxPackages = @( + "Microsoft.Windows.NarratorQuickStart" + "Microsoft.Wallet" + "3DBuilder" + "Microsoft.Microsoft3DViewer" + "WindowsAlarms" + "BingSports" + "WindowsCommunicationsapps" + "WindowsCamera" + "Feedback" + "Microsoft.GetHelp" + "GetStarted" + "ZuneMusic" + "WindowsMaps" + "Microsoft.Messaging" + "Microsoft.MixedReality.Portal" + "Microsoft.OneConnect" + "BingFinance" + "Microsoft.MSPaint" + "People" + "WindowsPhone" + "Microsoft.YourPhone" + "Microsoft.Print3D" + "Microsoft.ScreenSketch" + "Microsoft.MicrosoftStickyNotes" + "SoundRecorder" + + ) | Where-Object { $_ -notin $Exclude } - if ($null -eq (Get-CimInstance Win32_VideoController | - Where-Object { $_.Name -like "NVIDIA*" })) { - Write-Host "No NVIDIA GPU found." -ForegroundColor DarkRed - return + $AppxPackages += $Add # Appends the Appx packages given by the user (if any) + + if (-Not($KeepXboxPackages)){ + $AppxPackages += @( + "XboxApp" + "Microsoft.XboxGameOverlay" + "Microsoft.XboxGamingOverlay" + "Microsoft.XboxSpeechToTextOverlay" + "Microsoft.XboxIdentityProvider" + "Microsoft.XboxGameCallableUI" + ) } + + ForEach ($Package in $AppxPackages){ - # Disable Telemetry. - New-ItemProperty -Path "HKLM:\SOFTWARE\NVIDIA Corporation\NvControlPanel2\Client" -Name "OptInOrOutPreference" -Value 0 -PropertyType DWORD -Force -ErrorAction SilentlyContinue | Out-Null - New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm\Global\Startup" -Name "SendTelemetryData" -Value 0 -PropertyType DWORD -Force -ErrorAction SilentlyContinue | Out-Null + if ($PSVersionTable.PSEdition -eq 'Core'){ # Newer PowerShell versions don't have Appx cmdlets, manually calling PowerShell to + + powershell.exe -command "Get-AppxPackage `"*$Package*`" | Remove-AppxPackage" + + }else{ + Get-AppxPackage "*$Package*" | Remove-AppxPackage + } + + } + +} + +function Remove-UselessFiles { - # Using rg-adguard to fetch the latest version of the NVIDIA Control Panel. - $Body = @{ - type = 'url' - url = "https://apps.microsoft.com/store/detail/nvidia-control-panel/9NF8H0H7WMLT" - ring = 'RP' - lang = 'en-US' - } - Write-Output "Getting the latest version of the NVIDIA Control Panel from the Microsoft Store..." - $Link = ((Invoke-RestMethod -Method Post -Uri "https://store.rg-adguard.net/api/GetFiles" -ContentType "application/x-www-form-urlencoded" -Body $Body) -Split "`n" | - ForEach-Object { $_.Trim() } | - Where-Object { $_ -like ("*http://tlu.dl.delivery.mp.microsoft.com*") } | - ForEach-Object { ((($_ -split "", 2, "SimpleMatch")[1] -Split "rel=", 2, "SimpleMatch")[0] -Split "