Skip to content

Instantly share code, notes, and snippets.

@servel333
Last active April 13, 2024 12:38
Show Gist options
  • Save servel333/66f376ba38c3fb298111b3997ede9e5d to your computer and use it in GitHub Desktop.
Save servel333/66f376ba38c3fb298111b3997ede9e5d to your computer and use it in GitHub Desktop.
Downloads older versions of Beat Saber through Steam and can backup and overwrite the installed version.
@echo off
setlocal
:: Downloads older versions of Beat Saber through Steam and can backup and overwrite the installed version.
:: #### Configuration #### -------------------------------------------------------------------------
set "username=natep"
:: if BACKUP_DIRECTORY is not set it will default to a path. See LOAD DEFAULTS.
:: set "BACKUP_DIRECTORY=C:\Users\%username%\Documents\Beat Saber Backup"
:: #### Constants #### -----------------------------------------------------------------------------
set "BEAT_SABER_INSTALL_PATH=C:\Program Files (x86)\Steam\steamapps\common\Beat Saber"
set "STEAM_APP_ID=620980"
set "STEAM_APP_DEPOT=620981"
:: The path the old version is downloaded to
set "BEAT_SABER_OLD_VERSION_PATH=C:\Program Files (x86)\Steam\steamapps\content\app_%STEAM_APP_ID%\depot_%STEAM_APP_DEPOT%"
:: #### Get date and time #### ---------------------------------------------------------------------
:: wmic OS Get localdatetime /value
:: Output example: 20241122T195959.500000-240
:: Meaning 2024-11-22 T 19:59:59.500000 UTC-240
:: Retrieve date and time using WMIC
for /f "tokens=2 delims==" %%x in ('wmic OS Get localdatetime /value') do set datetime=%%x
echo Now: [%datetime%]
:: Extract date and time components
set "year=%datetime:~0,4%"
set "month=%datetime:~4,2%"
set "day=%datetime:~6,2%"
set "hours=%datetime:~8,2%"
set "minutes=%datetime:~10,2%"
set "seconds=%datetime:~12,2%"
set "timezone=%datetime:~21,4%"
:: echo "## DEBUG ## [%year%]-[%month%]-[%day%] T [%hours%]:[%minutes%]:[%seconds%] z [%timezone%]"
:: :: Remove leading zeros for numerical operations
:: call set /a "month_nlz=1%month% - 100"
:: call set /a "day_nlz=1%day% - 100"
:: call set /a "hours_nlz=1%hours% - 100"
:: call set /a "minutes_nlz=1%minutes% - 100"
:: call set /a "seconds_nlz=1%seconds% - 100"
:: echo "## DEBUG ## [%year%]-[%month_nlz%]-[%day_nlz%] T [%hours_nlz%]:[%minutes_nlz%]:[%seconds_nlz%] z [%timezone%]"
echo Now: %year%-%month%-%day% T %hours%:%minutes%:%seconds% UTC %timezone%
:: #### LOAD DEFAULTS #### -------------------------------------------------------------------------
if not defined BACKUP_DIRECTORY (
set "BACKUP_DIRECTORY=C:\Users\%username%\Documents\Beat Saber at %year%-%month%-%day%T%hours%UTC%timezone%"
)
:: #################################################################################################
:: #### MAIN #### ----------------------------------------------------------------------------------
:: Prints instructions for all versions not commented out
call :for_all_versions
call :open_steam_console
:: call :open_guide_instructions_url
:: call :open_old_version_download_directory
:: call :open_beat_saber_install_directory
:: call :backup_currently_installed_version
:: call :explore_backup_directory
:: call :overwrite_current_version_with_downloaded_old_version
:: #### WAIT #### ----------------------------------------------------------------------------------
timeout /t 120
:: set /P "=Press any key to exit..."
goto :eof
:: #### DONE MAIN #### -----------------------------------------------------------------------------
:: #################################################################################################
:: #### FUNCTION #### ------------------------------------------------------------------------------
:: :mkdir_and_xcopy_or_skip
:: copy a path to another path (xcopy).
:: The destination path is create (mkdir).
:: %1 = source :: source path to xcopy from, or skip if it does not exist.
:: %2 = destination :: destination path to xcopy to, or skip if it alreay exists.
:mkdir_and_xcopy_or_skip
set "source=%~1"
set "destination=%~2"
echo.
echo :mkdir_and_xcopy_or_skip > will copy or cancel
echo :mkdir_and_xcopy_or_skip > Source ""%source%""
echo :mkdir_and_xcopy_or_skip > Destionation ""%destination%""
if "%source%"=="" ( goto :eof )
if "%destination%"=="" ( goto :eof )
if not exist "%source%\*" (
echo :mkdir_and_xcopy_or_skip > Source does not exist, skipping copy...
goto :eof
)
if exist "%destination%\*" (
echo :mkdir_and_xcopy_or_skip > Destination already exists, skipping copy...
goto :eof
)
mkdir "%destination%"
xcopy "%source%\*" "%destination%" /I /E
echo :mkdir_and_xcopy_or_skip > complete
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:xcopy_overwrite_dest
set "source=%~1"
set "destination=%~2"
echo.
echo :xcopy_overwrite_dest > copy and replace
echo :xcopy_overwrite_dest > Source ""%source%""
echo :xcopy_overwrite_dest > Destionation ""%destination%""
if "%source%"=="" ( goto :eof )
if "%destination%"=="" ( goto :eof )
if not exist "%source%\*" (
echo :xcopy_overwrite_dest > Source does not exist, skipping copy...
goto :eof
)
xcopy "%source%\*" "%destination%\" /E /H /Y /I
if %ERRORLEVEL% neq 0 (
echo :xcopy_overwrite_dest > Error occurred during copying.
exit /b %ERRORLEVEL%
)
echo :xcopy_overwrite_dest > complete
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:overwrite_current_version_with_downloaded_old_version
echo.
echo Replacing current installed version with downloaded older version
echo %BEAT_SABER_OLD_VERSION_PATH%
echo.
call :xcopy_overwrite_dest "%BEAT_SABER_OLD_VERSION_PATH%" "%BEAT_SABER_INSTALL_PATH%"
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:backup_currently_installed_version
echo.
echo Backing up current install of Beat Saber to
echo %BACKUP_DIRECTORY%
:: Make backup copies of "Beat Saber_Data\CustomLevels", "DLC" (if you own any) and "UserData" somewhere on your PC (which you can restore later)
:: echo Backing up currently installed version of Beat Saber
:: call :mkdir_and_xcopy_or_skip "%BEAT_SABER_INSTALL_PATH%" "%BACKUP_DIRECTORY%"
echo Backing up user data of currently installed version of Beat Saber
call :mkdir_and_xcopy_or_skip "%BEAT_SABER_INSTALL_PATH%\Beat Saber_Data\CustomLevels" "%BACKUP_DIRECTORY%\Beat Saber_Data\CustomLevels"
call :mkdir_and_xcopy_or_skip "%BEAT_SABER_INSTALL_PATH%\DLC" "%BACKUP_DIRECTORY%\DLC"
call :mkdir_and_xcopy_or_skip "%BEAT_SABER_INSTALL_PATH%\UserData" "%BACKUP_DIRECTORY%\UserData"
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:explore_backup_directory
echo Opening backup directory [DISABLED]
explorer "%BACKUP_DIRECTORY%"
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:open_guide_instructions_url
echo.
echo Opening the guide for Beat Saber versions.
start "" "https://steamcommunity.com/sharedfiles/filedetails/?id=1805934840"
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:open_old_version_download_directory
echo.
echo Opening the folder where the file was deposited the last time. [DISABLED]
echo Look at the output of the finished download page to note directory.
explorer "%BEAT_SABER_OLD_VERSION_PATH%"
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:open_steam_console
echo.
echo Opening the Steam console.
start "" "steam://open/console"
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:open_beat_saber_install_directory
echo.
echo Opening Beat Saber install folder with exe. [DISABLED]
explorer "%BEAT_SABER_INSTALL_PATH%"
goto :eof
:: #### FUNCTION #### ------------------------------------------------------------------------------
:for_all_versions
:: :for_version "Date" "Time" "Version" "Manifest ID" "Notes"
:: call :for_version "2024-04-09" "14:45:50 UTC" "1.36.0" "8533509040167838423" ""
:: call :for_version "2024-03-07" "15:46:35 UTC" "1.35.0" "1490986193481243578" ""
:: call :for_version "2024-02-16" "13:51:13 UTC" "1.34.6" "4398761375819224126" ""
:: call :for_version "2024-02-12" "13:52:38 UTC" "1.34.5" "7413405154512822201" ""
:: call :for_version "2023-12-11" "15:51:33 UTC" "1.34.2" "8045892568861450718" ""
:: call :for_version "2023-12-05" "15:46:57 UTC" "1.34.0" "3651119791147907495" ""
call :for_version "2023-10-30" "14:45:36 UTC" "1.33.0" "706865160400890715" ""
:: call :for_version "2023-10-05" "14:54:40 UTC" "1.32.0" "1660149393914874041" ""
:: call :for_version "2023-08-28" "10:00:38 UTC" "1.31.1" "5239818041644201119" ""
:: call :for_version "2023-06-29" "14:51:20 UTC" "1.31.0" "676582354127623831" ""
:: call :for_version "2023-06-13" "14:51:06 UTC" "1.30.2" "8042804988990059618" ""
:: call :for_version "2023-05-24" "21:36:54 UTC" "1.30.0" "7304715857122259127" ""
:: call :for_version "2023-05-03" "15:11:46 UTC" "1.29.4" "6291266771922375922" ""
:: call :for_version "2023-04-04" "15:20:57 UTC" "1.29.1" "886973241045584398" ""
:: call :for_version "2023-03-30" "14:45:01 UTC" "1.29.0" "3341527958186345367" ""
:: call :for_version "2023-02-28" "15:46:08 UTC" "1.28.0" "7463243155526905423" ""
:: call :for_version "2022-12-13" "15:50:13 UTC" "1.27.0" "3485516174915301618" ""
:: call :for_version "2022-11-08" "15:47:41 UTC" "1.26.0" "3634450655207470002" ""
:: call :for_version "2022-10-13" "14:50:23 UTC" "1.25.1" "7372469314660649150" ""
:: call :for_version "2022-10-06" "14:46:01 UTC" "1.25.0" "4529582051007915041" ""
:: call :for_version "2022-07-14" "14:58:32 UTC" "1.24.0" "649695825989344999" ""
:: call :for_version "2022-06-14" "14:57:54 UTC" "1.23.0" "8051970117665729770" ""
:: call :for_version "2022-05-19" "11:57:58 UTC" "1.22.1" "3771211058784167267" ""
:: call :for_version "2022-05-05" "15:47:39 UTC" "1.22.0" "4038188869828689801" ""
:: call :for_version "2022-03-31" "14:12:22 UTC" "1.21.0" "3648558848715327622" ""
:: call :for_version "2022-03-08" "15:58:18 UTC" "1.20.0" "4202491068770948196" ""
:: call :for_version "2022-02-09" "10:55:34 UTC" "1.19.1" "1175216641760077721" "(as RC4)"
:: call :for_version "2021-12-10" "04:01:30 UTC" "1.19.0" "8948172000430595334" ""
:: call :for_version "2021-11-04" "10:53:50 UTC" "1.18.3" "6558821762131072991" ""
:: call :for_version "2021-10-25" "14:49:43 UTC" "1.18.2" "6835596583028648427" ""
:: call :for_version "2021-10-05" "16:15:19 UTC" "1.18.1" "8961661233382948062" "(as RC)"
:: call :for_version "2021-09-21" "14:41:49 UTC" "1.18.0" "5599254819160454367" ""
:: call :for_version "2021-09-09" "14:55:02 UTC" "1.17.1" "4668547658954826996" ""
:: call :for_version "2021-08-31" "14:43:39 UTC" "1.17.0" "7826684224434229804" ""
:: call :for_version "2021-07-22" "17:17:47 UTC" "1.16.4" "8820433629543698585" "(as RC)"
:: call :for_version "2021-07-20" "17:05:23 UTC" "1.16.3" "6392596175313869009" ""
:: call :for_version "2021-06-04" "15:07:53 UTC" "1.16.2" "3692829915208062825" "(as RC2)"
:: call :for_version "2021-05-28" "15:52:08 UTC" "1.16.1" "9201874499606445062" ""
:: call :for_version "2021-05-27" "14:52:30 UTC" "1.16.0" "3667184295685865706" ""
:: call :for_version "2021-04-29" "14:57:36 UTC" "1.15.0" "7624554893344753887" ""
:: call :for_version "2021-03-18" "13:44:36 UTC" "1.14.0" "9218225910501819399" ""
:: call :for_version "2021-03-12" "14:23:00 UTC" "1.13.5" "7007516983116400336" ""
:: call :for_version "2021-03-09" "13:54:44 UTC" "1.13.4" "1257277263145069282" ""
:: call :for_version "2021-01-21" "14:15:25 UTC" "1.13.2" "8571679771389514488" ""
:: call :for_version "2020-11-12" "14:00:38 UTC" "1.13.0" "4635119747389290346" ""
:: call :for_version "2020-10-19" "16:50:57 UTC" "1.12.2" "543439039654962432" ""
:: call :for_version "2020-10-13" "17:01:04 UTC" "1.12.1" "2928416283534881313" ""
:: call :for_version "2020-08-20" "16:28:32 UTC" "1.11.1" "3268824881806146387" ""
:: call :for_version "2020-08-17" "12:03:07 UTC" "1.11.0" "1919603726987963829" ""
:: call :for_version "2020-05-25" "12:32:11 UTC" "1.10.0" "6711131863503994755" ""
:: call :for_version "2020-05-05" "09:32:31 UTC" "1.9.1" "6222769774084748916" ""
:: call :for_version "2020-04-09" "12:41:25 UTC" "1.9.0" "7885463693258878294" ""
:: call :for_version "2020-03-26" "12:27:34 UTC" "1.8.0" "3177969677109016846" ""
:: call :for_version "2020-01-29" "12:40:33 UTC" "1.7.0" "3516084911940449222" ""
:: call :for_version "2020-01-09" "20:19:21 UTC" "1.6.2" "4932559146183937357" ""
:: call :for_version "2020-01-07" "17:47:38 UTC" "1.6.1" "6122319670026856947" ""
:: call :for_version "2019-12-13" "08:21:10 UTC" "1.6.0" "1869974316274529288" ""
:: call :for_version "2019-11-07" "15:58:59 UTC" "1.5.0" "2831333980042022356" ""
:: call :for_version "2019-10-11" "09:36:58 UTC" "1.4.2" "1199049250928380207" ""
:: call :for_version "2019-10-04" "16:11:04 UTC" "1.4.0" "3532596684905902618" ""
:: call :for_version "2019-08-29" "17:12:22 UTC" "1.3.0" "2440312204809283162" ""
:: call :for_version "2019-07-25" "18:26:46 UTC" "1.2.0" "3820905673516362176" ""
:: call :for_version "2019-07-15" "13:27:12 UTC" "p1" "1041583928494277430" ""
:: call :for_version "2019-06-10" "16:03:43 UTC" "1.1.0" "1400454104881094752" ""
:: call :for_version "2019-05-27" "13:55:54 UTC" "1.0.1" "7950322551526208347" ""
:: call :for_version "2019-05-21" "20:52:46 UTC" "1.0.0" "152937782137361764" ""
:: call :for_version "2019-04-04" "12:42:16 UTC" "0.13.2" "6839388023573913446" ""
:: call :for_version "2019-04-01" "20:35:39 UTC" "0.13.1" "6033025349617217666" ""
:: call :for_version "2019-03-19" "17:27:41 UTC" "p1" "6827433614670733798" ""
:: call :for_version "2019-03-14" "14:57:45 UTC" "0.13.0" "3102409495238838111" ""
:: call :for_version "2018-12-21" "09:04:35 UTC" "0.12.2" "5325635033564462932" ""
:: call :for_version "2018-12-14" "19:57:11 UTC" "0.12.1" "2472041066434647526" ""
:: call :for_version "2018-11-28" "21:56:53 UTC" "p1" "2068421223689664394" ""
:: call :for_version "2018-11-27" "01:11:44 UTC" "0.12.0" "6094599000655593822" ""
:: call :for_version "2018-08-20" "17:15:57 UTC" "0.11.2" "2707973953401625222" ""
:: call :for_version "2018-07-20" "21:06:22 UTC" "0.11.1" "6574193224879562324" ""
:: call :for_version "2018-07-19" "18:06:18 UTC" "0.11.0" "8700049030626148111" ""
:: call :for_version "2018-05-20" "12:23:14 UTC" "p1" "5611588554149133260" ""
:: call :for_version "2018-05-10" "22:10:19 UTC" "0.10.2" "2542095265882143144" ""
:: call :for_version "2018-05-01" "16:01:23 UTC" "initial_release" "6316038906315325420" "? (initial release)"
:: Experimental Versions
:: Some experimental versions of Beat Saber, previously found in Public Beta branches, can be seen below. These follow :: chronological order but they may not necessarily be a successor of one another.
:: call :for_version "2023-04-24" "09:00:45 UTC" "OpenXR Beta" "8618396706007674506" ""
:: call :for_version "2023-04-14" "15:00:37 UTC" "OpenXR Alpha 2" "1829073560758833583" ""
:: call :for_version "2023-03-22" "13:59:32 UTC" "OpenXR Alpha 1" "7451458216441819087" ""
:: call :for_version "2022-11-15" "17:40:44 UTC" "Beta" "1251433115430405795" ""
:: call :for_version "2022-08-30" "15:22:06 UTC" "RC2" "3141359577983993890" ""
:: call :for_version "2022-08-30" "14:56:00 UTC" "RC1" "3684718000373511599" ""
:: call :for_version "2022-05-05" "15:41:34 UTC" "RC2" "2444647800492773078" ""
:: call :for_version "2022-05-05" "14:55:57 UTC" "RC1" "3127490762128419443" ""
:: call :for_version "2022-02-28" "16:57:17 UTC" "RC1" "7544910552308977013" ""
:: call :for_version "2022-02-03" "16:49:23 UTC" "RC3" "6695934593516653206" ""
:: call :for_version "2022-01-21" "14:41:03 UTC" "RC2" "3400399060417199651" ""
:: call :for_version "2021-12-21" "14:54:23 UTC" "RC1" "6504575834439294596" ""
:: call :for_version "2021-07-15" "18:00:11 UTC" "RC1" "359870355216685341" ""
:: call :for_version "2021-06-03" "17:06:24 UTC" "RC1" "8138074968751658813" ""
:: call :for_version "2020-03-24" "18:22:42 UTC" "RC3" "6406030817654977349" ""
:: call :for_version "2020-03-23" "20:32:44 UTC" "RC2" "5034868045536418671" ""
:: call :for_version "2020-02-25" "18:20:02 UTC" "RC1" "7895726645002193553" ""
:: call :for_version "2019-12-05" "14:39:38 UTC" "Beta" "1558719508179518807" ""
:: call :for_version "2019-08-20" "19:53:26 UTC" "Beta" "754277321799466058" ""
:: call :for_version "2019-06-04" "11:53:37 UTC" "Beta" "7328426073746555634" ""
:: call :for_version "2019-05-27" "09:33:43 UTC" "RC2" "7961522920183992795" ""
:: call :for_version "2019-05-22" "10:01:18 UTC" "RC1" "21808000064636298" ""
:: call :for_version "2019-03-28" "12:03:12 UTC" "Beta" "2479716787273789866" ""
:: call :for_version "2019-03-19" "09:48:46 UTC" "p1 RC4" "1734028250351204547" ""
:: call :for_version "2019-03-19" "09:13:06 UTC" "p1 RC3" "5229520613372353827" ""
:: call :for_version "2019-03-18" "23:14:21 UTC" "p1 RC2" "7517656838619538465" ""
:: call :for_version "2019-03-18" "14:41:42 UTC" "p1 RC1" "25913810314273081" ""
:: call :for_version "2018-12-01" "12:14:32 UTC" "Beta" "4435387545491908757" ""
:: call :for_version "2018-06-06" "15:50:19 UTC" "Beta" "8892605455517437772" ""
:: call :for_version "2018-05-04" "07:39:18 UTC" "Beta" "7674013830649003337" ""
:: #### FUNCTION #### ------------------------------------------------------------------------------
goto :eof
:: Currently prints instructions to download the version
:for_version
set "date=%~1"
set "time=%~2"
set "version=%~3"
set "manifest_id=%~4"
set "notes=%~5"
if "%version%"=="" ( goto :eof )
if "%manifest_id%"=="" ( goto :eof )
echo.
echo Command to use to download the Beat Saber v%version% %date% T %time% Notes: %notes%
echo download_depot %STEAM_APP_ID% %STEAM_APP_DEPOT% %manifest_id%
echo download_depot %STEAM_APP_ID% %STEAM_APP_DEPOT% %manifest_id% | clip
echo ^ Copied to the clipborad!
goto :eof
:: #### END #### -----------------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment