Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

batocera-wine: fix save_install() - Wine refused to work then #13666

Merged
merged 1 commit into from
Mar 6, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 53 additions & 65 deletions package/batocera/utils/batocera-wine/batocera-wine
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ WINE64=
WINESERVER=
MSIEXEC=
WINETRICKS=
# Save function carried out in save_install()
# Save function carried out in saveFilesToUserdata()
WINE_SAVEDIR=
WINE_SAVEFILES=
SYSTEM_SAVEDIR=
# createAutorunCmd() tries to creates automatically autorun.cmd if you use windows_installs with msi/exe
# a basic exe-filter is here in the script, user can set advanced one, see i and ii in function
AUTORUN_FILEMASK="$4"
Expand Down Expand Up @@ -284,63 +285,6 @@ redist_install() {
return 0
}

save_install() {
WINEPREFIX=$1
GAMENAME=$2
WINE_SAVEDIR=$3
WINE_SAVEFILES=$4

if [[ -n "${WINE_SAVEDIR}" ]]; then
GAME_SAVEDIR=$(dirname "${WINE_SAVEDIR}")
GAME_SAVEDIR="${WINEPOINT}/${GAME_SAVEDIR}"
SYSTEM_SAVEDIR="/userdata/saves/${SYSTEM}/${ROMGAMENAME%.*}"
WINE_SAVEDIR="${WINEPOINT}/${WINE_SAVEDIR}"

#create save directory, or move existing savedir content
if [[ ! -d "${SYSTEM_SAVEDIR}" ]]; then
if [[ -z "${WINE_SAVEFILES}" && ! -L "${WINE_SAVEDIR}" && -d "${WINE_SAVEDIR}" ]]; then
mv "${WINE_SAVEDIR}" "${SYSTEM_SAVEDIR}"
else
mkdir -p "${SYSTEM_SAVEDIR}"
fi
fi

#if no specific save files, symlink the whole wine_savedir directroy
if [[ -z "${WINE_SAVEFILES}" ]]; then

if [[ ! -d "${GAME_SAVEDIR}" ]]; then
mkdir -p "${GAME_SAVEDIR}"
fi

if [[ ! -L "${WINE_SAVEDIR}" ]]; then
rm -rf "${WINE_SAVEDIR}"
fi

ln -s "${SYSTEM_SAVEDIR}" "${WINE_SAVEDIR}"
else
if [[ ! -d "${WINE_SAVEDIR}" ]]; then
mkdir -p "${WINE_SAVEDIR}"
fi
#split the files list to array with ; delimiter
IFS=';' read -r -a SAVEFILES_ARRAY <<< "${WINE_SAVEFILES}"
for SAVEFILE in "${SAVEFILES_ARRAY[@]}"; do

if [[ -e "${WINE_SAVEDIR}/${SAVEFILE}" ]]; then
#if savefiles exist in the prefix and not yet in system save, move it once
if [[ ! -e "${SYSTEM_SAVEDIR}/${SAVEFILE}" && ! -L "${WINE_SAVEDIR}/${SAVEFILE}" ]]; then
mv "${WINE_SAVEDIR}/${SAVEFILE}" "${SYSTEM_SAVEDIR}/${SAVEFILE}"
else
rm "${WINE_SAVEDIR}/${SAVEFILE}"
fi
fi

ln -sf "${SYSTEM_SAVEDIR}/${SAVEFILE}" "${WINE_SAVEDIR}/${SAVEFILE}"
done
fi

fi
}

msi_install() {
WINEPREFIX=$1
local i; local ii
Expand Down Expand Up @@ -497,6 +441,51 @@ sandboxing_prefix() {
return 0
}

saveFilesToUserdata() {
WINEPREFIX="$1"
GAMENAME="$2"
WINE_SAVEDIR="$3"
WINE_SAVEFILES="$4"

[[ -z "${WINE_SAVEDIR}" && -z "${WINE_SAVEFILES}" ]] && return 0 #No argument in autorun.cmd -> return

#Prepare for Savegames Files or Folders, SYSTEM_SAVEDIR and WINE_SAVEDIR are needed here
SYSTEM_SAVEDIR="/userdata/saves/${SYSTEM}/${ROMGAMENAME%.*}"
mkdir -p "${SYSTEM_SAVEDIR}" #Create dir to store our savegames in /userdata
mkdir -p "${WINEPOINT}/$(dirname "${WINE_SAVEDIR}")" #Create SAVEGAME_ROOT_DIR from there we can cp the files
pushd "${WINEPOINT}/$(dirname "${WINE_SAVEDIR}")" >/dev/null #Enter SAVEGAME_ROOT_DIR
WINE_SAVEDIR="$(basename "${WINE_SAVEDIR}")" #Savegamedir itself, content is copied/linked
echo "Preparing Savefiles: WINE_SAVEDIR: ${WINE_SAVEDIR} -> SYSTEM_SAVEDIR: ${SYSTEM_SAVEDIR}"

if [[ -z "${WINE_SAVEFILES}" ]]; then
#Copy existing savedir content and link whole wine_savedir directory, check if dir is a symlink or not
if [[ ! -L "${WINE_SAVEDIR}" && -d "${WINE_SAVEDIR}" ]]; then
cp -r "${WINE_SAVEDIR}/." "${SYSTEM_SAVEDIR}"
rm -rf "${WINE_SAVEDIR}"
fi
[[ ! -L "${WINE_SAVEDIR}" ]] && ln -s "${SYSTEM_SAVEDIR}" "${WINE_SAVEDIR}"
popd >/dev/null

elif [[ -n "${WINE_SAVEFILES}" ]]; then
mkdir "${WINE_SAVEDIR}"
pushd "${WINE_SAVEDIR}" >/dev/null #You are working inside the game saves dir
#split the files list to array with ; delimiter
IFS=';' read -r -a SAVEFILES_ARRAY <<< "${WINE_SAVEFILES}"
for SAVEFILE in "${SAVEFILES_ARRAY[@]}"; do
if [[ -e "${SAVEFILE}" ]]; then
#if savefiles exist in the prefix and not yet in system save, move it once
if [[ ! -e "${SYSTEM_SAVEDIR}/${SAVEFILE}" && ! -L "${SAVEFILE}" ]]; then
mv -f "${SAVEFILE}" "${SYSTEM_SAVEDIR}/${SAVEFILE}"
else
rm "${SAVEFILE}"
fi
fi
ln -sf "${SYSTEM_SAVEDIR}/${SAVEFILE}" "${SAVEFILE}"
done
popd >/dev/null; popd >/dev/null #Clear stack
fi
}

createWineDirectory() {
WINEPREFIX=$1

Expand Down Expand Up @@ -559,7 +548,7 @@ play_wine() {
WINE_ENV=$(getWine_var "${WINEPOINT}" "ENV" "")
WINE_SAVEDIR=$(getWine_var "${WINEPOINT}" "SAVEDIR" "")
WINE_SAVEFILES=$(getWine_var "${WINEPOINT}" "SAVEFILES" "")
save_install "${WINEPOINT}" "${GAMENAME}" "${WINE_SAVEDIR}" "${WINE_SAVEFILES}" || return 1
saveFilesToUserdata "${WINEPOINT}" "${GAMENAME}" "${WINE_SAVEDIR}" "${WINE_SAVEFILES}" || return 1

if [[ -n "${WINE_LANG}" ]]; then
(cd "${WINEPOINT}/${WINE_DIR}" && LC_ALL=${WINE_LANG} WINEPREFIX=${WINEPOINT} eval "${WINE_ENV}" "${WINE} ${VDESKTOP} ${WINE_CMD}")
Expand Down Expand Up @@ -589,7 +578,7 @@ play_pc() {
WINE_ENV=$(getWine_var "${GAMENAME}" "ENV" "")
WINE_SAVEDIR=$(getWine_var "${GAMENAME}" "SAVEDIR" "")
WINE_SAVEFILES=$(getWine_var "${GAMENAME}" "SAVEFILES" "")
save_install "${WINEPOINT}" "${GAMENAME}" "${WINE_SAVEDIR}" "${WINE_SAVEFILES}" || return 1
saveFilesToUserdata "${WINEPOINT}" "${GAMENAME}" "${WINE_SAVEDIR}" "${WINE_SAVEFILES}" || return 1

env
if [[ -n "${WINE_LANG}" ]]; then
Expand Down Expand Up @@ -661,7 +650,7 @@ play_winetgz() {
WINE_ENV=$(getWine_var "${WINEPOINT}" "ENV" "")
WINE_SAVEDIR=$(getWine_var "${WINEPOINT}" "SAVEDIR" "")
WINE_SAVEFILES=$(getWine_var "${WINEPOINT}" "SAVEFILES" "")
save_install "${WINEPOINT}" "${GAMENAME}" "${WINE_SAVEDIR}" "${WINE_SAVEFILES}" || return 1
saveFilesToUserdata "${WINEPOINT}" "${GAMENAME}" "${WINE_SAVEDIR}" "${WINE_SAVEFILES}" || return 1

if [[ -n "${WINE_LANG}" ]]; then
(cd "${WINEPOINT}/${WINE_DIR}" && LC_ALL=${WINE_LANG} WINEPREFIX=${WINEPOINT} eval "${WINE_ENV}" "${WINE} ${VDESKTOP} ${WINE_CMD}")
Expand Down Expand Up @@ -742,7 +731,7 @@ play_squashfs() {
WINE_ENV=$(getWine_var "${WINEPOINT}" "ENV" "")
WINE_SAVEDIR=$(getWine_var "${WINEPOINT}" "SAVEDIR" "")
WINE_SAVEFILES=$(getWine_var "${WINEPOINT}" "SAVEFILES" "")
save_install "${WINEPOINT}" "${GAMENAME}" "${WINE_SAVEDIR}" "${WINE_SAVEFILES}" || return 1
saveFilesToUserdata "${WINEPOINT}" "${GAMENAME}" "${WINE_SAVEDIR}" "${WINE_SAVEFILES}" || return 1

if [[ -n "${WINE_LANG}" ]]; then
(cd "${WINEPOINT}/${WINE_DIR}" && LC_ALL=${WINE_LANG} WINEPREFIX=${WINEPOINT} eval "${WINE_ENV}" "${WINE} ${VDESKTOP} ${WINE_CMD}")
Expand All @@ -762,17 +751,16 @@ createAutorunCmd() {
#Using RexEx extensions from user created files, ~/../roms/windows_installers is prefered over ~/../saves/windows_installers
i="/userdata/roms/windows_installers/autorun-regex.txt"
ii="/userdata/saves/windows_installers/autorun-regex.txt"
[[ -e "$i" ]] || { [[ -e "$ii" ]] && i="$ii"; } && { dos2unix -k -q "$i"; readarray -t AUTORUN_FILTER < <(grep -v [#] "$i"); }
[[ -e "$i" ]] || { [[ -e "$ii" ]] && i="$ii"; } && { dos2unix -k -q "$i"; readarray -t AUTORUN_FILTER < <(grep -v -E "^[[:space:]*]|[#]|^[[:space:]]*$" "$i"); }
# Pre-setted filter to exclude some standard files from created WINEPREFIX
AUTORUN_FILTER+=("^.*/Windows Media Player/.*$" "^.*/Windows NT/.*$" "^.*/Internet Explorer/.*$" "^.*/drive_c/windows/.*$"
"^.*/[Uu]nins[[:alnum:]]{0,6}\.exe$" "^.*/[Ii]nstall(..)?\.exe$" "^.*/[Ss]etup\.exe$")
"^.*/[Uu]nins[[:alnum:]]{0,6}\.exe$" "^.*/[Ii]nstall(..)?\.exe$" "^.*/[Ss]etup\.exe$" "^.*/[Uu]nwise(..)?\.exe$")

#We search in WINEPOINT dir for exes and I assume it's somewhere installed in Program Files, or Program Files(x86)
pushd "$WINEPOINT" > /dev/null
readarray -t AUTORUN_FOUNDEXE < <(find ${AUTORUN_FILEMASK} -type f -iname "*.exe" -printf "%p\n" | sort -n)

for i in "${AUTORUN_FILTER[@]}"; do
[[ "${#i}" -lt 3 || "$i" =~ [[:space:]]{2} ]] && continue #No empty/invalid values allowed!
for ii in "${!AUTORUN_FOUNDEXE[@]}"; do
[[ "${AUTORUN_FOUNDEXE[$ii]}" =~ $i ]] && unset AUTORUN_FOUNDEXE[$ii]
done
Expand Down