#!/usr/bin/env bash
set -x # activate debugging (execution shown)
set -o pipefail # capture error from pipes
# ENVIRONMENT VARIABLES
# Get the logged-in user, fallback to whoami if needed
logged_in_user=$(logname 2>/dev/null || whoami)
# DBUS
# Add the DBUS_SESSION_BUS_ADDRESS environment variable if missing
if [[ -z "$DBUS_SESSION_BUS_ADDRESS" ]]; then
eval "$(dbus-launch --sh-syntax)"
fi
# Try Zenity notification, fallback if it fails
if ! zenity --notification --text="NonSteamLaunchers is running tests..." >/dev/null 2>&1; then
export GSK_RENDERER=cairo
export GDK_BACKEND=x11
export LIBGL_ALWAYS_SOFTWARE=1
fi
# Set LD_LIBRARY_PATH to current directory (prepend if you want to keep existing)
export LD_LIBRARY_PATH="$(pwd):${LD_LIBRARY_PATH:-}"
# Get logged-in user's UID and HOME directory
logged_in_uid=$(id -u "${logged_in_user}")
logged_in_home=$(eval echo "~${logged_in_user}")
# Setup download directory and log file path
download_dir="${logged_in_home}/Downloads/NonSteamLaunchersInstallation"
log_file="${logged_in_home}/Downloads/NonSteamLaunchers-install.log"
#Cleaning
# Define the path to the compatdata directory
compatdata_dir="${logged_in_home}/.local/share/Steam/steamapps/compatdata"
# Define the NonSteamLaunchers directory path for cleaning .tmp files
non_steam_launchers_dir="${compatdata_dir}/NonSteamLaunchers/pfx/drive_c/"
# Define an array of folder names
folder_names=("NonSteamLaunchers" "EpicGamesLauncher" "GogGalaxyLauncher" "UplayLauncher" "Battle.netLauncher" "TheEAappLauncher" "AmazonGamesLauncher" "itchioLauncher" "LegacyGamesLauncher" "HumbleGamesLauncher" "IndieGalaLauncher" "RockstarGamesLauncher" "GlyphLauncher" "PlaystationPlusLauncher" "VKPlayLauncher" "HoYoPlayLauncher" "NexonLauncher" "GameJoltLauncher" "ArtixGameLauncher" "ARCLauncher" "PokeTCGLauncher" "AntstreamLauncher" "PURPLELauncher" "PlariumLauncher" "VFUNLauncher" "TempoLauncher" "BigFishLauncher" "GryphlinkLauncher")
# Cleaning up empty directories in compatdata (maxdepth 1 to avoid subdirectories)
echo "Cleaning up empty directories in $compatdata_dir..."
find "${compatdata_dir}" -maxdepth 1 -type d -empty -delete
echo "Empty directories cleaned up."
# Cleaning up .tmp files in the NonSteamLaunchers directory
echo "Cleaning up .tmp files in $non_steam_launchers_dir..."
find "${non_steam_launchers_dir}" -maxdepth 1 -type f -name "*.tmp" -delete
echo ".tmp files cleaned up."
# Loop through each folder name for symlink checking and deletion
for folder in "${folder_names[@]}"; do
SYMLINK="$compatdata_dir/$folder"
# Check if it's a symlink and if the target is broken
if [ -L "$SYMLINK" ] && [ ! -e "$(readlink "$SYMLINK")" ]; then
echo "The symlink $SYMLINK is broken. Deleting it..."
# Delete the broken symlink
rm "$SYMLINK"
echo "Symlink $SYMLINK deleted successfully."
else
echo "The symlink $SYMLINK is either not a symlink or not broken. No action taken."
fi
# Check if the folder exists and clean up any .tmp files in it if applicable
TARGET_DIR="$compatdata_dir/$folder/pfx/drive_c/"
if [ -d "$TARGET_DIR" ]; then
echo "Cleaning up .tmp files in $TARGET_DIR..."
find "$TARGET_DIR" -maxdepth 1 -type f -name "*.tmp" -delete
echo ".tmp files cleaned up in $TARGET_DIR."
else
echo "No valid directory found for $folder at $TARGET_DIR. No .tmp cleanup needed."
fi
done
echo "Cleanup completed!"
# Remove existing log file if it exists
if [[ -f $log_file ]]; then
rm $log_file
fi
# Redirect all output to the log file
exec > >(tee -a "$log_file") 2>&1
# Version number (major.minor)
version=v4.2.87
#NSL Decky Plugin Latest Github Version
deckyversion=$(curl -s https://raw.githubusercontent.com/moraroy/NonSteamLaunchersDecky/refs/heads/main/package.json | grep -o '"version": "[^"]*' | sed 's/"version": "//')
# Function to display a Zenity message
show_message() {
zenity --notification --text="$1" --timeout=1
}
# Check repo releases via GitHub API then display current stable version
check_for_updates() {
local api_url="https://api.github.com/repos/moraroy/NonSteamLaunchers-On-Steam-Deck/releases/latest"
local latest_version=$(curl -s "$api_url" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [ "$version" != "$latest_version" ]; then
zenity --info --text="A new version is available: $latest_version\nPlease download it from GitHub." --width=200 --height=100 --timeout=5
else
echo "You are already running the latest version: $version"
fi
}
# Check if Zenity is installed
if ! command -v zenity &> /dev/null; then
echo "Zenity is not installed. Installing Zenity..."
if command -v apt-get &> /dev/null; then
sudo apt-get install -y zenity
elif command -v dnf &> /dev/null; then
sudo dnf install -y zenity
elif command -v pacman &> /dev/null; then
sudo pacman -S --noconfirm zenity
else
echo "Unknown package manager. Please install Zenity manually."
exit 1
fi
fi
# Check if Steam is installed (non-flatpak)
if ! command -v steam &> /dev/null; then
echo "Steam is not installed. Please install the non-flatpak version of Steam."
# Provide instructions for different package managers:
if command -v apt-get &> /dev/null; then
echo "To install Steam on a Debian-based system (e.g., Ubuntu, Pop!_OS), run:"
echo " sudo apt update && sudo apt install steam"
elif command -v dnf &> /dev/null; then
echo "To install Steam on a Fedora-based system, run:"
echo " sudo dnf install steam"
elif command -v pacman &> /dev/null; then
echo "To install Steam on an Arch-based system (e.g., ChimeraOS), run:"
echo " sudo pacman -S steam"
else
echo "Unknown package manager. Please install Steam manually."
exit 1
fi
fi
# Check if wget is installed
if ! command -v wget &> /dev/null; then
echo "wget is not installed. Installing wget..."
if command -v apt-get &> /dev/null; then
sudo apt-get install -y wget
elif command -v dnf &> /dev/null; then
sudo dnf install -y wget
elif command -v pacman &> /dev/null; then
sudo pacman -S --noconfirm wget
else
echo "Unknown package manager. Please install wget manually."
exit 1
fi
fi
# Check if curl is installed
if ! command -v curl &> /dev/null; then
echo "curl is not installed. Installing curl..."
if command -v apt-get &> /dev/null; then
sudo apt-get install -y curl
elif command -v dnf &> /dev/null; then
sudo dnf install -y curl
elif command -v pacman &> /dev/null; then
sudo pacman -S --noconfirm curl
else
echo "Unknown package manager. Please install curl manually."
exit 1
fi
fi
# Check if jq is installed
if ! command -v jq &> /dev/null; then
echo "jq is not installed. Installing jq..."
if command -v apt-get &> /dev/null; then
sudo apt-get install -y jq
elif command -v dnf &> /dev/null; then
sudo dnf install -y jq
elif command -v pacman &> /dev/null; then
sudo pacman -S --noconfirm jq
else
echo "Unknown package manager. Please install jq manually."
exit 1
fi
fi
# Get the command line arguments
args=("$@")
echo "Arguments passed: ${args[@]}" # Debugging the passed arguments
# First Run: VARIABLE SETUP
# Function to extract steamid3 from Steam config
get_steam_user_info() {
if [[ -f "${logged_in_home}/.steam/root/config/loginusers.vdf" ]] || [[ -f "${logged_in_home}/.local/share/Steam/config/loginusers.vdf" ]]; then
if [[ -f "${logged_in_home}/.steam/root/config/loginusers.vdf" ]]; then
file_path="${logged_in_home}/.steam/root/config/loginusers.vdf"
else
file_path="${logged_in_home}/.local/share/Steam/config/loginusers.vdf"
fi
most_recent_user=$(sed -n '/"users"/,/"MostRecent" "1"/p' "$file_path")
max_timestamp=0
current_user=""
current_steamid=""
while IFS="," read -r steamid account timestamp; do
if (( timestamp > max_timestamp )); then
max_timestamp=$timestamp
current_user=$account
current_steamid=$steamid
fi
done < <(echo "$most_recent_user" | awk -v RS='}\n' -F'\n' '
{
for(i=1;i<=NF;i++){
if($i ~ /[0-9]{17}/){ split($i,a, "\""); steamid=a[2]; }
if($i ~ /"AccountName"/){ split($i,b, "\""); account=b[4]; }
if($i ~ /"Timestamp"/){ split($i,c, "\""); timestamp=c[4]; }
}
print steamid "," account "," timestamp
}')
steamid3=$((current_steamid - 76561197960265728))
echo "$steamid3"
else
return 0
fi
}
# Suppress all Steam ID output temporarily
{
set +x
steamid3=$(get_steam_user_info | tail -n1)
set -x
} 2>/dev/null
# Get Proton compatibility tool name or fall back
proton_dir=$(find -L "${logged_in_home}/.steam/root/compatibilitytools.d" -maxdepth 1 -type d -name "GE-Proton*" | sort -V | tail -n1)
if [[ -n "$proton_dir" ]]; then
compat_tool_name=$(basename "$proton_dir")
else
compat_tool_name="Proton Experimental"
fi
# Get Python version
python_version=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null)
# Always assign these for Steam shortcut compatibility
chromedirectory="/usr/bin/flatpak"
chrome_startdir="/usr/bin"
# Optional extra variables
separate_appids=false
# Write to env_vars
env_file="${logged_in_home}/.config/systemd/user/env_vars"
mkdir -p "$(dirname "$env_file")"
# Declare vars to check and write
declare -A vars_to_set
vars_to_set["separate_appids"]=$separate_appids
[[ -n "$steamid3" ]] && vars_to_set["steamid3"]=$steamid3
vars_to_set["logged_in_home"]=$logged_in_home
vars_to_set["compat_tool_name"]=$compat_tool_name
[[ -n "$python_version" ]] && vars_to_set["python_version"]=$python_version
vars_to_set["chromedirectory"]=$chromedirectory
vars_to_set["chrome_startdir"]=$chrome_startdir
# Variables that should be quoted
declare -A quote_vars
quote_vars["chromedirectory"]=1
quote_vars["chrome_startdir"]=1
# If file is missing or empty, write everything at once
if [[ ! -s "$env_file" ]]; then
{
for key in "${!vars_to_set[@]}"; do
value="${vars_to_set[$key]}"
if [[ -n "${quote_vars[$key]:-}" ]]; then
echo "export $key=\"$value\""
else
echo "export $key=$value"
fi
done
} > "$env_file"
echo "Environment variables written to $env_file (new file)."
else
# Append only missing variables
for key in "${!vars_to_set[@]}"; do
if ! grep -qE "^export $key=" "$env_file"; then
value="${vars_to_set[$key]}"
if [[ -n "${quote_vars[$key]:-}" ]]; then
echo "export $key=\"$value\"" >> "$env_file"
else
echo "export $key=$value" >> "$env_file"
fi
echo "Added: export $key=$value"
fi
done
echo "Environment variables updated in $env_file (if needed)."
fi
#End of First Run Env_vars
### NSL Game Scanner.py Update/Scan
update_nsl_game_scanner() {
repo_url='https://github.com/moraroy/NonSteamLaunchers-On-Steam-Deck/archive/refs/heads/main.zip'
folders_to_clone=('urllib3' 'vdf' 'charset_normalizer')
parent_folder="${logged_in_home}/.config/systemd/user/Modules"
python_script_path="${logged_in_home}/.config/systemd/user/NSLGameScanner.py"
github_link="https://raw.githubusercontent.com/moraroy/NonSteamLaunchers-On-Steam-Deck/main/NSLGameScanner.py"
env_vars="${logged_in_home}/.config/systemd/user/env_vars"
steam_debug_file="${logged_in_home}/.local/share/Steam/.cef-enable-remote-debugging"
nsl_config_dir="${logged_in_home}/.var/app/com.github.mtkennerly.ludusavi/config/ludusavi/NSLconfig"
# Stop and disable the service if it exists
if systemctl --user list-unit-files | grep -q "nslgamescanner.service"; then
if systemctl --user is-active --quiet nslgamescanner.service; then
systemctl --user stop nslgamescanner.service
fi
systemctl --user disable nslgamescanner.service 2>/dev/null || true
fi
# Remove the old python script if it exists
rm -f "$python_script_path"
# Create the parent folder if it doesn't exist
mkdir -p "${parent_folder}"
folders_exist=true
for folder in "${folders_to_clone[@]}"; do
if [ ! -d "${parent_folder}/${folder}" ]; then
folders_exist=false
break
fi
done
# Download and unzip the repo if necessary
if [ "${folders_exist}" = false ]; then
zip_file_path="${parent_folder}/repo.zip"
wget -O "${zip_file_path}" "${repo_url}" || { echo 'Download failed'; exit 1; }
unzip -d "${parent_folder}" "${zip_file_path}" || { echo 'Unzip failed'; exit 1; }
for folder in "${folders_to_clone[@]}"; do
destination_path="${parent_folder}/${folder}"
source_path="${parent_folder}/NonSteamLaunchers-On-Steam-Deck-main/Modules/${folder}"
if [ -d "${source_path}" ]; then
mv "${source_path}" "${destination_path}" || { echo "Move failed for ${folder}"; exit 1; }
fi
done
rm -f "${zip_file_path}"
rm -rf "${parent_folder}/NonSteamLaunchers-On-Steam-Deck-main"
fi
# Download the latest Python script
curl -fsSL -o "$python_script_path" "$github_link"
chmod +x "$python_script_path"
}
update_nsl_game_scanner
funny_messages=(
"Wow, you have a lot of games!"
"Getting artwork and descriptions for note system..."
"So many launchers, so little time..."
"Much game. Very library. Wow."
"Looking under the Steam Deck couch cushions..."
"Injecting metadata directly into your eyeballs..."
"Downloading more RAM... just kidding."
"Scanning your games like a barcode at checkout!"
"Adding +10 charm to your launcher list..."
"Man this is taking a long time..."
"Removing NSL from Decky Loader Store... jk that happened in real life."
"Learning your game choices and judging you for them..."
"But why is that game in here!!??"
"Downloading any boot videos for your enjoyment..."
"Thank you for being patient..."
"This may take a while..."
"You may need to grab a coffee..."
"If you see this notification, I'm still working don't worry..."
"Getting Descriptions, Artwork and Boot Videos if applicable..."
)
(
while true; do
sleep 2
loop_msg="${funny_messages[$RANDOM % ${#funny_messages[@]}]}"
show_message "Still scanning... ${loop_msg}"
sleep 15
done
) &
message_pid=$!
python3 "$python_script_path"
kill $message_pid 2>/dev/null
show_message "Scanning complete! Your game library looks good!"
if [ ! -f "$steam_debug_file" ]; then
touch "$steam_debug_file" || { echo "Failed to create $steam_debug_file"; exit 1; }
echo "Restarting Steam..."
killall steam 2>/dev/null || true
while pgrep -x steam >/dev/null; do sleep 1; done
nohup /usr/bin/steam -silent %U &>/dev/null &
fi
if systemctl --user list-unit-files | grep -q "nslgamescanner.service"; then
echo "[NSL] Starting NSL Game Scanner service..."
systemctl --user start nslgamescanner.service
else
echo "[NSL] Service file not found — skipping start."
fi
if [ -d "$nsl_config_dir" ] && flatpak list --app | grep -q "com.github.mtkennerly.ludusavi"; then
nohup flatpak run com.github.mtkennerly.ludusavi --config "$nsl_config_dir" backup --force > /dev/null 2>&1 &
wait $!
show_message "Game Saves have been backed up! Please check here: /home/deck/NSLGameSaves"
sleep 3
fi
show_message "Finished! Welcome to NonSteamLaunchers!"
sleep 3
###End of NSL Game Scanner update
# Check if any command line arguments were provided
if [ ${#args[@]} -eq 0 ]; then
# No command line arguments were provided, so check for updates and display the zenity window if necessary
check_for_updates
fi
# Check if the NonSteamLaunchersInstallation subfolder exists in the Downloads folder
if [ -d "$download_dir" ]; then
# Delete the NonSteamLaunchersInstallation subfolder
rm -rf "$download_dir"
echo "Deleted NonSteamLaunchersInstallation subfolder"
else
echo "NonSteamLaunchersInstallation subfolder does not exist"
fi
# Game Launchers
# TODO: parameterize hard-coded client versions (cf. 'app-26.1.9')
# Set the paths to the launcher executables
epic_games_launcher_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Epic Games/Launcher/Portal/Binaries/Win64/EpicGamesLauncher.exe"
epic_games_launcher_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/EpicGamesLauncher/pfx/drive_c/Program Files/Epic Games/Launcher/Portal/Binaries/Win64/EpicGamesLauncher.exe"
gog_galaxy_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/GOG Galaxy/GalaxyClient.exe"
gog_galaxy_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/GogGalaxyLauncher/pfx/drive_c/Program Files (x86)/GOG Galaxy/GalaxyClient.exe"
uplay_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Ubisoft/Ubisoft Game Launcher/upc.exe"
uplay_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/UplayLauncher/pfx/drive_c/Program Files (x86)/Ubisoft/Ubisoft Game Launcher/upc.exe"
battlenet_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Battle.net/Battle.net Launcher.exe"
battlenet_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/Battle.netLauncher/pfx/drive_c/Program Files (x86)/Battle.net/Battle.net Launcher.exe"
eaapp_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Electronic Arts/EA Desktop/EA Desktop/EADesktop.exe"
eaapp_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/TheEAappLauncher/pfx/drive_c/Program Files/Electronic Arts/EA Desktop/EA Desktop/EADesktop.exe"
amazongames_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/Amazon Games/App/Amazon Games.exe"
amazongames_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/AmazonGamesLauncher/pfx/drive_c/users/steamuser/AppData/Local/Amazon Games/App/Amazon Games.exe"
itchio_path1=$(ls -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/itch/app-"*/itch.exe | sort -V | tail -n 1)
itchio_path2=$(ls -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/itchioLauncher/pfx/drive_c/users/steamuser/AppData/Local/itch/app-"*/itch.exe | sort -V | tail -n 1)
legacygames_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Legacy Games/Legacy Games Launcher/Legacy Games Launcher.exe"
legacygames_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/LegacyGamesLauncher/pfx/drive_c/Program Files/Legacy Games/Legacy Games Launcher/Legacy Games Launcher.exe"
humblegames_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Humble App/Humble App.exe"
humblegames_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/HumbleGamesLauncher/pfx/drive_c/Program Files/Humble App/Humble App.exe"
indiegala_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/IGClient/IGClient.exe"
indiegala_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/IndieGalaLauncher/pfx/drive_c/Program Files/IGClient/IGClient.exe"
rockstar_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Rockstar Games/Launcher/Launcher.exe"
rockstar_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/RockstarGamesLauncher/pfx/drive_c/Program Files/Rockstar Games/Launcher/Launcher.exe"
glyph_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Glyph/GlyphClient.exe"
glyph_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/GlyphLauncher/pfx/drive_c/Program Files (x86)/Glyph/GlyphClient.exe"
minecraft_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Minecraft Launcher/MinecraftLauncher.exe"
minecraft_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/MinecraftLauncher/pfx/drive_c/Program Files (x86)/Minecraft Launcher/MinecraftLauncher.exe"
psplus_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/PlayStationPlus/pspluslauncher.exe"
psplus_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlaystationPlusLauncher/pfx/drive_c/Program Files (x86)/PlayStationPlus/pspluslauncher.exe"
vkplay_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/GameCenter/GameCenter.exe"
vkplay_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/VKPlayLauncher/pfx/drive_c/users/steamuser/AppData/Local/GameCenter/GameCenter.exe"
hoyoplay_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/HoYoPlay/launcher.exe"
hoyoplay_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/HoYoPlayLauncher/pfx/drive_c/Program Files/HoYoPlay/launcher.exe"
nexon_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Nexon/Nexon Launcher/nexon_launcher.exe"
nexon_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NexonLauncher/pfx/drive_c/Program Files (x86)/Nexon/Nexon Launcher/nexon_launcher.exe"
gamejolt_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/GameJoltClient/GameJoltClient.exe"
gamejolt_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/GameJoltLauncher/pfx/drive_c/users/steamuser/AppData/Local/GameJoltClient/GameJoltClient.exe"
artixgame_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Artix Game Launcher/Artix Game Launcher.exe"
artixgame_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/ArtixGameLauncher/pfx/drive_c/Program Files/Artix Game Launcher/Artix Game Launcher.exe"
arc_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Arc/Arc.exe"
arc_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/ARCLauncher/pfx/drive_c/Program Files (x86)/Arc/Arc.exe"
poketcg_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/The Pokémon Company International/Pokémon Trading Card Game Live/Pokemon TCG Live.exe"
poketcg_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PokeTCGLauncher/pfx/drive_c/users/steamuser/The Pokémon Company International/Pokémon Trading Card Game Live/Pokemon TCG Live.exe"
antstream_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Antstream Ltd/Antstream/AntstreamArcade.exe"
antstream_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/AntstreamLauncher/pfx/drive_c/Program Files (x86)/Antstream Ltd/Antstream/AntstreamArcade.exe"
purple_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/NCSOFT/Purple/PurpleLauncher.exe"
purple_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PURPLELauncher/pfx/drive_c/Program Files (x86)/NCSOFT/Purple/PurpleLauncher.exe"
plarium_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/PlariumPlay/PlariumPlay.exe"
plarium_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlariumLauncher/pfx/drive_c/users/steamuser/AppData/Local/PlariumPlay/PlariumPlay.exe"
vfun_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/VFUN/VLauncher/VFUNLauncher.exe"
vfun_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/VFUNLauncher/pfx/drive_c/VFUN/VLauncher/VFUNLauncher.exe"
tempo_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Tempo Launcher - Beta/Tempo Launcher - Beta.exe"
tempo_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/TempoLauncher/pfx/drive_c/Program Files/Tempo Launcher - Beta/Tempo Launcher - Beta.exe"
stove_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/ProgramData/Smilegate/STOVE/STOVE.exe"
stove_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/STOVELauncher/pfx/drive_c/ProgramData/Smilegate/STOVE/STOVE.exe"
bigfish_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/bfgclient/bfgclient.exe"
bigfish_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/BigFishLauncher/pfx/drive_c/Program Files (x86)/bfgclient/bfgclient.exe"
gryphlink_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/GRYPHLINK/Launcher.exe"
gryphlink_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/GryphlinkLauncher/pfx/drive_c/Program Files/GRYPHLINK/Launcher.exe"
# Chrome File Path
# chrome_installpath="/app/bin/chrome"
chrome_path="/usr/bin/flatpak"
chrome_startdir="\"/usr/bin\""
chromedirectory="\"$chrome_path\""
#Zenity Launcher Check Installation
function CheckInstallations {
declare -A paths1 paths2 names
paths1=(["epic_games"]="$epic_games_launcher_path1" ["gog_galaxy"]="$gog_galaxy_path1" ["uplay"]="$uplay_path1" ["battlenet"]="$battlenet_path1" ["eaapp"]="$eaapp_path1" ["amazongames"]="$amazongames_path1" ["itchio"]="$itchio_path1" ["legacygames"]="$legacygames_path1" ["humblegames"]="$humblegames_path1" ["indiegala"]="$indiegala_path1" ["rockstar"]="$rockstar_path1" ["glyph"]="$glyph_path1" ["minecraft"]="$minecraft_path1" ["psplus"]="$psplus_path1" ["vkplay"]="$vkplay_path1" ["hoyoplay"]="$hoyoplay_path1" ["nexon"]="$nexon_path1" ["gamejolt"]="$gamejolt_path1" ["artixgame"]="$artixgame_path1" ["arc"]="$arc_path1" ["poketcg"]="$poketcg_path1" ["antstream"]="$antstream_path1" ["purple"]="$purple_path1" ["plarium"]="$plarium_path1" ["vfun"]="$vfun_path1" ["tempo"]="$tempo_path1" ["stove"]="$stove_path1" ["bigfish"]="$bigfish_path1" ["gryphlink"]="$gryphlink_path1")
paths2=(["epic_games"]="$epic_games_launcher_path2" ["gog_galaxy"]="$gog_galaxy_path2" ["uplay"]="$uplay_path2" ["battlenet"]="$battlenet_path2" ["eaapp"]="$eaapp_path2" ["amazongames"]="$amazongames_path2" ["itchio"]="$itchio_path2" ["legacygames"]="$legacygames_path2" ["humblegames"]="$humblegames_path2" ["indiegala"]="$indiegala_path2" ["rockstar"]="$rockstar_path2" ["glyph"]="$glyph_path2" ["minecraft"]="$minecraft_path2" ["psplus"]="$psplus_path2" ["vkplay"]="$vkplay_path2" ["hoyoplay"]="$hoyoplay_path2" ["nexon"]="$nexon_path2" ["gamejolt"]="$gamejolt_path2" ["artixgame"]="$artixgame_path2" ["arc"]="$arc_path2" ["poketcg"]="$poketcg_path2" ["antstream"]="$antstream_path2" ["purple"]="$purple_path2" ["plarium"]="$plarium_path2" ["vfun"]="$vfun_path2" ["tempo"]="$tempo_path2" ["stove"]="$stove_path2" ["bigfish"]="$bigfish_path2" ["gryphlink"]="$gryphlink_path1")
names=(["epic_games"]="Epic Games" ["gog_galaxy"]="GOG Galaxy" ["uplay"]="Ubisoft Connect" ["battlenet"]="Battle.net" ["eaapp"]="EA App" ["amazongames"]="Amazon Games" ["itchio"]="itch.io" ["legacygames"]="Legacy Games" ["humblegames"]="Humble Games Collection" ["indiegala"]="IndieGala" ["rockstar"]="Rockstar Games Launcher" ["glyph"]="Glyph Launcher" ["minecraft"]="Minecraft Launcher" ["psplus"]="Playstation Plus" ["vkplay"]="VK Play" ["hoyoplay"]="HoYoPlay" ["nexon"]="Nexon Launcher" ["gamejolt"]="Game Jolt Client" ["artixgame"]="Artix Game Launcher" ["arc"]="ARC Launcher" ["poketcg"]="Pokémon Trading Card Game Live" ["antstream"]="Antstream Arcade" ["purple"]="PURPLE Launcher" ["plarium"]="Plarium Play" ["vfun"]="VFUN Launcher" ["tempo"]="Tempo Launcher" ["stove"]="STOVE Client" ["bigfish"]="Big Fish Games Manager" ["gryphlink"]="Gryphlink")
for launcher in "${!names[@]}"; do
if [[ -f "${paths1[$launcher]}" ]]; then
declare -g "${launcher}_value"="FALSE"
declare -g "${launcher}_text"="${names[$launcher]} ===> ${paths1[$launcher]}"
elif [[ -f "${paths2[$launcher]}" ]]; then
declare -g "${launcher}_value"="FALSE"
declare -g "${launcher}_text"="${names[$launcher]} ===> ${paths2[$launcher]}"
else
declare -g "${launcher}_value"="FALSE"
declare -g "${launcher}_text"="${names[$launcher]}"
fi
done
}
# Verify launchers are installed
function CheckInstallationDirectory {
declare -A paths names
paths=(["nonsteamlauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers" ["epicgameslauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/EpicGamesLauncher" ["goggalaxylauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/GogGalaxyLauncher" ["uplaylauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/UplayLauncher" ["battlenetlauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/Battle.netLauncher" ["eaapplauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/TheEAappLauncher" ["amazongameslauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/AmazonGamesLauncher" ["itchiolauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/itchioLauncher" ["legacygameslauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/LegacyGamesLauncher" ["humblegameslauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/HumbleGamesLauncher" ["indiegalalauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/IndieGalaLauncher" ["rockstargameslauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/RockstarGamesLauncher" ["glyphlauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/GlyphLauncher" ["minecraftlauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/MinecraftLauncher" ["pspluslauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlaystationPlusLauncher" ["vkplaylauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/VKPlayLauncher" ["hoyoplaylauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/HoYoPlayLauncher" ["nexonlauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NexonLauncher" ["gamejoltlauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/GameJoltLauncher" ["artixgamelauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/ArtixGameLauncher" ["arc"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/ARCLauncher" ["poketcglauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PokeTCGLauncher" ["antstreamlauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/AntstreamLauncher" ["purplelauncher"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PURPLELauncher" ["plarium"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlariumLauncher" ["vfun"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/VFUNLauncher" ["tempo"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/TempoLauncher" ["stove"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/STOVELauncher" ["bigfish"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/BigFishLauncher" ["gryphlink"]="${logged_in_home}/.local/share/Steam/steamapps/compatdata/GryphlinkLauncher")
names=(["nonsteamlauncher"]="NonSteamLaunchers" ["epicgameslauncher"]="EpicGamesLauncher" ["goggalaxylauncher"]="GogGalaxyLauncher" ["uplaylauncher"]="UplayLauncher" ["battlenetlauncher"]="Battle.netLauncher" ["eaapplauncher"]="TheEAappLauncher" ["amazongameslauncher"]="AmazonGamesLauncher" ["itchiolauncher"]="itchioLauncher" ["legacygameslauncher"]="LegacyGamesLauncher" ["humblegameslauncher"]="HumbleGamesLauncher" ["indiegalalauncher"]="IndieGalaLauncher" ["rockstargameslauncher"]="RockstarGamesLauncher" ["glyphlauncher"]="GlyphLauncher" ["minecraftlauncher"]="MinecraftLauncher" ["pspluslauncher"]="PlaystationPlusLauncher" ["vkplaylauncher"]="VKPlayLauncher" ["hoyoplaylauncher"]="HoYoPlayLauncher" ["nexonlauncher"]="NexonLauncher" ["gamejoltlauncher"]="GameJoltLauncher" ["artixgamelauncher"]="ArtixGameLauncher" ["arc"]="ARCLauncher" ["poketcg"]="PokeTCGLauncher" ["antstreamlauncher"]="AntstreamLauncher" ["purplelauncher"]="PURPLELauncher" ["plariumlauncher"]="PlariumLauncher" ["vfunlauncher"]="VFUNLauncher" ["tempolauncher"]="TempoLauncher" ["stovelauncher"]="STOVELauncher" ["bigfishlauncher"]="BigFishLauncher")
for launcher in "${!names[@]}"; do
if [[ -d "${paths[$launcher]}" ]]; then
declare -g "${launcher}_move_value"="TRUE"
else
declare -g "${launcher}_move_value"="FALSE"
fi
done
}
#Get SD Card Path
get_sd_path() {
local sd_mount
sd_mount=$(lsblk -nr -o NAME,MOUNTPOINT \
| awk '$1 ~ /^mmcblk.*p[0-9]+$/ && $2 != "" { print $2; exit }')
if [[ -z "$sd_mount" ]]; then
zenity --error --text="No SD card detected. Please insert and mount an SD card."
exit 1
fi
echo "$sd_mount"
}
### update proton ge
function patch_proton_script() {
proton_dir=$(find -L "${logged_in_home}/.steam/root/compatibilitytools.d" \
-maxdepth 1 -type d -name "GE-Proton*" | sort -V | tail -n1)
if [ -z "$proton_dir" ]; then
echo "No GE-Proton installation found to patch."
return
fi
proton_script="${proton_dir}/proton"
insert_line="os.environ['ENABLE_GAMESCOPE_WSI'] = '0'"
if [ -f "$proton_script" ] && ! grep -q "ENABLE_GAMESCOPE_WSI" "$proton_script"; then
echo "Patching Proton Python script to disable Gamescope WSI..."
sed -i "/^import protonfixes/a $insert_line" "$proton_script"
else
echo "Proton Python script already patched or not found."
fi
}
# Function For Updating Proton-GE
function download_ge_proton() {
echo "Downloading GE-Proton using the GitHub API"
cd "${logged_in_home}/Downloads/NonSteamLaunchersInstallation" || {
echo "Failed to change directory. Exiting."
exit 1
}
tarball_url=$(curl -s https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/latest \
| grep browser_download_url | cut -d\" -f4 | grep .tar.gz)
if [ -z "$tarball_url" ]; then
echo "Failed to get tarball URL. Exiting."
exit 1
fi
curl --retry 5 --retry-delay 0 --retry-max-time 60 -sLOJ "$tarball_url" || {
echo "Curl failed to download tarball. Exiting."
exit 1
}
checksum_url=$(curl -s https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/latest \
| grep browser_download_url | cut -d\" -f4 | grep .sha512sum)
if [ -z "$checksum_url" ]; then
echo "Failed to get checksum URL. Exiting."
exit 1
fi
curl --retry 5 --retry-delay 0 --retry-max-time 60 -sLOJ "$checksum_url" || {
echo "Curl failed to download checksum. Exiting."
exit 1
}
sha512sum -c ./*.sha512sum || {
echo "Checksum verification failed. Exiting."
exit 1
}
ge_folder_name=$(tar -tf GE-Proton*.tar.gz | head -n1 | cut -d/ -f1)
target_dir="${logged_in_home}/.steam/root/compatibilitytools.d/${ge_folder_name}"
if [ -d "$target_dir" ]; then
echo "Removing existing ${ge_folder_name} for clean replacement..."
rm -rf "$target_dir"
fi
tar -xf GE-Proton*.tar.gz -C "${logged_in_home}/.steam/root/compatibilitytools.d/" || {
echo "Tar extraction failed. Exiting."
exit 1
}
echo "All done :)"
}
function update_proton() {
echo "0"
echo "# Detecting, Updating and Installing GE-Proton...please wait..."
if [ ! -d "${logged_in_home}/.steam/root/compatibilitytools.d" ]; then
mkdir -p "${logged_in_home}/.steam/root/compatibilitytools.d" || {
echo "Failed to create directory. Exiting."
exit 1
}
fi
mkdir -p "${logged_in_home}/Downloads/NonSteamLaunchersInstallation" || {
echo "Failed to create directory. Exiting."
exit 1
}
proton_dir=$(find -L "${logged_in_home}/.steam/root/compatibilitytools.d" \
-maxdepth 1 -type d -name "GE-Proton*" | sort -V | tail -n1)
if [ -z "$proton_dir" ]; then
download_ge_proton
else
installed_version=$(basename "$proton_dir" | sed 's/GE-Proton-//')
latest_version=$(curl -s https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/latest \
| grep tag_name | cut -d '"' -f 4)
if [ "$installed_version" != "$latest_version" ]; then
download_ge_proton
fi
fi
patch_proton_script
}
### End of updating proton ge
# Function For Updating UMU Launcher
function download_umu_launcher() {
echo "Downloading UMU Launcher using the GitHub API"
cd "${logged_in_home}/Downloads/NonSteamLaunchersInstallation" || { echo "Failed to change directory. Exiting."; exit 1; }
# Get the download URL for a file that matches the pattern 'umu-launcher-*zipapp*.tar.gz'
zip_url=$(curl -s https://api.github.com/repos/Open-Wine-Components/umu-launcher/releases/latest | \
grep '"browser_download_url":' | grep -E 'umu-launcher-.*-zipapp.*\.(zip|tar\.gz|tar)' | \
cut -d '"' -f 4)
if [ -z "$zip_url" ]; then
echo "Failed to get zip/tar URL. Exiting."
fi
echo "Found download URL: $zip_url"
# Download the file
curl --retry 5 --retry-delay 0 --retry-max-time 60 -sLOJ "$zip_url"
if [ $? -ne 0 ]; then
echo "Curl failed to download the file. Exiting."
fi
# Ensure the bin directory exists
if [ ! -d "${logged_in_home}/bin" ]; then
mkdir -p "${logged_in_home}/bin" || { echo "Failed to create bin directory. Exiting."; exit 1; }
fi
# Get the downloaded file name
downloaded_file=$(basename "$zip_url")
# Check if the downloaded file is a .zip file or a .tar.gz file and extract accordingly
if [[ "$downloaded_file" =~ \.zip$ ]]; then
# Extract the .zip file into without preserving directory structure
unzip -o -j "$downloaded_file" -d "${logged_in_home}/bin/"
if [ $? -ne 0 ]; then
echo "Zip extraction failed. Exiting."
fi
elif [[ "$downloaded_file" =~ \.tar\.gz$ ]] || [[ "$downloaded_file" =~ \.tar$ ]]; then
# Check the actual file type using the `file` command
file_type=$(file --mime-type -b "$downloaded_file")
if [[ "$file_type" == "application/gzip" ]]; then
# If it's a gzipped tar file, extract it without leading directory (strip umu/)
tar --strip-components=1 -xvzf "$downloaded_file" -C "${logged_in_home}/bin/"
if [ $? -ne 0 ]; then
echo "Tar.gz extraction failed. Exiting."
exit 1
fi
elif [[ "$file_type" == "application/x-tar" ]]; then
# If it's a tar file (without gzip), extract it without leading directory
tar --strip-components=1 -xvf "$downloaded_file" -C "${logged_in_home}/bin/"
if [ $? -ne 0 ]; then
echo "Tar extraction failed. Exiting."
fi
else
echo "Unknown file type: $file_type. Exiting."
fi
else
echo "Unsupported file type: $downloaded_file. Exiting."
fi
# Make all extracted files executable
find "${logged_in_home}/bin/" -type f -exec chmod +x {} \;
if [ -f "${logged_in_home}/bin/umu-run" ]; then
"${logged_in_home}/bin/umu-run" winetricks --self-update
else
echo "umu-run not found. Skipping self-update."
fi
echo "UMU Launcher update completed :)"
}
function update_umu_launcher() {
echo "0"
echo "# Detecting, Updating and Installing UMU Launcher...please wait..."
# Create NonSteamLaunchersInstallation subfolder in Downloads folder
mkdir -p "${logged_in_home}/Downloads/NonSteamLaunchersInstallation" || { echo "Failed to create directory. Exiting."; exit 1; }
# Set the path to the UMU Launcher directory
umu_dir="${logged_in_home}/bin/umu-launcher"
# Check if UMU Launcher is installed
if [ ! -d "$umu_dir" ]; then
download_umu_launcher
else
# Check if installed version is the latest version
installed_version=$(cat "$umu_dir/version.txt")
latest_version=$(curl -s https://api.github.com/repos/Open-Wine-Components/umu-launcher/releases/latest | grep tag_name | cut -d '"' -f 4)
if [ "$installed_version" != "$latest_version" ]; then
download_umu_launcher
fi
fi
}
# Pre-logic system cleanup
CheckInstallations
CheckInstallationDirectory
#rm -rf "${logged_in_home}/.config/systemd/user/nslgamescanner.service"
#unlink "${logged_in_home}/.config/systemd/user/default.target.wants/nslgamescanner.service"
#systemctl --user daemon-reload
#systemctl --user reset-failed
# Define launcher entries
launcher_entries=(
"FALSE|SEPARATE APP IDS - CHECK THIS TO SEPARATE YOUR PREFIX"
"$epic_games_value|$epic_games_text"
"$gog_galaxy_value|$gog_galaxy_text"
"$uplay_value|$uplay_text"
"$battlenet_value|$battlenet_text"
"$amazongames_value|$amazongames_text"
"$eaapp_value|$eaapp_text"
"$legacygames_value|$legacygames_text"
"$itchio_value|$itchio_text"
"$humblegames_value|$humblegames_text"
"$indiegala_value|$indiegala_text"
"$rockstar_value|$rockstar_text"
"$glyph_value|$glyph_text"
"$minecraft_value|$minecraft_text"
"$psplus_value|$psplus_text"
"$vkplay_value|$vkplay_text"
"$hoyoplay_value|$hoyoplay_text"
"$nexon_value|$nexon_text"
"$gamejolt_value|$gamejolt_text"
"$artixgame_value|$artixgame_text"
"$arc_value|$arc_text"
"$purple_value|$purple_text"
"$plarium_value|$plarium_text"
"$vfun_value|$vfun_text"
"$tempo_value|$tempo_text"
"$poketcg_value|$poketcg_text"
"$antstream_value|$antstream_text"
"$stove_value|$stove_text"
"$bigfish_value|$bigfish_text"
"$gryphlink_value|$gryphlink_text"
"FALSE|Hytale"
"FALSE|RemotePlayWhatever"
"FALSE|NVIDIA GeForce NOW"
"FALSE|Moonlight Game Streaming"
)
chrome_entries=(
"FALSE|Fortnite"
"FALSE|Venge"
"FALSE|PokéRogue"
"FALSE|Xbox Game Pass"
"FALSE|Better xCloud"
"FALSE|GeForce Now"
"FALSE|Amazon Luna"
"FALSE|Stim.io"
"FALSE|Boosteroid Cloud Gaming"
"FALSE|Cloudy Pad"
"FALSE|Rocketcrab"
"FALSE|WebRcade"
"FALSE|WebRcade Editor"
"FALSE|Afterplay.io"
"FALSE|OnePlay"
"FALSE|AirGPU"
"FALSE|CloudDeck"
"FALSE|JioGamesCloud"
"FALSE|WatchParty"
"FALSE|Netflix"
"FALSE|Hulu"
"FALSE|Tubi"
"FALSE|Disney+"
"FALSE|Amazon Prime Video"
"FALSE|Youtube"
"FALSE|Youtube TV"
"FALSE|Twitch"
"FALSE|Apple TV+"
"FALSE|Crunchyroll"
"FALSE|Plex"
)
# Convert to newline-separated strings
launcher_data=$(IFS=$'\n'; echo "${launcher_entries[*]}")
chrome_data=$(IFS=$'\n'; echo "${chrome_entries[*]}")
# Export environment variables for GTK UI
export LAUNCHER_DATA="${launcher_data}"
export CHROME_DATA="${chrome_data}"
export UI_VERSION="${version}"
export UI_LIVE="${live}"
# Arrays and flags to be filled
selected_launchers=()
custom_websites=()
separate_appids=false
# --- Handle command line arguments or fallback to GTK UI ---
if [ $# -eq 0 ]; then
readarray -t gtk_output < <(python3 - <<'EOF'
import gi, os, sys, subprocess, re
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
def get_screen_resolution():
xrandr_output = subprocess.check_output(["xrandr"]).decode("utf-8")
resolutions = re.findall(r"(\d+)x(\d+)\s*\*+", xrandr_output)
return map(int, resolutions[0]) if resolutions else (1920,1080)
def is_multiple_monitors():
xrandr_output = subprocess.check_output(["xrandr"]).decode("utf-8")
return len(re.findall(r" connected", xrandr_output))>1
screen_width, screen_height = get_screen_resolution()
if is_multiple_monitors():
xrandr_output = subprocess.check_output(["xrandr"]).decode("utf-8")
match = re.search(r"(\d+)x(\d+)\s+connected", xrandr_output)
if match:
screen_width, screen_height = map(int, match.groups())
zenity_width = screen_width*80//100
zenity_height = screen_height*80//100
version = os.environ.get("UI_VERSION","NSL")
live = os.environ.get("UI_LIVE","")
launcher_lines = os.environ.get("LAUNCHER_DATA","").splitlines()
chrome_lines = os.environ.get("CHROME_DATA","").splitlines()
class LauncherUI(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Which launchers do you want to download and install?")
self.set_default_size(zenity_width, zenity_height)
self.store_launchers = Gtk.ListStore(bool, str)
self.store_chrome = Gtk.ListStore(bool, str)
for line in launcher_lines:
if "|" in line:
value,label = line.split("|",1)
self.store_launchers.append([value=="TRUE", label])
for line in chrome_lines:
if "|" in line:
value,label = line.split("|",1)
self.store_chrome.append([value=="TRUE", label])
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6, margin=10)
self.add(main_box)
header_label = Gtk.Label()
header_label.set_markup(
f"{version} — Default = one App ID Installation, One Prefix, "
f"NonSteamLaunchers - updated the NSLGameScanner.py {live}"
)
header_label.set_line_wrap(True)
header_label.set_xalign(0)
main_box.pack_start(header_label, False, False, 0)
# Helper for toggles
def create_tree(model,toggle_callback):
tree = Gtk.TreeView(model=model)
toggle = Gtk.CellRendererToggle()
toggle.connect("toggled",toggle_callback)
tree.append_column(Gtk.TreeViewColumn("Select",toggle,active=0))
tree.append_column(Gtk.TreeViewColumn("Name",Gtk.CellRendererText(),text=1))
return tree
# Launchers Tree
main_box.pack_start(Gtk.Label(label="Launchers:", xalign=0), False, False, 0)
launcher_tree = create_tree(self.store_launchers,self.on_toggle_launcher)
scrolled1 = Gtk.ScrolledWindow()
scrolled1.set_vexpand(True)
scrolled1.add(launcher_tree)
main_box.pack_start(scrolled1, True, True, 0)
# Chrome Tree
main_box.pack_start(Gtk.Label(label="Browser-based Services:", xalign=0), False, False,0)
chrome_tree = create_tree(self.store_chrome,self.on_toggle_chrome)
scrolled2 = Gtk.ScrolledWindow()
scrolled2.set_vexpand(True)
scrolled2.add(chrome_tree)
main_box.pack_start(scrolled2, True, True, 0)
# Horizontal browser checkboxes
main_box.pack_start(Gtk.Label(label="Select a browser (required for web services or websites & will attempt to be installed if needed):", xalign=0), False, False,0)
self.browser_names = ["Google Chrome","Mozilla Firefox","Brave","Microsoft Edge", "Vivaldi", "LibreWolf"]
self.browser_checks = {}
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=20, margin=5)
for name in self.browser_names:
check = Gtk.CheckButton(label=name)
check.connect("toggled", self.on_browser_checked, name)
self.browser_checks[name] = check
hbox.pack_start(check, False, False, 5)
main_box.pack_start(hbox, False, False, 0)
# Custom website names entry
self.entry_names = Gtk.Entry()
self.entry_names.set_placeholder_text("Enter the names for each site, separated by commas. E.g. Myspace, Limewire, AOL")
main_box.pack_start(self.entry_names, False, False, 0)
# Custom websites entry
self.entry = Gtk.Entry()
self.entry.set_placeholder_text("Enter custom websites that you want shortcuts for, separated by commas. Leave blank and press ok if you don't want any. E.g. myspace.com, limewire.com, my.screenname.aol.com")
main_box.pack_start(self.entry, False, False, 0)
# Buttons
button_box = Gtk.Box(spacing=6)
self.button_result = None
for label in ["Cancel","OK","❤️","Uninstall","🔍","Start Fresh","Move to SD Card","Update Proton-GE","🖥️ Off","NSLGameSaves","README"]:
btn = Gtk.Button(label=label)
btn.connect("clicked", self.on_button_clicked, label)
button_box.pack_start(btn, True, True, 0)
main_box.pack_start(button_box, False, False, 0)
# Toggle handlers
def on_toggle_launcher(self, widget, path):
self.store_launchers[path][0] = not self.store_launchers[path][0]
def on_toggle_chrome(self, widget, path):
self.store_chrome[path][0] = not self.store_chrome[path][0]
# Only one browser can be selected
def on_browser_checked(self, widget, name):
if widget.get_active():
for other_name, other_check in self.browser_checks.items():
if other_name != name:
other_check.set_active(False)
# Button click
def on_button_clicked(self, button, label):
selected_launchers = [row[1] for row in self.store_launchers if row[0]]
selected_chrome = [row[1] for row in self.store_chrome if row[0]]
selected_browser = [name for name, check in self.browser_checks.items() if check.get_active()]
website_names = self.entry_names.get_text().strip()
websites = self.entry.get_text().strip()
if label in ["Uninstall", "Move to SD Card"]:
if selected_launchers or selected_chrome or selected_browser or website_names or websites:
dlg = Gtk.MessageDialog(
parent=self,
flags=0,
message_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.OK,
text=f"{label} requires no other selections."
)
dlg.format_secondary_text(
"Please uncheck all launchers, services, browsers, and clear any custom websites before continuing."
)
dlg.run()
dlg.destroy()
return
# Enforce browser selection if needed
if (selected_chrome or websites) and not selected_browser:
dlg = Gtk.MessageDialog(parent=self, flags=0, message_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.OK,
text="You must select a browser if you chose a web service or entered a website.")
dlg.run()
dlg.destroy()
return
selected = selected_launchers + selected_chrome + selected_browser
print("|".join(selected))
print(website_names)
print(websites)
print(label)
print("|".join(selected_browser))
sys.stdout.flush()
Gtk.main_quit()
win = LauncherUI()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
EOF
)
selected_launchers_str="${gtk_output[0]}"
custom_website_names_str="${gtk_output[1]}"
custom_websites_str="${gtk_output[2]}"
extra_button="${gtk_output[3]}"
selected_browser="${gtk_output[4]}"
IFS=',' read -ra custom_website_names <<< "$custom_website_names_str"
IFS=',' read -ra custom_websites <<< "$custom_websites_str"
IFS='|' read -ra selected_launchers <<< "$selected_launchers_str"
# Determine what to put in options:
if [[ "$extra_button" == "OK" ]]; then
options="$selected_launchers_str"
elif [[ "$selected_launchers_str" == "" ]]; then
# Only a button was pressed, no launchers selected
options="$extra_button"
else
# Button pressed with launchers selected, combine both
options="$extra_button|$selected_launchers_str"
fi
else
# CLI args present — parse them
for arg in "$@"; do
if [[ "$arg" =~ ^https?:// ]]; then
website=${arg#http://}
website=${website#https://}
IFS=',' read -ra websites <<< "$website"
for site in "${websites[@]}"; do
custom_websites+=("$site")
done
else
selected_launchers+=("$arg")
fi
done
custom_websites_str=$(IFS=', '; echo "${custom_websites[*]}")
extra_button="OK"
options="${selected_launchers[*]}"
fi
# Handle validation (skip if extra button is special)
case "$extra_button" in
"Start Fresh"|"Uninstall"|"Move to SD Card"|"Update Proton-GE"|"NSLGameSaves"|"README"|"🖥️ Off"|"❤️"|"🔍")
# Skip validation
;;
*)
if [ ${#selected_launchers[@]} -eq 0 ] && [ ${#custom_websites[@]} -eq 0 ]; then
zenity --error --text="No launchers or websites selected. Exiting." --width=300 --timeout=5
exit 1
fi
;;
esac
# Handle special buttons
if [[ "$extra_button" == "🖥️ Off" ]]; then
sleep 1
xset dpms force off
exit 0
fi
if [[ "$extra_button" == "README" ]]; then
README_URL="https://raw.githubusercontent.com/moraroy/NonSteamLaunchers-On-Steam-Deck/main/README.md"
TEMP_FILE=$(mktemp)
curl -s "$README_URL" |
sed 's/<[^>]*>//g' |
sed 's/^###\s*/---\n/g' |
sed 's/^##\s*/--\n/g' |
sed 's/^#\s*/\n/g' |
sed 's/^[-*]\s*/- /g' > "$TEMP_FILE"
zenity --text-info --title="NonSteamLaunchers README" --width=800 --height=600 --filename="$TEMP_FILE"
rm "$TEMP_FILE"
exit 1
fi
# Determine if separate app ID option was selected
for launcher in "${selected_launchers[@]}"; do
if [[ "$launcher" == "SEPARATE APP IDS - CHECK THIS TO SEPARATE YOUR PREFIX" ]]; then
separate_appids=true
break
fi
done
# Check if the user selected to use separate app IDs
if [[ $options == *"SEPARATE APP IDS - CHECK THIS TO SEPARATE YOUR PREFIX"* ]]; then
# User selected to use separate app IDs
use_separate_appids=true
else
# User did not select to use separate app IDs
use_separate_appids=false
fi
# Debug Output (optional)
echo "Selected launchers: ${selected_launchers[*]}"
echo "Custom websites: ${custom_websites[*]}"
echo "Separate App IDs: $separate_appids"
echo "Extra button: $extra_button"
echo "Options: $options"
# Define the StartFreshFunction
StartFreshFunction() {
sd_path=$(get_sd_path)
compatdata_dir="${logged_in_home}/.local/share/Steam/steamapps/compatdata"
other_dir="${logged_in_home}/.local/share/Steam/steamapps/shadercache"
folder_names=("EpicGamesLauncher" "GogGalaxyLauncher" "UplayLauncher" "Battle.netLauncher" "TheEAappLauncher" "AmazonGamesLauncher" "itchioLauncher" "LegacyGamesLauncher" "HumbleGamesLauncher" "IndieGalaLauncher" "RockstarGamesLauncher" "GlyphLauncher" "PlaystationPlusLauncher" "VKPlayLauncher" "HoYoPlayLauncher" "NexonLauncher" "GameJoltLauncher" "ArtixGameLauncher" "ARCLauncher" "PokeTCGLauncher" "AntstreamLauncher" "PURPLELauncher" "PlariumLauncher" "VFUNLauncher" "TempoLauncher" "STOVELauncher" "BigFishLauncher" "NonSteamLaunchers" "MinecraftLauncher" "GryphlinkLauncher")
app_ids=("3772819390" "4294900670" "4063097571" "3786021133" "3448088735" "3923904787" "3440562512" "2948446662" "3908676077" "4206469918" "3303169468" "3595505624" "4272271078" "3259996605" "2588786779" "4090616647" "3494943831" "2390200925" "4253976432" "2221882453" "2296676888" "2486751858" "3974004104" "3811372789" "3788101956" "3782277090" "3640061468" "3216372511" "2882622939" "2800812206" "2580882702" "4022508926" "4182617613" "1981254598" "2136059209" "1401184678" "3141683525")
delete_path() {
local path="$1"
if [ -e "$path" ]; then
if [ -L "$path" ]; then
target=$(readlink -f "$path")
rm -rf "$target"
unlink "$path"
echo "Deleted symlink and target: $path -> $target"
else
rm -rf "$path"
echo "Deleted folder: $path"
fi
fi
}
for folder in "${folder_names[@]}"; do
delete_path "${compatdata_dir}/${folder}"
done
for app_id in "${app_ids[@]}"; do
delete_path "${other_dir}/${app_id}"
done
for folder_path in "$compatdata_dir"/*; do
[ -d "$folder_path" ] && [ -z "$(ls -A "$folder_path")" ] && rmdir "$folder_path" && echo "Deleted empty folder: $(basename "$folder_path")"
done
# Remove folders on SD card dynamically
for folder in "${folder_names[@]}"; do
delete_path "${sd_path}/${folder}"
done
delete_path "${logged_in_home}/Downloads/NonSteamLaunchersInstallation"
delete_path "${logged_in_home}/.config/systemd/user/Modules"
delete_path "${logged_in_home}/.config/systemd/user/env_vars"
delete_path "${logged_in_home}/.config/systemd/user/NSLGameScanner.py"
delete_path "${logged_in_home}/.config/systemd/user/shortcuts"
delete_path "${logged_in_home}/.config/systemd/user/descriptions.json"
delete_path "${logged_in_home}/.local/share/applications/RemotePlayWhatever"
delete_path "${logged_in_home}/.local/share/applications/RemotePlayWhatever.desktop"
delete_path "${logged_in_home}/Downloads/NonSteamLaunchers-install.log"
delete_path "${logged_in_home}/.config/systemd/user/nslgamescanner.service"
unlink "${logged_in_home}/.config/systemd/user/default.target.wants/nslgamescanner.service" 2>/dev/null || true
systemctl --user daemon-reload
systemctl --user reset-failed
show_message "NonSteamLaunchers has been wiped!"
exit 0
}
# Check if the Start Fresh button was clicked or if the Start Fresh option was passed as a command line argument
if [[ $options == "Start Fresh" ]] || [[ $selected_launchers == "Start Fresh" ]]; then
# The Start Fresh button was clicked or the Start Fresh option was passed as a command line argument
if [ ${#args[@]} -eq 0 ]; then
# No command line arguments were provided, so display the zenity window
if zenity --question --text="aaahhh it always feels good to start fresh :) but...This will delete the App ID folders you installed inside the steamapps/compatdata/ directory as well as the Shader Cache associated with them in the steamapps/shadercache directory. The nslgamescanner.service will also be terminated at /.config/systemd/user/ This means anything youve installed (launchers or games) WITHIN THIS SCRIPT will be deleted if you have them there. Everything will be wiped. Are you sure?" --width=300 --height=260; then
# The user clicked the "Yes" button, so call the StartFreshFunction
StartFreshFunction
# If the Start Fresh function was called, set an environment variable
if [ "$?" -eq 0 ]; then
export START_FRESH=true
else
export START_FRESH=false
fi
else
# The user clicked the "No" button, so exit with exit code 0 to indicate success.
exit 0
fi
else
# Command line arguments were provided, so skip displaying the zenity window and directly perform any necessary actions to start fresh by calling the StartFreshFunction
StartFreshFunction
fi
fi
#Set Downloads INFO
echo "10"
echo "# Setting files in their place"
# Set the appid for the non-Steam game
appid=NonSteamLaunchers
# Set the URL to download the MSI file from
msi_url=https://launcher-public-service-prod06.ol.epicgames.com/launcher/api/installer/download/EpicGamesLauncherInstaller.msi
# Set the path to save the MSI file to
msi_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/EpicGamesLauncherInstaller.msi
# Set the URL to download the second file from
exe_url=https://content-system.gog.com/open_link/download?path=/open/galaxy/client/2.0.74.352/setup_galaxy_2.0.74.352.exe
#exe_url=https://webinstallers.gog-statics.com/download/GOG_Galaxy_2.0.exe
# Set the path to save the second file to
exe_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/setup_galaxy_2.0.74.352.exe
#exe_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/GOG_Galaxy_2.0.exe
# Set the URL to download the third file from
ubi_url=https://ubi.li/4vxt9
# Set the path to save the third file to
ubi_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/UbisoftConnectInstaller.exe
# Set the URL to download the fifth file from
battle_url="https://www.battle.net/download/getInstallerForGame?os=win&gameProgram=BATTLENET_APP&version=Live"
# Set the path to save the fifth file to
battle_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/Battle.net-Setup.exe
# Set the URL to download the sixth file from
amazon_url=https://download.amazongames.com/AmazonGamesSetup.exe
# Set the path to save the sixth file to
amazon_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/AmazonGamesSetup.exe
# Set the URL to download the seventh file from
eaapp_url=https://origin-a.akamaihd.net/EA-Desktop-Client-Download/installer-releases/EAappInstaller.exe
# Set the path to save the seventh file to
eaapp_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/EAappInstaller.exe
# Set the URL to download the eighth file from
itchio_url=https://itch.io/app/download?platform=windows
# Set the path to save the eighth file to
itchio_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/itch-setup.exe
# Set the URL to download the ninth file from
legacygames_url=https://cdn.legacygames.com/LegacyGamesLauncher/legacy-games-launcher-setup-1.10.0-x64-full.exe
# Set the path to save the ninth file to
legacygames_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/legacy-games-launcher-setup-1.10.0-x64-full.exe
# Set the URL to download the tenth file from
humblegames_url=https://www.humblebundle.com/app/download
# Set the path to save the tenth file to
humblegames_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/Humble-App-Setup-1.1.8+411.exe
# Set the URL to download the eleventh file from
indiegala_url=https://content.indiegalacdn.com/common/IGClientSetup.exe
# Set the path to save the eleventh file to
indiegala_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/IGClientSetup.exe
# Set the URL to download the twelfth file from
rockstar_url=https://gamedownloads.rockstargames.com/public/installer/Rockstar-Games-Launcher.exe
# Set the path to save the twelfth file to
rockstar_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/Rockstar-Games-Launcher.exe
# Set the URL to download the Glyph Launcher file from
glyph_url=https://glyph.dyn.triongames.com/glyph/live/GlyphInstall.exe
# Set the path to save the Glyph Launcher to
glyph_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/GlyphInstall.exe
# Set the URL to download the Minecraft Launcher file from
minecraft_url=https://aka.ms/minecraftClientWindows
# Set the path to save the Minecraft Launcher to
minecraft_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/MinecraftInstaller.msi
# Set the URL to download the Playstation Launcher file from
psplus_url=https://download-psplus.playstation.com/downloads/psplus/pc/latest
# Set the path to save the Playstation Launcher to
psplus_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/PlayStationPlus-12.2.0.exe
# Set the URL to download the VK Play Launcher file from
vkplay_url=https://static.gc.vkplay.ru/VKPlayLoader.exe
# Set the path to save the VK Play Launcher to
vkplay_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/VKPlayLoader.exe
# Set the URL to download the Hoyo Play Play Launcher file from
hoyoplay_url="https://download-porter.hoyoverse.com/download-porter/2025/02/21/VYTpXlbWo8_1.4.5.222_1_0_hyp_hoyoverse_prod_202502081529_XFGRLkBk.exe"
# Set the path to save the Hoyo Play Launcher to
hoyoplay_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/HoYoPlay_install.exe"
# Set the URL to download the Nexon Launcher file from
nexon_url="https://download.nxfs.nexon.com/download-launcher?file=NexonLauncherSetup.exe&client-id=959013368.1720525616"
# Set the path to save the Nexon Launcher to
nexon_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/NexonLauncherSetup.exe
# Set the URL to download the GameJolt Launcher file from
gamejolt_url="https://files.catbox.moe/mv4jos"
# Set the path to save the GameJolt Launcher to
gamejolt_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/gamejoltclientsetup.exe
# Set the URL to download the artix Launcher file from
artixgame_url=https://launch.artix.com/latest/ArtixLauncher_win_x64.exe
# Set the path to save the artix Launcher to
artixgame_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/ArtixLauncher_win_x64.exe"
# Set the URL to download the arc Launcher file from
arc_url=https://www.arcgames.com/download
# Set the path to save the arc Launcher to
arc_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/Ar3Setup.exe"
#PokemonTCGLIVE
poketcg_url=https://installer.studio-prod.pokemon.com/installer/PokemonTCGLiveInstaller.msi
poketcg_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/PokemonTCGLiveInstaller.msi
#Antstream Arcade
antstream_url=https://downloads.antstream.com/antstreamInstaller-2.1.2986.exe
antstream_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/antstreamInstaller-2.1.2986.exe
#PURPLE Launcher
purple_url=https://gs-purple-inst.download.ncupdate.com/Purple/PurpleInstaller_2_25_325_23.exe
purple_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/PurpleInstaller_2_25_325_23.exe
#Plarium Launcher
plarium_url="https://installer.plarium.com/desktop?lid=1&arc=64&os=windows"
plarium_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/PlariumPlaySetup.exe
#VFUNLauncher
vfun_url=https://vfun-cdn.qijisoft.com/vlauncher/fullclient/VFUNLauncherInstaller.exe
vfun_file=${logged_in_home}/Downloads/NonSteamLaunchersInstallation/VFUNLauncherInstaller.exe
# TempoLauncher
tempo_url="https://cdn.playthebazaar.com/launcher-0ca5d6/Tempo%20Launcher%20-%20Beta%20Setup%201.0.4.exe"
tempo_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/TempoLauncherSetup.exe"
#StoveLauncher
stove_url="https://sgs-live-dl.game.playstove.com/game/lcs/STOVESetup.exe"
stove_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/STOVESetup.exe"
#bigfishLauncher
bigfish_url="https://cdn-content.bigfishgames.com/prodstatic/games/gm_32/gm_installers/currentInstallers/Windows/bfginstaller32_s1_l1.exe"
bigfish_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/bfginstaller32_s1_l1.exe"
gryphlink_url="https://launcher.hg-cdn.com/TiaytKBUIEdoEwRT/launcher/1.1.0/6/6/NVX60B0FgrIAIWH2/GRYPHLINK_v1.1.0.1107_6_6_endfield.exe"
gryph_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/GRYPHLINK_v1.1.0.1107_6_6_endfield.exe"
#End of Downloads INFO
# Function to handle common uninstallation tasks
handle_uninstall_common() {
compatdata_dir=$1
uninstaller_path=$2
uninstaller_options=$3
app_name=$4
# Set the path to the Proton directory
proton_dir=$(find -L "${logged_in_home}/.steam/root/compatibilitytools.d" -maxdepth 1 -type d -name "GE-Proton*" | sort -V | tail -n1)
# Set the paths for the environment variables
STEAM_RUNTIME="${logged_in_home}/.steam/root/ubuntu12_32/steam-runtime/run.sh"
STEAM_COMPAT_CLIENT_INSTALL_PATH="${logged_in_home}/.local/share/Steam"
STEAM_COMPAT_DATA_PATH="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${compatdata_dir}"
# Export the STEAM_COMPAT_DATA_PATH variable
export STEAM_COMPAT_DATA_PATH
export STEAM_COMPAT_CLIENT_INSTALL_PATH
# Run the uninstaller using Proton with the specified options
echo "Running uninstaller using Proton with the specified options"
"$STEAM_RUNTIME" "$proton_dir/proton" run "$uninstaller_path" $uninstaller_options
# Display Zenity window
zenity --info --text="$app_name has been uninstalled." --width=200 --height=150 &
sleep 3
killall zenity
}
# Function to handle EA App uninstallation
handle_uninstall_ea() {
mkdir -p ${logged_in_home}/Downloads/NonSteamLaunchersInstallation
# Download EA App file
if [ ! -f "$eaapp_file" ]; then
echo "Downloading EA App file"
wget $eaapp_url -O $eaapp_file
fi
handle_uninstall_common "$1" "$eaapp_file" "/uninstall /quiet" "EA App"
}
# Uninstall EA App
if [[ $uninstall_options == *"Uninstall EA App"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Electronic Arts" ]]; then
handle_uninstall_ea "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/TheEAappLauncher/pfx/drive_c/Program Files/Electronic Arts" ]]; then
handle_uninstall_ea "TheEAappLauncher"
fi
fi
# Function to handle GOG Galaxy uninstallation
handle_uninstall_gog() {
gog_uninstaller="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${1}/pfx/drive_c/Program Files (x86)/GOG Galaxy/unins000.exe"
handle_uninstall_common "$1" "$gog_uninstaller" "/SILENT" "GOG Galaxy"
}
# Uninstall GOG Galaxy
if [[ $uninstall_options == *"Uninstall GOG Galaxy"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/GOG Galaxy" ]]; then
handle_uninstall_gog "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/GogGalaxyLauncher/pfx/drive_c/Program Files (x86)/GOG Galaxy" ]]; then
handle_uninstall_gog "GogGalaxyLauncher"
fi
fi
# Function to handle Legacy Games Launcher uninstallation
handle_uninstall_legacy() {
legacy_uninstaller="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${1}/pfx/drive_c/Program Files/Legacy Games/Legacy Games Launcher/Uninstall Legacy Games Launcher.exe"
handle_uninstall_common "$1" "$legacy_uninstaller" "/allusers /S" "Legacy Games Launcher"
}
# Uninstall Legacy Games Launcher
if [[ $uninstall_options == *"Uninstall Legacy Games Launcher"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Legacy Games/Legacy Games Launcher" ]]; then
handle_uninstall_legacy "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/LegacyGamesLauncher/pfx/drive_c/Program Files/Legacy Games/Legacy Games Launcher" ]]; then
handle_uninstall_legacy "LegacyGamesLauncher"
fi
fi
# Function to handle PlayStation Plus uninstallation
handle_uninstall_psplus() {
reg_paths=(
"$logged_in_home/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/system.reg"
"$logged_in_home/.local/share/Steam/steamapps/compatdata/PlaystationPlusLauncher/pfx/system.reg"
)
psplus_uninstaller="MsiExec.exe"
psplus_uninstaller_options=""
for reg_file in "${reg_paths[@]}"; do
[ -f "$reg_file" ] || continue
uninstall_string=$(awk '
BEGIN { in_section=0 }
/^\[/ {
in_section=0
next
}
/"DisplayName"="PlayStation Plus"/ {
in_section=1
next
}
in_section && /"UninstallString"=str\(2\):"/ {
match($0, /str\(2\):"(.*)"/, arr)
if (arr[1] != "") {
print arr[1]
exit
}
}
' "$reg_file")
if [[ -n "$uninstall_string" ]]; then
# Remove leading "MsiExec.exe " from uninstall string to get only options
psplus_uninstaller_options="${uninstall_string#MsiExec.exe }"
# Append /quiet if not already present
if [[ "$psplus_uninstaller_options" != *"/quiet"* ]]; then
psplus_uninstaller_options="$psplus_uninstaller_options /quiet"
fi
break
fi
done
if [ -z "$psplus_uninstaller_options" ]; then
echo "PlayStation Plus uninstaller not found."
return 1
fi
# Call the common uninstall handler with executable and options separated properly
handle_uninstall_common "$1" "$psplus_uninstaller" "$psplus_uninstaller_options" "PlayStation Plus"
}
# Uninstall PlayStation Plus
if [[ $uninstall_options == *"Uninstall PlayStation Plus"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/PlayStationPlus" ]]; then
handle_uninstall_psplus "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlaystationPlusLauncher/pfx/drive_c/Program Files (x86)/PlayStationPlus" ]]; then
handle_uninstall_psplus "PlaystationPlusLauncher"
fi
fi
# Function to handle Artix uninstallation
handle_uninstall_artix() {
artix_uninstaller="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${1}/pfx/drive_c/Program Files/Artix Game Launcher/Uninstall Artix Game Launcher.exe"
handle_uninstall_common "$1" "$artix_uninstaller" "/S" "Artix Game Launcher"
}
# Uninstall Artix
if [[ $uninstall_options == *"Uninstall Artix Game Launcher"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Artix Game Launcher" ]]; then
handle_uninstall_artix "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/ArtixGameLauncher/pfx/drive_c/Program Files/Artix Game Launcher" ]]; then
handle_uninstall_artix "ArtixGameLauncher"
fi
fi
# Function to handle Antstream uninstallation
handle_uninstall_antstream() {
mkdir -p ${logged_in_home}/Downloads/NonSteamLaunchersInstallation
# Download Antstream file
if [ ! -f "$antstream_file" ]; then
echo "Downloading Antstream Arcade file"
wget $antstream_url -O $antstream_file
fi
handle_uninstall_common "$1" "$antstream_file" "/uninstall /quiet" "AntStream Arcade"
}
# Uninstall Antstream Arcade
if [[ $uninstall_options == *"Uninstall Antstream Arcade"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Antstream Ltd" ]]; then
handle_uninstall_antstream "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/AntstreamLauncher/pfx/drive_c/Program Files (x86)/Antstream Ltd" ]]; then
handle_uninstall_antstream "AntstreamLauncher"
fi
fi
# Function to handle PURPLE uninstallation
handle_uninstall_purple() {
# Define the path to the Purple uninstaller
purpleun_file="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${1}/pfx/drive_c/Program Files (x86)/NCSOFT/Purple/Uninstall.exe"
# Call the common uninstallation handler with necessary parameters
handle_uninstall_common "$1" "$purpleun_file" "/S" "PURPLE Launcher"
sleep 5
# Timeout duration (30 seconds)
timeout=30
elapsed=0
while [ $elapsed -lt $timeout ]; do
# Check if Un_A.exe is running
if pgrep -f "Un_A.exe" > /dev/null; then
# Kill the Un_A.exe process
pkill -f "Un_A.exe"
echo "Un_A.exe has been terminated."
return
fi
# Wait for 1 second before checking again
sleep 1
elapsed=$((elapsed + 1))
done
# If we reach here, Un_A.exe wasn't found within the timeout
echo "Un_A.exe was not found within the $timeout seconds timeout."
}
# Uninstall PURPLE
if [[ $uninstall_options == *"Uninstall PURPLE Launcher"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Antstream Ltd" ]]; then
handle_uninstall_purple "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Antstream Ltd" ]]; then
handle_uninstall_purple "PURPLELauncher"
fi
fi
# Function to handle Plarium Play folder deletion
handle_uninstall_plarium() {
# Define the two possible paths
plarium_play_dir_1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/PlariumPlay"
plarium_play_dir_2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlariumLauncher/pfx/drive_c/users/steamuser/AppData/Local/PlariumPlay"
# Check if either of the directories exists and delete the first one found
if [ -d "$plarium_play_dir_1" ]; then
echo "Deleting PlariumPlay folder from path 1... and is now uninstalled."
rm -rf "$plarium_play_dir_1"
# Notify the user via Zenity
zenity --info --text="Plarium Play folder has been successfully deleted from path 1." --width=300 --height=150 &
sleep 3
killall zenity
elif [ -d "$plarium_play_dir_2" ]; then
echo "Deleting PlariumPlay folder from path 2...and is now uninstalled."
rm -rf "$plarium_play_dir_2"
# Notify the user via Zenity
zenity --info --text="Plarium Play folder has been successfully deleted from path 2." --width=300 --height=150 &
sleep 3
killall zenity
else
# Notify the user if neither folder exists
zenity --error --text="Plarium Play folder not found at either path. Please check the paths." --width=300 --height=150 &
fi
}
# Function to handle Tempo uninstallation
handle_uninstall_tempo() {
tempo_uninstaller="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${1}/pfx/drive_c/Program Files/Tempo Launcher - Beta/Uninstall Tempo Launcher - Beta.exe"
handle_uninstall_common "$1" "$tempo_uninstaller" "/S" "Tempo Launcher"
}
# Uninstall Tempo
if [[ $uninstall_options == *"Uninstall Tempo Launcher"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Tempo Launcher - Beta" ]]; then
handle_uninstall_tempo "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/TempoLauncher/pfx/drive_c/Program Files/Tempo Launcher - Beta" ]]; then
handle_uninstall_tempo "TempoLauncher"
fi
fi
# Function to handle Stove uninstallation
handle_uninstall_stove() {
stove_uninstaller="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${1}/pfx/drive_c/users/steamuser/AppData/Local/STOVE/Uninstall/STOVE/uninstall.exe"
handle_uninstall_common "$1" "$stove_uninstaller" "" "STOVE Client"
}
# Uninstall Stove
if [[ $uninstall_options == *"Uninstall STOVE Client"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/ProgramData/Smilegate/STOVE" ]]; then
handle_uninstall_stove "NonSteamLaunchers"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/STOVELauncher/pfx/drive_c/ProgramData/Smilegate/STOVE" ]]; then
handle_uninstall_stove "STOVELauncher"
fi
fi
handle_uninstall_bfg() {
bfg_uninstaller="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${1}/pfx/drive_c/Program Files (x86)/bfgclient/uninstall.exe"
handle_uninstall_common "$1" "$bfg_uninstaller" "/S" "Big Fish Games Manager"
}
# Uninstall BFG Client
if [[ $uninstall_options == *"Uninstall Big Fish Games Manager"* ]]; then
if [[ -f "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/bfgclient/uninstall.exe" ]]; then
handle_uninstall_bfg "NonSteamLaunchers"
elif [[ -f "${logged_in_home}/.local/share/Steam/steamapps/compatdata/BigFishLauncher/pfx/drive_c/Program Files (x86)/bfgclient/uninstall.exe" ]]; then
handle_uninstall_bfg "BigFishLauncher"
fi
fi
uninstall_launcher() {
local uninstall_options=$1
local launcher=$2
local path1=$3
local path2=$4
local remove_path1=$5
local remove_path2=$6
shift 6
if [[ $uninstall_options == *"Uninstall $launcher"* ]]; then
if [[ -f "$path1" ]]; then
rm -rf "$remove_path1"
zenity --info --text="$launcher has been uninstalled." --width=200 --height=150 &
sleep 3
killall zenity
elif [[ -f "$path2" ]]; then
rm -rf "$remove_path2"
zenity --info --text="$launcher has been uninstalled." --width=200 --height=150 &
sleep 3
killall zenity
fi
for env_var_prefix in "$@"; do # Loop over the remaining arguments
sed -i "/^export ${env_var_prefix}.*/Id" "${logged_in_home}/.config/systemd/user/env_vars"
done
echo "Deleted environment variables for $launcher"
fi
}
# Function to process uninstall options
process_uninstall_options() {
local uninstall_options=$1
if [[ -n $uninstall_options ]]; then
# Call uninstall_launcher for each launcher
# Add more launchers as needed
if [[ $uninstall_options == *"Uninstall GOG Galaxy"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/GOG Galaxy" ]]; then
handle_uninstall_gog "NonSteamLaunchers"
rm -rf "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/GOG.com"
uninstall_launcher "$uninstall_options" "GOG Galaxy" "$gog_galaxy_path1" "$gog_galaxy_path2" "" "" "gog"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/GogGalaxyLauncher/pfx/drive_c/Program Files (x86)/GOG Galaxy" ]]; then
handle_uninstall_gog "GogGalaxyLauncher"
rm -rf "${logged_in_home}/.local/share/Steam/steamapps/compatdata/GogGalaxyLauncher/pfx/drive_c/users/steamuser/AppData/Local/GOG.com"
uninstall_launcher "$uninstall_options" "GOG Galaxy" "$gog_galaxy_path1" "$gog_galaxy_path2" "" "" "gog"
fi
fi
if [[ $uninstall_options == *"Uninstall EA App"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Electronic Arts" ]]; then
handle_uninstall_ea "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "EA App" "$eaapp_path1" "$eaapp_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/Downloads/EAappInstaller.exe" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/TheEAappLauncher/pfx/drive_c/users/steamuser/Downloads/EAappInstaller.exe" "eaapp" "ea_app"
sed -i '/repaireaapp/d' "${logged_in_home}/.config/systemd/user/env_vars"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/TheEAappLauncher/pfx/drive_c/Program Files/Electronic Arts" ]]; then
handle_uninstall_ea "TheEAappLauncher"
uninstall_launcher "$uninstall_options" "EA App" "$eaapp_path1" "$eaapp_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/Downloads/EAappInstaller.exe" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/TheEAappLauncher/pfx/drive_c/users/steamuser/Downloads/EAappInstaller.exe" "eaapp" "ea_app"
sed -i '/repaireaapp/d' "${logged_in_home}/.config/systemd/user/env_vars"
fi
fi
if [[ $uninstall_options == *"Uninstall Legacy Games"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Legacy Games" ]]; then
handle_uninstall_legacy "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "Legacy Games" "$legacygames_path1" "$legacygames_path2" "" "" "legacy"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/LegacyGamesLauncher/pfx/drive_c/Program Files/Legacy Games" ]]; then
handle_uninstall_legacy "LegacyGamesLauncher"
uninstall_launcher "$uninstall_options" "Legacy Games" "$legacygames_path1" "$legacygames_path2" "" "" "legacy"
fi
fi
if [[ $uninstall_options == *"Uninstall Playstation Plus"* ]]; then
# NonSteamLaunchers prefix: run uninstaller, do not delete prefix
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/PlayStationPlus" ]]; then
handle_uninstall_psplus "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "Playstation Plus" "$psplus_path1" "" "" "" "psplus"
fi
# PlaystationPlusLauncher prefix: run uninstaller and delete prefix
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlaystationPlusLauncher/pfx/drive_c/Program Files (x86)/PlayStationPlus" ]]; then
handle_uninstall_psplus "PlaystationPlusLauncher"
uninstall_launcher "$uninstall_options" "Playstation Plus" "$psplus_path2" "" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlaystationPlusLauncher" "" "psplus"
rm -rf "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlaystationPlusLauncher"
fi
fi
if [[ $uninstall_options == *"Uninstall Artix Game Launcher"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Artix Game Launcher" ]]; then
handle_uninstall_artix "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "Artix Game Launcher" "$artixgame_path1" "$artixgame_path2" "" "" "artixgame"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/ArtixGameLauncher/pfx/drive_c/Program Files/Artix Game Launcher" ]]; then
handle_uninstall_artix "ArtixGameLauncher"
uninstall_launcher "$uninstall_options" "Artix Game Launcher" "$artixgame_path1" "$artixgame_path2" "" "" "artixgame"
fi
fi
if [[ $uninstall_options == *"Uninstall Antstream Arcade"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Antstream Ltd" ]]; then
handle_uninstall_antstream "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "Antstream Arcade" "$antstream_path1" "$antstream_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Antstream Ltd" "antstream" "antstream"
sed -i '' "${logged_in_home}/.config/systemd/user/env_vars"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/AntstreamLauncher/pfx/drive_c/Program Files (x86)/Antstream Ltd" ]]; then
handle_uninstall_antstream "AntstreamLauncher"
uninstall_launcher "$uninstall_options" "Antstream Arcade" "$antstream_path1" "$antstream_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Antstream Ltd" "antstream" "antstream"
sed -i '' "${logged_in_home}/.config/systemd/user/env_vars"
fi
fi
# Uninstall PURPLE Launcher
if [[ $uninstall_options == *"Uninstall PURPLE Launcher"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/NCSOFT" ]]; then
handle_uninstall_purple "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "PURPLE Launcher" "$purple_path1" "$purple_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/NCSOFT" "" "purple"
sed -i '' "${logged_in_home}/.config/systemd/user/env_vars"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PURPLELauncher/pfx/drive_c/Program Files (x86)/NCSOFT" ]]; then
handle_uninstall_purple "PURPLELauncher"
uninstall_launcher "$uninstall_options" "PURPLE Launcher" "$purple_path1" "$purple_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PURPLELauncher/pfx/drive_c/Program Files (x86)/NCSOFT" "" "purple"
sed -i '' "${logged_in_home}/.config/systemd/user/env_vars"
fi
fi
if [[ $uninstall_options == *"Uninstall Plarium Play"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/PlariumPlay" ]]; then
handle_uninstall_plarium "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "Plarium Play" "$plarium_path1" "$plarium_path2" "plarium" "plarium"
sed -i '' "${logged_in_home}/.config/systemd/user/env_vars"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlariumLauncher" ]]; then
handle_uninstall_plarium "PlariumLauncher"
uninstall_launcher "$uninstall_options" "Plarium Play" "$eaapp_path1" "$eaapp_path2" "plarium" "plarium"
sed -i '' "${logged_in_home}/.config/systemd/user/env_vars"
fi
fi
if [[ $uninstall_options == *"Uninstall Tempo Launcher"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Tempo Launcher - Beta" ]]; then
handle_uninstall_tempo "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "Tempo Launcher" "$tempo_path1" "$tempo_path2" "" "" "tempo"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/TempoLauncher/pfx/drive_c/Program Files/Tempo Launcher - Beta" ]]; then
handle_uninstall_tempo "TempoLauncher"
uninstall_launcher "$uninstall_options" "Tempo Launcher" "$tempo_path1" "$tempo_path2" "" "" "tempo"
fi
fi
if [[ $uninstall_options == *"Uninstall STOVE Client"* ]]; then
if [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/ProgramData/Smilegate/STOVE" ]]; then
handle_uninstall_stove "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "STOVE Client" "$stove_path1" "$stove_path2" "" "" "stove"
elif [[ -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/STOVELauncher/pfx/drive_c/ProgramData/Smilegate/STOVE" ]]; then
handle_uninstall_stove "STOVELauncher"
uninstall_launcher "$uninstall_options" "STOVE Client" "$stove_path1" "$stove_path2" "" "" "stove"
fi
fi
if [[ "$uninstall_options" == *"Uninstall Big Fish Games Manager"* ]]; then
if [[ -f "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/bfgclient/uninstall.exe" ]]; then
handle_uninstall_bfg "NonSteamLaunchers"
uninstall_launcher "$uninstall_options" "Big Fish Games Manager" "$bigfish_path1" "$bigfish_path2" "" "" "bigfish"
elif [[ -f "${logged_in_home}/.local/share/Steam/steamapps/compatdata/BigFishLauncher/pfx/drive_c/Program Files (x86)/bfgclient/uninstall.exe" ]]; then
handle_uninstall_bfg "BigFishLauncher"
uninstall_launcher "$uninstall_options" "Big Fish Games Manager" "$bigfish_path1" "$bigfish_path2" "" "" "bigfish"
rm -rf "${logged_in_home}/.local/share/Steam/steamapps/compatdata/BigFishLauncher"
fi
fi
if [[ $uninstall_options == *"Uninstall Hytale"* ]]; then
# Uninstall Hytale Launcher Flatpak app (user scope)
flatpak uninstall -y --delete-data --force-remove --user com.hypixel.HytaleLauncher
# Notify user
zenity --info --text="Hytale has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall RemotePlayWhatever"* ]]; then
rm -rf "${logged_in_home}/.local/share/applications/RemotePlayWhatever"
rm -rf "${logged_in_home}/.local/share/applications/RemotePlayWhatever.desktop"
zenity --info --text="RemotePlayWhatever has been uninstalled." --width=200 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall NVIDIA GeForce NOW"* ]]; then
# Uninstall GeForce NOW Flatpak app and repository (user scope)
flatpak uninstall -y --delete-data --force-remove --user com.nvidia.geforcenow
flatpak remote-delete --user GeForceNOW
zenity --info --text="NVIDIA GeForce NOW has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall Moonlight Game Streaming"* ]]; then
flatpak uninstall -y --force-remove --user com.moonlight_stream.Moonlight
zenity --info --text="Moonlight Game Streaming has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall Google Chrome"* ]]; then
flatpak uninstall -y --force-remove --user com.google.Chrome
zenity --info --text="Google Chrome has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall Mozilla Firefox"* ]]; then
flatpak uninstall -y --force-remove --user org.mozilla.firefox
zenity --info --text="Mozilla Firefox has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall Brave"* ]]; then
flatpak uninstall -y --force-remove --user com.brave.Browser
zenity --info --text="Brave has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall Microsoft Edge"* ]]; then
flatpak uninstall -y --force-remove --user com.microsoft.Edge
zenity --info --text="Microsoft Edge has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall Vivaldi"* ]]; then
flatpak uninstall -y --force-remove --user com.vivaldi.Vivaldi
zenity --info --text="Vivaldi has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
if [[ $uninstall_options == *"Uninstall LibreWolf"* ]]; then
flatpak uninstall -y --force-remove --user io.gitlab.librewolf-community
zenity --info --text="LibreWolf has been uninstalled." --width=250 --height=150 &
sleep 3
killall zenity
fi
uninstall_launcher "$uninstall_options" "Uplay" "$uplay_path1" "$uplay_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Ubisoft" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/UplayLauncher" "uplay" "ubisoft"
uninstall_launcher "$uninstall_options" "Battle.net" "$battlenet_path1" "$battlenet_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Battle.net" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/Battle.netLauncher" "battle" "bnet"
uninstall_launcher "$uninstall_options" "Epic Games" "$epic_games_launcher_path1" "$epic_games_launcher_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Epic Games" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/EpicGamesLauncher" "epic"
uninstall_launcher "$uninstall_options" "Amazon Games" "$amazongames_path1" "$amazongames_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/Amazon Games" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/AmazonGamesLauncher" "amazon"
uninstall_launcher "$uninstall_options" "itch.io" "$itchio_path1" "$itchio_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/itch" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/itchioLauncher" "itchio"
uninstall_launcher "$uninstall_options" "Humble Games Collection" "$humblegames_path1" "$humblegames_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Humble App" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/HumbleGamesLauncher" "humble"
uninstall_launcher "$uninstall_options" "IndieGala" "$indiegala_path1" "$indiegala_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/IGClient" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/IndieGalaLauncher" "indie"
uninstall_launcher "$uninstall_options" "Rockstar Games Launcher" "$rockstar_path1" "$rockstar_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/Rockstar Games" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/RockstarGamesLauncher" "rockstar"
uninstall_launcher "$uninstall_options" "Glyph Launcher" "$glyph_path1" "$glyph_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Glyph" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/GlyphLauncher" "glyph"
uninstall_launcher "$uninstall_options" "Minecraft Launcher" "$minecraft_path1" "$minecraft_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Minecraft Launcher" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/MinecraftLauncher" "minecraft"
uninstall_launcher "$uninstall_options" "VK Play" "$vkplay_path1" "$vkplay_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/GameCenter" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/VKPlayLauncher" "vkplay"
uninstall_launcher "$uninstall_options" "HoYoPlay" "$hoyoplay_path1" "$hoyoplay_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/HoYoPlay" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/HoYoPlayLauncher" "hoyoplay"
uninstall_launcher "$uninstall_options" "Nexon Launcher" "$nexon_path1" "$nexon_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Nexon" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NexonLauncher" "nexon"
uninstall_launcher "$uninstall_options" "Game Jolt Client" "$gamejolt_path1" "$gamejolt_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/GameJoltClient" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/GameJoltLauncher" "gamejolt"
uninstall_launcher "$uninstall_options" "ARC Launcher" "$arc_path1" "$arc_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/Arc" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/ARCLauncher" "arc"
uninstall_launcher "$uninstall_options" "Pokémon Trading Card Game Live" "$poketcg_path1" "$poketcg_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/The Pokémon Company International" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PokeTCGLauncher" "poketcg"
uninstall_launcher "$uninstall_options" "Plarium Play" "$plarium_path1" "$plarium_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/AppData/Local/PlariumPlay" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlariumLauncher" "plarium"
uninstall_launcher "$uninstall_options" "VFUN Launcher" "$vfun_path1" "$vfun_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/VFUN/VLauncher" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/VFUNLauncher" "vfun"
uninstall_launcher "$uninstall_options" "Gryphlink" "$gryphlink_path1" "$gryphlink_path2" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/GRYPHLINK" "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files/GRYPHLINK" "gryphlink"
fi
# If the uninstall was successful, set uninstalled_any_launcher to true
if [ $? -eq 0 ]; then
uninstalled_any_launcher=true
fi
}
if [ $# -gt 0 ]; then
# Add a flag that gets set when any launcher is uninstalled
uninstalled_any_launcher=false
for arg in "$@"; do
if [[ $arg == *"Uninstall "* ]]; then
launcher=${arg#"Uninstall "}
# Set the flag to true
uninstalled_any_launcher=true
if [[ -n $launcher ]]; then
process_uninstall_options "Uninstall $launcher"
fi
fi
done
# Check the flag after the loop
if $uninstalled_any_launcher; then
echo "Uninstallation completed successfully."
rm -rf "$download_dir"
exit 0
fi
else
# No command line arguments were provided
# Check if the Uninstall button was clicked in the GUI
if [[ $options == "Uninstall" ]] || [[ $selected_launchers == "Uninstall" ]]; then
# The Uninstall button was clicked in the GUI
# Display the zenity window to select launchers to uninstall
uninstall_options=$(zenity --list --checklist \
--title="Uninstall Launchers" \
--text="Select the launchers you want to Uninstall..." \
--column="Select" --column="This will delete the launcher and all of its games and files." \
--width=508 --height=507 \
FALSE "Epic Games" \
FALSE "GOG Galaxy" \
FALSE "Uplay" \
FALSE "Battle.net" \
FALSE "EA App" \
FALSE "Amazon Games" \
FALSE "Legacy Games" \
FALSE "itch.io" \
FALSE "Humble Games Collection" \
FALSE "IndieGala" \
FALSE "Rockstar Games Launcher" \
FALSE "Glyph Launcher" \
FALSE "Minecraft Launcher" \
FALSE "Playstation Plus" \
FALSE "VK Play" \
FALSE "HoYoPlay" \
FALSE "Nexon Launcher" \
FALSE "Game Jolt Client" \
FALSE "Artix Game Launcher" \
FALSE "ARC Launcher" \
FALSE "PURPLE Launcher" \
FALSE "Plarium Play" \
FALSE "VFUN Launcher" \
FALSE "Tempo Launcher" \
FALSE "Pokémon Trading Card Game Live" \
FALSE "Antstream Arcade" \
FALSE "Big Fish Games Manager" \
FALSE "RemotePlayWhatever" \
FALSE "NVIDIA GeForce NOW" \
FALSE "STOVE Client" \
FALSE "Moonlight Game Streaming" \
FALSE "Google Chrome" \
FALSE "Mozilla Firefox" \
FALSE "Brave" \
FALSE "Microsoft Edge" \
FALSE "Vivaldi" \
FALSE "LibreWolf" \
FALSE "Hytale" \
FALSE "Gryphlink" \
)
# Convert the returned string to an array
IFS='|' read -r -a uninstall_options_array <<< "$uninstall_options"
# Loop through the array and uninstall each selected launcher
for launcher in "${uninstall_options_array[@]}"; do
process_uninstall_options "Uninstall $launcher"
done
echo "Uninstallation completed successfully."
rm -rf "$download_dir"
exit 0
fi
fi
#End of Uninstall
#SD CARD
#SD CARD
move_launcher_to_sd() {
local launcher_name=$1
local compat_dir="${logged_in_home}/.local/share/Steam/steamapps/compatdata"
local sd_path
sd_path=$(get_sd_path) || return 1
local launcher_link="${compat_dir}/${launcher_name}"
# Check if launcher exists
if [[ ! -e "$launcher_link" ]]; then
zenity --warning --text="$launcher_name does not exist." --width=300 --height=100
echo "$launcher_name does not exist"
return 1
fi
local number_folder
number_folder=$(readlink -f "$launcher_link")
if [[ "$number_folder" == "$sd_path"* ]]; then
echo "# $launcher_name is already on the SD card."
return 0
fi
local sd_folder="${sd_path}/${launcher_name}"
echo "# Moving $launcher_name to SD card..."
mkdir -p "$sd_folder"
rsync -a "$number_folder/" "$sd_folder/" || {
zenity --error --text="Failed to copy $launcher_name to SD card." --width=300 --height=100
return 1
}
rm -rf "$number_folder"
ln -s "$sd_folder" "$number_folder"
rm -f "$launcher_link"
ln -s "$number_folder" "$launcher_link"
}
move_all_selected() {
local any_moved=0
(
for launcher in "${selected_launchers[@]}"; do
if move_launcher_to_sd "$launcher"; then
any_moved=1
fi
done
) | zenity --progress \
--title="Moving Launchers to SD Card" \
--text="Copying files…" \
--pulsate \
--auto-close \
--width=400
if [[ $any_moved -eq 0 ]]; then
zenity --info --text="No launchers were moved. They may already be on the SD card or do not exist." --width=350 --height=100
fi
}
# Main script logic
if [[ $1 == "Move to SD Card" ]]; then
shift
for launcher in "$@"; do
move_launcher_to_sd "$launcher"
done
else
if [[ $options == "Move to SD Card" ]]; then
CheckInstallationDirectory
move_options=$(zenity --list --text="Which launcher IDs do you want to move to the SD card?" \
--checklist --column="Select" --column="Launcher ID" \
$nonsteamlauncher_move_value "NonSteamLaunchers" \
$epicgameslauncher_move_value "EpicGamesLauncher" \
$goggalaxylauncher_move_value "GogGalaxyLauncher" \
$uplaylauncher_move_value "UplayLauncher" \
$battlenetlauncher_move_value "Battle.netLauncher" \
$eaapplauncher_move_value "TheEAappLauncher" \
$amazongameslauncher_move_value "AmazonGamesLauncher" \
$itchiolauncher_move_value "itchioLauncher" \
$legacygameslauncher_move_value "LegacyGamesLauncher" \
$humblegameslauncher_move_value "HumbleGamesLauncher" \
$indiegalalauncher_move_value "IndieGalaLauncher" \
$rockstargameslauncher_move_value "RockstarGamesLauncher" \
$glyphlauncher_move_value "GlyphLauncher" \
$minecraftlauncher_move_value "MinecraftLauncher" \
$pspluslauncher_move_value "PlaystationPlusLauncher" \
$vkplaylauncher_move_value "VKPlayLauncher" \
$hoyoplaylauncher_move_value "HoYoPlayLauncher" \
$nexonlauncher_move_value "NexonLauncher" \
$gamejoltlauncher_move_value "GameJoltLauncher" \
$artixgame_move_value "ArtixGameLauncher" \
$arc_move_value "ARCLauncher" \
$purple_move_value "PURPLELauncher" \
$plarium_move_value "PlariumLauncher" \
$vfun_move_value "VFUNLauncher" \
$tempo_move_value "TempoLauncher" \
$poketcg_move_value "PokeTCGLauncher" \
$antstream_move_value "AntstreamLauncher" \
$stove_move_value "STOVELauncher" \
$bigfish_move_value "BigFishLauncher" \
--width=335 --height=524)
if [[ $? -eq 0 ]]; then
IFS="|" read -ra selected_launchers <<< "$move_options"
move_all_selected
fi
exit 0
fi
fi
#Stop Scanner
function stop_service {
# Stop the service
systemctl --user stop nslgamescanner.service
# Delete the NSLGameScanner.py
rm -rf ${logged_in_home}/.config/systemd/user/NSLGameScanner.py
rm -rf ${logged_in_home}/.config/systemd/user/descriptions.json
# Delete the service file
rm -rf ${logged_in_home}/.config/systemd/user/nslgamescanner.service
# Remove the symlink
unlink ${logged_in_home}/.config/systemd/user/default.target.wants/nslgamescanner.service
# Reload the systemd user instance
systemctl --user daemon-reload
systemctl --user reset-failed
}
update_nsl_game_scanner() {
repo_url='https://github.com/moraroy/NonSteamLaunchers-On-Steam-Deck/archive/refs/heads/main.zip'
folders_to_clone=('requests' 'urllib3' 'steamgrid' 'vdf' 'charset_normalizer')
parent_folder="${logged_in_home}/.config/systemd/user/Modules"
python_script_path="${logged_in_home}/.config/systemd/user/NSLGameScanner.py"
github_link="https://raw.githubusercontent.com/moraroy/NonSteamLaunchers-On-Steam-Deck/main/NSLGameScanner.py"
env_vars="${logged_in_home}/.config/systemd/user/env_vars"
steam_debug_file="${logged_in_home}/.local/share/Steam/.cef-enable-remote-debugging"
nsl_config_dir="${logged_in_home}/.var/app/com.github.mtkennerly.ludusavi/config/ludusavi/NSLconfig"
# Stop and disable the service if it exists
if systemctl --user list-unit-files | grep -q "nslgamescanner.service"; then
if systemctl --user is-active --quiet nslgamescanner.service; then
systemctl --user stop nslgamescanner.service
fi
systemctl --user disable nslgamescanner.service 2>/dev/null || true
fi
# Remove the old python script if it exists
rm -f "$python_script_path"
# Create the parent folder if it doesn't exist
mkdir -p "${parent_folder}"
folders_exist=true
for folder in "${folders_to_clone[@]}"; do
if [ ! -d "${parent_folder}/${folder}" ]; then
folders_exist=false
break
fi
done
# Download and unzip the repo if necessary
if [ "${folders_exist}" = false ]; then
zip_file_path="${parent_folder}/repo.zip"
wget -O "${zip_file_path}" "${repo_url}" || { echo 'Download failed'; exit 1; }
unzip -d "${parent_folder}" "${zip_file_path}" || { echo 'Unzip failed'; exit 1; }
for folder in "${folders_to_clone[@]}"; do
destination_path="${parent_folder}/${folder}"
source_path="${parent_folder}/NonSteamLaunchers-On-Steam-Deck-main/Modules/${folder}"
if [ -d "${source_path}" ]; then
mv "${source_path}" "${destination_path}" || { echo "Move failed for ${folder}"; exit 1; }
fi
done
rm -f "${zip_file_path}"
rm -rf "${parent_folder}/NonSteamLaunchers-On-Steam-Deck-main"
fi
# Download the latest Python script
curl -fsSL -o "$python_script_path" "$github_link"
chmod +x "$python_script_path"
python3 "$python_script_path"
}
# Get the command line arguments
args=("$@")
# Check if the 🔍 option was passed as a command line argument or clicked in the GUI
if [[ " ${args[@]} " =~ " 🔍 " ]] || [[ $options == "🔍" ]]; then
stop_service
# If command line arguments were provided, exit the script
if [ ${#args[@]} -ne 0 ]; then
rm -rf ${logged_in_home}/.config/systemd/user/env_vars
exit 0
fi
# If no command line arguments were provided, display the zenity window
zenity --question --text="NSLGameScanner has been stopped and is no longer scanning for games. Do you want to run it again? Pressing 'Yes' will turn on 'Auto Scan' until you stop it again." --width=200 --height=150
if [ $? = 0 ]; then
# User wants to run NSLGameScanner again
show_message "NSLGameScanner is now restarting!"
update_nsl_game_scanner
if systemctl --user list-unit-files | grep -q "nslgamescanner.service"; then
echo "[NSL] Starting NSL Game Scanner service..."
systemctl --user start nslgamescanner.service
else
echo "[NSL] Service file not found — skipping start."
fi
else
# User does not want to run NSLGameScanner again
stop_service
exit 0
fi
fi
# Stop Scanner
# TODO: probably better to break this subshell into a function that can then be redirected to zenity
# Massive subshell pipes into `zenity --progress` around L2320 for GUI rendering
(
#Update Proton GE
# Call the function directly
update_proton
update_umu_launcher
# Also call the function when the button is pressed
if [[ $options == *"Update Proton-GE"* ]]; then
update_proton
update_umu_launcher
fi
echo "20"
echo "# Creating files & folders"
# Check if the user selected any launchers
if [ -n "$options" ]; then
# User selected at least one launcher
# Create app id folder in compatdata folder if it doesn't exist and if the user selected to use a single app ID folder
if [ "$use_separate_appids" = false ] && [ ! -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid" ]; then
mkdir -p "${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid"
fi
fi
# Change working directory to Proton's
cd $proton_dir
# Set the STEAM_RUNTIME environment variable
export STEAM_RUNTIME="${logged_in_home}/.steam/root/ubuntu12_32/steam-runtime/run.sh"
# Set the STEAM_COMPAT_CLIENT_INSTALL_PATH environment variable
export STEAM_COMPAT_CLIENT_INSTALL_PATH="${logged_in_home}/.local/share/Steam"
# Set the STEAM_COMPAT_DATA_PATH environment variable for the first file
export STEAM_COMPAT_DATA_PATH="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${appid}"
if [[ $options == *"NSLGameSaves"* ]]; then
zenity --info --text="Restoring your game saves from: /home/deck/NSLGameSaves, back into your prefix and launchers, all at once." --timeout=5
echo "Running restore..."
nohup flatpak run com.github.mtkennerly.ludusavi --config "${logged_in_home}/.var/app/com.github.mtkennerly.ludusavi/config/ludusavi/NSLconfig/" restore --force > /dev/null 2>&1 &
wait $!
echo "Restore completed"
zenity --info --text="Restore was successful, you may now download your games from your launchers, and verify if the game saves are restored." --timeout=5
exit 0
fi
###Launcher Installations
#Terminate Processese
function terminate_processes {
process_names=("$@") # Array of process names
for process_name in "${process_names[@]}"; do
end=$((SECONDS+75)) # Timeout
while ! pgrep -f "$process_name" > /dev/null; do
if [ $SECONDS -gt $end ]; then
echo "Timeout while waiting for $process_name to start"
return 1
fi
sleep 1
done
echo "Attempting to terminate $process_name"
pkill -f "$process_name"
end=$((SECONDS+60)) # Timeout
while pgrep -f "$process_name" > /dev/null; do
if [ $SECONDS -gt $end ]; then
echo "Timeout while trying to kill $process_name, force terminating"
pkill -9 -f "$process_name"
break
fi
sleep 1
done
echo "$process_name terminated successfully"
done
}
function install_gog {
echo "45"
echo "# Downloading & Installing Gog Galaxy...Please wait..."
# Cancel & Exit the GOG Galaxy Setup Wizard
end=$((SECONDS+90)) # Timeout after 90 seconds
while true; do
if pgrep -f "GalaxySetup.tmp" > /dev/null; then
pkill -f "GalaxySetup.tmp"
break
fi
if [ $SECONDS -gt $end ]; then
echo "Timeout while trying to kill GalaxySetup.tmp"
break
fi
sleep 1
done
# Check both Temp directories for Galaxy installer folder
temp_dir1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid/pfx/drive_c/users/steamuser/AppData/Local/Temp"
temp_dir2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid/pfx/drive_c/users/steamuser/Temp"
# First check temp_dir1 (AppData/Local/Temp)
if [ -d "$temp_dir1" ]; then
cd "$temp_dir1"
# Check if we found the installer folder
for dir in GalaxyInstaller_*; do
if [ -d "$dir" ]; then
galaxy_installer_folder="$dir"
break
fi
done
fi
# If not found, check temp_dir2 (Temp)
if [ -z "$galaxy_installer_folder" ] && [ -d "$temp_dir2" ]; then
cd "$temp_dir2"
# Now check if we found the installer folder in the second directory
for dir in GalaxyInstaller_*; do
if [ -d "$dir" ]; then
galaxy_installer_folder="$dir"
break
fi
done
fi
# If no installer folder was found in either directory, exit
if [ -z "$galaxy_installer_folder" ]; then
echo "Galaxy installer folder not found in either Temp directory"
return 1
fi
# Copy the GalaxyInstaller_* folder to Downloads
echo "Found Galaxy installer folder: $galaxy_installer_folder"
cp -r "$galaxy_installer_folder" "${logged_in_home}/Downloads/NonSteamLaunchersInstallation/"
# Navigate to the copied folder in Downloads
cd "${logged_in_home}/Downloads/NonSteamLaunchersInstallation/$(basename "$galaxy_installer_folder")"
# Run GalaxySetup.exe with the /VERYSILENT and /NORESTART options
echo "Running GalaxySetup.exe with the /VERYSILENT and /NORESTART options"
"$STEAM_RUNTIME" "$proton_dir/proton" run GalaxySetup.exe /VERYSILENT /NORESTART &
# Wait for the GalaxySetup.exe to finish running with a timeout of 90 seconds
end=$((SECONDS+90)) # Timeout after 90 seconds
while true; do
# Kill GalaxyClient.exe every 10 seconds if it's running
if [ $((SECONDS % 20)) -eq 0 ]; then
if pgrep -f "GalaxyClient.exe" > /dev/null; then
echo "Killing GalaxyClient.exe"
pkill -f "GalaxyClient.exe"
fi
fi
# Break the loop when GalaxySetup.exe finishes
if ! pgrep -f "GalaxySetup.exe" > /dev/null; then
echo "GalaxySetup.exe has finished running"
break
fi
# Timeout check (90 seconds)
if [ $SECONDS -gt $end ]; then
echo "Timeout while waiting for GalaxySetup.exe to finish"
break
fi
sleep 1
done
}
function install_gog2 {
echo "45"
echo "# Downloading & Installing GOG Galaxy... Please wait..."
# Check if either of the GOG Galaxy executables exists
if [ -e "${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/Program Files (x86)/GOG Galaxy/GalaxyClient.exe" ] || \
[ -e "${logged_in_home}/.local/share/Steam/steamapps/compatdata/GogGalaxyLauncher/pfx/drive_c/Program Files (x86)/GOG Galaxy/GalaxyClient.exe" ]; then
echo "GOG Galaxy executable found. Checking for setup_galaxy_2 process..."
# Now, check if setup_galaxy_2 is running and kill it
end=$((SECONDS+90)) # Timeout after 90 seconds
while true; do
if pgrep -f "setup_galaxy_2." > /dev/null; then
pkill -f "setup_galaxy_2."
echo "Setup process killed."
break
fi
if [ $SECONDS -gt $end ]; then
echo "Timeout while trying to kill setup_galaxy_2."
break
fi
sleep 1
done
else
echo "GOG Galaxy executable not found, skipping process kill."
fi
}
# Battle.net specific installation steps
function install_battlenet {
# Terminate any existing Battle.net processes before starting installation
#terminate_processes "Battle.net.exe" #"BlizzardError.exe"
# Start the first installation
echo "Starting first installation of Battle.net"
"$STEAM_RUNTIME" "$proton_dir/proton" run "$battle_file" Battle.net-Setup.exe --lang=enUS --installpath="C:\Program Files (x86)\Battle.net"
# Optional: kill wineserver after installation is completely done
#pkill wineserver
echo "Battle.net installation complete."
sleep 1
}
# Amazon Games specific installation steps
function install_amazon {
terminate_processes "Amazon Games.exe"
}
function install_eaapp {
terminate_processes "EADesktop.exe"
# Additional download for EA App
eaapp_download_dir="${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid/pfx/drive_c/users/steamuser/Downloads/"
eaapp_file_name="EAappInstaller.exe" # Replace with the actual file name if different
# Create the directory if it doesn't exist
mkdir -p "$eaapp_download_dir"
# Download the file
wget "$eaapp_url" -O "${eaapp_download_dir}${eaapp_file_name}"
}
# itch.io specific installation steps
function install_itchio {
terminate_processes "itch.exe"
}
# Humble Games specific installation steps
function install_humblegames {
# Create the handle-humble-scheme script
cat << EOF > "${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid/pfx/handle-humble-scheme"
#!/usr/bin/env sh
set -e
export STEAM_COMPAT_CLIENT_INSTALL_PATH=~/.local/share/Steam
export STEAM_COMPAT_DATA_PATH=~/.steam/steam/steamapps/compatdata/$appid
FIXED_SCHEME="\$(echo "\$1" | sed "s/?/\//")"
echo \$FIXED_SCHEME > "${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid/pfx/drive_c/.auth"
"$STEAM_RUNTIME" "$proton_dir/proton" run ~/.local/share/Steam/steamapps/compatdata/$appid/pfx/start-humble.cmd
EOF
chmod +x "${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid/pfx/handle-humble-scheme"
# Create the Humble-scheme-handler.desktop file
cat << EOF > "${logged_in_home}/.local/share/applications/Humble-scheme-handler.desktop"
[Desktop Entry]
Name=Humble App (Login)
Comment=Target for handling Humble App logins. You should not run this manually.
Exec=${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid/pfx/handle-humble-scheme %u
Type=Application
MimeType=x-scheme-handler/humble;
EOF
desktop-file-install --rebuild-mime-info-cache --dir=${logged_in_home}/.local/share/applications "${logged_in_home}/.local/share/applications/Humble-scheme-handler.desktop"
# Create the start-humble.cmd script
cat << EOF > "${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid/pfx/start-humble.cmd"
@echo off
cd /d "C:\Program Files\Humble App\"
set /p Url=<"C:\.auth"
if defined Url (
start "" "Humble App.exe" "%Url%"
) else (
start "" "Humble App.exe" "%*"
)
exit
EOF
wait
}
# Rockstar Games Launcher specific installation steps
function install_rockstar {
#Manually Install Rockstar Game Launcher
# Define directories and files
toolsDir=$(dirname "$(readlink -f "$0")")
checksumType='sha256'
rstarInstallUnzipFileDir="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/Rockstar"
rstarInstallDir="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${appid}/pfx/drive_c/Program Files/Rockstar Games/Launcher"
rstarStartMenuRunShortcutFolder="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${appid}/pfx/drive_c/users/steamuser/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Rockstar Games"
rstarStartMenuRunShortcut="$rstarStartMenuRunShortcutFolder/Rockstar Games Launcher.lnk"
rstarRunTarget="$rstarInstallDir/LauncherPatcher.exe"
rstarInstallUnzipFile=$rockstar_file
url=$rockstar_url
# Define checksum
checksum='589f6b251424e01dcd912e6a059d2d98f33fa73aadcd6376c0e1f1109f594b48'
# Verify checksum (sha256sum command may vary based on distribution)
echo "$checksum $rstarInstallUnzipFile" | sha256sum -c -
# Extract files from EXE and capture the output
output=$(7z e "$rockstar_file" -o"$rstarInstallUnzipFileDir" -aoa)
# Parse the output to get the ProductVersion
version=$(echo "$output" | grep 'ProductVersion:' | awk '{print $2}')
ls -l "$rstarInstallUnzipFileDir"
# Create Program Files folders to prepare for copying files
mkdir -p "$rstarInstallDir/Redistributables/VCRed"
mkdir -p "$rstarInstallDir/ThirdParty/Steam"
mkdir -p "$rstarInstallDir/ThirdParty/Epic"
cp "$rstarInstallUnzipFileDir/449" "$rstarInstallDir/Redistributables/VCRed/vc_redist.x64.exe"
cp "$rstarInstallUnzipFileDir/450" "$rstarInstallDir/Redistributables/VCRed/vc_redist.x86.exe"
cp "$rstarInstallUnzipFileDir/451" "$rstarInstallDir/ThirdParty/Steam/steam_api64.dll"
while IFS=' ' read -r number dll; do
dll=${dll//\//\\}
filename=$(basename "$dll" | tr -d '\r')
if [[ $dll == Redistributables\\* ]] || [[ $dll == ThirdParty\\Steam\\* ]] || [[ $number == 474 ]] || [[ $number == 475 ]]; then
continue
elif [[ $dll == ThirdParty\\Epic\\* ]]; then
cp "$rstarInstallUnzipFileDir/$number" "$epicInstallDir/$filename"
else
cp "$rstarInstallUnzipFileDir/$number" "$rstarInstallDir/$filename"
fi
done < "$download_dir/Rockstar/211"
cp "$rstarInstallUnzipFileDir/474" "$rstarInstallDir/ThirdParty/Epic/EOSSDK-Win64-Shipping.dll"
cp "$rstarInstallUnzipFileDir/475" "$rstarInstallDir/ThirdParty/Epic/EOSSDK-Win64-Shipping-1.14.2.dll"
# Use a loop for chmod commands
for file in Launcher.exe LauncherPatcher.exe offline.pak RockstarService.exe RockstarSteamHelper.exe uninstall.exe; do
chmod +x "$rstarInstallDir/$file"
done
size_kb=$(du -sk "$rstarInstallDir" | cut -f1)
size_hex=$(printf '%08x\n' $size_kb)
wine_registry_path="HKEY_LOCAL_MACHINE\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Rockstar Games Launcher"
# Use a loop for registry commands
declare -A registry_keys=(
["DisplayName"]="Rockstar Games Launcher"
["DisplayIcon"]="C:\\Program Files\\Rockstar Games\\Launcher\\Launcher.exe, 0"
["DisplayVersion"]="$version"
["Publisher"]="Rockstar Games"
["InstallLocation"]="C:\\Program Files\\Rockstar Games\\Launcher"
["EstimatedSize"]="0x$size_hex"
["UninstallString"]="C:\\Program Files\\Rockstar Games\\Launcher\\uninstall.exe"
["QuietUninstallString"]="\"C:\\Program Files\\Rockstar Games\\Launcher\\uninstall.exe\" /S"
["HelpLink"]="https://www.rockstargames.com/support"
["URLInfoAbout"]="https://www.rockstargames.com/support"
["URLUpdateInfo"]="https://www.rockstargames.com"
["NoModify"]="0x1"
["NoRepair"]="0x1"
["Comments"]="Rockstar Games Launcher"
["Readme"]="https://www.rockstargames.com/support"
)
for key in "${!registry_keys[@]}"; do
"$STEAM_RUNTIME" "$proton_dir/proton" run reg add "$wine_registry_path" /v "$key" /t REG_SZ /d "${registry_keys[$key]}" /f
done
"$STEAM_RUNTIME" "$proton_dir/proton" run "$rstarInstallDir/Redistributables/VCRed/vc_redist.x64.exe" /install /quiet /norestart
"$STEAM_RUNTIME" "$proton_dir/proton" run "$rstarInstallDir/Redistributables/VCRed/vc_redist.x86.exe" /install /quiet /norestart
wait
}
# VK Play specific installation steps
function install_vkplay {
terminate_processes "GameCenter.exe"
}
# Nexon specific installation steps
function install_nexon {
terminate_processes "nexon_runtime.e"
}
# Big Fish specific installation function
function install_bigfish {
"$STEAM_RUNTIME" "$proton_dir/proton" run "$bigfish_file" /S &
bigfish_pid=$!
wait $bigfish_pid
echo "Big Fish Games Manager installation complete."
pkill CrBrowserMain
}
# HoYo specific installation steps
function install_hoyo {
hoyo_dir="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${appid}/pfx/drive_c/Program Files/HoYoPlay"
installer_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/HoYoPlay_install.exe"
target_dir="${hoyo_dir}/1.4.5.222"
echo "Creating directory for HoYoPlay..."
mkdir -p "${hoyo_dir}" || { echo "Failed to create directory"; return 1; }
echo "Copying installer to the target directory..."
cp "${installer_file}" "${hoyo_dir}" || { echo "Failed to copy installer"; return 1; }
echo "Changing directory to the target directory..."
cd "${hoyo_dir}" || { echo "Failed to change directory"; return 1; }
echo "Running 7z extraction..."
output=$(7z x "HoYoPlay_install.exe" -o"${hoyo_dir}" -aoa)
if [ $? -ne 0 ]; then
echo "Extraction failed"
echo "7z output: $output"
return 1
fi
echo "Extraction completed successfully"
echo "Copying launcher.exe to the HoYoPlay directory..."
cp "${target_dir}/launcher.exe" "${hoyo_dir}/launcher.exe" || { echo "Failed to copy launcher.exe"; return 1; }
echo "Running HYP.exe..."
"$STEAM_RUNTIME" "$proton_dir/proton" run "${target_dir}/HYP.exe" || { echo "Failed to run HYP.exe"; return 1; } &
sleep 5 # Wait for 5 seconds before terminating HYP.exe
terminate_processes "HYP.exe"
echo "Removing installer file..."
rm -f "${hoyo_dir}/HoYoPlay_install.exe" || { echo "Failed to remove installer file"; return 1; }
echo "HoYoPlay installation steps completed successfully"
}
install_stove() {
local url="https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/815d89c2-508a-4010-89af-4a6770e178d9/MicrosoftEdgeWebview2Setup.exe"
local installer="MicrosoftEdgeWebview2Setup.exe"
echo "Attempting to download $installer..."
if curl -fLo "$installer" "$url"; then
echo "Download successful. Running $installer silently..."
# Start the installer with Proton and capture PID
"$STEAM_RUNTIME" "$proton_dir/proton" run "$installer" /silent /install &
local pid=$!
echo "Installer PID: $pid. Waiting for it to complete..."
wait $pid
local exit_code=$?
if [ $exit_code -eq 0 ]; then
echo "$installer finished successfully."
else
echo "$installer exited with error code $exit_code."
fi
else
echo "Download failed. Skipping installation."
fi
}
install_psplus() {
local url="https://aka.ms/highdpimfc2013x86enu"
local installer="vcredist_x86.exe"
echo "Attempting to download $installer..."
if curl -fLo "$installer" "$url"; then
echo "Download successful. Running $installer silently..."
# Start the installer with Proton and capture PID
"$STEAM_RUNTIME" "$proton_dir/proton" run "$installer" /q /norestart &
local pid=$!
echo "Installer PID: $pid. Waiting for it to complete..."
wait $pid
local exit_code=$?
if [ $exit_code -eq 0 ]; then
echo "$installer finished successfully."
else
echo "$installer exited with error code $exit_code."
fi
else
echo "Download failed. Skipping installation."
fi
}
# Gryphlink specific installation steps
install_gryphlink() {
gryphlink_dir="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${appid}/pfx/drive_c/Program Files/GRYPHLINK"
tmp_installer="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/GRYPHLINK_installer.exe"
version="$(echo "${gryphlink_url}" | sed -E 's#.*/launcher/([^/]+)/.*#\1#')"
[ ! -d "${gryphlink_dir}" ] && mkdir -p "${gryphlink_dir}"
curl -L -o "${tmp_installer}" "${gryphlink_url}"
command -v 7z >/dev/null 2>&1 || { echo "7z not found, install p7zip"; exit 1; }
7z x "${tmp_installer}" -o"${gryphlink_dir}" -aoa
[ -d "${gryphlink_dir}/\$0/${version}" ] && mv "${gryphlink_dir}/\$0/${version}" "${gryphlink_dir}/${version}"
rm -rf "${gryphlink_dir}/\$0" "${gryphlink_dir}/\$PLUGINSDIR"
rm -f "${tmp_installer}"
mkdir -p "${gryphlink_dir}/Cache/Config"
[ -f "${gryphlink_dir}/${version}/Launcher.exe" ] && cp "${gryphlink_dir}/${version}/Launcher.exe" "${gryphlink_dir}/Launcher.exe"
[ -f "${gryphlink_dir}/${version}/Uninstall.exe" ] && cp "${gryphlink_dir}/${version}/Uninstall.exe" "${gryphlink_dir}/Uninstall.exe"
if command -v tree >/dev/null 2>&1; then
tree -L 3 "${gryphlink_dir}"
else
ls -R "${gryphlink_dir}"
fi
echo "Removing installer file..."
rm -f "${gryphlink_dir}/GRYPHLINK_installer.exe" || {
echo "Failed to remove installer file"
return 1
}
echo "Gryphlink installation steps completed successfully"
}
#Launcher Installs
function install_launcher {
launcher_name=$1
appid_name=$2
file_name=$3
file_url=$4
run_command=$5
progress_update=$6
pre_install_command=$7
post_install_command=$8
run_in_background=$9 # New parameter to specify if the launcher should run in the background
echo "${progress_update}"
echo "# Downloading & Installing ${launcher_name}...please wait..."
# Check if the user selected the launcher
if [[ $options == *"${launcher_name}"* ]]; then
# User selected the launcher
echo "User selected ${launcher_name}"
# Set the appid for the launcher
if [ "$use_separate_appids" = true ]; then
appid=${appid_name}
else
appid=NonSteamLaunchers
fi
# Create app id folder in compatdata folder if it doesn't exist
if [ ! -d "${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid" ]; then
mkdir -p "${logged_in_home}/.local/share/Steam/steamapps/compatdata/$appid"
fi
# Change working directory to Proton's
cd $proton_dir
# Set the STEAM_COMPAT_CLIENT_INSTALL_PATH environment variable
export STEAM_COMPAT_CLIENT_INSTALL_PATH="${logged_in_home}/.local/share/Steam"
# Set the STEAM_COMPAT_DATA_PATH environment variable for the launcher
export STEAM_COMPAT_DATA_PATH="${logged_in_home}/.local/share/Steam/steamapps/compatdata/${appid}"
# Download file
if [ ! -f "$file_name" ]; then
echo "Downloading ${file_name}"
curl -L $file_url -o $file_name
fi
# Execute the pre-installation command, if provided
if [ -n "$pre_install_command" ]; then
echo "Executing pre-install command for ${launcher_name}"
eval "$pre_install_command"
fi
# Run the file using Proton with the specified command
echo "Running ${file_name} using Proton with the specified command"
if [ "$run_in_background" = true ]; then
if [ "$launcher_name" = "GOG Galaxy" ]; then
"$STEAM_RUNTIME" "$proton_dir/proton" run "$exe_file" /silent &
install_gog2
elif [ "$launcher_name" = "Battle.net" ]; then
install_battlenet
elif [ "$launcher_name" = "Big Fish Games Manager" ]; then
install_bigfish
elif [ "$launcher_name" = "Amazon Games" ]; then
"$STEAM_RUNTIME" "$proton_dir/proton" run "$amazon_file" &
install_amazon
elif [ "$launcher_name" = "Humble Games Collection" ]; then
"$STEAM_RUNTIME" "$proton_dir/proton" run "$humblegames_file" /S /D="C:\Program Files\Humble App"
wait
install_humblegames
elif [ "$launcher_name" = "Rockstar Games Launcher" ]; then
install_rockstar
elif [ "$launcher_name" = "ARC Launcher" ]; then
"$STEAM_RUNTIME" "$proton_dir/proton" run "$arc_file"
pid=$!
while pgrep -x "Arc3Install_202" > /dev/null; do
sleep 1
done
sleep 5
echo "ARC Launcher installation complete."
else
"$STEAM_RUNTIME" "$proton_dir/proton" run "$run_command" &
fi
else
"$STEAM_RUNTIME" "$proton_dir/proton" run ${run_command}
fi
# Execute the post-installation command, if provided
if [ -n "$post_install_command" ]; then
echo "Executing post-install command for ${launcher_name}"
eval "$post_install_command"
fi
wait
pkill -f wineserver
fi
}
# Install Epic Games Launcher
install_launcher "Epic Games" "EpicGamesLauncher" "$msi_file" "$msi_url" "MsiExec.exe /i "$msi_file" -opengl /qn" "70" "" ""
# Install GOG Galaxy
install_launcher "GOG Galaxy" "GogGalaxyLauncher" "$exe_file" "$exe_url" "$exe_file /silent" "71" "" "" true
# Install Ubisoft Connect
install_launcher "Ubisoft Connect" "UplayLauncher" "$ubi_file" "$ubi_url" "$ubi_file /S" "72" "" ""
# Install Battle.net
install_launcher "Battle.net" "Battle.netLauncher" "$battle_file" "$battle_url" "" "73" "" "" true
#Install Amazon Games
install_launcher "Amazon Games" "AmazonGamesLauncher" "$amazon_file" "$amazon_url" "" "74" "" "" true
#Install EA App
install_launcher "EA App" "TheEAappLauncher" "$eaapp_file" "$eaapp_url" "$eaapp_file /quiet" "75" "" "install_eaapp" true
# Install itch.io
install_launcher "itch.io" "itchioLauncher" "$itchio_file" "$itchio_url" "$itchio_file --silent" "76" "" "install_itchio" true
# Install Legacy Games
install_launcher "Legacy Games" "LegacyGamesLauncher" "$legacygames_file" "$legacygames_url" "$legacygames_file /S" "77" "" ""
# Install Humble Games
install_launcher "Humble Games Collection" "HumbleGamesLauncher" "$humblegames_file" "$humblegames_url" "" "78" "" "" true
# Install IndieGala
install_launcher "IndieGala" "IndieGalaLauncher" "$indiegala_file" "$indiegala_url" "$indiegala_file /S" "79" "" ""
# Install Rockstar Games Launcher
install_launcher "Rockstar Games Launcher" "RockstarGamesLauncher" "$rockstar_file" "$rockstar_url" "" "80" "" "" true
# Install Glyph Launcher
install_launcher "Glyph Launcher" "GlyphLauncher" "$glyph_file" "$glyph_url" "$glyph_file" "81" "" ""
# Install Minecraft Legacy Launcher
install_launcher "Minecraft Launcher" "MinecraftLauncher" "$minecraft_file" "$minecraft_url" "MsiExec.exe /i "$minecraft_file" /q" "82" "" ""
# Install Playstation Plus Launcher
install_launcher "Playstation Plus" "PlaystationPlusLauncher" "$psplus_file" "$psplus_url" "$psplus_file /q" "83" "install_psplus" "" true
# Install VK Play
install_launcher "VK Play" "VKPlayLauncher" "$vkplay_file" "$vkplay_url" "$vkplay_file" "84" "" "install_vkplay" true
# Install Hoyo Play
install_launcher "HoYoPlay" "HoYoPlayLauncher" "$hoyoplay_file" "$hoyoplay_url" "" "85" "" "install_hoyo" true
# Install Nexon Launcher
install_launcher "Nexon Launcher" "NexonLauncher" "$nexon_file" "$nexon_url" "$nexon_file" "86" "" "install_nexon" true
# Install GameJolt Launcher
install_launcher "Game Jolt Client" "GameJoltLauncher" "$gamejolt_file" "$gamejolt_url" "$gamejolt_file /silent" "67" "" ""
# Install artix Launcher
install_launcher "Artix Game Launcher" "ArtixGameLauncher" "$artixgame_file" "$artixgame_url" "$artixgame_file /S" "88" "" ""
# Install ARC Launcher
install_launcher "ARC Launcher" "ARCLauncher" "$arc_file" "$arc_url" "$arc_file" "89" "" "" true
# Install PokemonTCGLIVE
install_launcher "Pokémon Trading Card Game Live" "PokeTCGLauncher" "$poketcg_file" "$poketcg_url" "MsiExec.exe /i "$poketcg_file" /qn" "90" "" ""
# Install Antstream Arcade
install_launcher "Antstream Arcade" "AntstreamLauncher" "$antstream_file" "$antstream_url" "$antstream_file /quiet" "91" "" ""
# Install Purple Launcher
install_launcher "PURPLE Launcher" "PURPLELauncher" "$purple_file" "$purple_url" "$purple_file /S" "92" "" ""
# Install Plarium Launcher
install_launcher "Plarium Play" "PlariumLauncher" "$plarium_file" "$plarium_url" "$plarium_file /S" "93" "" ""
#Install VFUN Launcher
install_launcher "VFUN Launcher" "VFUNLauncher" "$vfun_file" "$vfun_url" "$vfun_file /S" "94" "" ""
#Install Tempo Launcher
install_launcher "Tempo Launcher" "TempoLauncher" "$tempo_file" "$tempo_url" "$tempo_file /S" "95" "" ""
#Install Stove Client
install_launcher "STOVE Client" "STOVELauncher" "$stove_file" "$stove_url" "$stove_file" "96" "install_stove" "" true
install_launcher "Big Fish Games Manager" "BigFishLauncher" "$bigfish_file" "$bigfish_url" "$bigfish_file /S" "97" "" "" true
install_launcher "Gryphlink" "GryphlinkLauncher" "$gryphlink_file" "$gryphlink_url" "" "98" "" "install_gryphlink" true
#End of Launcher Installations
echo "99"
echo "# Checking if a browser is needed...please wait..."
# Check if user selected any browser-based service or entered a website
if [[ $options == *"Apple TV+"* ]] || [[ $options == *"Plex"* ]] || [[ $options == *"Crunchyroll"* ]] || \
[[ $options == *"WebRcade"* ]] || [[ $options == *"WebRcade Editor"* ]] || [[ $options == *"Netflix"* ]] || \
[[ $options == *"Fortnite"* ]] || [[ $options == *"Venge"* ]] || [[ $options == *"Xbox Game Pass"* ]] || \
[[ $options == *"Better xCloud"* ]] || [[ $options == *"Geforce Now"* ]] || [[ $options == *"Boosteroid Cloud Gaming"* ]] || \
[[ $options == *"Amazon Luna"* ]] || [[ $options == *"Hulu"* ]] || [[ $options == *"Tubi"* ]] || \
[[ $options == *"Disney+"* ]] || [[ $options == *"Amazon Prime Video"* ]] || [[ $options == *"Youtube"* ]] || \
[[ $options == *"Youtube TV"* ]] || [[ $options == *"Twitch"* ]] || [[ $options == *"Stim.io"* ]] || \
[[ $options == *"WatchParty"* ]] || [[ $options == *"PokéRogue"* ]] || [[ $options == *"Afterplay.io"* ]] || \
[[ $options == *"OnePlay"* ]] || [[ $options == *"AirGPU"* ]] || [[ $options == *"CloudDeck"* ]] || \
[[ $options == *"JioGamesCloud"* ]] || [[ $options == *"Cloudy Pad"* ]] || [[ -n "$custom_websites_str" ]]; then
echo "User selected a Browser-based service or entered a website"
# Determine which browser the user selected (correct Flatpak IDs)
selected_browser=""
if [[ "$options" == *"Google Chrome"* ]]; then
selected_browser="com.google.Chrome"
elif [[ "$options" == *"Mozilla Firefox"* ]]; then
selected_browser="org.mozilla.firefox"
elif [[ "$options" == *"Brave"* ]]; then
selected_browser="com.brave.Browser"
elif [[ "$options" == *"Microsoft Edge"* ]]; then
selected_browser="com.microsoft.Edge"
elif [[ "$options" == *"Vivaldi"* ]]; then
selected_browser="com.vivaldi.Vivaldi"
elif [[ "$options" == *"LibreWolf"* ]]; then
selected_browser="io.gitlab.librewolf-community"
fi
# Install the selected browser if any
if [[ -n "$selected_browser" ]]; then
echo "User selected browser: $selected_browser"
# Ensure Flathub repository exists
if ! flatpak remote-list | grep flathub &> /dev/null; then
echo "Adding Flathub repository..."
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
fi
# Install the browser if not already installed
if flatpak list | grep "$selected_browser" &> /dev/null; then
echo "$selected_browser is already installed"
else
echo "Installing $selected_browser..."
flatpak install --user flathub "$selected_browser" -y
fi
# Apply the override (if applicable)
flatpak --user override --filesystem=/run/udev:ro "$selected_browser"
fi
fi
echo "99.1"
echo "# Installing NVIDIA GeForce NOW (Native Linux) ...please wait..."
if [[ $options == *"NVIDIA GeForce NOW"* ]]; then
if flatpak info --user com.nvidia.geforcenow &>/dev/null || flatpak info --system com.nvidia.geforcenow &>/dev/null; then
echo "NVIDIA GeForce NOW is already installed (user or system)."
else
echo "Adding NVIDIA GeForce NOW Flatpak repository..."
flatpak remote-add --user --if-not-exists GeForceNOW https://international.download.nvidia.com/GFNLinux/flatpak/geforcenow.flatpakrepo
echo "Installing NVIDIA GeForce NOW Flatpak app (user scope)..."
if flatpak install -y --user GeForceNOW com.nvidia.geforcenow; then
echo "NVIDIA GeForce NOW installed successfully."
else
echo "Failed to install NVIDIA GeForce NOW."
fi
fi
fi
echo "99.2"
echo "# Installing Moonlight Game Streaming...please wait..."
if [[ $options == *"Moonlight Game Streaming"* ]]; then
if flatpak info --user com.moonlight_stream.Moonlight &>/dev/null || flatpak info --system com.moonlight_stream.Moonlight &>/dev/null; then
echo "Moonlight Game Streaming is already installed (user or system)."
else
echo "Installing Moonlight Flatpak app (user scope)..."
if flatpak install -y --user flathub com.moonlight_stream.Moonlight; then
echo "Moonlight installed successfully."
else
echo "Failed to install Moonlight."
fi
fi
fi
echo "99.3"
echo "# Installing Hytale (Native Linux) ...please wait..."
if [[ $options == *"Hytale"* ]]; then
if flatpak info --user com.hypixel.HytaleLauncher &>/dev/null || flatpak info --system com.hypixel.HytaleLauncher &>/dev/null; then
echo "Hytale is already installed (user or system)."
else
echo "Downloading Hytale Flatpak..."
curl -L -o /tmp/hytale-launcher.flatpak https://launcher.hytale.com/builds/release/linux/amd64/hytale-launcher-latest.flatpak
echo "Installing Hytale Flatpak app (user scope)..."
if flatpak install -y --user /tmp/hytale-launcher.flatpak; then
echo "Hytale Launcher installed successfully."
else
echo "Failed to install Hytale Launcher."
fi
fi
fi
echo "99.4"
echo "# Checking if Ludusavi is installed...please wait..."
# AutoInstall Ludusavi
# Check if Ludusavi is already installed
if flatpak list | grep com.github.mtkennerly.ludusavi &> /dev/null; then
echo "Ludusavi is already installed"
else
# Check if the Flathub repository exists
if flatpak remote-list | grep flathub &> /dev/null; then
echo "Flathub repository exists"
else
# Add the Flathub repository
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
fi
# Install Ludusavi
flatpak install --user flathub com.github.mtkennerly.ludusavi -y
fi
echo "Ludusavi installation script completed"
# Ensure Ludusavi is installed before proceeding
if ! flatpak list | grep com.github.mtkennerly.ludusavi &> /dev/null; then
echo "Ludusavi installation failed. Exiting script."
fi
rclone_zip_url="https://downloads.rclone.org/rclone-current-linux-amd64.zip"
rclone_zip_file="${logged_in_home}/Downloads/NonSteamLaunchersInstallation/rclone-current-linux-amd64.zip"
rclone_base_dir="${logged_in_home}/Downloads/NonSteamLaunchersInstallation"
nsl_config_dir="${logged_in_home}/.var/app/com.github.mtkennerly.ludusavi/config/ludusavi/NSLconfig"
# Function to download and extract rclone
download_and_extract_rclone() {
# Check if rclone already exists in the NSLconfig directory
if [ -f "${nsl_config_dir}/rclone" ]; then
echo "rclone already exists in ${nsl_config_dir}. Skipping download."
return
fi
if [ -d "$rclone_base_dir" ]; then
echo "Downloading rclone..."
if ! wget -O "$rclone_zip_file" "$rclone_zip_url"; then
echo "Failed to download rclone. Exiting script."
exit 1
fi
echo "Extracting rclone..."
if ! unzip -o "$rclone_zip_file" -d "$rclone_base_dir"; then
echo "Failed to extract rclone. Exiting script."
exit 1
fi
echo "rclone downloaded and extracted"
else
echo "Download directory does not exist. Exiting script."
return
fi
# Find the extracted rclone directory dynamically
rclone_extract_dir=$(find "$rclone_base_dir" -maxdepth 1 -type d -name "rclone-v*-linux-amd64" | head -n 1)
rclone_bin="${rclone_extract_dir}/rclone"
# Debug: Check if rclone_bin exists
if [ -f "$rclone_bin" ]; then
echo "rclone binary found at $rclone_bin"
else
echo "rclone binary not found at $rclone_bin. Exiting script."
return
fi
# Ensure the NSLconfig directory exists
mkdir -p "$nsl_config_dir"
# Move rclone to the NSLconfig directory
if [ -f "$rclone_bin" ]; then
echo "Moving rclone to $nsl_config_dir"
mv "$rclone_bin" "$nsl_config_dir"
rclone_path="${nsl_config_dir}/rclone"
echo "rclone moved to $nsl_config_dir"
else
echo "rclone binary not found. Exiting script."
fi
}
# Run the function in a separate process
download_and_extract_rclone &
rclone_pid=$!
wait $rclone_pid
# Setting up Backup Saves through Ludusavi
# Define the directory and file path
config_dir="${logged_in_home}/.var/app/com.github.mtkennerly.ludusavi/config/ludusavi"
nsl_config_dir="$config_dir/NSLconfig"
backup_dir="$config_dir/config_backups"
timestamp=$(date +%m-%d-%Y_%H:%M:%S)
backup_config_file="$backup_dir/config.yaml.bak_$timestamp"
# Create the backup directory if it doesn't exist
mkdir -p "$backup_dir"
# Backup existing config.yaml if it exists
if [ -f "$config_dir/config.yaml" ]; then
cp "$config_dir/config.yaml" "$backup_config_file"
echo "Existing config.yaml backed up to $backup_config_file"
fi
# Create the NSLconfig directory if it doesn't exist
mkdir -p "$nsl_config_dir"
# Write the configuration to the NSLconfig file
cat < "$nsl_config_dir/config.yaml"
---
runtime:
threads: ~
release:
check: true
manifest:
enable: true
language: en-US
theme: light
roots:
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/EpicGamesLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/GogGalaxyLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/UplayLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/Battle.netLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/TheEAappLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/AmazonGamesLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/itchioLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/LegacyGamesLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/HumbleGamesLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/IndieGalaLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/RockstarGamesLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/GlyphLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlaystationPlusLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/VKPlayLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/HoYoPlayLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/NexonLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/GameJoltLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/ArtixGameLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/ARCLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/PokeTCGLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/MinecraftLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/AntstreamLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/PURPLELauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/PlariumLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/VFUNLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/TempoLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/STOVELauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/BigFishLauncher/pfx/drive_c/
- store: otherWindows
path: ${logged_in_home}/.local/share/Steam/steamapps/compatdata/GryphlinkLauncher/pfx/drive_c/
redirects: []
backup:
path: ${logged_in_home}/NSLGameSaves
ignoredGames: []
filter:
excludeStoreScreenshots: false
cloud:
exclude: false
epic: false
gog: false
origin: false
steam: false
uplay: false
ignoredPaths: []
ignoredRegistry: []
toggledPaths: {}
toggledRegistry: {}
sort:
key: status
reversed: false
retention:
full: 1
differential: 0
format:
chosen: simple
zip:
compression: deflate
compression:
deflate:
level: 6
bzip2:
level: 6
zstd:
level: 10
restore:
path: ${logged_in_home}/NSLGameSaves
ignoredGames: []
toggledPaths: {}
toggledRegistry: {}
sort:
key: status
reversed: false
scan:
showDeselectedGames: true
showUnchangedGames: true
showUnscannedGames: true
cloud:
remote: ~
path: NSLGameSaves
synchronize: true
apps:
rclone:
path: "${logged_in_home}/.var/app/com.github.mtkennerly.ludusavi/config/ludusavi/NSLconfig/rclone"
arguments: "--fast-list --ignore-checksum"
customGames: []
EOL
# Run Once
echo "Running backup..."
nohup flatpak run com.github.mtkennerly.ludusavi --config "$nsl_config_dir" backup --force > /dev/null 2>&1 &
wait $!
echo "Backup completed"
# End of Ludusavi configuration
echo "100"
echo "# Installation Complete - Steam will now restart. Your launchers will be in your library!...Food for thought...do Jedis use Force Compatability?"
) |
zenity --progress \
--title="Update Status" \
--text="Starting update...please wait..." --width=450 --height=350\
--percentage=0 --auto-close
# Write to env_vars
# Initialize the env_vars file
> ${logged_in_home}/.config/systemd/user/env_vars
write_env_vars() {
local launcher_path="$1"
local launcher_name="$2"
local launcher_dir_name="$3"
local launcher_args="$4" # Additional parameter for launcher-specific arguments
local launcher_env_var_name="$5" # Additional parameter for the environment variable name
local shortcut_directory="\"${launcher_path}\" ${launcher_args}"
local launch_options="STEAM_COMPAT_DATA_PATH=\"${logged_in_home}/.local/share/Steam/steamapps/compatdata/${launcher_dir_name}/\" %command%"
local starting_dir="\"$(dirname "${launcher_path}")\""
# Write the variables directly to the env_vars file
echo "export ${launcher_name}shortcutdirectory=${shortcut_directory}" >> "${logged_in_home}/.config/systemd/user/env_vars"
echo "export ${launcher_name}launchoptions=${launch_options}" >> "${logged_in_home}/.config/systemd/user/env_vars"
echo "export ${launcher_name}startingdir=${starting_dir}" >> "${logged_in_home}/.config/systemd/user/env_vars"
echo "export ${launcher_env_var_name}=${launcher_dir_name}" >> "${logged_in_home}/.config/systemd/user/env_vars"
echo "${launcher_name^} Launcher found at ${launcher_path}"
}
check_and_write() {
local launcher_name="$1"
local path1="$2"
local path2="$3"
local launcher_dir_name_path1="$4"
local launcher_dir_name_path2="$5"
local launcher_args="$6"
local launcher_env_var_name="$7"
if [[ -f "$path1" ]]; then
write_env_vars "$path1" "$launcher_name" "$launcher_dir_name_path1" "$launcher_args" "$launcher_env_var_name"
elif [[ -f "$path2" ]]; then
write_env_vars "$path2" "$launcher_name" "$launcher_dir_name_path2" "$launcher_args" "$launcher_env_var_name"
else
echo "${launcher_name^} Launcher not found"
fi
}
# Env_vars Configuration Paths
check_and_write "epic" "$epic_games_launcher_path1" "$epic_games_launcher_path2" "NonSteamLaunchers" "EpicGamesLauncher" "-opengl" "epic_games_launcher"
check_and_write "gog" "$gog_galaxy_path1" "$gog_galaxy_path2" "NonSteamLaunchers" "GogGalaxyLauncher" "" "gog_galaxy_launcher"
check_and_write "uplay" "$uplay_path1" "$uplay_path2" "NonSteamLaunchers" "UplayLauncher" "" "ubisoft_connect_launcher"
check_and_write "battlenet" "$battlenet_path1" "$battlenet_path2" "NonSteamLaunchers" "Battle.netLauncher" "" "bnet_launcher"
check_and_write "eaapp" "$eaapp_path1" "$eaapp_path2" "NonSteamLaunchers" "TheEAappLauncher" "" "ea_app_launcher"
check_and_write "amazon" "$amazongames_path1" "$amazongames_path2" "NonSteamLaunchers" "AmazonGamesLauncher" "" "amazon_launcher"
check_and_write "itchio" "$itchio_path1" "$itchio_path2" "NonSteamLaunchers" "itchioLauncher" "" "itchio_launcher"
check_and_write "legacy" "$legacygames_path1" "$legacygames_path2" "NonSteamLaunchers" "LegacyGamesLauncher" "" "legacy_launcher"
check_and_write "humble" "$humblegames_path1" "$humblegames_path2" "NonSteamLaunchers" "HumbleGamesLauncher" "" "humble_launcher"
check_and_write "indie" "$indiegala_path1" "$indiegala_path2" "NonSteamLaunchers" "IndieGalaLauncher" "" "indie_launcher"
check_and_write "rockstar" "$rockstar_path1" "$rockstar_path2" "NonSteamLaunchers" "RockstarGamesLauncher" "" "rockstar_launcher"
check_and_write "glyph" "$glyph_path1" "$glyph_path2" "NonSteamLaunchers" "GlyphLauncher" "" "glyph_launcher"
check_and_write "minecraft" "$minecraft_path1" "$minecraft_path2" "NonSteamLaunchers" "MinecraftLauncher" "" "minecraft_launcher"
check_and_write "psplus" "$psplus_path1" "$psplus_path2" "NonSteamLaunchers" "PlaystationPlusLauncher" "" "psplus_launcher"
check_and_write "vkplay" "$vkplay_path1" "$vkplay_path2" "NonSteamLaunchers" "VKPlayLauncher" "" "vkplay_launcher"
check_and_write "hoyoplay" "$hoyoplay_path1" "$hoyoplay_path2" "NonSteamLaunchers" "HoYoPlayLauncher" "" "hoyoplay_launcher"
check_and_write "nexon" "$nexon_path1" "$nexon_path2" "NonSteamLaunchers" "NexonLauncher" "" "nexon_launcher"
check_and_write "gamejolt" "$gamejolt_path1" "$gamejolt_path2" "NonSteamLaunchers" "GameJoltLauncher" "" "gamejolt_launcher"
check_and_write "artixgame" "$artixgame_path1" "$artixgame_path2" "NonSteamLaunchers" "ArtixGameLauncher" "" "artixgame_launcher"
check_and_write "arc" "$arc_path1" "$arc_path2" "NonSteamLaunchers" "ARCLauncher" "" "arc_launcher"
check_and_write "poketcg" "$poketcg_path1" "$poketcg_path2" "NonSteamLaunchers" "PokeTCGLauncher" "" "poketcg_launcher"
check_and_write "antstream" "$antstream_path1" "$antstream_path2" "NonSteamLaunchers" "AntstreamLauncher" "" "antstream_launcher"
check_and_write "purple" "$purple_path1" "$purple_path2" "NonSteamLaunchers" "PURPLELauncher" "" "purple_launcher"
check_and_write "plarium" "$plarium_path1" "$plarium_path2" "NonSteamLaunchers" "PlariumLauncher" "" "plarium_launcher"
check_and_write "vfun" "$vfun_path1" "$vfun_path2" "NonSteamLaunchers" "VFUNLauncher" "" "vfun_launcher"
check_and_write "tempo" "$tempo_path1" "$tempo_path2" "NonSteamLaunchers" "TempoLauncher" "" "tempo_launcher"
check_and_write "stove" "$stove_path1" "$stove_path2" "NonSteamLaunchers" "STOVELauncher" "" "stove_launcher"
check_and_write "bigfish" "$bigfish_path1" "$bigfish_path2" "NonSteamLaunchers" "BigFishLauncher" "" "bigfish_launcher"
check_and_write "gryphlink" "$gryphlink_path1" "$gryphlink_path2" "NonSteamLaunchers" "GryphlinkLauncher" "" "gryphlink_launcher"
# Special Shortcut for EA App NoRepair
eaapp_path1="${logged_in_home}/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c/users/steamuser/Downloads/EAappInstaller.exe"
eaapp_path2="${logged_in_home}/.local/share/Steam/steamapps/compatdata/TheEAappLauncher/pfx/drive_c/users/steamuser/Downloads/EAappInstaller.exe"
check_and_write "repaireaapp" "$eaapp_path1" "$eaapp_path2" "NonSteamLaunchers" "TheEAappLauncher" "" "repaireaapp"
# End of writing to env_vars
# Set the env_vars variable
if [ "$use_separate_appids" != true ]; then
echo "export separate_appids=$use_separate_appids" >> ${logged_in_home}/.config/systemd/user/env_vars
fi
#Other Applications
if [[ $options == *"RemotePlayWhatever"* ]]; then
# Set the directory path
DIRECTORY="${logged_in_home}/.local/share/applications"
# Check if the directory exists
if [ ! -d "$DIRECTORY" ]; then
mkdir -p "$DIRECTORY"
fi
# Get the latest release URL for RemotePlayWhatever
RELEASE_URL=$(curl -s https://api.github.com/repos/m4dEngi/RemotePlayWhatever/releases/latest | grep -o 'https://github.com/m4dEngi/RemotePlayWhatever/releases/download/.*RemotePlayWhatever.*\.AppImage')
# Download the latest RemotePlayWhatever AppImage
wget -P "$DIRECTORY" "$RELEASE_URL"
# Get the downloaded file name
DOWNLOADED_FILE=$(basename "$RELEASE_URL")
# Rename the downloaded file
mv "$DIRECTORY/$DOWNLOADED_FILE" "$DIRECTORY/RemotePlayWhatever"
# Make the file executable
chmod +x "$DIRECTORY/RemotePlayWhatever"
echo "RemotePlayWhatever downloaded, renamed to Remote Play Whatever, made executable, created in $DIRECTORY"
# Create a new .desktop file
echo "[Desktop Entry]
Type=Application
Exec=$DIRECTORY/RemotePlayWhatever \"--appid 0\"
Name=RemotePlayWhatever
Icon=$DIRECTORY/RemotePlayWhatever" > "$DIRECTORY/RemotePlayWhatever.desktop"
# Make the .desktop file executable
chmod +x "$DIRECTORY/RemotePlayWhatever.desktop"
steamos-add-to-steam "$DIRECTORY/RemotePlayWhatever.desktop"
sleep 5
echo "added RemotePlayWhatever to steamos"
fi
# Set Chrome options based on user's selection
ENV_FILE="${logged_in_home}/.config/systemd/user/env_vars"
set_browser_launch_options() {
local key="$1" # netflix, xbox, custom
local website="$2" # optional
local option_var="${key}chromelaunchoptions"
local launch_options=""
if [[ "$options" == *"Google Chrome"* ]]; then
launch_options="run --branch=stable --arch=x86_64 \
--command=/app/bin/chrome --file-forwarding com.google.Chrome @@u @@ \
--window-size=1280,800 --force-device-scale-factor=1.00 \
--device-scale-factor=1.00 --start-fullscreen --no-first-run \
--enable-features=OverlayScrollbar"
elif [[ "$options" == *"Mozilla Firefox"* ]]; then
launch_options="run --branch=stable --arch=x86_64 \
org.mozilla.firefox --kiosk"
elif [[ "$options" == *"Microsoft Edge"* ]]; then
launch_options="run --arch=x86_64 com.microsoft.Edge \
--window-size=1280,800 --force-device-scale-factor=1.00 \
--device-scale-factor=1.00 --start-fullscreen --no-first-run"
elif [[ "$options" == *"Brave"* ]]; then
launch_options="run --arch=x86_64 com.brave.Browser \
--start-fullscreen --window-size=1280,800 \
--force-device-scale-factor=1.00 --no-first-run \
--no-default-browser-check \
--enable-features=OverlayScrollbar,HardwareMediaKeyHandling"
elif [[ "$options" == *"LibreWolf"* ]]; then
launch_options="run --branch=stable --arch=x86_64 \
io.gitlab.librewolf-community --kiosk"
elif [[ "$options" == *"Vivaldi"* ]]; then
launch_options="run --branch=stable --arch=x86_64 \
--command=vivaldi com.vivaldi.Vivaldi \
--start-fullscreen"
fi
# Append URL only if provided
if [[ -n "$website" ]]; then
launch_options="$launch_options $website"
fi
echo "$option_var=$launch_options" >> "$ENV_FILE"
}
# Array of options, command names, and corresponding URLs
declare -A services=(
["Xbox Game Pass"]="xbox|https://www.xbox.com/play"
["WatchParty"]="watchparty|https://www.watchparty.me"
["Netflix"]="netflix|https://www.netflix.com"
["GeForce Now"]="geforce|https://play.geforcenow.com"
["Hulu"]="hulu|https://www.hulu.com/welcome"
["Tubi"]="tubi|https://tubitv.com"
["Disney+"]="disney|https://www.disneyplus.com"
["Amazon Prime Video"]="amazon|https://www.amazon.com/primevideo"
["Youtube"]="youtube|https://www.youtube.com"
["Youtube TV"]="youtubetv|https://youtube.com/tv"
["Amazon Luna"]="luna|https://luna.amazon.com"
["Twitch"]="twitch|https://www.twitch.tv"
["Fortnite"]="fortnite|https://www.xbox.com/en-US/play/games/fortnite/BT5P2X999VH2"
["Better xCloud"]="xcloud|https://better-xcloud.github.io"
["Venge"]="venge|https://venge.io"
["PokéRogue"]="pokerogue|https://pokerogue.net"
["Boosteroid Cloud Gaming"]="boosteroid|https://cloud.boosteroid.com"
["WebRcade"]="webrcade|https://play.webrcade.com"
["WebRcade Editor"]="webrcadeedit|https://editor.webrcade.com"
["Afterplay.io"]="afterplayio|https://afterplay.io/play/recently-played"
["OnePlay"]="oneplay|https://www.oneplay.in/dashboard/home"
["AirGPU"]="airgpu|https://app.airgpu.com"
["CloudDeck"]="clouddeck|https://clouddeck.app"
["JioGamesCloud"]="jio|https://cloudplay.jiogames.com"
["Plex"]="plex|https://app.plex.tv/desktop/#!"
["Crunchyroll"]="crunchy|https://www.crunchyroll.com"
["Apple TV+"]="apple|https://tv.apple.com"
["Stim.io"]="stimio|https://stim.io"
["Rocketcrab"]="rocketcrab|https://rocketcrab.com"
["Cloudy Pad"]="cloudy|https://cloudypad.gg"
)
for option in "${!services[@]}"; do
if [[ "$options" == *"$option"* ]]; then
IFS='|' read -r name url <<< "${services[$option]}"
set_browser_launch_options "$name" "$url"
fi
done
if [ "${#custom_websites[@]}" -gt 0 ]; then
# Split if comma-separated (legacy safety)
if [ "${#custom_websites[@]}" -eq 1 ] && [[ "${custom_websites[0]}" == *,* ]]; then
IFS=',' read -ra custom_websites <<< "${custom_websites[0]}"
IFS=',' read -ra custom_website_names <<< "${custom_website_names[0]}"
fi
# Trim whitespace (URLs)
for i in "${!custom_websites[@]}"; do
custom_websites[$i]=$(echo "${custom_websites[$i]}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
done
# Trim whitespace (Names)
for i in "${!custom_website_names[@]}"; do
custom_website_names[$i]=$(echo "${custom_website_names[$i]}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
done
# Join into strings
custom_websites_str=$(IFS=', '; echo "${custom_websites[*]}")
custom_website_names_str=$(IFS=', '; echo "${custom_website_names[*]}")
# Export both
echo "export custom_websites_str=$custom_websites_str" >> "$ENV_FILE"
echo "export custom_website_names_str=$custom_website_names_str" >> "$ENV_FILE"
set_browser_launch_options "custom"
fi
# Create the download directory if it doesn't exist
mkdir -p "$download_dir"
# Get the version of Python being used
python_version=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
# Create a directory for the vdf module
mkdir -p "${download_dir}/lib/python${python_version}/site-packages/vdf"
# Download the vdf module from the GitHub repository
download_url="https://github.com/moraroy/NonSteamLaunchers-On-Steam-Deck/raw/main/Modules/vdf/__init__.py"
wget -P "${download_dir}/lib/python${python_version}/site-packages/vdf" "$download_url"
# Set the PYTHONPATH environment variable
export PYTHONPATH="${download_dir}/lib/python${python_version}/site-packages/:$PYTHONPATH"
# Set the default Steam directory
steam_dir="${logged_in_home}/.local/share/Steam"
set +x
# Check if the loginusers.vdf file exists in either of the two directories
if [[ -f "${logged_in_home}/.steam/root/config/loginusers.vdf" ]] || [[ -f "${logged_in_home}/.local/share/Steam/config/loginusers.vdf" ]]; then
if [[ -f "${logged_in_home}/.steam/root/config/loginusers.vdf" ]]; then
file_path="${logged_in_home}/.steam/root/config/loginusers.vdf"
else
file_path="${logged_in_home}/.local/share/Steam/config/loginusers.vdf"
fi
# Extract the block of text for the most recent user
most_recent_user=$(sed -n '/"users"/,/"MostRecent" "1"/p' "$file_path")
# Initialize variables
max_timestamp=0
current_user=""
current_steamid=""
# Process each user block
# Set IFS to only look for Commas to avoid issues with Whitespace in older account names.
while IFS="," read steamid account timestamp; do
if (( timestamp > max_timestamp )); then
max_timestamp=$timestamp
current_user=$account
current_steamid=$steamid
fi
# Output our discovered values as comma seperated string to be read into the IDs.
done < <(echo "$most_recent_user" | awk -v RS='}\n' -F'\n' '
{
for(i=1;i<=NF;i++){
if($i ~ /[0-9]{17}/){
split($i,a, "\""); steamid=a[2];
}
if($i ~ /"AccountName"/){
split($i,b, "\""); account=b[4];
}
if($i ~ /"Timestamp"/){
split($i,c, "\""); timestamp=c[4];
}
}
print steamid "," account "," timestamp
}')
# Print the currently logged in user
if [[ -n $current_user ]]; then
echo "SteamID: $current_steamid"
else
echo "No users found."
fi
# Convert steamid to steamid3
steamid3=$((current_steamid - 76561197960265728))
# Directly map steamid3 to userdata folder
userdata_folder="${logged_in_home}/.steam/root/userdata/${steamid3}"
# Check if userdata_folder exists
if [[ -d "$userdata_folder" ]]; then
echo "Found userdata folder for user with SteamID $current_steamid: $userdata_folder"
else
echo "Could not find userdata folder for user with SteamID $current_steamid"
fi
else
echo "Could not find loginusers.vdf file"
fi
#set -x
# Check if userdata folder was found
if [[ -n "$userdata_folder" ]]; then
# Userdata folder was found
echo "Current user's userdata folder found at: $userdata_folder"
# Find shortcuts.vdf file for current user
shortcuts_vdf_path=$(find "$userdata_folder" -type f -name shortcuts.vdf)
# Check if shortcuts_vdf_path is not empty
if [[ -n "$shortcuts_vdf_path" ]]; then
# Define backup directory
backup_dir="$(dirname "$shortcuts_vdf_path")/shortcuts.vdf_backups"
mkdir -p "$backup_dir"
# Create backup of shortcuts.vdf file
cp "$shortcuts_vdf_path" "$backup_dir/shortcuts.vdf.bak_$(date +%m-%d-%Y_%H:%M:%S)"
else
# Find config directory for current user
config_dir=$(find "$userdata_folder" -maxdepth 1 -type d -name config)
# Check if config_dir is not empty
if [[ -n "$config_dir" ]]; then
# Create new shortcuts.vdf file at expected location for current user
touch "$config_dir/shortcuts.vdf"
shortcuts_vdf_path="$config_dir/shortcuts.vdf"
else
# Create new config directory and new shortcuts.vdf file at expected location for current user
mkdir "$userdata_folder/config/"
touch "$userdata_folder/config/shortcuts.vdf"
config_dir="$userdata_folder/config/"
shortcuts_vdf_path="$config_dir/shortcuts.vdf"
fi
fi
else
# Userdata folder was not found
echo "Current user's userdata folder not found"
fi
# Send Notes
if [[ $options == *"❤️"* ]]; then
show_message "Sending any #nsl notes to the community!<3"
# Check if steamid3 is not empty
if [[ -n "$steamid3" ]]; then
remote_dir="${logged_in_home}/.steam/root/userdata/${steamid3}/2371090/remote"
echo "Searching directory: $remote_dir"
# Create the remote directory if it doesn't exist
mkdir -p "$remote_dir"
echo "Directory $remote_dir is ready."
# Check if the remote directory exists now
if [[ -d "$remote_dir" ]]; then
echo "Found matching remote directory: $remote_dir"
else
echo "Error: No matching remote directory found."
fi
else
echo "Error: steamid3 variable is not set."
fi
# Path for the new "NSL Notes" folder
nsl_notes_folder="$remote_dir/NSL Notes"
echo "NSL Notes folder path: $nsl_notes_folder"
# Create the "NSL Notes" folder if it doesn't exist
echo "Creating NSL Notes folder if it doesn't exist..."
mkdir -p "$nsl_notes_folder" > /dev/null 2>&1
echo "NSL Notes folder created."
# Output JSON file
output_file="$nsl_notes_folder/nsl_notes_cache.json"
echo "Output file will be: $output_file"
# Initialize an empty array for collected data
collected_notes="[]"
note_count=0
echo "Initializing collection of notes..."
# Check if the file exists
if [[ -f "$output_file" ]]; then
# Read the existing data from the file (which should be a valid JSON array)
collected_notes=$(<"$output_file")
else
# If the file doesn't exist, start with an empty array
collected_notes="[]"
fi
# Loop through all files matching the pattern "notes_shortcut_*"
echo "Processing notes_shortcut_* files..."
for note_file in "$remote_dir"/notes_shortcut_*; do
[[ -f "$note_file" ]] || continue # Skip if it's not a regular file
echo "Processing file: $note_file"
# Read the content of the current file all at once
data=$(<"$note_file")
# Parse the JSON structure and iterate over "notes" array
note_count_in_file=$(echo "$data" | jq '.notes | length')
echo "Found $note_count_in_file notes in file $note_file."
for i in $(seq 0 $((note_count_in_file - 1))); do
echo "Processing note $i..."
# Extract data for each note
id=$(echo "$data" | jq -r ".notes[$i].id")
shortcut_name=$(echo "$data" | jq -r ".notes[$i].shortcut_name")
ordinal=0 # Ordinal is always 0
time_created=$(echo "$data" | jq -r ".notes[$i].time_created")
time_modified=$(echo "$data" | jq -r ".notes[$i].time_modified")
title=$(echo "$data" | jq -r ".notes[$i].title")
content=$(echo "$data" | jq -r ".notes[$i].content")
echo "Processing note with ID: $id, Title: $title"
# Skip if ID contains the word "note"
[[ "$id" == *"note"* ]] && continue
# Process only the entries with #nsl in the title
[[ "$title" =~ "#nsl" ]] || continue
# Clean the content by removing #nsl and HTML tags
cleaned_content=$(echo "$content" | sed 's/#nsl//g' | sed 's/<[^>]*>//g')
# Decode HTML entities (such as & to &)
cleaned_content=$(echo "$cleaned_content" | sed -e 's/&/\&/g' -e 's/<//g' -e 's/"/"/g' -e 's/'/\'\''/g')
# Get just the file name (without the full path)
file_name=$(basename "$note_file")
# Ensure Time Created and Time Modified are treated as integers
time_created_int=$(echo "$time_created" | sed 's/^0*//') # Remove leading zeros if any
time_modified_int=$(echo "$time_modified" | sed 's/^0*//') # Remove leading zeros if any
# Add data to the collected_notes array (as a valid JSON object)
collected_notes=$(echo "$collected_notes" | jq ". += [{
\"ID\": \"$id\",
\"Shortcut Name\": \"$shortcut_name\",
\"Ordinal\": $ordinal,
\"Time Created\": $time_created_int,
\"Time Modified\": $time_modified_int,
\"Title\": \"$title\",
\"Content\": \"$cleaned_content\",
\"File Name\": \"$file_name\"
}]")
# Increment the note count
note_count=$((note_count + 1))
done
done
# Write the updated collected_notes array to the output file (appending properly formatted JSON)
echo "Writing collected notes to output file: $output_file"
echo "$collected_notes" > "$output_file" 2>/dev/null
# Send the collected data to the API
echo "Sending collected data to API..."
url="https://nslnotes.onrender.com/api/notes/"
response=$(curl -s -w "%{http_code}" -o /dev/null -X POST -H "Content-Type: application/json" -d "$collected_notes" "$url")
# Check if the request was successful
if [[ "$response" == "200" ]]; then
echo "$note_count notes successfully sent to the API."
else
echo "Failed to send data to the API. Status code: $response"
fi
show_message "#nsl notes have been sent :) looking for new ones!<3"
fi
#recieve noooooooooooootes
# Paths
# Paths
proton_dir=$(find -L "${logged_in_home}/.steam/root/compatibilitytools.d" -maxdepth 1 -type d -name "GE-Proton*" | sort -V | tail -n1)
CSV_FILE="$proton_dir/protonfixes/umu-database.csv"
echo "$CSV_FILE"
shortcuts_file="${logged_in_home}/.steam/root/userdata/${steamid3}/config/shortcuts.vdf"
output_dir="${logged_in_home}/.steam/root/userdata/${steamid3}/2371090/remote"
# Function to get the current Unix timestamp
get_current_timestamp() {
date +%s
}
# Function to validate JSON
validate_json() {
local file_path="$1"
if ! jq . "$file_path" > /dev/null 2>&1; then
echo "Error: Invalid JSON in file $file_path"
return 1
fi
return 0
}
# Function to URL encode a string (replace spaces with %20 and other special characters)
urlencode() {
local raw="$1"
echo -n "$raw" | jq -sRr @uri
}
# Function to fetch all notes from the API at once
fetch_all_notes_from_api() {
response=$(curl -s "https://nslnotes.onrender.com/api/notes")
if ! jq . <<< "$response" > /dev/null 2>&1; then
echo "Error: Invalid JSON response from the API"
return 1
fi
echo "$response"
}
# Function to update notes in the file for a game
update_notes_in_file() {
local file_path="$1"
local game_name="$2"
local api_response="$3"
sanitized_game_name="$game_name"
sanitized_game_name="${sanitized_game_name// /_}"
sanitized_game_name="${sanitized_game_name//[^a-zA-Z0-9]/_}"
encoded_game_name=$(urlencode "$sanitized_game_name")
filtered_notes=$(echo "$api_response" | jq -r ".[] | select(.\"File Name\" == \"notes_shortcut_${encoded_game_name}\")")
if [[ -z "$filtered_notes" ]]; then
echo "No notes found for game $game_name"
return
fi
nsl_content=""
for note in $(echo "$filtered_notes" | jq -r '@base64'); do
note_decoded=$(echo "$note" | base64 --decode)
user=$(echo "$note_decoded" | jq -r '."user"')
content=$(echo "$note_decoded" | jq -r '."Content"')
time_created=$(echo "$note_decoded" | jq -r '."Time Created"')
content_sanitized=$(echo "$content" | sed 's/\[\/\?p\]//g')
content_sanitized=$(echo "$content_sanitized" | sed 's/\n/
/g')
nsl_content+=$"[p][i]A note called \"$user\" says,[/i][/p]"
nsl_content+=$"[p]$content_sanitized[/p]"
nsl_content+=$"[p]$time_created[/p]"
done
local current_time=$(get_current_timestamp)
game_details=$(grep -i "$game_name" "$CSV_FILE")
if [[ -z "$game_details" ]]; then
game_details="N/A,N/A,N/A,N/A,N/A,N/A"
fi
echo "$game_details" | while IFS=',' read -r title store codename umu_id common_acronym note; do
title=${title:-N/A}
store=${store:-N/A}
codename=${codename:-N/A}
umu_id=${umu_id:-N/A}
common_acronym=${common_acronym:-N/A}
note=${note:-N/A}
proton_ge_content="[p]Title: $title[/p][p]Store: $store[/p][p]Codename: $codename[/p][p]UMU ID: $umu_id[/p][p]Common Acronym: $common_acronym[/p][p]Note: $note[/p]"
local note_1=$(jq -n --arg shortcut_name "$game_name" --argjson time_created "$current_time" --arg proton_ge_content "$proton_ge_content" \
'{"id":"note1675","shortcut_name":$shortcut_name,"ordinal":0,"time_created":$time_created,"time_modified":$time_created,"title":"Proton-GE & UMU","content":$proton_ge_content}')
local note_2=$(jq -n --arg shortcut_name "$game_name" --argjson time_created "$current_time" --arg nsl_content "$nsl_content" \
'{"id":"note2675","shortcut_name":$shortcut_name,"ordinal":0,"time_created":$time_created,"time_modified":$time_created,"title":"NSL Community Notes","content":$nsl_content}')
if [[ -f "$file_path" ]]; then
if validate_json "$file_path"; then
if jq -e '.notes | type == "array"' "$file_path" > /dev/null; then
jq --argjson note1 "$note_1" --argjson note2 "$note_2" \
'.notes = [$note1, $note2] + (.notes | map(select(.id != "note1675" and .id != "note2675")))' \
"$file_path" > "$file_path.tmp" && mv "$file_path.tmp" "$file_path"
echo "Replaced Proton and NSL Community Notes in $file_path"
else
echo "Error: The 'notes' field is not an array or is missing in $file_path."
return 1
fi
else
echo "Invalid JSON. Skipping update."
return 1
fi
else
if jq -n --argjson note1 "$note_1" --argjson note2 "$note_2" \
'{"notes":[$note1, $note2]}' > "$file_path"; then
echo "Created new file with notes: $file_path"
else
echo "Error creating file: $file_path"
return 1
fi
fi
done
}
# Function to list game names from the shortcuts file
list_game_names() {
local skip_ext='\.(exe|sh|bat|msi|app|apk|url|desktop|appimage)$'
if [[ ! -f "$shortcuts_file" ]]; then
echo "No shortcuts.vdf found at $shortcuts_file"
return 1
fi
echo "Reading game names from $shortcuts_file..."
games=()
mapfile -t lines < <(tr '\0\1\2' '\n\n\n' < "$shortcuts_file" | grep -v '^$')
for ((i=0; i < ${#lines[@]} - 1; i++)); do
if [[ "${lines[i],,}" == "appname" ]]; then
local appname="${lines[i+1]}"
appname="${appname#"${appname%%[![:space:]]*}"}"
appname="${appname%"${appname##*[![:space:]]}"}"
if [[ -n "$appname" && ! "${appname,,}" =~ $skip_ext ]]; then
games+=("$appname")
echo "Added game: $appname"
else
echo "Skipped: $appname"
fi
fi
done
return 0
}
echo "Starting script..."
api_response=$(fetch_all_notes_from_api)
if [[ $? -ne 0 ]]; then
echo "Failed to fetch all notes from the API"
exit 1
fi
list_game_names
for game_name in "${games[@]}"; do
sanitized_game_name="$game_name"
sanitized_game_name="${sanitized_game_name//\(/_}"
sanitized_game_name="${sanitized_game_name//\)/_}"
sanitized_game_name="${sanitized_game_name// /_}"
sanitized_game_name="${sanitized_game_name//[^a-zA-Z0-9™]/_}"
file_path="$output_dir/notes_shortcut_$sanitized_game_name"
echo "Processing: $game_name (File: $file_path)"
update_notes_in_file "$file_path" "$game_name" "$api_response"
done
echo "Notes execution complete."
show_message "Notes have been recieved!"
#noooooooooooooooootes
# Pre check for updating the config file
# Set the default Steam directory
steam_dir_root="${logged_in_home}/.steam/root"
# Set the path to the config.vdf file
config_vdf_path="${steam_dir_root}/config/config.vdf"
# Check if the config.vdf file exists
if [ -f "$config_vdf_path" ]; then
# Create a backup of the config.vdf file
backup_path="${steam_dir_root}/config/config.vdf.bak"
cp "$config_vdf_path" "$backup_path"
# Set the name of the compatibility tool to use
compat_tool_name=$(ls "${logged_in_home}/.steam/root/compatibilitytools.d" | grep "GE-Proton" | sort -V | tail -n1)
else
echo "Could not find config.vdf file"
fi
# Write variables to a file before script is detached
echo "export steamid3=$steamid3" >> ${logged_in_home}/.config/systemd/user/env_vars
echo "export logged_in_home=$logged_in_home" >> ${logged_in_home}/.config/systemd/user/env_vars
echo "export compat_tool_name=$compat_tool_name" >> ${logged_in_home}/.config/systemd/user/env_vars
echo "export python_version=$python_version" >> ${logged_in_home}/.config/systemd/user/env_vars
echo "export chromedirectory=$chromedirectory" >> ${logged_in_home}/.config/systemd/user/env_vars
echo "export chrome_startdir=$chrome_startdir" >> ${logged_in_home}/.config/systemd/user/env_vars
# TODO: might be better to relocate temp files to `/tmp` or even use `mktemp -d` since `rm -rf` is potentially dangerous without the `-i` flag
# Delete NonSteamLaunchersInstallation subfolder in Downloads folder
rm -rf "$download_dir"
echo "Script completed successfully."
# Check if the symlink exists
if [ -L "${logged_in_home}/.config/systemd/user/default.target.wants/nslgamescanner.service" ]; then
# Symlink exists, show message
show_message "Script finished...and the NSLGamesScanner is actively scanning!"
else
# Symlink does not exist
echo "Symlink does not exist."
fi
exit 0