Merge pull request #626 from XargonWan/feat/logging

Enhanced logging
This commit is contained in:
XargonWan 2024-02-28 18:18:44 +01:00 committed by GitHub
commit 4aba7708c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 507 additions and 287 deletions

View file

@ -7,24 +7,24 @@ source automation_tools/version_extractor.sh
# Fetch appdata version
appdata_version=$(fetch_appdata_version)
echo -e "Appdata:\t\t$appdata_version"
log i "Appdata:\t\t$appdata_version"
# Defining manifest file location
appdata_file="net.retrodeck.retrodeck.appdata.xml"
# Check if release with appdata_version already exists
if grep -q "version=\"$appdata_version\"" "$appdata_file"; then
echo "Deleting existing release version $appdata_version..."
log i "Deleting existing release version $appdata_version..."
# Remove the existing release entry
sed -i "/<release version=\"$appdata_version\"/,/<\/release>/d" "$appdata_file"
fi
echo "Adding new release version $appdata_version..."
log i "Adding new release version $appdata_version..."
# Get today's date in the required format (YYYY-MM-DD)
today_date=$(date +"%Y-%m-%d")
echo "Today is $today_date"
log i "Today is $today_date"
# Construct the release snippet
release_snippet="\

View file

@ -8,16 +8,6 @@ IWAD_FILES=("DOOM1.WAD" "DOOM.WAD" "DOOM2.WAD" "DOOM2F.WAD" "DOOM64.WAD" "TNT.WA
"doom_complete.pk3"
)
# Function to log messages to terminal and a log file
log() {
local message="$1"
local logfile="$rdhome/logs/gzdoom.log"
local timestamp="$(date +[%Y-%m-%d\ %H:%M:%S])"
echo "$timestamp $message" | tee -a "$logfile"
}
# Function to check if a file is an IWAD
is_iwad() {
local file="$1"
@ -62,8 +52,8 @@ if [[ "${1##*.}" != "doom" ]]; then
fi
# Log the command
log "[INFO] Loading: \"$1\""
log "[INFO] Executing command \"$command\""
log i "Loading: \"$1\""
log i "Executing command \"$command\""
# Execute the command
eval "$command"
@ -71,11 +61,11 @@ if [[ "${1##*.}" != "doom" ]]; then
# Check if $1 is a .doom file
else
doom_file="$1"
log "[INFO] Found a doom file: \"$1\""
log i "Found a doom file: \"$1\""
# Check if the .doom file exists
if [[ ! -e "$doom_file" ]]; then
log "[Error] doom file not found in \"$doom_file\""
log e "doom file not found in \"$doom_file\""
zenity --error --no-wrap \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK" \
@ -103,15 +93,15 @@ else
# Check if the file is an IWAD
if [[ $(is_iwad "$found_file") == "true" ]]; then
command+=" -iwad $found_file"
log "[INFO] Appending the param \"-iwad $found_file\""
log i "Appending the param \"-iwad $found_file\""
else
command+=" -file $found_file"
log "[INFO] Appending the param \"-file $found_file\""
log i "Appending the param \"-file $found_file\""
fi
done < "$doom_file"
# Log the command
log "[INFO] Executing command \"$command\""
log i "Executing command \"$command\""
# Execute the command
eval "$command"

View file

@ -13,7 +13,7 @@ save_migration() {
# ROMs on Internal
roms_folder="$HOME/retrodeck/roms"
fi
echo "ROMs folder found at $roms_folder"
log i "ROMs folder found at $roms_folder"
# Unhiding downloaded media from the previous versions
if [ -d "$rdhome/.downloaded_media" ]
@ -30,7 +30,7 @@ save_migration() {
# Doing the dir prep as we don't know from which version we came
dir_prep "$media_folder" "/var/config/ES-DE/downloaded_media"
dir_prep "$themes_folder" "/var/config/ES-DE/themes"
mkdir -pv $rdhome/logs #this was added later, maybe safe to remove in a few versions
create_dir $rdhome/logs #this was added later, maybe safe to remove in a few versions
# Resetting es_settings, now we need it but in the future I should think a better solution, maybe with sed
cp -fv /app/retrodeck/es_settings.xml /var/config/ES-DE/settings/es_settings.xml
@ -72,9 +72,9 @@ save_migration() {
gamestoskip=
tar -C $rdhome -czf $save_backup_file saves # Backup save directory for safety
echo "Saves backed up to" $save_backup_file >> $migration_logfile
log i "Saves backed up to" $save_backup_file $migration_logfile
tar -C $rdhome -czf $state_backup_file states # Backup state directory for safety
echo "States backed up to" $state_backup_file >> $migration_logfile
log i "States backed up to" $state_backup_file $migration_logfile
(
movefile() { # Take matching save and rom files and sort save into appropriate system folder
@ -92,21 +92,22 @@ save_migration() {
gamestoskip+=("$1")
return
fi
echo "INFO: Examining ROM file:" "$game" >> $migration_logfile
echo "INFO: System detected as" $systemdir >> $migration_logfile
log i "Examining ROM file:" "$game" $migration_logfile
log i "System detected as" $systemdir $migration_logfile
sosfile=$(sed -e "s/\^/ /g" <<< "$2") # Remove whitespace placeholder from s-ave o-r s-tate file
sospurebasename="$(basename "$sosfile")" # Extract pure file name ie. /saves/game1.sav becomes game1
echo "INFO: Current save or state being examined for match:" $sosfile >> $migration_logfile
echo "INFO: Matching save or state" $sosfile "and game" $game "found." >> $migration_logfile
echo "INFO: Moving save or state to" $current_dest_folder"/"$systemdir"/"$sosbasename >> $migration_logfile
log i "Current save or state being examined for match:" $sosfile $migration_logfile
log i "Matching save or state" $sosfile "and game" $game "found." $migration_logfile
log i "Moving save or state to $current_dest_folder/$systemdir/$sosbasename" $migration_logfile
if [[ ! -d $current_dest_folder"/"$systemdir ]]; then # If system directory doesn't exist for save yet, create it
echo "WARNING: Creating missing system directory" $current_dest_folder"/"$systemdir
log w "Creating missing system directory $current_dest_folder/$systemdir"
mkdir $current_dest_folder/$systemdir
fi
mv "$sosfile" -t $current_dest_folder/$systemdir # Move save to appropriate system directory
return
else
echo "WARNING: Game with name" "$(basename "$1" | sed -e "s/\^/ /g")" "already found. Skipping to next game..." >> $migration_logfile # Inform user of game being skipped due to duplicate ROM names
local name="$(basename "$1" | sed -e "s/\^/ /g")"
log w "Game with name \"$name\" already found. Skipping to next game..." $migration_logfile # Inform user of game being skipped due to duplicate ROM names
fi
}
@ -167,6 +168,6 @@ save_migration() {
fi
else
echo "Version" $version "is after the save and state organization was changed, no need to sort again"
log i "Version $version is after the save and state organization was changed, no need to sort again"
fi
}

View file

@ -82,7 +82,7 @@ check_for_version_update() {
configurator_generic_dialog "RetroDECK Online Update" "The update process may take several minutes.\n\nAfter the update is complete, RetroDECK will close. When you run it again you will be using the latest version."
(
local latest_cooker_download=$(curl --silent https://api.github.com/repos/XargonWan/$update_repo/releases/latest | grep '"browser_download_url":' | sed -E 's/.*"([^"]+)".*/\1/')
mkdir -p "$rdhome/RetroDECK_Updates"
create_dir "$rdhome/RetroDECK_Updates"
wget -P "$rdhome/RetroDECK_Updates" $latest_cooker_download
flatpak-spawn --host flatpak remove --noninteractive -y net.retrodeck.retrodeck # Remove current version before installing new one, to avoid duplicates
flatpak-spawn --host flatpak install --user --bundle --noninteractive -y "$rdhome/RetroDECK_Updates/RetroDECK-cooker.flatpak"

View file

@ -162,6 +162,8 @@ changelog_dialog() {
# The function also accepts "all" as a version, and will print the entire changelog
# USAGE: changelog_dialog "version"
log d "Showing changelog dialog"
if [[ "$1" == "all" ]]; then
xml sel -t -m "//release" -v "concat('RetroDECK version: ', @version)" -n -v "description" -n $rd_appdata | awk '{$1=$1;print}' | sed -e '/./b' -e :n -e 'N;s/\n$//;tn' > "/var/config/retrodeck/changelog.txt"
@ -186,6 +188,8 @@ get_cheevos_token_dialog() {
# This function will return a RetroAchvievements token from a valid username and password, will return "login failed" otherwise
# USAGE: get_cheevos_token_dialog
log d "Opening RetroAchievements dialog"
local cheevos_info=$(zenity --forms --title="Cheevos" \
--text="Username and password." \
--separator="^" \
@ -211,15 +215,20 @@ desktop_mode_warning() {
# USAGE: desktop_mode_warning
if [[ $(check_desktop_mode) == "true" && $desktop_mode_warning == "true" ]]; then
local message='You appear to be running RetroDECK in the Steam Deck'\''s Desktop mode!\n\nSome functions of RetroDECK may not work properly in Desktop mode, such as the Steam Deck'\''s normal controls.\n\nRetroDECK is best enjoyed in Game mode!\n\nDo you still want to proceed?'
log i "Showing message:\n$message"
choice=$(zenity --icon-name=net.retrodeck.retrodeck --info --no-wrap --ok-label="Yes" --extra-button="No" --extra-button="Never show this again" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Desktop Mode Warning" \
--text="You appear to be running RetroDECK in the Steam Deck's Desktop mode!\n\nSome functions of RetroDECK may not work properly in Desktop mode, such as the Steam Deck's normal controls.\n\nRetroDECK is best enjoyed in Game mode!\n\nDo you still want to proceed?")
--text="$message")
rc=$? # Capture return code, as "Yes" button has no text value
if [[ $rc == "1" ]]; then # If any button other than "Yes" was clicked
log i "Selected: \"Yes\""
if [[ $choice == "No" ]]; then
log i "Selected: \"No\""
exit 1
elif [[ $choice == "Never show this again" ]]; then
log i "Selected: \"Never show this again\""
set_setting_value $rd_conf "desktop_mode_warning" "false" retrodeck "options" # Store desktop mode warning variable for future checks
fi
fi
@ -233,13 +242,17 @@ low_space_warning() {
if [[ $low_space_warning == "true" ]]; then
local used_percent=$(df --output=pcent "$HOME" | tail -1 | tr -d " " | tr -d "%")
if [[ "$used_percent" -ge 90 && -d "$HOME/retrodeck" ]]; then # If there is any RetroDECK data on the main drive to move
local message='Your main drive is over 90% full!\n\nIf your drive fills completely this can lead to data loss or system crash.\n\nPlease consider moving some RetroDECK folders to other storage locations using the Configurator.'
log i "Showing message:\n$message"
choice=$(zenity --icon-name=net.retrodeck.retrodeck --info --no-wrap --ok-label="OK" --extra-button="Never show this again" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Low Space Warning" \
--text="Your main drive is over 90% full!\n\nIf your drive fills completely this can lead to data loss or system crash.\n\nPlease consider moving some RetroDECK folders to other storage locations using the Configurator.")
--text="$message")
if [[ $choice == "Never show this again" ]]; then
set_setting_value $rd_conf "low_space_warning" "false" retrodeck "options" # Store low space warning variable for future checks
log i "Selected: \"Never show this again\""
set_setting_value $rd_conf "low_space_warning" "false" retrodeck "options" # Store low space warning variable for future checks
fi
fi
log i "Selected: \"OK\""
fi
}

View file

@ -16,6 +16,7 @@ directory_browse() {
if [ $? == 0 ]
then
path_selected=true
log i "\"$target\" selected."
echo "$target"
break
fi
@ -46,6 +47,7 @@ file_browse() {
if [ $? == 0 ]
then
file_selected=true
log i "\"$target\" selected."
echo "$target"
break
fi
@ -69,9 +71,12 @@ verify_space() {
source_size=$((source_size+(source_size/10))) # Add 10% to source size for safety
dest_avail=$(df -k --output=avail "$2" | tail -1)
log i "Checking free disk space"
if [[ $source_size -ge $dest_avail ]]; then
log e "Not enough disk space: $dest_avail"
echo "false"
else
log i "Disk space is enough: $dest_avail"
echo "true"
fi
}
@ -83,6 +88,8 @@ move() {
source_dir="$(echo $1 | sed 's![^/]$!&/!')" # Add trailing slash if it is missing
dest_dir="$(echo $2 | sed 's![^/]$!&/!')" # Add trailing slash if it is missing
log d "Moving \"$source_dir\" to \"$dest_dir\""
(
rsync -a --remove-source-files --ignore-existing --mkpath "$source_dir" "$dest_dir" # Copy files but don't overwrite conflicts
find "$source_dir" -type d -empty -delete # Cleanup empty folders that were left behind
@ -100,6 +107,27 @@ move() {
fi
}
create_dir() {
# A simple function that creates a directory checking if is still there while logging the activity
# If -d it will delete it prior the creation
if [[ "$1" == "-d" ]]; then
# If "force" flag is provided, delete the directory first
shift # Remove the first argument (-f)
if [[ -e "$1" ]]; then
rm -rf "$1" # Forcefully delete the directory
log d "Found \"$1\", deleting it."
fi
fi
if [[ ! -d "$1" ]]; then
mkdir -p "$1" # Create directory if it doesn't exist
log d "Created directory: $1"
else
log d "Directory \"$1\" already exists, skipping."
fi
}
download_file() {
# Function to download file from the Internet, with Zenity progress bar
# USAGE: download_file $source_url $file_dest $file_name
@ -216,51 +244,51 @@ dir_prep() {
real="$1"
symlink="$2"
echo -e "\n[DIR PREP]\nMoving $symlink in $real" #DEBUG
log d "[DIR PREP]\nMoving $symlink in $real" #DEBUG
# if the symlink dir is already a symlink, unlink it first, to prevent recursion
if [ -L "$symlink" ];
then
echo "$symlink is already a symlink, unlinking to prevent recursives" #DEBUG
log d "$symlink is already a symlink, unlinking to prevent recursives" #DEBUG
unlink "$symlink"
fi
# if the dest dir exists we want to backup it
if [ -d "$symlink" ];
then
echo "$symlink found" #DEBUG
log d "$symlink found" #DEBUG
mv -f "$symlink" "$symlink.old"
fi
# if the real dir is already a symlink, unlink it first
if [ -L "$real" ];
then
echo "$real is already a symlink, unlinking to prevent recursives" #DEBUG
log d "$real is already a symlink, unlinking to prevent recursives" #DEBUG
unlink "$real"
fi
# if the real dir doesn't exist we create it
if [ ! -d "$real" ];
then
echo "$real not found, creating it" #DEBUG
mkdir -pv "$real"
log d "$real not found, creating it" #DEBUG
create_dir "$real"
fi
# creating the symlink
echo "linking $real in $symlink" #DEBUG
mkdir -pv "$(dirname "$symlink")" # creating the full path except the last folder
log d "linking $real in $symlink" #DEBUG
create_dir "$(dirname "$symlink")" # creating the full path except the last folder
ln -svf "$real" "$symlink"
# moving everything from the old folder to the new one, delete the old one
if [ -d "$symlink.old" ];
then
echo "Moving the data from $symlink.old to $real" #DEBUG
log d "Moving the data from $symlink.old to $real" #DEBUG
mv -f "$symlink.old"/{.[!.],}* "$real"
echo "Removing $symlink.old" #DEBUG
log d "Removing $symlink.old" #DEBUG
rm -rf "$symlink.old"
fi
echo -e "$symlink is now $real\n"
log i "$symlink is now $real\n"
}
check_bios_files() {
@ -294,7 +322,7 @@ check_bios_files() {
}
update_rpcs3_firmware() {
mkdir -p "$roms_folder/ps3/tmp"
create_dir "$roms_folder/ps3/tmp"
chmod 777 "$roms_folder/ps3/tmp"
download_file "$rpcs3_firmware" "$roms_folder/ps3/tmp/PS3UPDAT.PUP" "RPCS3 Firmware"
rpcs3 --installfw "$roms_folder/ps3/tmp/PS3UPDAT.PUP"
@ -309,7 +337,7 @@ update_vita3k_firmware() {
}
backup_retrodeck_userdata() {
mkdir -p "$backups_folder"
create_dir "$backups_folder"
zip -rq9 "$backups_folder/$(date +"%0m%0d")_retrodeck_userdata.zip" "$saves_folder" "$states_folder" "$bios_folder" "$media_folder" "$themes_folder" "$logs_folder" "$screenshots_folder" "$mods_folder" "$texture_packs_folder" "$borders_folder" > $logs_folder/$(date +"%0m%0d")_backup_log.log
}
@ -340,6 +368,7 @@ do
if [ $? == 0 ] #yes
then
path_selected=true
log i "\"$target/retrodeck\" selected."
echo "$target/retrodeck"
break
else
@ -381,28 +410,29 @@ finit_user_options_dialog() {
--column "option_flag" \
"${finit_available_options[@]}")
log i "User choiches: \"${choices[*]}\"."
echo "${choices[*]}"
}
finit() {
# Force/First init, depending on the situation
echo "Executing finit"
log i "Executing finit"
# Internal or SD Card?
local finit_dest_choice=$(configurator_destination_choice_dialog "RetroDECK data" "Welcome to the first configuration of RetroDECK.\nThe setup will be quick but please READ CAREFULLY each message in order to avoid misconfigurations.\n\nWhere do you want your RetroDECK data folder to be located?\n\nThis folder will contain all ROMs, BIOSs and scraped data." )
echo "Choice is $finit_dest_choice"
log i "Choice is $finit_dest_choice"
case "$finit_dest_choice" in
"Back" | "" ) # Back or X button quits
rm -f "$rd_conf" # Cleanup unfinished retrodeck.cfg if first install is interrupted
echo "Now quitting"
log i "Now quitting"
quit_retrodeck
;;
"Internal Storage" ) # Internal
echo "Internal selected"
log i "Internal selected"
rdhome="$HOME/retrodeck"
if [[ -L "$rdhome" ]]; then #Remove old symlink from existing install, if it exists
unlink "$rdhome"
@ -410,10 +440,10 @@ finit() {
;;
"SD Card" )
echo "SD Card selected"
log i "SD Card selected"
if [ ! -d "$sdcard" ] # SD Card path is not existing
then
echo "Error: SD card not found"
log e "SD card not found"
zenity --error --no-wrap \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK" \
@ -426,14 +456,14 @@ finit() {
fi
elif [ ! -w "$sdcard" ] #SD card found but not writable
then
echo "Error: SD card found but not writable"
log e "SD card found but not writable"
zenity --error --no-wrap \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK" \
--ok-label "Quit" \
--text="SD card was found but is not writable\nThis can happen with cards formatted on PC.\nPlease format the SD card through the Steam Deck's Game Mode and run RetroDECK again."
rm -f "$rd_conf" # Cleanup unfinished retrodeck.cfg if first install is interrupted
echo "Now quitting"
log i "Now quitting"
quit_retrodeck
else
rdhome="$sdcard/retrodeck"
@ -441,7 +471,7 @@ finit() {
;;
"Custom Location" )
echo "Custom Location selected"
log i "Custom Location selected"
zenity --info --no-wrap \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK" \
@ -513,11 +543,11 @@ install_retrodeck_starterpack() {
## DOOM section ##
cp /app/retrodeck/extras/doom1.wad "$roms_folder/doom/doom1.wad" # No -f in case the user already has it
mkdir -p "/var/config/ES-DE/gamelists/doom"
create_dir "/var/config/ES-DE/gamelists/doom"
if [[ ! -f "/var/config/ES-DE/gamelists/doom/gamelist.xml" ]]; then # Don't overwrite an existing gamelist
cp "/app/retrodeck/rd_prepacks/doom/gamelist.xml" "/var/config/ES-DE/gamelists/doom/gamelist.xml"
fi
mkdir -p "$media_folder/doom"
create_dir "$media_folder/doom"
unzip -oq "/app/retrodeck/rd_prepacks/doom/doom.zip" -d "$media_folder/doom/"
}
@ -599,7 +629,7 @@ manage_ryujinx_keys() {
# This function checks if Switch keys are existing and symlinks them inside the Ryujinx system folder
# If the symlinks are broken it recreates them
echo "Checking Ryujinx Switch keys." #TODO logging
log i "Checking Ryujinx Switch keys."
local ryujinx_system="/var/config/Ryujinx/system" # Set the path to the Ryujinx system folder
# Check if the keys folder exists
if [ -d "$bios_folder/switch/keys" ]; then
@ -612,12 +642,12 @@ manage_ryujinx_keys() {
# Check if the symlink exists and is valid
if [ -L "$symlink" ] && [ "$(readlink -f "$symlink")" = "$file" ]; then
echo "Found \"$symlink\" and it's a valid symlink." #TODO logging
log i "Found \"$symlink\" and it's a valid symlink."
continue # Skip if the symlink is already valid
fi
# Remove broken symlink or non-symlink file
echo "Found \"$symlink\" but it's not a valid symlink. Repairing it" #TODO logging
log w "Found \"$symlink\" but it's not a valid symlink. Repairing it"
[ -e "$symlink" ] && rm "$symlink"
# Create symlink
@ -625,18 +655,17 @@ manage_ryujinx_keys() {
echo "Created symlink: \"$symlink\""
done
else
echo "No files found in $bios_folder/switch/keys. Continuing" #TODO logging
log w "No files found in $bios_folder/switch/keys. Continuing..."
fi
else
echo "Directory $bios_folder/switch/keys does not exist. Maybe Ryujinx was never run. Continuing" #TODO logging
log w "Directory $bios_folder/switch/keys does not exist. Maybe Ryujinx was never run. Continuing..."
fi
}
# TODO: this function is not yet used
branch_selector() {
# Fetch branches from GitHub API excluding "main"
log d "Fetch branches from GitHub API excluding \"main\""
branches=$(curl -s https://api.github.com/repos/XargonWan/RetroDECK/branches | grep '"name":' | awk -F '"' '$4 != "main" {print $4}')
# TODO: logging - Fetching branches from GitHub API
# Create an array to store branch names
branch_array=()
@ -674,7 +703,7 @@ branch_selector() {
configurator_generic_dialog "RetroDECK Online Update" "The update process may take several minutes.\n\nAfter the update is complete, RetroDECK will close. When you run it again you will be using the latest version."
(
local desired_flatpak_file=$(curl --silent $flatpak_file_url | grep '"browser_download_url":' | sed -E 's/.*"([^"]+)".*/\1/')
mkdir -p "$rdhome/RetroDECK_Updates"
create_dir "$rdhome/RetroDECK_Updates"
wget -P "$rdhome/RetroDECK_Updates" $desired_flatpak_file
flatpak-spawn --host flatpak remove --noninteractive -y net.retrodeck.retrodeck # Remove current version before installing new one, to avoid duplicates
flatpak-spawn --host flatpak install --user --bundle --noninteractive -y "$rdhome/RetroDECK_Updates/RetroDECK-cooker.flatpak"
@ -700,6 +729,6 @@ quit_retrodeck() {
start_retrodeck() {
easter_eggs # Check if today has a surprise splashscreen and load it if so
# normal startup
echo "Starting RetroDECK v$version"
log i "Starting RetroDECK v$version"
es-de --home /var/config/
}

View file

@ -12,6 +12,7 @@ source /app/libexec/patching.sh
source /app/libexec/post_update.sh
source /app/libexec/prepare_component.sh
source /app/libexec/presets.sh
source /app/libexec/logger.sh
# Static variables
rd_conf="/var/config/retrodeck/retrodeck.cfg" # RetroDECK config file path
@ -125,15 +126,15 @@ fi
# If there is no config file I initalize the file with the the default values
if [[ ! -f "$rd_conf" ]]; then
mkdir -p /var/config/retrodeck
echo "RetroDECK config file not found in $rd_conf"
echo "Initializing"
create_dir /var/config/retrodeck
log w "RetroDECK config file not found in $rd_conf"
log i "Initializing"
# if we are here means that the we are in a new installation, so the version is valorized with the hardcoded one
# Initializing the variables
if [[ -z "$version" ]]; then
if [[ -f "$lockfile" ]]; then
if [[ $(cat $lockfile) == *"0.4."* ]] || [[ $(cat $lockfile) == *"0.3."* ]] || [[ $(cat $lockfile) == *"0.2."* ]] || [[ $(cat $lockfile) == *"0.1."* ]]; then # If the previous version is very out of date, pre-rd_conf
echo "Running version workaround"
log d "Running version workaround"
version=$(cat $lockfile)
fi
else
@ -161,17 +162,16 @@ if [[ ! -f "$rd_conf" ]]; then
set_setting_value $rd_conf "developer_options" "true" retrodeck "options"
fi
echo "Setting config file permissions"
log i "Setting config file permissions"
chmod +rw $rd_conf
echo "RetroDECK config file initialized. Contents:"
echo
cat $rd_conf
log i "RetroDECK config file initialized. Contents:\n\n$(cat $rd_conf\n)"
conf_read # Load new variables into memory
tmplog_merger
# If the config file is existing i just read the variables
else
echo "Found RetroDECK config file in $rd_conf"
echo "Loading it"
log i "Found RetroDECK config file in $rd_conf"
log i "Loading it"
if grep -qF "cooker" <<< $hard_version; then # If newly-installed version is a "cooker" build
set_setting_value $rd_conf "update_repo" "RetroDECK-cooker" retrodeck "options"
@ -180,6 +180,7 @@ else
fi
conf_read
tmplog_merger
# Verify rdhome is where it is supposed to be.
if [[ ! -d "$rdhome" ]]; then
@ -188,6 +189,7 @@ else
new_home_path=$(directory_browse "RetroDECK folder location")
set_setting_value $rd_conf "rdhome" "$new_home_path" retrodeck "paths"
conf_read
tmplog_merger
prepare_component "retrodeck" "postmove"
prepare_component "all" "postmove"
conf_write
@ -197,3 +199,5 @@ else
backups_folder="$rdhome/backups" # A standard location for backup file storage
multi_user_data_folder="$rdhome/multi-user-data" # The default location of multi-user environment profiles
fi
logs_folder="$rdhome/logs" # The path of the logs folder, here we collect all the logs

126
functions/logger.sh Executable file
View file

@ -0,0 +1,126 @@
# This script provides a logging function 'log' that can be sourced in other scripts.
# It logs messages to both the terminal and a specified logfile, allowing different log levels.
# The log function takes three parameters: log level, log message, and optionally the logfile. If no logfile is specified, it writes to retrodeck/logs/retrodeck.log
# Example usage:
# log w "foo" -> logs a warning with message foo in the default log file retrodeck/logs/retrodeck.log
# log e "bar" -> logs an error with message bar in the default log file retrodeck/logs/retrodeck.log
# log i "par" rekku.log -> logs an information with message in the specified log file inside the logs folder retrodeck/logs/rekku.log
# if [ "${log_init:-false}" = false ]; then
# logs_folder=${logs_folder:-"/tmp"}
# touch "$logs_folder/retrodeck.log"
# # exec > >(tee "$logs_folder/retrodeck.log") 2>&1 # this is broken, creates strange artifacts and corrupts the log file
# log_init=true
# fi
log() {
# exec > >(tee "$logs_folder/retrodeck.log") 2>&1 # this is broken, creates strange artifacts and corrupts the log file
local level="$1"
local message="$2"
local timestamp="$(date +[%Y-%m-%d\ %H:%M:%S.%3N])"
local colorize_terminal
# Use specified logfile or default to retrodeck.log
local logfile
if [ -n "$3" ]; then
logfile="$3"
else
logfile="$logs_folder/retrodeck.log"
fi
# Check if the shell is sh (not bash or zsh) to avoid colorization
if [ "${SHELL##*/}" = "sh" ]; then
colorize_terminal=false
else
colorize_terminal=true
fi
case "$level" in
w)
if [ "$colorize_terminal" = true ]; then
# Warning (yellow) for terminal
colored_message="\e[33m[WARN] $message\e[0m"
else
# Warning (no color for sh) for terminal
colored_message="$timestamp [WARN] $message"
fi
# Write to log file without colorization
log_message="$timestamp [WARN] $message"
;;
e)
if [ "$colorize_terminal" = true ]; then
# Error (red) for terminal
colored_message="\e[31m[ERROR] $message\e[0m"
else
# Error (no color for sh) for terminal
colored_message="$timestamp [ERROR] $message"
fi
# Write to log file without colorization
log_message="$timestamp [ERROR] $message"
;;
i)
# Write to log file without colorization for info message
log_message="$timestamp [INFO] $message"
colored_message=$log_message
;;
d)
if [ "$colorize_terminal" = true ]; then
# Debug (green) for terminal
colored_message="\e[32m[DEBUG] $message\e[0m"
else
# Debug (no color for sh) for terminal
colored_message="$timestamp [DEBUG] $message"
fi
# Write to log file without colorization
log_message="$timestamp [DEBUG] $message"
;;
*)
# Default (no color for other shells) for terminal
colored_message="$timestamp $message"
# Write to log file without colorization
log_message="$timestamp $message"
;;
esac
# Display the message in the terminal
echo -e "$colored_message"
# Write the log message to the log file
if [ ! -f "$logfile" ]; then
echo "$timestamp [WARN] Log file not found in \"$logfile\", creating it"
touch "$logfile"
fi
echo "$log_message" >> "$logfile"
}
# This function is merging the temporary log file into the actual one
tmplog_merger() {
create_dir "$logs_folder"
# Check if /tmp/retrodeck.log exists
if [ -e "/tmp/retrodeck.log" ] && [ -e "$logs_folder/retrodeck.log" ]; then
# Sort both temporary and existing log files by timestamp
sort -k1,1n -k2,2M -k3,3n -k4,4n -k5,5n "/tmp/retrodeck.log" "$logs_folder/retrodeck.log" > "$logs_folder/merged_logs.tmp"
# Move the merged logs to replace the original log file
mv "$logs_folder/merged_logs.tmp" "$logs_folder/retrodeck.log"
# Remove the temporary file
rm "/tmp/retrodeck.log"
fi
local ESDE_source_logs="/var/config/ES-DE/logs/es_log.txt"
# Check if the source file exists
if [ -e "$ESDE_source_logs" ]; then
# Create the symlink in the logs folder
ln -sf "$ESDE_source_logs" "$logs_folder/ES-DE.log"
log i "ES-DE log file linked to \"$logs_folder/ES-DE.log\""
fi
}

View file

@ -43,7 +43,7 @@ multi_user_enable_multi_user_mode() {
if [[ -d "$multi_user_data_folder" && $(ls -1 "$multi_user_data_folder" | wc -l) -gt 0 ]]; then # If multi-user data folder exists from prior use and is not empty
if [[ -d "$multi_user_data_folder/$SteamAppUser" ]]; then # Current user has an existing save folder
configurator_generic_dialog "RetroDECK Multi-User Mode" "The current user $SteamAppUser has an existing folder in the multi-user data folder.\n\nThe saves here are likely older than the ones currently used by RetroDECK.\n\nThe old saves will be backed up to $backups_folder and the current saves will be loaded into the multi-user data folder."
mkdir -p "$backups_folder"
create_dir "$backups_folder"
tar -C "$multi_user_data_folder" -cahf "$backups_folder/multi-user-backup_$SteamAppUser_$(date +"%Y_%m_%d").zip" "$SteamAppUser"
rm -rf "$multi_user_data_folder/$SteamAppUser" # Remove stale data after backup
fi
@ -162,18 +162,18 @@ multi_user_return_to_single_user() {
# XEMU one-offs, because it stores its config in /var/data, not /var/config like everything else
unlink "/var/config/xemu"
unlink "/var/data/xemu/xemu"
mkdir -p "/var/config/xemu"
create_dir "/var/config/xemu"
mv -f "$multi_user_data_folder/$single_user/config/xemu"/{.[!.],}* "/var/config/xemu"
dir_prep "/var/config/xemu" "/var/data/xemu/xemu"
mkdir -p "$saves_folder"
mkdir -p "$states_folder"
create_dir "$saves_folder"
create_dir "$states_folder"
mv -f "$multi_user_data_folder/$single_user/saves"/{.[!.],}* "$saves_folder"
mv -f "$multi_user_data_folder/$single_user/states"/{.[!.],}* "$states_folder"
for emu_conf in $(find "$multi_user_data_folder/$single_user/config" -mindepth 1 -maxdepth 1 -type d -printf '%f\n')
do
if [[ ! -z $(grep "^$emu_conf$" "$multi_user_emulator_config_dirs") ]]; then
unlink "/var/config/$emu_conf"
mkdir -p "/var/config/$emu_conf"
create_dir "/var/config/$emu_conf"
mv -f "$multi_user_data_folder/$single_user/config/$emu_conf"/{.[!.],}* "/var/config/$emu_conf"
fi
done
@ -187,11 +187,11 @@ multi_user_setup_new_user() {
unlink "$states_folder"
dir_prep "$multi_user_data_folder/$SteamAppUser/saves" "$saves_folder"
dir_prep "$multi_user_data_folder/$SteamAppUser/states" "$states_folder"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/retrodeck"
create_dir "$multi_user_data_folder/$SteamAppUser/config/retrodeck"
cp -L "$rd_conf" "$multi_user_data_folder/$SteamAppUser/config/retrodeck/retrodeck.cfg" # Copy existing rd_conf file for new user.
rm -f "$rd_conf"
ln -sfT "$multi_user_data_folder/$SteamAppUser/config/retrodeck/retrodeck.cfg" "$rd_conf"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/retroarch"
create_dir "$multi_user_data_folder/$SteamAppUser/config/retroarch"
if [[ ! -L "/var/config/retroarch/retroarch.cfg" ]]; then
mv "/var/config/retroarch/retroarch.cfg" "$multi_user_data_folder/$SteamAppUser/config/retroarch/retroarch.cfg"
mv "/var/config/retroarch/retroarch-core-options.cfg" "$multi_user_data_folder/$SteamAppUser/config/retroarch/retroarch-core-options.cfg"

View file

@ -104,9 +104,9 @@ post_update() {
deploy_single_patch "$emuconfigs/duckstation/settings.ini" "/var/config/duckstation/duckstation-cheevos-upgrade.patch" "$duckstationconf"
rm -f "/var/config/duckstation/duckstation-cheevos-upgrade.patch"
mkdir -p "$mods_folder"
mkdir -p "$texture_packs_folder"
mkdir -p "$borders_folder"
create_dir "$mods_folder"
create_dir "$texture_packs_folder"
create_dir "$borders_folder"
dir_prep "$mods_folder/Primehack" "/var/data/primehack/Load/GraphicMods"
dir_prep "$texture_packs_folder/Primehack" "/var/data/primehack/Load/Textures"
@ -142,13 +142,13 @@ post_update() {
rm "$roms_folder/ps3/emudir"
configurator_generic_dialog "RetroDECK 0.7.0b Upgrade" "As part of this update and due to a RPCS3 config upgrade, the files that used to exist at\n\n~/retrodeck/roms/ps3/emudir\n\nare now located at\n\n~/retrodeck/bios/rpcs3.\nYour existing files have been moved automatically."
fi
mkdir -p "$bios_folder/rpcs3/dev_hdd0"
mkdir -p "$bios_folder/rpcs3/dev_hdd1"
mkdir -p "$bios_folder/rpcs3/dev_flash"
mkdir -p "$bios_folder/rpcs3/dev_flash2"
mkdir -p "$bios_folder/rpcs3/dev_flash3"
mkdir -p "$bios_folder/rpcs3/dev_bdvd"
mkdir -p "$bios_folder/rpcs3/dev_usb000"
create_dir "$bios_folder/rpcs3/dev_hdd0"
create_dir "$bios_folder/rpcs3/dev_hdd1"
create_dir "$bios_folder/rpcs3/dev_flash"
create_dir "$bios_folder/rpcs3/dev_flash2"
create_dir "$bios_folder/rpcs3/dev_flash3"
create_dir "$bios_folder/rpcs3/dev_bdvd"
create_dir "$bios_folder/rpcs3/dev_usb000"
dir_prep "$bios_folder/rpcs3/dev_hdd0/home/00000001/savedata" "$saves_folder/ps3/rpcs3"
set_setting_value $es_settings "ApplicationUpdaterFrequency" "never" "es_settings"
@ -156,7 +156,7 @@ post_update() {
if [[ -f "$saves_folder/duckstation/shared_card_1.mcd" || -f "$saves_folder/duckstation/shared_card_2.mcd" ]]; then
configurator_generic_dialog "RetroDECK 0.7.0b Upgrade" "As part of this update, the location of saves and states for Duckstation has been changed.\n\nYour files will be moved automatically, and can now be found at\n\n~.../saves/psx/duckstation/memcards/\nand\n~.../states/psx/duckstation/"
fi
mkdir -p "$saves_folder/psx/duckstation/memcards"
create_dir "$saves_folder/psx/duckstation/memcards"
mv "$saves_folder/duckstation/"* "$saves_folder/psx/duckstation/memcards/"
rmdir "$saves_folder/duckstation" # File-safe folder cleanup
unlink "/var/config/duckstation/memcards"
@ -164,7 +164,7 @@ post_update() {
set_setting_value "$duckstationconf" "Card2Path" "$saves_folder/psx/duckstation/memcards/shared_card_2.mcd" "duckstation" "MemoryCards"
set_setting_value "$duckstationconf" "Directory" "$saves_folder/psx/duckstation/memcards" "duckstation" "MemoryCards"
set_setting_value "$duckstationconf" "RecursivePaths" "$roms_folder/psx" "duckstation" "GameList"
mkdir -p "$states_folder/psx"
create_dir "$states_folder/psx"
mv -t "$states_folder/psx/" "$states_folder/duckstation"
unlink "/var/config/duckstation/savestates"
dir_prep "$states_folder/psx/duckstation" "/var/config/duckstation/savestates"
@ -237,7 +237,7 @@ post_update() {
# - Remove RetroDECK controller profile from existing template location
# - Change section name in retrodeck.cfg for ABXY button swap preset
# - Force disable global rewind in RA in prep for preset system
if [[ -f "$HOME/.steam/steam/controller_base/templates/RetroDECK_controller_config.vdf"]]; then # Only remove if file had been previously installed
if [[ -f "$HOME/.steam/steam/controller_base/templates/RetroDECK_controller_config.vdf" ]]; then # Only remove if file had been previously installed
rm -f "$HOME/.steam/steam/controller_base/templates/RetroDECK_controller_config.vdf"
fi
sed -i 's^nintendo_button_layout^abxy_button_swap^' "$rd_conf" # This is a one-off sed statement as there are no functions for replacing section names

View file

@ -20,10 +20,10 @@ prepare_component() {
if [[ ! $current_setting_name =~ (rdhome|sdcard) ]]; then # Ignore these locations
local current_setting_value=$(get_setting_value "$rd_conf" "$current_setting_name" "retrodeck" "paths")
declare -g "$current_setting_name=$rdhome/$(basename $current_setting_value)"
mkdir -p "$rdhome/$(basename $current_setting_value)"
create_dir "$rdhome/$(basename $current_setting_value)"
fi
done < <(grep -v '^\s*$' $rd_conf | awk '/^\[paths\]/{f=1;next} /^\[/{f=0} f')
mkdir -p "/var/config/retrodeck/godot"
create_dir "/var/config/retrodeck/godot"
fi
if [[ "$action" == "postmove" ]]; then # Update the paths of any folders that came with the retrodeck folder during a move
while read -r config_line; do
@ -41,7 +41,7 @@ prepare_component() {
if [[ "$component" =~ ^(es-de|ES-DE|all)$ ]]; then # For use after ESDE-related folders are moved or a reset
if [[ "$action" == "reset" ]]; then
rm -rf /var/config/ES-DE
mkdir -p /var/config/ES-DE/settings
create_dir /var/config/ES-DE/settings
cp -f /app/retrodeck/es_settings.xml /var/config/ES-DE/settings/es_settings.xml
set_setting_value "$es_settings" "ROMDirectory" "$roms_folder" "es_settings"
set_setting_value "$es_settings" "MediaDirectory" "$media_folder" "es_settings"
@ -61,16 +61,14 @@ prepare_component() {
if [[ "$component" =~ ^(retroarch|RetroArch|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/retroarch"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/retroarch"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/retroarch"
cp -fv $emuconfigs/retroarch/retroarch.cfg "$multi_user_data_folder/$SteamAppUser/config/retroarch/"
cp -fv $emuconfigs/retroarch/retroarch-core-options.cfg "$multi_user_data_folder/$SteamAppUser/config/retroarch/"
else # Single-user actions
rm -rf /var/config/retroarch
mkdir -p /var/config/retroarch
create_dir -d /var/config/retroarch
dir_prep "$bios_folder" "/var/config/retroarch/system"
dir_prep "$logs_folder/retroarch" "/var/config/retroarch/logs"
mkdir -pv /var/config/retroarch/shaders/
create_dir /var/config/retroarch/shaders/
cp -rf /app/share/libretro/shaders /var/config/retroarch/
dir_prep "$rdhome/shaders/retroarch" "/var/config/retroarch/shaders"
rsync -rlD --mkpath "/app/share/libretro/cores/" "/var/config/retroarch/cores/"
@ -88,9 +86,9 @@ prepare_component() {
# Shared actions
# PPSSPP
echo "--------------------------------"
echo "Initializing PPSSPP_LIBRETRO"
echo "--------------------------------"
log i "--------------------------------"
log i "Initializing PPSSPP_LIBRETRO"
log i "--------------------------------"
if [ -d $bios_folder/PPSSPP/flash0/font ]
then
mv -fv $bios_folder/PPSSPP/flash0/font $bios_folder/PPSSPP/flash0/font.bak
@ -102,16 +100,16 @@ prepare_component() {
fi
# MSX / SVI / ColecoVision / SG-1000
echo "-----------------------------------------------------------"
echo "Initializing MSX / SVI / ColecoVision / SG-1000 LIBRETRO"
echo "-----------------------------------------------------------"
log i "-----------------------------------------------------------"
log i "Initializing MSX / SVI / ColecoVision / SG-1000 LIBRETRO"
log i "-----------------------------------------------------------"
cp -rf "/app/retrodeck/extras/MSX/Databases" "$bios_folder/Databases"
cp -rf "/app/retrodeck/extras/MSX/Machines" "$bios_folder/Machines"
# AMIGA
echo "-----------------------------------------------------------"
echo "Initializing AMIGA LIBRETRO"
echo "-----------------------------------------------------------"
log i "-----------------------------------------------------------"
log i "Initializing AMIGA LIBRETRO"
log i "-----------------------------------------------------------"
cp -f "/app/retrodeck/extras/Amiga/capsimg.so" "$bios_folder/capsimg.so"
dir_prep "$texture_packs_folder/RetroArch-Mesen" "/var/config/retroarch/system/HdPacks"
@ -157,19 +155,17 @@ prepare_component() {
if [[ "$component" =~ ^(cemu|Cemu|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "----------------------"
echo "Initializing CEMU"
echo "----------------------"
log i "----------------------"
log i "Initializing CEMU"
log i "----------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/Cemu"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/Cemu"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/Cemu"
cp -fr "$emuconfigs/cemu/"* "$multi_user_data_folder/$SteamAppUser/config/Cemu/"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/Cemu/settings.ini" "mlc_path" "$bios_folder/cemu" "cemu"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/Cemu/settings.ini" "Entry" "$roms_folder/wiiu" "cemu" "GamePaths"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/Cemu" "/var/config/Cemu"
else
rm -rf /var/config/Cemu
mkdir -pv /var/config/Cemu/
create_dir -d /var/config/Cemu/
cp -fr "$emuconfigs/cemu/"* /var/config/Cemu/
set_setting_value "$cemuconf" "mlc_path" "$bios_folder/cemu" "cemu"
set_setting_value "$cemuconf" "Entry" "$roms_folder/wiiu" "cemu" "GamePaths"
@ -186,12 +182,11 @@ prepare_component() {
if [[ "$component" =~ ^(citra|citra-emu|Citra|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "------------------------"
echo "Initializing CITRA"
echo "------------------------"
log i "------------------------"
log i "Initializing CITRA"
log i "------------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/citra-emu"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/citra-emu"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/citra-emu"
cp -fv $emuconfigs/citra/qt-config.ini "$multi_user_data_folder/$SteamAppUser/config/citra-emu/qt-config.ini"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/citra-emu/qt-config.ini" "nand_directory" "$saves_folder/n3ds/citra/nand/" "citra" "Data%20Storage"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/citra-emu/qt-config.ini" "sdmc_directory" "$saves_folder/n3ds/citra/sdmc/" "citra" "Data%20Storage"
@ -199,8 +194,7 @@ prepare_component() {
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/citra-emu/qt-config.ini" "Paths\screenshotPath" "$screenshots_folder" "citra" "UI"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/citra-emu" "/var/config/citra-emu"
else # Single-user actions
rm -rf /var/config/citra-emu
mkdir -pv /var/config/citra-emu/
create_dir -d /var/config/citra-emu/
cp -f $emuconfigs/citra/qt-config.ini /var/config/citra-emu/qt-config.ini
set_setting_value "$citraconf" "nand_directory" "$saves_folder/n3ds/citra/nand/" "citra" "Data%20Storage"
set_setting_value "$citraconf" "sdmc_directory" "$saves_folder/n3ds/citra/sdmc/" "citra" "Data%20Storage"
@ -208,8 +202,8 @@ prepare_component() {
set_setting_value "$citraconf" "Paths\screenshotPath" "$screenshots_folder" "citra" "UI"
fi
# Shared actions
mkdir -pv "$saves_folder/n3ds/citra/nand/"
mkdir -pv "$saves_folder/n3ds/citra/sdmc/"
create_dir "$saves_folder/n3ds/citra/nand/"
create_dir "$saves_folder/n3ds/citra/sdmc/"
dir_prep "$bios_folder/citra/sysdata" "/var/data/citra-emu/sysdata"
dir_prep "$logs_folder/citra" "/var/data/citra-emu/log"
dir_prep "$mods_folder/Citra" "/var/data/citra-emu/load/mods"
@ -233,12 +227,11 @@ prepare_component() {
if [[ "$component" =~ ^(dolphin|dolphin-emu|Dolphin|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "----------------------"
echo "Initializing DOLPHIN"
echo "----------------------"
log i "----------------------"
log i "Initializing DOLPHIN"
log i "----------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/dolphin-emu"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/dolphin-emu"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/dolphin-emu"
cp -fvr "$emuconfigs/dolphin/"* "$multi_user_data_folder/$SteamAppUser/config/dolphin-emu/"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/dolphin-emu/Dolphin.ini" "BIOS" "$bios_folder" "dolphin" "GBA"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/dolphin-emu/Dolphin.ini" "SavesPath" "$saves_folder/gba" "dolphin" "GBA"
@ -247,8 +240,7 @@ prepare_component() {
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/dolphin-emu/Dolphin.ini" "WiiSDCardPath" "$saves_folder/wii/dolphin/sd.raw" "dolphin" "General"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/dolphin-emu" "/var/config/dolphin-emu"
else # Single-user actions
rm -rf /var/config/dolphin-emu
mkdir -pv /var/config/dolphin-emu/
create_dir -d /var/config/dolphin-emu/
cp -fvr "$emuconfigs/dolphin/"* /var/config/dolphin-emu/
set_setting_value "$dolphinconf" "BIOS" "$bios_folder" "dolphin" "GBA"
set_setting_value "$dolphinconf" "SavesPath" "$saves_folder/gba" "dolphin" "GBA"
@ -288,12 +280,11 @@ prepare_component() {
if [[ "$component" =~ ^(duckstation|Duckstation|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "------------------------"
echo "Initializing DUCKSTATION"
echo "------------------------"
log i "------------------------"
log i "Initializing DUCKSTATION"
log i "------------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/duckstation"
mkdir -p "$multi_user_data_folder/$SteamAppUser/data/duckstation/"
create_dir -d "$multi_user_data_folder/$SteamAppUser/data/duckstation/"
cp -fv "$emuconfigs/duckstation/"* "$multi_user_data_folder/$SteamAppUser/data/duckstation"
set_setting_value "$multi_user_data_folder/$SteamAppUser/data/duckstation/settings.ini" "SearchDirectory" "$bios_folder" "duckstation" "BIOS"
set_setting_value "$multi_user_data_folder/$SteamAppUser/data/duckstation/settings.ini" "Card1Path" "$saves_folder/psx/duckstation/memcards/shared_card_1.mcd" "duckstation" "MemoryCards"
@ -302,9 +293,8 @@ prepare_component() {
set_setting_value "$multi_user_data_folder/$SteamAppUser/data/duckstation/settings.ini" "RecursivePaths" "$roms_folder/psx" "duckstation" "GameList"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/duckstation" "/var/config/duckstation"
else # Single-user actions
rm -rf "/var/config/duckstation"
mkdir -p "/var/config/duckstation/"
mkdir -p "$saves_folder/psx/duckstation/memcards"
create_dir -d "/var/config/duckstation/"
create_dir "$saves_folder/psx/duckstation/memcards"
cp -fv "$emuconfigs/duckstation/"* /var/config/duckstation
set_setting_value "$duckstationconf" "SearchDirectory" "$bios_folder" "duckstation" "BIOS"
set_setting_value "$duckstationconf" "Card1Path" "$saves_folder/psx/duckstation/memcards/shared_card_1.mcd" "duckstation" "MemoryCards"
@ -335,12 +325,11 @@ prepare_component() {
if [[ "$component" =~ ^(melonds|melonDS|MelonDS|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "----------------------"
echo "Initializing MELONDS"
echo "----------------------"
log i "----------------------"
log i "Initializing MELONDS"
log i "----------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/melonDS"
mkdir -pv "$multi_user_data_folder/$SteamAppUser/config/melonDS/"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/melonDS/"
cp -fvr $emuconfigs/melonds/melonDS.ini "$multi_user_data_folder/$SteamAppUser/config/melonDS/"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/melonDS/melonDS.ini" "BIOS9Path" "$bios_folder/bios9.bin" "melonds"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/melonDS/melonDS.ini" "BIOS7Path" "$bios_folder/bios7.bin" "melonds"
@ -349,8 +338,7 @@ prepare_component() {
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/melonDS/melonDS.ini" "SavestatePath" "$states_folder/nds/melonds" "melonds"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/melonDS" "/var/config/melonDS"
else # Single-user actions
rm -rf /var/config/melonDS
mkdir -pv /var/config/melonDS/
create_dir -d /var/config/melonDS/
cp -fvr $emuconfigs/melonds/melonDS.ini /var/config/melonDS/
set_setting_value "$melondsconf" "BIOS9Path" "$bios_folder/bios9.bin" "melonds"
set_setting_value "$melondsconf" "BIOS7Path" "$bios_folder/bios7.bin" "melonds"
@ -359,8 +347,8 @@ prepare_component() {
set_setting_value "$melondsconf" "SavestatePath" "$states_folder/nds/melonds" "melonds"
fi
# Shared actions
mkdir -pv "$saves_folder/nds/melonds"
mkdir -pv "$states_folder/nds/melonds"
create_dir "$saves_folder/nds/melonds"
create_dir "$states_folder/nds/melonds"
dir_prep "$bios_folder" "/var/config/melonDS/bios"
fi
if [[ "$action" == "postmove" ]]; then # Run only post-move commands
@ -375,12 +363,11 @@ prepare_component() {
if [[ "$component" =~ ^(pcsx2|PCSX2|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "----------------------"
echo "Initializing PCSX2"
echo "----------------------"
log i "----------------------"
log i "Initializing PCSX2"
log i "----------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/PCSX2"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/PCSX2/inis"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/PCSX2/inis"
cp -fvr "$emuconfigs/PCSX2/"* "$multi_user_data_folder/$SteamAppUser/config/PCSX2/inis/"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/PCSX2/inis/PCSX2.ini" "Bios" "$bios_folder" "pcsx2" "Folders"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/PCSX2/inis/PCSX2.ini" "Snapshots" "$screenshots_folder" "pcsx2" "Folders"
@ -389,8 +376,7 @@ prepare_component() {
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/PCSX2/inis/PCSX2.ini" "RecursivePaths" "$roms_folder/ps2" "pcsx2" "GameList"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/PCSX2" "/var/config/PCSX2"
else # Single-user actions
rm -rf /var/config/PCSX2
mkdir -pv "/var/config/PCSX2/inis"
create_dir -d "/var/config/PCSX2/inis"
cp -fvr "$emuconfigs/PCSX2/"* /var/config/PCSX2/inis/
set_setting_value "$pcsx2conf" "Bios" "$bios_folder" "pcsx2" "Folders"
set_setting_value "$pcsx2conf" "Snapshots" "$screenshots_folder" "pcsx2" "Folders"
@ -399,8 +385,8 @@ prepare_component() {
set_setting_value "$pcsx2conf" "RecursivePaths" "$roms_folder/ps2" "pcsx2" "GameList"
fi
# Shared actions
mkdir -pv "$saves_folder/ps2/pcsx2/memcards"
mkdir -pv "$states_folder/ps2/pcsx2"
create_dir "$saves_folder/ps2/pcsx2/memcards"
create_dir "$states_folder/ps2/pcsx2"
dir_prep "$texture_packs_folder/PCSX2" "/var/config/PCSX2/textures"
# Reset default preset settings
@ -431,18 +417,16 @@ prepare_component() {
if [[ "$component" =~ ^(ppsspp|PPSSPP|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "------------------------"
echo "Initializing PPSSPPSDL"
echo "------------------------"
log i "------------------------"
log i "Initializing PPSSPPSDL"
log i "------------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/ppsspp"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/ppsspp/PSP/SYSTEM/"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/ppsspp/PSP/SYSTEM/"
cp -fv "$emuconfigs/ppssppsdl/"* "$multi_user_data_folder/$SteamAppUser/config/ppsspp/PSP/SYSTEM/"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/ppsspp/PSP/SYSTEM/ppsspp.ini" "CurrentDirectory" "$roms_folder/psp" "ppsspp" "General"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/ppsspp" "/var/config/ppsspp"
else # Single-user actions
rm -rf /var/config/ppsspp
mkdir -p /var/config/ppsspp/PSP/SYSTEM/
create_dir -d /var/config/ppsspp/PSP/SYSTEM/
cp -fv "$emuconfigs/ppssppsdl/"* /var/config/ppsspp/PSP/SYSTEM/
set_setting_value "$ppssppconf" "CurrentDirectory" "$roms_folder/psp" "ppsspp" "General"
fi
@ -461,18 +445,16 @@ prepare_component() {
if [[ "$component" =~ ^(primehack|Primehack|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "----------------------"
echo "Initializing Primehack"
echo "----------------------"
log i "----------------------"
log i "Initializing Primehack"
log i "----------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/primehack"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/primehack"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/primehack"
cp -fvr "$emuconfigs/primehack/"* "$multi_user_data_folder/$SteamAppUser/config/primehack/"
set_setting_value ""$multi_user_data_folder/$SteamAppUser/config/primehack/Dolphin.ini"" "ISOPath0" "$roms_folder/gc" "primehack" "General"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/primehack" "/var/config/primehack"
else # Single-user actions
rm -rf /var/config/primehack
mkdir -pv /var/config/primehack/
create_dir -d /var/config/primehack/
cp -fvr "$emuconfigs/primehack/"* /var/config/primehack/
set_setting_value "$primehackconf" "ISOPath0" "$roms_folder/gc" "primehack" "General"
fi
@ -482,7 +464,7 @@ prepare_component() {
dir_prep "$saves_folder/gc/primehack/JP" "/var/data/primehack/GC/JAP"
dir_prep "$screenshots_folder" "/var/data/primehack/ScreenShots"
dir_prep "$states_folder/primehack" "/var/data/primehack/StateSaves"
mkdir -pv /var/data/primehack/Wii/
create_dir /var/data/primehack/Wii/
dir_prep "$saves_folder/wii/primehack" "/var/data/primehack/Wii"
dir_prep "$mods_folder/Primehack" "/var/data/primehack/Load/GraphicMods"
dir_prep "$texture_packs_folder/Primehack" "/var/data/primehack/Load/Textures"
@ -505,20 +487,18 @@ prepare_component() {
if [[ "$component" =~ ^(rpcs3|RPCS3|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "------------------------"
echo "Initializing RPCS3"
echo "------------------------"
log i "------------------------"
log i "Initializing RPCS3"
log i "------------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/rpcs3"
mkdir -pv "$multi_user_data_folder/$SteamAppUser/config/rpcs3/"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/rpcs3/"
cp -fr "$emuconfigs/rpcs3/"* "$multi_user_data_folder/$SteamAppUser/config/rpcs3/"
# This is an unfortunate one-off because set_setting_value does not currently support settings with $ in the name.
sed -i 's^\^$(EmulatorDir): .*^$(EmulatorDir): '"$bios_folder/rpcs3/"'^' "$multi_user_data_folder/$SteamAppUser/config/rpcs3/vfs.yml"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/rpcs3/vfs.yml" "/games/" "$roms_folder/ps3/" "rpcs3"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/rpcs3" "/var/config/rpcs3"
else # Single-user actions
rm -rf /var/config/rpcs3
mkdir -pv /var/config/rpcs3/
create_dir -d /var/config/rpcs3/
cp -fr "$emuconfigs/rpcs3/"* /var/config/rpcs3/
# This is an unfortunate one-off because set_setting_value does not currently support settings with $ in the name.
sed -i 's^\^$(EmulatorDir): .*^$(EmulatorDir): '"$bios_folder/rpcs3/"'^' "$rpcs3vfsconf"
@ -526,13 +506,13 @@ prepare_component() {
dir_prep "$saves_folder/ps3/rpcs3" "$bios_folder/rpcs3/dev_hdd0/home/00000001/savedata"
fi
# Shared actions
mkdir -p "$bios_folder/rpcs3/dev_hdd0"
mkdir -p "$bios_folder/rpcs3/dev_hdd1"
mkdir -p "$bios_folder/rpcs3/dev_flash"
mkdir -p "$bios_folder/rpcs3/dev_flash2"
mkdir -p "$bios_folder/rpcs3/dev_flash3"
mkdir -p "$bios_folder/rpcs3/dev_bdvd"
mkdir -p "$bios_folder/rpcs3/dev_usb000"
create_dir "$bios_folder/rpcs3/dev_hdd0"
create_dir "$bios_folder/rpcs3/dev_hdd1"
create_dir "$bios_folder/rpcs3/dev_flash"
create_dir "$bios_folder/rpcs3/dev_flash2"
create_dir "$bios_folder/rpcs3/dev_flash3"
create_dir "$bios_folder/rpcs3/dev_bdvd"
create_dir "$bios_folder/rpcs3/dev_usb000"
fi
if [[ "$action" == "postmove" ]]; then # Run only post-move commands
# This is an unfortunate one-off because set_setting_value does not currently support settings with $ in the name.
@ -545,12 +525,12 @@ prepare_component() {
# NOTE: for techincal reasons the system folder of Ryujinx IS NOT a sumlink of the bios/switch/keys as not only the keys are located there
# When RetroDECK starts there is a "manage_ryujinx_keys" function that symlinks the keys only in Rryujinx/system.
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "------------------------"
echo "Initializing RYUJINX"
echo "------------------------"
log i "------------------------"
log i "Initializing RYUJINX"
log i "------------------------"
if [[ $multi_user_mode == "true" ]]; then
rm -rf "$multi_user_data_folder/$SteamAppUser/config/Ryujinx"
#mkdir -p "$multi_user_data_folder/$SteamAppUser/config/Ryujinx/system"
#create_dir "$multi_user_data_folder/$SteamAppUser/config/Ryujinx/system"
# TODO: add /var/config/Ryujinx/system system folder management
cp -fv $emuconfigs/ryujinx/* "$multi_user_data_folder/$SteamAppUser/config/Ryujinx"
sed -i 's#RETRODECKHOMEDIR#'$rdhome'#g' "$multi_user_data_folder/$SteamAppUser/config/Ryujinx/Config.json"
@ -561,7 +541,7 @@ prepare_component() {
else
# removing config directory to wipe legacy files
rm -rf /var/config/Ryujinx
mkdir -p /var/config/Ryujinx/system
create_dir /var/config/Ryujinx/system
cp -fv $emuconfigs/ryujinx/* /var/config/Ryujinx
sed -i 's#RETRODECKHOMEDIR#'$rdhome'#g' "$ryujinxconf"
# Linking switch nand/saves folder
@ -581,14 +561,13 @@ prepare_component() {
if [[ "$component" =~ ^(xemu|XEMU|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "------------------------"
echo "Initializing XEMU"
echo "------------------------"
log i "------------------------"
log i "Initializing XEMU"
log i "------------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf /var/config/xemu
rm -rf /var/data/xemu
rm -rf "$multi_user_data_folder/$SteamAppUser/config/xemu"
mkdir -pv "$multi_user_data_folder/$SteamAppUser/config/xemu/"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/xemu/"
cp -fv $emuconfigs/xemu/xemu.toml "$multi_user_data_folder/$SteamAppUser/config/xemu/xemu.toml"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/xemu/xemu.toml" "screenshot_dir" "'$screenshots_folder'" "xemu" "General"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/xemu/xemu.toml" "bootrom_path" "'$bios_folder/mcpx_1.0.bin'" "xemu" "sys.files"
@ -608,7 +587,7 @@ prepare_component() {
set_setting_value "$xemuconf" "eeprom_path" "'$saves_folder/xbox/xemu/xbox-eeprom.bin'" "xemu" "sys.files"
set_setting_value "$xemuconf" "hdd_path" "'$bios_folder/xbox_hdd.qcow2'" "xemu" "sys.files"
fi # Shared actions
mkdir -pv $saves_folder/xbox/xemu/
create_dir $saves_folder/xbox/xemu/
# Preparing HD dummy Image if the image is not found
if [ ! -f $bios_folder/xbox_hdd.qcow2 ]
then
@ -626,12 +605,11 @@ prepare_component() {
if [[ "$component" =~ ^(yuzu|Yuzu|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "----------------------"
echo "Initializing YUZU"
echo "----------------------"
log i "----------------------"
log i "Initializing YUZU"
log i "----------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
rm -rf "$multi_user_data_folder/$SteamAppUser/config/yuzu"
mkdir -p "$multi_user_data_folder/$SteamAppUser/config/yuzu"
create_dir -d "$multi_user_data_folder/$SteamAppUser/config/yuzu"
cp -fvr "$emuconfigs/yuzu/"* "$multi_user_data_folder/$SteamAppUser/config/yuzu/"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/yuzu/qt-config.ini" "nand_directory" "$saves_folder/switch/yuzu/nand" "yuzu" "Data%20Storage"
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/yuzu/qt-config.ini" "sdmc_directory" "$saves_folder/switch/yuzu/sdmc" "yuzu" "Data%20Storage"
@ -639,8 +617,7 @@ prepare_component() {
set_setting_value "$multi_user_data_folder/$SteamAppUser/config/yuzu/qt-config.ini" "Screenshots\screenshot_path" "$screenshots_folder" "yuzu" "UI"
dir_prep "$multi_user_data_folder/$SteamAppUser/config/yuzu" "/var/config/yuzu"
else # Single-user actions
rm -rf /var/config/yuzu
mkdir -pv /var/config/yuzu/
create_dir -d /var/config/yuzu/
cp -fvr "$emuconfigs/yuzu/"* /var/config/yuzu/
set_setting_value "$yuzuconf" "nand_directory" "$saves_folder/switch/yuzu/nand" "yuzu" "Data%20Storage"
set_setting_value "$yuzuconf" "sdmc_directory" "$saves_folder/switch/yuzu/sdmc" "yuzu" "Data%20Storage"
@ -655,7 +632,7 @@ prepare_component() {
dir_prep "$logs_folder/yuzu" "/var/data/yuzu/log"
dir_prep "$screenshots_folder" "/var/data/yuzu/screenshots"
dir_prep "$mods_folder/Yuzu" "/var/data/yuzu/load"
mkdir -pv "$rdhome/customs/yuzu"
create_dir "$rdhome/customs/yuzu"
# removing dead symlinks as they were present in a past version
if [ -d $bios_folder/switch ]; then
find $bios_folder/switch -xtype l -exec rm {} \;
@ -682,15 +659,15 @@ prepare_component() {
if [[ "$component" =~ ^(vita3k|Vita3K|all)$ ]]; then
if [[ "$action" == "reset" ]]; then # Run reset-only commands
echo "----------------------"
echo "Initializing Vita3K"
echo "----------------------"
log i "----------------------"
log i "Initializing Vita3K"
log i "----------------------"
if [[ $multi_user_mode == "true" ]]; then # Multi-user actions
echo "Figure out what Vita3k needs for multi-user"
log d "Figure out what Vita3k needs for multi-user"
else # Single-user actions
# NOTE: the component is writing in "." so it must be placed in the rw filesystem. A symlink of the binary is already placed in /app/bin/Vita3K
rm -rf "/var/data/Vita3K"
mkdir -p "/var/data/Vita3K/Vita3K"
create_dir "/var/data/Vita3K/Vita3K"
cp -fvr "$emuconfigs/vita3k/config.yml" "/var/data/Vita3K" # component config
cp -fvr "$emuconfigs/vita3k/ux0" "$bios_folder/Vita3K/Vita3K" # User config
set_setting_value "$vita3kconf" "pref-path" "$rdhome/bios/Vita3K/Vita3K/" "vita3k"
@ -706,55 +683,55 @@ prepare_component() {
if [[ "$component" =~ ^(mame|MAME|all)$ ]]; then
# TODO: do a proper script
# This is just a placeholder script to test the component's flow
echo "----------------------"
echo "Initializing MAME"
echo "----------------------"
# This is just a placeholder script to test the emulator's flow
log i "----------------------"
log i "Initializing MAME"
log i "----------------------"
# TODO: probably some of these needs to be put elsewhere
mkdir -p "$saves_folder/mame-sa"
mkdir -p "$saves_folder/mame-sa/nvram"
mkdir -p "$states_folder/mame-sa"
mkdir -p "$rdhome/screenshots/mame-sa"
mkdir -p "$saves_folder/mame-sa/diff"
create_dir "$saves_folder/mame-sa"
create_dir "$saves_folder/mame-sa/nvram"
create_dir "$states_folder/mame-sa"
create_dir "$rdhome/screenshots/mame-sa"
create_dir "$saves_folder/mame-sa/diff"
mkdir -p "/var/config/ctrlr"
mkdir -p "/var/config/mame/ini"
mkdir -p "/var/config/mame/cfg"
mkdir -p "/var/config/mame/inp"
create_dir "/var/config/ctrlr"
create_dir "/var/config/mame/ini"
create_dir "/var/config/mame/cfg"
create_dir "/var/config/mame/inp"
mkdir -p "/var/data/mame/plugin-data"
mkdir -p "/var/data/mame/hash"
mkdir -p "/var/data/mame/assets/samples"
mkdir -p "/var/data/mame/assets/artwork"
mkdir -p "/var/data/mame/assets/fonts"
mkdir -p "/var/data/mame/cheat"
mkdir -p "/var/data/mame/assets/crosshair"
mkdir -p "/var/data/mame/plugins"
mkdir -p "/var/data/mame/assets/language"
mkdir -p "/var/data/mame/assets/software"
mkdir -p "/var/data/mame/assets/comments"
mkdir -p "/var/data/mame/assets/share"
mkdir -p "/var/data/mame/dats"
mkdir -p "/var/data/mame/folders"
mkdir -p "/var/data/mame/assets/cabinets"
mkdir -p "/var/data/mame/assets/cpanel"
mkdir -p "/var/data/mame/assets/pcb"
mkdir -p "/var/data/mame/assets/flyers"
mkdir -p "/var/data/mame/assets/titles"
mkdir -p "/var/data/mame/assets/ends"
mkdir -p "/var/data/mame/assets/marquees"
mkdir -p "/var/data/mame/assets/artwork-preview"
mkdir -p "/var/data/mame/assets/bosses"
mkdir -p "/var/data/mame/assets/logo"
mkdir -p "/var/data/mame/assets/scores"
mkdir -p "/var/data/mame/assets/versus"
mkdir -p "/var/data/mame/assets/gameover"
mkdir -p "/var/data/mame/assets/howto"
mkdir -p "/var/data/mame/assets/select"
mkdir -p "/var/data/mame/assets/icons"
mkdir -p "/var/data/mame/assets/covers"
mkdir -p "/var/data/mame/assets/ui"
create_dir "/var/data/mame/plugin-data"
create_dir "/var/data/mame/hash"
create_dir "/var/data/mame/assets/samples"
create_dir "/var/data/mame/assets/artwork"
create_dir "/var/data/mame/assets/fonts"
create_dir "/var/data/mame/cheat"
create_dir "/var/data/mame/assets/crosshair"
create_dir "/var/data/mame/plugins"
create_dir "/var/data/mame/assets/language"
create_dir "/var/data/mame/assets/software"
create_dir "/var/data/mame/assets/comments"
create_dir "/var/data/mame/assets/share"
create_dir "/var/data/mame/dats"
create_dir "/var/data/mame/folders"
create_dir "/var/data/mame/assets/cabinets"
create_dir "/var/data/mame/assets/cpanel"
create_dir "/var/data/mame/assets/pcb"
create_dir "/var/data/mame/assets/flyers"
create_dir "/var/data/mame/assets/titles"
create_dir "/var/data/mame/assets/ends"
create_dir "/var/data/mame/assets/marquees"
create_dir "/var/data/mame/assets/artwork-preview"
create_dir "/var/data/mame/assets/bosses"
create_dir "/var/data/mame/assets/logo"
create_dir "/var/data/mame/assets/scores"
create_dir "/var/data/mame/assets/versus"
create_dir "/var/data/mame/assets/gameover"
create_dir "/var/data/mame/assets/howto"
create_dir "/var/data/mame/assets/select"
create_dir "/var/data/mame/assets/icons"
create_dir "/var/data/mame/assets/covers"
create_dir "/var/data/mame/assets/ui"
dir_prep "$saves_folder/mame-sa/hiscore" "/var/config/mame/hiscore"
cp -fvr "$emuconfigs/mame/mame.ini" "$mameconf"
@ -771,13 +748,13 @@ prepare_component() {
if [[ "$component" =~ ^(gzdoom|GZDOOM|all)$ ]]; then
# TODO: do a proper script
# This is just a placeholder script to test the component's flow
echo "----------------------"
echo "Initializing GZDOOM"
echo "----------------------"
# This is just a placeholder script to test the emulator's flow
log i "----------------------"
log i "Initializing GZDOOM"
log i "----------------------"
mkdir -p "/var/config/gzdoom"
mkdir -p "/var/data/gzdoom"
create_dir "/var/config/gzdoom"
create_dir "/var/data/gzdoom"
cp -fvr "$emuconfigs/gzdoom/gzdoom.ini" "/var/config/gzdoom"
cp -fvr "$emuconfigs/gzdoom/gzdoom.pk3" "/var/data/gzdoom"
@ -786,11 +763,11 @@ prepare_component() {
fi
if [[ "$component" =~ ^(boilr|BOILR|all)$ ]]; then
echo "----------------------"
echo "Initializing BOILR"
echo "----------------------"
log i "----------------------"
log i "Initializing BOILR"
log i "----------------------"
mkdir -p "/var/config/boilr"
create_dir "/var/config/boilr"
cp -fvr "/app/libexec/steam-sync/config.toml" "/var/config/boilr"
fi

View file

@ -125,7 +125,7 @@ build_preset_config() {
fi
if [[ "$read_config_format" == "retroarch" && ! "$retroarch_all" == "true" ]]; then # If this is a RetroArch core, generate the override file
if [[ ! -f "$read_target_file" ]]; then
mkdir -p "$(realpath "$(dirname "$read_target_file")")"
create_dir "$(realpath "$(dirname "$read_target_file")")"
echo "$read_setting_name = \""$new_setting_value"\"" > "$read_target_file"
else
if [[ -z $(grep "$read_setting_name" "$read_target_file") ]]; then

View file

@ -104,7 +104,7 @@ done
if [ -f "$lockfile" ]; then
# ...but the version doesn't match with the config file
if [ "$hard_version" != "$version" ]; then
echo "Config file's version is $version but the actual version is $hard_version"
log i "Config file's version is $version but the actual version is $hard_version"
if grep -qF "cooker" <<< $hard_version; then # If newly-installed version is a "cooker" build
configurator_generic_dialog "RetroDECK Cooker Warning" "RUNNING COOKER VERSIONS OF RETRODECK CAN BE EXTREMELY DANGEROUS AND ALL OF YOUR RETRODECK DATA\n(INCLUDING BIOS FILES, BORDERS, DOWNLOADED MEDIA, GAMELISTS, MODS, ROMS, SAVES, STATES, SCREENSHOTS, TEXTURE PACKS AND THEMES)\nARE AT RISK BY CONTINUING!"
set_setting_value $rd_conf "update_repo" "RetroDECK-cooker" retrodeck "options"
@ -118,7 +118,7 @@ if [ -f "$lockfile" ]; then
rc=$? # Capture return code, as "Yes" button has no text value
if [[ $rc == "1" ]]; then # If any button other than "Yes" was clicked
if [[ $choice == "Don't Upgrade" ]]; then # If user wants to bypass the post_update.sh process this time.
echo "Skipping upgrade process for cooker build, updating stored version in retrodeck.cfg"
log i "Skipping upgrade process for cooker build, updating stored version in retrodeck.cfg"
set_setting_value $rd_conf "version" "$hard_version" retrodeck # Set version of currently running RetroDECK to updated retrodeck.cfg
elif [[ $choice == "Full Wipe and Fresh Install" ]]; then # Remove all RetroDECK data and start a fresh install
if [[ $(configurator_generic_question_dialog "RetroDECK Cooker Reset" "This is going to remove all of the data in all locations used by RetroDECK!\n\n(INCLUDING BIOS FILES, BORDERS, DOWNLOADED MEDIA, GAMELISTS, MODS, ROMS, SAVES, STATES, SCREENSHOTS, TEXTURE PACKS AND THEMES)\n\nAre you sure you want to contine?") == "true" ]]; then
@ -126,7 +126,7 @@ if [ -f "$lockfile" ]; then
if [[ $(configurator_generic_question_dialog "RetroDECK Cooker Reset" "But are you super DUPER sure? We REAAAALLLLLYY want to make sure you know what is happening here.\n\nThe ~/retrodeck and ~/.var/app/net.retrodeck.retrodeck folders and ALL of their contents\nare about to be PERMANENTLY removed.\n\nStill sure you want to proceed?") == "true" ]]; then
configurator_generic_dialog "RetroDECK Cooker Reset" "Ok, if you're that sure, here we go!"
if [[ $(configurator_generic_question_dialog "RetroDECK Cooker Reset" "(Are you actually being serious here? Because we are...\n\nNo backsies.)") == "true" ]]; then
echo "Removing RetroDECK data and starting fresh"
log w "Removing RetroDECK data and starting fresh"
rm -rf /var
rm -rf "$HOME/retrodeck"
source /app/libexec/global.sh
@ -137,7 +137,7 @@ if [ -f "$lockfile" ]; then
fi
fi
else
echo "Performing normal upgrade process for version" $cooker_base_version
log i "Performing normal upgrade process for version" $cooker_base_version
version=$cooker_base_version # Temporarily assign cooker base version to $version so update script can read it properly.
post_update
fi
@ -156,7 +156,7 @@ if [ -f "$lockfile" ]; then
# Else, LOCKFILE IS NOT EXISTING (WAS REMOVED)
# if the lock file doesn't exist at all means that it's a fresh install or a triggered reset
else
echo "Lockfile not found"
log w "Lockfile not found"
finit # Executing First/Force init
fi

View file

@ -105,6 +105,7 @@ source /app/libexec/global.sh
# DIALOG TREE FUNCTIONS
configurator_welcome_dialog() {
log i "Configurator: opening welcome dialog"
if [[ $developer_options == "true" ]]; then
welcome_menu_options=("Presets & Settings" "Here you find various presets, tweaks and settings to customize your RetroDECK experience" \
"Open Emulator" "Launch and configure each emulators settings (for advanced users)" \
@ -130,35 +131,43 @@ configurator_welcome_dialog() {
case $choice in
"Presets & Settings" )
log i "Configurator: opening \"$choice\" menu"
configurator_presets_and_settings_dialog
;;
"Open Emulator" )
log i "Configurator: opening \"$choice\" menu"
configurator_power_user_warning_dialog
;;
"RetroDECK: Tools" )
log i "Configurator: opening \"$choice\" menu"
configurator_retrodeck_tools_dialog
;;
"RetroDECK: Troubleshooting" )
log i "Configurator: opening \"$choice\" menu"
configurator_retrodeck_troubleshooting_dialog
;;
"RetroDECK: About" )
log i "Configurator: opening \"$choice\" menu"
configurator_about_retrodeck_dialog
;;
"Sync with Steam" )
log i "Configurator: opening \"$choice\" menu"
configurator_add_steam
;;
"Developer Options" )
log i "Configurator: opening \"$choice\" menu"
configurator_generic_dialog "RetroDECK Configurator - Developer Options" "The following features and options are potentially VERY DANGEROUS for your RetroDECK install!\n\nThey should be considered the bleeding-edge of upcoming RetroDECK features, and never used when you have important saves/states/roms that are not backed up!\n\nYOU HAVE BEEN WARNED!"
configurator_developer_dialog
;;
"" )
log i "Configurator: closing"
exit 1
;;
@ -176,18 +185,22 @@ configurator_presets_and_settings_dialog() {
case $choice in
"Global: Presets & Settings" )
log i "Configurator: opening \"$choice\" menu"
configurator_global_presets_and_settings_dialog
;;
"RetroArch: Presets & Settings" )
log i "Configurator: opening \"$choice\" menu"
configurator_retroarch_presets_and_settings_dialog
;;
"Wii & GameCube: Presets & Settings" )
log i "Configurator: opening \"$choice\" menu"
configurator_wii_and_gamecube_presets_and_settings_dialog
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_welcome_dialog
;;
@ -210,11 +223,13 @@ configurator_global_presets_and_settings_dialog() {
case $choice in
"Widescreen: Enable/Disable" )
log i "Configurator: opening \"$choice\" menu"
change_preset_dialog "widescreen"
configurator_global_presets_and_settings_dialog
;;
"Ask-to-Exit: Enable/Disable" )
log i "Configurator: opening \"$choice\" menu"
change_preset_dialog "ask_to_exit"
configurator_global_presets_and_settings_dialog
;;
@ -248,21 +263,20 @@ configurator_global_presets_and_settings_dialog() {
;;
"RetroAchievements: Hardcore Mode" )
log i "Configurator: opening \"$choice\" menu"
change_preset_dialog "cheevos_hardcore"
configurator_global_presets_and_settings_dialog
;;
"Rewind: Enable/Disable" )
change_preset_dialog "rewind"
configurator_global_presets_and_settings_dialog
;;
"Swap A/B and X/Y Buttons: Enable/Disable" )
log i "Configurator: opening \"$choice\" menu"
change_preset_dialog "abxy_button_swap"
configurator_global_presets_and_settings_dialog
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_presets_and_settings_dialog
;;
@ -278,11 +292,13 @@ configurator_retroarch_presets_and_settings_dialog() {
case $choice in
"Borders: Enable/Disable" )
log i "Configurator: opening \"$choice\" menu"
change_preset_dialog "borders"
configurator_retroarch_presets_and_settings_dialog
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_presets_and_settings_dialog
;;
@ -299,14 +315,17 @@ configurator_wii_and_gamecube_presets_and_settings_dialog() {
case $choice in
"Dolphin Textures: Universal Dynamic Input" )
log i "Configurator: opening \"$choice\" menu"
configurator_dolphin_input_textures_dialog
;;
"Primehack Textures: Universal Dynamic Input" )
log i "Configurator: opening \"$choice\" menu"
configurator_primehack_input_textures_dialog
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_presets_and_settings_dialog
;;
@ -435,66 +454,82 @@ configurator_open_emulator_dialog() {
case $emulator in
"RetroArch" )
log i "Configurator: \"$emulator\""
retroarch
;;
"Cemu" )
log i "Configurator: \"$emulator\""
Cemu-wrapper
;;
"Citra" )
log i "Configurator: \"$emulator\""
citra-qt
;;
"Dolphin" )
log i "Configurator: \"$emulator\""
dolphin-emu
;;
"Duckstation" )
log i "Configurator: \"$emulator\""
duckstation-qt
;;
"MAME" )
log i "Configurator: \"$emulator\""
mame-rdwrapper.sh
;;
"MelonDS" )
log i "Configurator: \"$emulator\""
melonDS
;;
"PCSX2" )
log i "Configurator: \"$emulator\""
pcsx2-qt
;;
"PPSSPP" )
log i "Configurator: \"$emulator\""
PPSSPPSDL
;;
"Primehack" )
log i "Configurator: \"$emulator\""
primehack-wrapper
;;
"RPCS3" )
log i "Configurator: \"$emulator\""
rpcs3
;;
"Ryujinx" )
log i "Configurator: \"$emulator\""
Ryujinx.sh
;;
"Vita3K" )
log i "Configurator: \"$emulator\""
Vita3K
;;
"XEMU" )
log i "Configurator: \"$emulator\""
xemu
;;
"Yuzu" )
log i "Configurator: \"$emulator\""
yuzu
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_welcome_dialog
;;
@ -517,15 +552,18 @@ configurator_retrodeck_tools_dialog() {
case $choice in
"Tool: Move Folders" )
log i "Configurator: opening \"$choice\" menu"
configurator_retrodeck_move_tool_dialog
;;
"Tool: Compress Games" )
log i "Configurator: opening \"$choice\" menu"
configurator_generic_dialog "RetroDECK Configurator - Compression Tool" "Depending on your library and compression choices, the process can sometimes take a long time.\nPlease be patient once it is started!"
configurator_compression_tool_dialog
;;
"Install: RetroDECK SD Controller Profile" )
log i "Configurator: opening \"$choice\" menu"
configurator_generic_dialog "RetroDECK Configurator - Install: RetroDECK Controller Profile" "We are now offering a new official RetroDECK controller profile!\nIt is an optional component that helps you get the most out of RetroDECK with a new in-game radial menu for unified hotkeys across emulators.\n\nThe files need to be installed outside of the normal ~/retrodeck folder, so we wanted your permission before proceeding.\n\nThe files will be installed at the following shared Steam locations:\n\n$HOME/.steam/steam/tenfoot/resource/images/library/controller/binding_icons/\n$HOME/.steam/steam/controller_base/templates"
if [[ $(configurator_generic_question_dialog "Install: RetroDECK Controller Profile" "Would you like to install the official RetroDECK controller profile?") == "true" ]]; then
install_retrodeck_controller_profile
@ -535,6 +573,7 @@ configurator_retrodeck_tools_dialog() {
;;
"Install: PS3 Firmware" )
log i "Configurator: opening \"$choice\" menu"
if [[ $(check_network_connectivity) == "true" ]]; then
configurator_generic_dialog "RetroDECK Configurator - Install: PS3 firmware" "This tool will download firmware required by RPCS3 to emulate PS3 games.\n\nThe process will take several minutes, and the emulator will launch to finish the installation.\nPlease close RPCS3 manually once the installation is complete."
(
@ -571,10 +610,12 @@ configurator_retrodeck_tools_dialog() {
;;
"RetroDECK: Change Update Setting" )
log i "Configurator: opening \"$choice\" menu"
configurator_online_update_setting_dialog
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_welcome_dialog
;;
@ -599,42 +640,52 @@ configurator_retrodeck_move_tool_dialog() {
case $choice in
"Move all of RetroDECK" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "rdhome"
;;
"Move ROMs folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "roms_folder"
;;
"Move BIOS folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "bios_folder"
;;
"Move Downloaded Media folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "media_folder"
;;
"Move Saves folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "saves_folder"
;;
"Move States folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "states_folder"
;;
"Move Themes folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "themes_folder"
;;
"Move Screenshots folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "screenshots_folder"
;;
"Move Mods folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "mods_folder"
;;
"Move Texture Packs folder" )
log i "Configurator: opening \"$choice\" menu"
configurator_move_folder_dialog "texture_packs_folder"
;;
@ -657,30 +708,37 @@ configurator_compression_tool_dialog() {
case $choice in
"Compress Single Game" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_single_game_dialog
;;
"Compress Multiple Games - CHD" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "chd"
;;
"Compress Multiple Games - ZIP" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "zip"
;;
"Compress Multiple Games - RVZ" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "rvz"
;;
"Compress Multiple Games - All Formats" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "all"
;;
"Compress All Games" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "everything"
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_retrodeck_tools_dialog
;;
@ -893,6 +951,7 @@ configurator_retrodeck_troubleshooting_dialog() {
case $choice in
"Backup: RetroDECK Userdata" )
log i "Configurator: opening \"$choice\" menu"
configurator_generic_dialog "RetroDECK Configurator - Backup: RetroDECK Userdata" "This tool will compress important RetroDECK userdata (basically everything except the ROMs folder) into a zip file.\n\nThis process can take several minutes, and the resulting zip file can be found in the ~/retrodeck/backups folder."
(
backup_retrodeck_userdata
@ -910,6 +969,7 @@ configurator_retrodeck_troubleshooting_dialog() {
;;
"Check & Verify: BIOS Files" )
log i "Configurator: opening \"$choice\" menu"
configurator_check_bios_files
;;
@ -918,14 +978,17 @@ configurator_retrodeck_troubleshooting_dialog() {
;;
"Check & Verify: Multi-file structure" )
log i "Configurator: opening \"$choice\" menu"
configurator_check_multifile_game_structure
;;
"RetroDECK: Reset" )
log i "Configurator: opening \"$choice\" menu"
configurator_reset_dialog
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_welcome_dialog
;;
@ -996,6 +1059,7 @@ configurator_reset_dialog() {
case $choice in
"Reset Specific Emulator" )
log i "Configurator: opening \"$choice\" menu"
component_to_reset=$(zenity --list \
--title "RetroDECK Configurator Utility - Reset Specific Standalone Emulator" --cancel-label="Back" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \
@ -1084,6 +1148,7 @@ configurator_reset_dialog() {
;;
"Reset All Emulators" )
log i "Configurator: opening \"$choice\" menu"
if [[ $(check_network_connectivity) == "true" ]]; then
if [[ $(configurator_reset_confirmation_dialog "all emulators" "Are you sure you want to reset all emulators to default settings?\n\nThis process cannot be undone.") == "true" ]]; then
(
@ -1105,6 +1170,7 @@ configurator_reset_dialog() {
;;
"Reset RetroDECK" )
log i "Configurator: opening \"$choice\" menu"
if [[ $(configurator_reset_confirmation_dialog "RetroDECK" "Are you sure you want to reset RetroDECK entirely?\n\nThis process cannot be undone.") == "true" ]]; then
zenity --icon-name=net.retrodeck.retrodeck --info --no-wrap \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
@ -1136,10 +1202,12 @@ configurator_about_retrodeck_dialog() {
case $choice in
"Version History" )
log i "Configurator: opening \"$choice\" menu"
configurator_version_history_dialog
;;
"Credits" )
log i "Configurator: opening \"$choice\" menu"
zenity --icon-name=net.retrodeck.retrodeck --text-info --width=1200 --height=720 \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Credits" \
@ -1148,6 +1216,7 @@ configurator_about_retrodeck_dialog() {
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_welcome_dialog
;;
@ -1214,10 +1283,12 @@ configurator_version_history_dialog() {
case $choice in
"Full RetroDECK Changelog" )
log i "Configurator: opening \"$choice\" menu"
changelog_dialog "all"
;;
"RetroDECK"*"Changelog" )
log i "Configurator: opening \"$choice\" menu"
local version=$(echo "$choice" | sed 's/^RetroDECK \(.*\) Changelog$/\1/')
changelog_dialog "$version"
;;
@ -1240,23 +1311,28 @@ configurator_developer_dialog() {
case $choice in
"Change Multi-user mode" )
log i "Configurator: opening \"$choice\" menu"
configurator_retrodeck_multiuser_dialog
;;
"Change Update Channel" )
log i "Configurator: opening \"$choice\" menu"
configurator_online_update_channel_dialog
;;
"Browse the Wiki" )
log i "Configurator: opening \"$choice\" menu"
xdg-open "https://github.com/XargonWan/RetroDECK/wiki"
configurator_developer_dialog
;;
"USB Import" )
log i "Configurator: opening \"$choice\" menu"
configurator_usb_import_dialog
;;
"Install RetroDECK Starter Pack" )
log i "Configurator: opening \"$choice\" menu"
if [[ $(configurator_generic_question_dialog "Install: RetroDECK Starter Pack" "The RetroDECK creators have put together a collection of classic retro games you might enjoy!\n\nWould you like to have them automatically added to your library?") == "true" ]]; then
install_retrodeck_starterpack
fi
@ -1264,6 +1340,7 @@ configurator_developer_dialog() {
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_welcome_dialog
;;
esac
@ -1335,6 +1412,7 @@ configurator_usb_import_dialog() {
case $choice in
"Prepare USB device" )
log i "Configurator: opening \"$choice\" menu"
external_devices=()
while read -r size device_path; do
@ -1362,6 +1440,7 @@ configurator_usb_import_dialog() {
;;
"Import from USB" )
log i "Configurator: opening \"$choice\" menu"
external_devices=()
while read -r size device_path; do
@ -1408,6 +1487,7 @@ configurator_usb_import_dialog() {
;;
"" ) # No selection made or Back button clicked
log i "Configurator: going back"
configurator_developer_dialog
;;
esac

View file

@ -7,7 +7,7 @@ source /app/libexec/global.sh
# Check if a function was specified
if [[ $# -lt 1 ]]; then
echo "Usage: $0 function_name [args...]"
log e "Usage: $0 function_name [args...]"
exit 1
fi
@ -17,7 +17,7 @@ shift
# Check if the function exists
if ! declare -f "$function_name" >/dev/null 2>&1; then
echo "Function '$function_name' not found"
log e "Function \'$function_name\' not found"
exit 1
fi