From c7b98802d4821165df2f858e72fdc348e0009c1b Mon Sep 17 00:00:00 2001 From: mrvictory1 Date: Sun, 21 Sep 2025 20:21:45 +0300 Subject: [PATCH 1/2] Add atomic distribution support --- cli/CMakeLists.txt | 2 +- cli/src/main.cc | 42 +++++++++++++++++++++++++++++++----------- scripts/posix/start.sh | 4 ++-- src/sys/env.cc | 20 +++++++++++++++++--- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index 68bebead..e5936079 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) # Set the project name and language diff --git a/cli/src/main.cc b/cli/src/main.cc index 52be5046..c9e34fe8 100644 --- a/cli/src/main.cc +++ b/cli/src/main.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include "incbin.h" #include "chown.h" @@ -50,8 +51,11 @@ INCTXT(PATCHED_START_SCRIPT, "../../scripts/posix/start.sh"); -#define START_SCRIPT_PATH "/usr/bin/steam" +// #define START_SCRIPT_PATH "/usr/bin/steam" #define BACKUP_PATH "/usr/bin/steam.millennium.bak" +const char * start_script_path = "/usr/bin/steam"; +const char * start_script_usrlocal_path = "/usr/local/bin/steam"; +const char * start_script_available_path; void check_sudo() { if (getuid() != 0) { @@ -62,10 +66,11 @@ void check_sudo() { const void patch_steam() { + start_script_available_path = start_script_path; std::cout << "Resolving permissions...\n"; check_sudo(); - if (access(START_SCRIPT_PATH, F_OK) == -1) + if (access(start_script_path, F_OK) == -1) { std::cerr << "Error: Steam start script not found. Ensure you're Steam installation is not flatpak, or snap.\n"; return; @@ -74,8 +79,23 @@ const void patch_steam() if (access(BACKUP_PATH, F_OK) == -1) { std::cout << "Backing up the original start script...\n"; - rename(START_SCRIPT_PATH, BACKUP_PATH); - std::cout << "Backup made at: " << BACKUP_PATH << "\n"; + rename(start_script_path, BACKUP_PATH); + if (access(BACKUP_PATH, F_OK) == -1) { + std::cout << "Backing up the original start script failed.\n"; + std::cout << "Attemting to create copy in /usr/local/bin...\n"; + std::filesystem::copy(start_script_path, start_script_usrlocal_path); + if (access(start_script_usrlocal_path, F_OK) == -1) { + std::cout << "Copying to /usr/local/bin failed, exiting.\n"; + return; + } + else { + std::cout << "Copy created at: " << start_script_usrlocal_path << "\n"; + start_script_available_path = start_script_usrlocal_path; + } + } + else { + std::cout << "Copy created at: " << start_script_path << "\n"; + } } else { @@ -86,7 +106,7 @@ const void patch_steam() if (response[0] == 'y' || response[0] == 'Y') { remove(BACKUP_PATH); - rename(START_SCRIPT_PATH, BACKUP_PATH); + rename(start_script_path, BACKUP_PATH); } else { std::cout << "Skipping backup...\n"; @@ -94,7 +114,7 @@ const void patch_steam() } std::cout << "Patching the Steam start script...\n"; - FILE *file = fopen(START_SCRIPT_PATH, "w"); + FILE *file = fopen(start_script_available_path, "w"); if (!file) { perror("Failed to open script for writing"); @@ -103,8 +123,8 @@ const void patch_steam() fputs(PATCHED_START_SCRIPT_data, file); fclose(file); - chmod(START_SCRIPT_PATH, 0555); - std::cout << "Successfully wrote: " << START_SCRIPT_PATH << "\n"; + chmod(start_script_available_path, 0555); + std::cout << "Successfully wrote: " << start_script_available_path << "\n"; return; }; @@ -112,13 +132,13 @@ const void check_patch_status() { check_sudo(); - if (access(START_SCRIPT_PATH, F_OK) == -1) + if (access(start_script_path, F_OK) == -1) { std::cerr << "Steam start script not found.\n"; return; } - FILE *file = fopen(START_SCRIPT_PATH, "r"); + FILE *file = fopen(start_script_path, "r"); if (!file) { perror("Failed to open script"); @@ -150,7 +170,7 @@ const void check_patch_status() int is_patched = (strcmp(buffer, PATCHED_START_SCRIPT_data) == 0); std::cout << "\n\033[32m>\e[0m \033[1mPatched:\033[0m \033[" << (is_patched ? 92 : 91) << "m" << (is_patched ? "yes" : "no") << "\033[0m\n"; - std::cout << "\033[32m>\e[0m \033[1mPath:\033[0m \033[92m" << START_SCRIPT_PATH << "\033[0m\n"; + std::cout << "\033[32m>\e[0m \033[1mPath:\033[0m \033[92m" << start_script_path << "\033[0m\n"; free(buffer); }; diff --git a/scripts/posix/start.sh b/scripts/posix/start.sh index 3bfedb7b..a29b2b3a 100755 --- a/scripts/posix/start.sh +++ b/scripts/posix/start.sh @@ -10,12 +10,12 @@ export OPENSSL_CONF=/dev/null # Only set LD_PRELOAD if MILLENNIUM_RUNTIME_PATH is not set if [ -z "${MILLENNIUM_RUNTIME_PATH}" ]; then - export LD_PRELOAD="/usr/lib/millennium/libmillennium_x86.so${LD_PRELOAD:+:$LD_PRELOAD}" # preload Millennium into Steam + export LD_PRELOAD="/usr/lib/millennium/libmillennium_x86.so:/usr/local/lib/millennium/libmillennium_x86.so${LD_PRELOAD:+:$LD_PRELOAD}" # preload Millennium into Steam else export LD_PRELOAD="${MILLENNIUM_RUNTIME_PATH}${LD_PRELOAD:+:$LD_PRELOAD}" # use custom LD_PRELOAD if set fi -export LD_LIBRARY_PATH="/usr/lib/millennium/${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +export LD_LIBRARY_PATH="/usr/lib/millennium/:/usr/local/lib/millennium/${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" # Millennium hooks __libc_start_main to initialize itself, which is a function that is called before main. # Besides that, Millennium does not alter Steam memory and runs completely disjoint. diff --git a/src/sys/env.cc b/src/sys/env.cc index e5b1116e..ccee819b 100644 --- a/src/sys/env.cc +++ b/src/sys/env.cc @@ -41,6 +41,7 @@ #include #include #include +#include #if defined(__linux__) || defined(__APPLE__) extern char** environ; @@ -157,7 +158,11 @@ const void SetupEnvironmentVariables() #ifdef _NIX_OS const auto shimsPath = fmt::format("{}/share/millennium/shims", __NIX_SHIMS_PATH); #else - const auto shimsPath = "/usr/share/millennium/shims"; + const char * shimsPath; + if (std::filesystem::exists("/usr/local/bin/millennium")) + shimsPath = "/usr/local/share/millennium/shims"; + else + shimsPath = "/usr/share/millennium/shims"; #endif #elif __APPLE__ const auto shimsPath = "/usr/local/share/millennium/shims"; @@ -174,7 +179,11 @@ const void SetupEnvironmentVariables() #ifdef _NIX_OS const auto assetsPath = fmt::format("{}/share/millennium/assets", __NIX_ASSETS_PATH); #else - const auto assetsPath = "/usr/share/millennium/assets"; + const char * assetsPath; + if (std::filesystem::exists("/usr/local/bin/millennium")) + assetsPath = "/usr/local/share/millennium/assets"; + else + assetsPath = "/usr/share/millennium/assets"; #endif #elif __APPLE__ const auto assetsPath = "/usr/local/share/millennium/assets"; @@ -208,6 +217,11 @@ const void SetupEnvironmentVariables() } const std::string customLdPreload = GetEnv("MILLENNIUM_RUNTIME_PATH"); + const char * millenium_runtime_path; + if (std::filesystem::exists("/usr/local/bin/millennium")) + millenium_runtime_path = "/usr/local/lib/millennium/libmillennium_x86.so"; + else + millenium_runtime_path = "/usr/lib/millennium/libmillennium_x86.so"; std::map environment_unix = { {"OPENSSL_CONF", "/dev/null"}, @@ -215,7 +229,7 @@ const void SetupEnvironmentVariables() #ifdef _NIX_OS fmt::format("{}/lib/millennium/libMillennium_x86.so", __NIX_SELF_PATH) #else - "/usr/lib/millennium/libmillennium_x86.so" + millenium_runtime_path #endif }, From fe26abe2c4ead8f54d2b855cd2c75819b9e5c87b Mon Sep 17 00:00:00 2001 From: mrvictory1 Date: Sun, 21 Sep 2025 20:53:37 +0300 Subject: [PATCH 2/2] Add atomic distribution support to installation script --- scripts/install.sh | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index 4262fb78..f3de8e95 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -29,6 +29,19 @@ if ! is_root; then exit 1 fi +if [ -w /usr/bin/steam ] ; then + log "/usr/bin/steam is writable." +else + log "/usr/bin/steam is NOT writable." + if [ -w /usr/local/bin/ ] ; then + log "/usr/local/bin is writable. Install location will be /usr/local/bin." + USE_USRLOCAL=1 + else + log "${BOLD_RED}!!${RESET} /usr/local/bin is not writable. Exiting." + exit 2 + fi +fi + case $(uname -sm) in "Linux x86_64") target="linux-x86_64" ;; *) log "${BOLD_RED}!!${RESET} Unsupported platform $(uname -sm). x86_64 is the only available platform."; exit ;; @@ -89,13 +102,22 @@ tar xzf "$tar" -C "$extract_path" folder_size=$(du -sb "$extract_path" | awk '{print $1}' | numfmt --to=iec-i --suffix=B --padding=7 | sed 's/\([0-9]\)\([A-Za-z]\)/\1 \2/') log "\nTotal Install Size: $folder_size" -cp -r "$extract_path"/* / || true +if ! [[ $USE_USRLOCAL ]] ; then + # Default installation method with writable /usr/bin. + cp -r "$extract_path"/* / || true + chmod +x /usr/bin/millennium +else + # Alternate installation method with writable /usr/local/bin. + cp -r "$extract_path"/usr/* /usr/local/ + cp -r "$extract_path"/opt/* /opt/ + chmod +x /usr/local/bin/millennium +fi -chmod +x /usr/bin/millennium +# This step is the same on both methods chmod +x /opt/python-i686-3.11.8/bin/python3.11 log "cleaning up packages..." rm -rf "$millennium_install" log "done." -log "\n${BOLD_PINK}::${RESET} To get started, see https://docs.steambrew.app/users/installing#post-installation.\n Your base installation of Steam has not been modified, this is simply an extension." \ No newline at end of file +log "\n${BOLD_PINK}::${RESET} To get started, see https://docs.steambrew.app/users/installing#post-installation.\n Your base installation of Steam has not been modified, this is simply an extension."