Compare commits

...

52 Commits

Author SHA1 Message Date
Mikhail Tergoev
a8c6ee55e7 Merge branch 'devel' 2025-02-04 22:19:18 +03:00
Mikhail Tergoev
c99435d2a1 STABLE: Scripts version 2388 2025-02-04 22:18:51 +03:00
Mikhail Tergoev
6fd26a2110 Scripts version 2387 2025-02-04 22:03:23 +03:00
Mikhail Tergoev
7cfd56f98e revert: lsbash to ls 2025-02-04 21:51:31 +03:00
Mikhail Tergoev
c784add1e2 HNY 2025 2025-02-04 20:24:58 +03:00
Mikhail Tergoev
b2830979bf added check scripts_ver file 2025-02-04 20:23:42 +03:00
Mikhail Tergoev
aa4c8cabf9 updated dxvk and vkd3d 2025-02-04 20:03:47 +03:00
Mikhail Tergoev
cae792b3f7 Merge branch 'alex2844-steamPlay' into devel 2025-02-04 19:55:35 +03:00
Mikhail Tergoev
f366f1e7e3 Merge branch 'steamPlay' of github.com:alex2844/PortWINE into alex2844-steamPlay 2025-02-04 19:55:26 +03:00
Mikhail Tergoev
3fb9cd8c7e Merge branch 'Htylol-umip_check' into devel 2025-02-04 19:52:42 +03:00
Mikhail Tergoev
4bff0c99de Merge branch 'umip_check' of github.com:Htylol/PortWINE into Htylol-umip_check 2025-02-04 19:52:29 +03:00
Mikhail Tergoev
b5370b3d42 Merge branch 'Htylol-update_resize_png' into devel 2025-02-04 19:51:01 +03:00
Mikhail Tergoev
2332b93353 Merge branch 'update_resize_png' of github.com:Htylol/PortWINE into Htylol-update_resize_png 2025-02-04 19:50:53 +03:00
Mikhail Tergoev
c4431536bf Merge branch 'Boria138-window-path-escaping' into devel 2025-02-04 19:49:18 +03:00
Mikhail Tergoev
1ae9f5a5b1 Merge branch 'window-path-escaping' of github.com:Boria138/PortWINE into Boria138-window-path-escaping 2025-02-04 19:49:08 +03:00
Htylol
54be04a474 Umip check for HogwartsLegacy 2025-01-27 13:18:47 +05:00
Alex Smith
fd3cfffcb5 support PW_DLL_INSTALL on steamplay_launch 2025-01-24 01:38:57 +05:00
Alex Smith
8d71f99b36 unset start_from_flatpak, move unset wineprefix 2025-01-24 01:38:03 +05:00
Htylol
cb8f27e673 resize_png can now create multiple icons at once 2025-01-19 14:55:47 +05:00
Alex Smith
4446ddd6ab cleaned 2025-01-18 17:04:01 +05:00
Alex Smith
e958e49b93 use start.sh 2025-01-18 17:02:49 +05:00
Alex Smith
c278df4e84 FLATPAK_IN_USE => START_FROM_FLATPAK 2025-01-18 04:24:32 +05:00
Alex Smith
4c0904a5f8 check if flatpak is installed 2025-01-18 03:44:54 +05:00
Alex Smith
4c5ce94067 cleaned 2025-01-18 03:29:54 +05:00
Alex Smith
109b27b3ba added saving statistics 2025-01-16 21:52:14 +05:00
Alex Smith
aa1e52602e support steamPlay 2025-01-16 02:54:28 +05:00
Mikhail Tergoev
47c0fb5b75 added the ability to replace arguments to the WINEDEBUG 2025-01-13 12:52:34 +03:00
Boris Yumankulov
df3f6de16f
edit_db_from_gui: impove windows paths escaping closed #217 2025-01-13 00:41:22 +05:00
Mikhail Tergoev
d91580f18e Scripts version 2386 2025-01-09 21:32:00 +03:00
Mikhail Tergoev
61216fb0dd Merge branch 'Boria138-permission' into devel 2025-01-09 20:55:17 +03:00
Mikhail Tergoev
ca175c2455 Merge branch 'permission' of github.com:Boria138/PortWINE into Boria138-permission 2025-01-09 20:55:05 +03:00
Mikhail Tergoev
46b1d240c5 Merge branch 'Boria138-crash' into devel 2025-01-09 20:54:02 +03:00
Mikhail Tergoev
5b833ec542 Merge branch 'crash' of github.com:Boria138/PortWINE into Boria138-crash 2025-01-09 20:53:54 +03:00
Mikhail Tergoev
0fa6efdf8d Merge branch 'minergenon-FRACTURED_ONLINE' into devel 2025-01-09 20:52:59 +03:00
Mikhail Tergoev
766013428f Merge branch 'FRACTURED_ONLINE' of github.com:minergenon/PortWINE into minergenon-FRACTURED_ONLINE 2025-01-09 20:52:49 +03:00
Mikhail Tergoev
544e572bde Merge branch 'minergenon-LastChaos' into devel 2025-01-09 20:51:46 +03:00
Mikhail Tergoev
a2a945bd46 Merge branch 'LastChaos' of github.com:minergenon/PortWINE into minergenon-LastChaos 2025-01-09 20:51:35 +03:00
Mikhail Tergoev
14c03a4d85 Merge branch 'alex2844-removeNonSteamGame' into devel 2025-01-09 20:50:37 +03:00
Mikhail Tergoev
1ca67cef0c Merge branch 'removeNonSteamGame' of github.com:alex2844/PortWINE into alex2844-removeNonSteamGame 2025-01-09 20:50:29 +03:00
Mikhail Tergoev
bffcdc692d Merge branch 'alex2844-getSteamId' into devel 2025-01-09 20:21:08 +03:00
Boris Yumankulov
97467d9925
Fix desktop file permission change on KDE 2025-01-08 22:35:25 +05:00
Alex Smith
59d3ee4f4e portwine_delete_shortcut 2025-01-07 17:59:14 +05:00
Boris Yumankulov
b0fa4a4355
Fixed crash if scripts_backup folder is missing when trying to rollback scripts 2025-01-07 12:53:52 +05:00
Sergey Palcheh
a031753a43 New game FRACTURED_ONLINE 2025-01-04 12:29:26 +06:00
Sergey Palcheh
ded69ca4eb New game LastChaos 2025-01-03 14:36:52 +06:00
Alex Smith
23be9fc637 addEntry 2025-01-02 03:09:24 +05:00
Alex Smith
df86ec0416 getAppExe 2024-12-31 20:55:49 +05:00
Alex Smith
f5dd208f2a getUserId getUserIds getUserPath 2024-12-31 19:53:44 +05:00
Alex Smith
b0864223f0 removeNonSteamGame 2024-12-31 17:27:12 +05:00
Alex Smith
2065560566 timeouts 2024-12-30 14:27:56 +05:00
Alex Smith
f27eb542b3 var USE_STEABGRIDDB 2024-12-30 14:18:36 +05:00
Alex Smith
b1388658cb check available steamgriddb 2024-12-29 23:42:46 +05:00
13 changed files with 569 additions and 230 deletions

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2024 Castro-Fidel (linux-gaming.ru) Copyright (c) 2025 Castro-Fidel (linux-gaming.ru)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

@ -2,6 +2,28 @@ You can help us in the development of the project on the website: https://linux-
---------------------------------------- ----------------------------------------
Changelog: Changelog:
###Scripts version 2388### / stable / Date: 04.02.2025 / Download update size: 10 megabytes
* cumulative update to the stable version of PortProton scripts
###Scripts version 2387### / Date: 04.02.2025 / Download update size: 10 megabytes
* updated versions:
* DXVK_GIT "2.5.3-31" (shared with dxvk-nvapi)
* VKD3D_GIT "1.1-4367" (shared with vkd3d-shader)
* added the ability to replace WINEDEBUG variable arguments in user.conf or .ppdb settings files.
* improved icon creation functions (thanks to Htylol)
* added Steam Play support for games supported via PortProton and the selected Proton version on Steam (thanks to alex2844)
* fixed windows operation, paths in game launch arguments (thanks to Boria138)
* fixed errors with empty "dist" directory
###Scripts version 2386### / Date: 09.01.2025 / Download update size: 4 megabytes
* corrected permissions when creating desktop files (thanks to Boria138)
* fixed the function of rolling back scripts from the archive if there is no scripts_backup directory (thanks to Boria138)
* added the ability to remove a game from the list in the Steam library using the functionality of changing the shortcut in PortProton (thanks to alex2844)
* when adding a game to the steam library, a check for the availability of the steamgriddb site has been added (thanks alex2844)
* added auto-installation of games (thanks to minergenon):
* Last Chaos
* Fractured Online
###Scripts version 2385### / stable / Date: 29.12.2024 / Download update size: 195 megabytes ###Scripts version 2385### / stable / Date: 29.12.2024 / Download update size: 195 megabytes
* cumulative update to the stable version of PortProton scripts * cumulative update to the stable version of PortProton scripts

@ -2,6 +2,28 @@
----------------------------------------- -----------------------------------------
История изменений: История изменений:
###Scripts version 2388### / stable / Дата: 04.02.2025 / Размер скачиваемого обновления: 10 мегабайт
* кумулятивное обновление стабильной версии скриптов PortProton
###Scripts version 2387### / Дата: 04.02.2025 / Размер скачиваемого обновления: 10 мегабайт
* обновлены версии:
* DXVK_GIT "2.5.3-31" (совместно с dxvk-nvapi)
* VKD3D_GIT "1.1-4367" (совместно vkd3d-shader)
* добавлена возможность замещения аргументов переменной WINEDEBUG в user.conf или .ppdb файлах настроек
* улучшение функций создания иконок (спасибо Htylol)
* добавлена поддержка Steam Play для игр установленных с помощью PortProton и когда выбрана версия proton в steam (спасибо alex2844)
* исправлена работа windows путей в аргументах запуска к игре (спасибо Boria138)
* исправлены ошибки при пустом каталоге "dist"
###Scripts version 2386### / Дата: 09.01.2025 / Размер скачиваемого обновления: 4 мегабайта
* исправление прав при создании desktop файлов (спасибо Boria138)
* исправлена функция отката скриптов из архива, если нет каталога scripts_backup (спасибо Boria138)
* добавлена возможность удаления игры из списка в библиотеке Steam с помощью функционала изменения ярлыка в PortProton (спасибо alex2844)
* при добавлении игры в библиотеку steam добавлена проверка на доступность сайта steamgriddb (спасибо alex2844)
* добавлены автоустановки игр (спасибо minergenon):
* Last Chaos
* Fractured Online
###Scripts version 2385### / stable / Дата: 29.12.2024 / Размер скачиваемого обновления: 195 мегабайт ###Scripts version 2385### / stable / Дата: 29.12.2024 / Размер скачиваемого обновления: 195 мегабайт
* кумулятивное обновление стабильной версии скриптов PortProton * кумулятивное обновление стабильной версии скриптов PortProton

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

@ -41,19 +41,22 @@ generateShortcutVDFHexAppId() {
} }
# Takes an signed 32bit integer and converts it to an unsigned 32bit integer # Takes an signed 32bit integer and converts it to an unsigned 32bit integer
generateShortcutGridAppId() { extractSteamId32() {
# STUID32=$((STUID64 - 76561197960265728))
echo $(($1 & 0xFFFFFFFF)) echo $(($1 & 0xFFFFFFFF))
} }
## ---------- ## ----------
### END MAGIC APPID FUNCTIONS ### END MAGIC APPID FUNCTIONS
getSteamShortcutsVdfFileHex() { getSteamShortcutsVdfFileHex() {
STCFGPATH="$(getUserPath)" if [[ -z "${STCFGPATH}" ]]; then
if [[ -n "${STCFGPATH}" ]]; then STCFGPATH="$(getUserPath)"
fi
if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then
SCPATH="${STCFGPATH}/shortcuts.vdf" SCPATH="${STCFGPATH}/shortcuts.vdf"
if [[ -f "${SCPATH}" ]]; then fi
LC_ALL=C perl -0777 -ne 'print unpack("H*", $_)' "${SCPATH}" if [[ -n "${SCPATH}" ]] && [[ -f "${SCPATH}" ]]; then
fi LC_ALL=C perl -0777 -ne 'print unpack("H*", $_)' "${SCPATH}"
fi fi
} }
@ -71,10 +74,14 @@ getSteamShortcutEntryHex() {
printf "%s" "${SHORTCUTSVDFINPUTHEX}" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" printf "%s" "${SHORTCUTSVDFINPUTHEX}" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})"
} }
getAppExe() {
[[ -n "$1" ]] && listNonSteamGames | jq -r --arg id "$1" 'map(select(.id == $id)) | first(.[].exe)'
}
getAppTarget() { getAppTarget() {
exe=$(listNonSteamGames | jq -r --arg id "$1" 'map(select(.id == $id)) | first(.[].exe)') exe=$(getAppExe "$1")
if [[ -n "${exe}" ]]; then if [[ -n "${exe}" ]]; then
if [[ "${exe}" =~ .sh$ ]] ; then if [[ "${exe}" =~ .sh$ ]]; then
parseSteamTargetExe "${exe}" parseSteamTargetExe "${exe}"
else else
echo "${exe}"; echo "${exe}";
@ -87,7 +94,7 @@ getSteamGameId() {
} }
getAppId() { getAppId() {
listNonSteamGames | jq -r --arg exe "$1" 'map(select(.exe == $exe)) | first(.[]?.id)' [[ -n "$1" ]] && listNonSteamGames | jq -r --arg exe "$1" 'map(select(.exe == $exe)) | first(.[]?.id)'
} }
getSteamId() { getSteamId() {
@ -100,14 +107,16 @@ getSteamId() {
if [[ -n "${SteamIds:-}" ]] && jq -e --arg key "$NOSTAPPNAME" 'has($key)' <<< "${SteamIds}" > /dev/null; then if [[ -n "${SteamIds:-}" ]] && jq -e --arg key "$NOSTAPPNAME" 'has($key)' <<< "${SteamIds}" > /dev/null; then
SteamAppId=$(jq -r --arg key "${NOSTAPPNAME}" '.[$key]' <<< "${SteamIds}") SteamAppId=$(jq -r --arg key "${NOSTAPPNAME}" '.[$key]' <<< "${SteamIds}")
else else
if [[ -n "${1:-}" ]]; then if [[ -n "${1:-}" ]] && [[ "${USE_STEABGRIDDB:-1}" == "1" ]]; then
getSteamGridDBId "${NOSTAPPNAME}" > /dev/null getSteamGridDBId "${NOSTAPPNAME}" > /dev/null
fi fi
if [[ $SteamGridDBTypeSteam == true ]]; then if [[ $SteamGridDBTypeSteam == true ]]; then
SRES=$(curl -Ls -e "https://www.steamgriddb.com/game/${SteamGridDBId}" "https://www.steamgriddb.com/api/public/game/${SteamGridDBId}") SRES=$(curl -Ls --connect-timeout 5 -m 10 -e "https://www.steamgriddb.com/game/${SteamGridDBId}" "https://www.steamgriddb.com/api/public/game/${SteamGridDBId}")
if jq -e ".success == true" <<< "${SRES}" > /dev/null 2>&1; then if jq -e ".success == true" <<< "${SRES}" > /dev/null 2>&1; then
SteamAppId="$(jq -r '.data.platforms.steam.id' <<< "${SRES}")" SteamAppId="$(jq -r '.data.platforms.steam.id' <<< "${SRES}")"
fi fi
elif [[ "${USE_STEABGRIDDB:-1}" == "0" ]]; then
SteamAppId="$(curl -s --connect-timeout 5 -m 10 "https://api.steampowered.com/ISteamApps/GetAppList/v2/" | jq --arg name "${NOSTAPPNAME}" '.applist.apps[] | select(.name == $name) | .appid')"
fi fi
SteamIds=$(jq --arg key "${NOSTAPPNAME}" --arg value "${SteamAppId:-}" '. + {($key): $value}' <<< "${SteamIds:-$(jq -n '{}')}") SteamIds=$(jq --arg key "${NOSTAPPNAME}" --arg value "${SteamAppId:-}" '. + {($key): $value}' <<< "${SteamIds:-$(jq -n '{}')}")
echo "${SteamIds}" > "${cache_file}" echo "${SteamIds}" > "${cache_file}"
@ -120,41 +129,70 @@ getSteamId() {
getSteamGridDBId() { getSteamGridDBId() {
unset SteamGridDBId unset SteamGridDBId
NOSTAPPNAME="$1" NOSTAPPNAME="$1"
SGDBRES=$(curl -Ls -H "Authorization: Bearer ${SGDBAPIKEY}" "${BASESTEAMGRIDDBAPI}/search/autocomplete/${NOSTAPPNAME// /_}") if [[ "${USE_STEABGRIDDB:-1}" == "1" ]] && [[ -n "${SGDBAPIKEY}" ]] && [[ -n "${BASESTEAMGRIDDBAPI}" ]] && curl -fs --connect-timeout 5 -m 10 -o /dev/null "${BASESTEAMGRIDDBAPI}"; then
if jq -e ".success == true and (.data | length > 0)" <<< "${SGDBRES}" > /dev/null 2>&1; then SGDBRES=$(curl -Ls --connect-timeout 5 -m 10 -H "Authorization: Bearer ${SGDBAPIKEY}" "${BASESTEAMGRIDDBAPI}/search/autocomplete/${NOSTAPPNAME// /_}")
if jq -e '.data[0].types | contains(["steam"])' <<< "${SGDBRES}" > /dev/null; then if jq -e ".success == true and (.data | length > 0)" <<< "${SGDBRES}" > /dev/null 2>&1; then
SteamGridDBTypeSteam=true if jq -e '.data[0].types | contains(["steam"])' <<< "${SGDBRES}" > /dev/null; then
else SteamGridDBTypeSteam=true
SteamGridDBTypeSteam=false else
SteamGridDBTypeSteam=false
fi
SteamGridDBId="$(jq '.data[0].id' <<< "${SGDBRES}")"
echo "${SteamGridDBId}"
fi fi
SteamGridDBId="$(jq '.data[0].id' <<< "${SGDBRES}")" else
echo "${SteamGridDBId}" USE_STEABGRIDDB="0"
fi fi
} }
getUserPath() { getUserIds() {
SLUF="${HOME}/.local/share/Steam/config/loginusers.vdf"
if [[ -f "${SLUF}" ]]; then
STUIDS=()
while read -r line; do
if [[ "${line}" =~ ^[[:space:]]*\"([0-9]+)\"$ ]]; then
STUIDS+=("$(extractSteamId32 "${BASH_REMATCH[1]}")")
fi
done < "${SLUF}"
if [[ ${#STUIDS[@]} -gt 0 ]]; then
echo "${STUIDS[@]}"
fi
fi
}
getUserId() {
SLUF="${HOME}/.local/share/Steam/config/loginusers.vdf" SLUF="${HOME}/.local/share/Steam/config/loginusers.vdf"
if [[ -f "${SLUF}" ]]; then if [[ -f "${SLUF}" ]]; then
SLUFUB=false SLUFUB=false
STUID64="" STUID=""
while read -r line; do while read -r line; do
if [[ "${line}" =~ ^[[:space:]]*\"([0-9]+)\"$ ]]; then if [[ "${line}" =~ ^[[:space:]]*\"([0-9]+)\"$ ]]; then
STUIDCUR="${BASH_REMATCH[1]}" STUIDCUR="${BASH_REMATCH[1]}"
SLUFUB=true SLUFUB=true
elif [[ "${line}" == *'"MostRecent"'*'"1"' && ${SLUFUB} = true ]]; then elif [[ "${line}" == *'"MostRecent"'*'"1"' && ${SLUFUB} = true ]]; then
STUID64="${STUIDCUR}" STUID=$(extractSteamId32 "${STUIDCUR}")
break break
elif [[ "${line}" == "}" ]]; then elif [[ "${line}" == "}" ]]; then
SLUFUB=false SLUFUB=false
fi fi
done < "${SLUF}" done < "${SLUF}"
if [ -n "${STUID64}" ]; then fi
STUID32=$((STUID64 - 76561197960265728)) if [ -n "${STUID}" ]; then
STUIDPATH="${HOME}/.local/share/Steam/userdata/${STUID32}" echo "${STUID}"
if [[ -d "${STUIDPATH}" ]]; then fi
if [[ -f "${STUIDPATH}/config/shortcuts.vdf" ]]; then }
echo "${STUIDPATH}/config"
fi getUserPath() {
if [[ -n "${1:-}" ]]; then
STUID="$1"
else
STUID="$(getUserId)"
fi
if [ -n "${STUID}" ]; then
STUIDPATH="${HOME}/.local/share/Steam/userdata/${STUID}"
if [[ -d "${STUIDPATH}" ]]; then
if [[ -f "${STUIDPATH}/config/shortcuts.vdf" ]]; then
echo "${STUIDPATH}/config"
fi fi
fi fi
fi fi
@ -178,19 +216,22 @@ listInstalledSteamGames() {
} }
listNonSteamGames() { listNonSteamGames() {
getSteamShortcutHex | while read -r SCVDFE; do getSteamShortcutHex | while read -r SCVDFE; do
jq -n \ jq -n \
--arg id "$(parseSteamShortcutEntryAppID "${SCVDFE}")" \ --arg id "$(parseSteamShortcutEntryAppID "${SCVDFE}")" \
--arg name "$(parseSteamShortcutEntryAppName "${SCVDFE}")" \ --arg name "$(parseSteamShortcutEntryAppName "${SCVDFE}")" \
--arg exe "$(parseSteamShortcutEntryExe "${SCVDFE}")" \ --arg exe "$(parseSteamShortcutEntryExe "${SCVDFE}")" \
'{id: $id, name: $name, exe: $exe}' --arg dir "$(parseSteamShortcutEntryStartDir "${SCVDFE}")" \
done | jq -s '.' --arg icon "$(parseSteamShortcutEntryIcon "${SCVDFE}")" \
--arg args "$(parseSteamShortcutEntryLaunchOptions "${SCVDFE}")" \
'{id: $id, name: $name, exe: $exe, dir: $dir, icon: $icon, args: $args}'
done | jq -s '.'
} }
listSteamGames() { listSteamGames() {
( (
jq -r 'map({AppId: .id, SteamAppId: .id, SteamGameId: .id, Name: .name}) | .[] | tostring' <<< "$(listInstalledSteamGames)" jq -r 'map({AppId: .id, SteamAppId: .id, SteamGameId: .id, Name: .name}) | .[] | tostring' <<< "$(listInstalledSteamGames)"
jq -r '.[] | tostring' <<< "$(listNonSteamGames)" | while read game; do jq -r '.[] | tostring' <<< "$(listNonSteamGames)" | while read -r game; do
id=$(jq -r '.id' <<< "${game}") id=$(jq -r '.id' <<< "${game}")
name=$(jq -r '.name' <<< "${game}") name=$(jq -r '.name' <<< "${game}")
jq -r \ jq -r \
@ -208,19 +249,22 @@ convertSteamShortcutAppID() {
} }
convertSteamShortcutHex() { convertSteamShortcutHex() {
# printf "%s" "$1" | xxd -r -p | tr -d '\0'
LC_ALL=C perl -le 'print pack "H*", $ARGV[0]' "$1" | tr -d '\0' LC_ALL=C perl -le 'print pack "H*", $ARGV[0]' "$1" | tr -d '\0'
} }
convertStringToSteamShortcutHex() {
LC_ALL=C perl -e 'print unpack "H*", "$ARGV[0]" . "\x00"' "$(echo "$1" | tr -cd '[:alpha:]')"
}
parseSteamShortcutEntryHex() { parseSteamShortcutEntryHex() {
SHORTCUTSVDFINPUTHEX="$1" # The hex block representing the shortcut SHORTCUTSVDFINPUTHEX="$1" # The hex block representing the shortcut
SHORTCUTSVDFMATCHPATTERN="$2" # The pattern to match against in the block SHORTCUTSVDFMATCHPATTERN="$2" # The pattern to match against in the block
convertSteamShortcutHex "$(getSteamShortcutEntryHex "${SHORTCUTSVDFINPUTHEX}" "${SHORTCUTSVDFMATCHPATTERN}")" convertSteamShortcutHex "$(getSteamShortcutEntryHex "${SHORTCUTSVDFINPUTHEX}" "${SHORTCUTSVDFMATCHPATTERN}")"
} }
parseSteamShortcutEntryExe() { parseSteamShortcutEntryAppID() {
SHORTCUTVDFEXEHEXPAT="000145786500" # 'Exe' ('exe' is 6578650a if we ever need it) SHORTCUTVDFAPPIDHEXPAT="617070696400" # 'appid'
parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFEXEHEXPAT}" | tr -d '"' convertSteamShortcutAppID "$(printf "%s" "$1" | grep -oP "${SHORTCUTVDFAPPIDHEXPAT}\K.{8}")"
} }
parseSteamShortcutEntryAppName() { parseSteamShortcutEntryAppName() {
@ -228,13 +272,28 @@ parseSteamShortcutEntryAppName() {
parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFNAMEHEXPAT}" parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFNAMEHEXPAT}"
} }
parseSteamShortcutEntryAppID() { parseSteamShortcutEntryExe() {
SHORTCUTVDFAPPIDHEXPAT="617070696400" # 'appid' SHORTCUTVDFEXEHEXPAT="000145786500" # 'Exe' ('exe' is 6578650a if we ever need it)
convertSteamShortcutAppID "$(printf "%s" "$1" | grep -oP "${SHORTCUTVDFAPPIDHEXPAT}\K.{8}")" parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFEXEHEXPAT}" | tr -d '"'
}
parseSteamShortcutEntryStartDir() {
SHORTCUTVDFSTARTDIRHEXPAT="0001537461727444697200"
parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFSTARTDIRHEXPAT}" | tr -d '"'
}
parseSteamShortcutEntryIcon() {
SHORTCUTVDFICONHEXPAT="000169636f6e00"
parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFICONHEXPAT}"
}
parseSteamShortcutEntryLaunchOptions() {
SHORTCUTVDFARGHEXPAT="00014c61756e63684f7074696f6e7300" # echo "0001$(convertStringToSteamShortcutHex "LaunchOptions")"
parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFARGHEXPAT}" | tr '\002' '\n' | head -n 1 | tr -d '\000'
} }
parseSteamTargetExe() { parseSteamTargetExe() {
grep -E 'flatpak|start\.sh' "$1" | head -n 1 | awk -F'"' '{print $(NF-1)}' grep -E '^[^# ]*?(flatpak|start\.sh)' "$1" | head -n 1 | sed 's/ "\$@"//' | awk -F'"' '{print $(NF-1)}'
} }
restartSteam() { restartSteam() {
@ -255,7 +314,7 @@ restartSteam() {
} }
downloadImage() { downloadImage() {
if ! curl -Lf# -o "${STCFGPATH}/grid/$2" "$1"; then if ! curl -Lf# --connect-timeout 5 -m 10 -o "${STCFGPATH}/grid/$2" "$1"; then
return 1 return 1
fi fi
} }
@ -272,109 +331,167 @@ downloadImageSteam() {
} }
downloadImageSteamGridDB() { downloadImageSteamGridDB() {
SGDBIMGAPI="${BASESTEAMGRIDDBAPI}/$1/game/${SteamGridDBId}?limit=1" if [[ -n "${SteamGridDBId}" ]]; then
[[ -n "$3" ]] && SGDBIMGAPI+="&$3" SGDBIMGAPI="${BASESTEAMGRIDDBAPI}/$1/game/${SteamGridDBId}?limit=1"
[[ -n "$4" ]] && SGDBIMGAPI+="&$4" [[ -n "$3" ]] && SGDBIMGAPI+="&$3"
SGDBIMGRES=$(curl -Ls -H "Authorization: Bearer ${SGDBAPIKEY}" "${SGDBIMGAPI}") [[ -n "$4" ]] && SGDBIMGAPI+="&$4"
if jq -e ".success == true and (.data | length > 0)" <<< "${SGDBIMGRES}" > /dev/null 2>&1; then SGDBIMGRES=$(curl -Ls --connect-timeout 5 -m 10 -H "Authorization: Bearer ${SGDBAPIKEY}" "${SGDBIMGAPI}")
SGDBIMGURL=$(jq -r '.data[0].url' <<< "${SGDBIMGRES}") if jq -e ".success == true and (.data | length > 0)" <<< "${SGDBIMGRES}" > /dev/null 2>&1; then
downloadImage "${SGDBIMGURL}" "$2" SGDBIMGURL=$(jq -r '.data[0].url' <<< "${SGDBIMGRES}")
elif [[ -n "$3" ]]; then downloadImage "${SGDBIMGURL}" "$2"
downloadImageSteamGridDB "$1" "$2" "" "$4" elif [[ -n "$3" ]]; then
downloadImageSteamGridDB "$1" "$2" "" "$4"
else
return 1
fi
else else
return 1 return 1
fi fi
} }
addGrids() { addGrids() {
if [[ -n "${SGDBAPIKEY}" ]]; then getSteamGridDBId "${name_desktop}" > /dev/null
getSteamGridDBId "${name_desktop}" > /dev/null if [[ "${USE_STEABGRIDDB:-1}" == "0" ]]; then
getSteamId > /dev/null
fi fi
if [[ -n "${SteamGridDBId}" ]]; then if [[ -n "${SteamGridDBId}" ]] || [[ -n "${SteamAppId}" ]]; then
create_new_dir "${STCFGPATH}/grid" create_new_dir "${STCFGPATH}/grid"
downloadImageSteamGridDB "grids" "${NOSTAIDGRID}.jpg" "mimes=image/jpeg" "dimensions=460x215,920x430" || downloadImageSteam "header.jpg" "${NOSTAIDGRID}.jpg" || echo "Failed to load header.jpg" downloadImageSteamGridDB "grids" "${NOSTAPPID:-0}.jpg" "mimes=image/jpeg" "dimensions=460x215,920x430" || downloadImageSteam "header.jpg" "${NOSTAPPID:-0}.jpg" || echo "Failed to load header.jpg"
downloadImageSteamGridDB "grids" "${NOSTAIDGRID}p.jpg" "mimes=image/jpeg" "dimensions=600x900,660x930" || downloadImageSteam "library_600x900_2x.jpg" "${NOSTAIDGRID}p.jpg" || echo "Failed to load library_600x900_2x.jpg" downloadImageSteamGridDB "grids" "${NOSTAPPID:-0}p.jpg" "mimes=image/jpeg" "dimensions=600x900,660x930" || downloadImageSteam "library_600x900_2x.jpg" "${NOSTAPPID:-0}p.jpg" || echo "Failed to load library_600x900_2x.jpg"
downloadImageSteamGridDB "heroes" "${NOSTAIDGRID}_hero.jpg" "mimes=image/jpeg" || downloadImageSteam "library_hero.jpg" "${NOSTAIDGRID}_hero.jpg" || echo "Failed to load library_hero.jpg" downloadImageSteamGridDB "heroes" "${NOSTAPPID:-0}_hero.jpg" "mimes=image/jpeg" || downloadImageSteam "library_hero.jpg" "${NOSTAPPID:-0}_hero.jpg" || echo "Failed to load library_hero.jpg"
downloadImageSteamGridDB "logos" "${NOSTAIDGRID}_logo.png" "mimes=image/png" || downloadImageSteam "logo.png" "${NOSTAIDGRID}_logo.png" || echo "Failed to load logo.png" downloadImageSteamGridDB "logos" "${NOSTAPPID:-0}_logo.png" "mimes=image/png" || downloadImageSteam "logo.png" "${NOSTAPPID:-0}_logo.png" || echo "Failed to load logo.png"
else else
echo "Game is not found" echo "Game is not found"
fi fi
} }
addNonSteamGame() { addEntry() {
NOSTAPPNAME="${name_desktop}" if [[ -n "${SCPATH}" ]]; then
NOSTSHPATH="${STEAM_SCRIPTS}/${name_desktop}.sh" if [[ -f "${SCPATH}" ]] ; then
NOSTEXEPATH="\"${NOSTSHPATH}\"" truncate -s-2 "${SCPATH}"
NOSTICONPATH="${PORT_WINE_PATH}/data/img/${name_desktop_png}.png" OLDSET="$(grep -aPo '\x00[0-9]\x00\x02appid' "${SCPATH}" | tail -n1 | tr -dc '0-9')"
if [[ -z "${NOSTSTDIR}" ]]; then NEWSET=$((OLDSET + 1))
NOSTSTDIR="\"${STEAM_SCRIPTS}\"" else
printf '\x00%s\x00' "shortcuts" > "${SCPATH}"
NEWSET=0
fi
NOSTAIDVDFHEXFMT="\x$(awk '{$1=$1}1' FPAT='.{2}' OFS="\\\x" <<< "$NOSTAIDVDFHEX")" # binary-formatted string hex of the above which we actually write out - ex: \xc1\xc2\x5a\xdc
{
printf '\x00%s\x00' "${NEWSET}"
printf '\x02%s\x00%b' "appid" "${NOSTAIDVDFHEXFMT}"
printf '\x01%s\x00%s\x00' "AppName" "${NOSTAPPNAME}"
printf '\x01%s\x00%s\x00' "Exe" "\"${NOSTEXEPATH}\""
printf '\x01%s\x00%s\x00' "StartDir" "\"${NOSTSTDIR}\""
printf '\x01%s\x00%s\x00' "icon" "${NOSTICONPATH}"
printf '\x01%s\x00%s\x00' "ShortcutPath" ""
printf '\x01%s\x00%s\x00' "LaunchOptions" "${NOSTARGS:-}"
printf '\x02%s\x00%b\x00\x00\x00' "IsHidden" "\x00"
printf '\x02%s\x00%b\x00\x00\x00' "AllowDesktopConfig" "\x00"
# These values are now stored in localconfig.vdf under the "Apps" section,
# under a block using the Non-Steam Game Signed 32bit AppID. (i.e., -223056321)
# This is handled by `updateLocalConfigAppsValue` below
#
# Unsure if required, but still write these to the shortcuts.vdf file for consistency
printf '\x02%s\x00%b\x00\x00\x00' "AllowOverlay" "\x00"
printf '\x02%s\x00%b\x00\x00\x00' "OpenVR" "\x00"
printf '\x02%s\x00\x00\x00\x00\x00' "Devkit"
printf '\x01%s\x00\x00' "DevkitGameID"
printf '\x02%s\x00\x00\x00\x00\x00' "DevkitOverrideAppID"
printf '\x02%s\x00\x00\x00\x00\x00' "LastPlayTime"
printf '\x01%s\x00\x00' "FlatpakAppID"
printf '\x00%s\x00' "tags"
printf '\x08\x08\x08\x08'
} >> "${SCPATH}"
fi fi
STCFGPATH="$(getUserPath)" }
if [[ -n "${STCFGPATH}" ]]; then
removeNonSteamGame() {
[[ -n "$1" ]] && appid="$1"
[[ -n "$2" ]] && NOSTSHPATH="$2"
[[ -z "${STUID}" ]] && STUID=$(getUserId)
[[ -z "${STCFGPATH}" ]] && STCFGPATH="$(getUserPath ${STUID})"
if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then
SCPATH="${STCFGPATH}/shortcuts.vdf"
fi
if [[ -n "${appid}" ]]; then
games=$(listNonSteamGames)
[[ -z "${NOSTSHPATH}" ]] && NOSTSHPATH=$(jq -r --arg id "${appid}" 'map(select(.id == $id)) | first(.[].exe)' <<< "${games}")
if [[ -n "${NOSTSHPATH}" ]]; then
mv "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null
jq --arg id "${appid}" 'map(select(.id != $id))' <<< "${games}" | jq -c '.[]' | while read -r game; do
NOSTAPPID=$(jq -r '.id' <<< "${game}")
NOSTAPPNAME=$(jq -r '.name' <<< "${game}")
NOSTEXEPATH=$(jq -r '.exe' <<< "${game}")
NOSTSTDIR=$(jq -r '.dir' <<< "${game}")
NOSTICONPATH=$(jq -r '.icon' <<< "${game}")
NOSTARGS=$(jq -r '.args' <<< "${game}")
NOSTAIDVDFHEX=$(bigToLittleEndian $(printf '%08x' "${NOSTAPPID}"))
addEntry
done
rm -f "${STCFGPATH}/grid/${appid}.jpg" "${STCFGPATH}/grid/${appid}p.jpg" "${STCFGPATH}/grid/${appid}_hero.jpg" "${STCFGPATH}/grid/${appid}_logo.png"
rm -rf "${HOME}/.local/share/Steam/steamapps/compatdata/${appid}"
rm -rf "${HOME}/.local/share/Steam/steamapps/shadercache/${appid}"
if [[ -f "${NOSTSHPATH}" ]]; then
isInstallGame=false
for STUIDCUR in $(getUserIds); do
[[ "${STUIDCUR}" == "${STUID}" ]] && continue
STCFGPATH="$(getUserPath ${STUIDCUR})"
SCPATH="${STCFGPATH}/shortcuts.vdf"
if [[ -n "$(getAppId "${NOSTSHPATH}")" ]]; then
isInstallGame=true
break
fi
done
unset STCFGPATH SCPATH
if [[ ${isInstallGame} == false ]]; then
rm "${NOSTSHPATH}"
fi
fi
restartSteam
fi
fi
}
addNonSteamGame() {
if [[ -z "${STCFGPATH}" ]]; then
STCFGPATH="$(getUserPath)"
fi
if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then
SCPATH="${STCFGPATH}/shortcuts.vdf" SCPATH="${STCFGPATH}/shortcuts.vdf"
fi fi
if [[ -n "${SCPATH}" ]]; then if [[ -n "${SCPATH}" ]]; then
NOSTAIDGRID=$(getAppId "${NOSTSHPATH}") [[ -z "${NOSTSHPATH}" ]] && NOSTSHPATH="${STEAM_SCRIPTS}/${name_desktop}.sh"
if [[ -z "${NOSTAIDGRID}" ]]; then NOSTAPPNAME="${name_desktop}"
NOSTAPPID=$(getAppId "${NOSTSHPATH}")
if [[ -z "${NOSTAPPID}" ]]; then
NOSTEXEPATH="${NOSTSHPATH}"
if [[ -z "${NOSTSTDIR}" ]]; then
NOSTSTDIR="${STEAM_SCRIPTS}"
fi
NOSTICONPATH="${PORT_WINE_PATH}/data/img/${name_desktop_png}.png"
NOSTAIDVDF="$(generateShortcutVDFAppId "${NOSTAPPNAME}${NOSTEXEPATH}")" # signed integer AppID, stored in the VDF as hexidecimal - ex: -598031679 NOSTAIDVDF="$(generateShortcutVDFAppId "${NOSTAPPNAME}${NOSTEXEPATH}")" # signed integer AppID, stored in the VDF as hexidecimal - ex: -598031679
NOSTAIDVDFHEX="$(generateShortcutVDFHexAppId "$NOSTAIDVDF")" # 4byte little-endian hexidecimal of above 32bit signed integer, which we write out to the binary VDF - ex: c1c25adc NOSTAIDVDFHEX="$(generateShortcutVDFHexAppId "$NOSTAIDVDF")" # 4byte little-endian hexidecimal of above 32bit signed integer, which we write out to the binary VDF - ex: c1c25adc
NOSTAIDVDFHEXFMT="\x$(awk '{$1=$1}1' FPAT='.{2}' OFS="\\\x" <<< "$NOSTAIDVDFHEX")" # binary-formatted string hex of the above which we actually write out - ex: \xc1\xc2\x5a\xdc NOSTAPPID="$(extractSteamId32 "$NOSTAIDVDF")" # unsigned 32bit ingeger version of "$NOSTAIDVDF", which is used as the AppID for Steam artwork ("grids"), as well as for our shortcuts
NOSTAIDGRID="$(generateShortcutGridAppId "$NOSTAIDVDF")" # unsigned 32bit ingeger version of "$NOSTAIDVDF", which is used as the AppID for Steam artwork ("grids"), as well as for our shortcuts
create_new_dir "${STEAM_SCRIPTS}" create_new_dir "${STEAM_SCRIPTS}"
echo "#!/usr/bin/env bash" > "${NOSTSHPATH}" cat <<-EOF > "${NOSTSHPATH}"
echo "export START_FROM_STEAM=1" >> "${NOSTSHPATH}" #!/usr/bin/env bash
echo "export LD_PRELOAD=" >> "${NOSTSHPATH}" export LD_PRELOAD=
if check_flatpak; then export START_FROM_STEAM=1
echo "flatpak run ru.linux_gaming.PortProton \"${portwine_exe}\" " >> "${NOSTSHPATH}" export START_FROM_FLATPAK=$(check_flatpak && echo 1 || echo 0)
else "${PORT_SCRIPTS_PATH}/start.sh" "${portwine_exe}" "\$@"
echo "\"${PORT_SCRIPTS_PATH}/start.sh\" \"${portwine_exe}\" " >> "${NOSTSHPATH}" EOF
fi
chmod u+x "${NOSTSHPATH}" chmod u+x "${NOSTSHPATH}"
if [[ -f "${SCPATH}" ]] ; then if [[ -f "${SCPATH}" ]] ; then
cp "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null cp "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null
truncate -s-2 "${SCPATH}"
OLDSET="$(grep -aPo '\x00[0-9]\x00\x02appid' "${SCPATH}" | tail -n1 | tr -dc '0-9')"
NEWSET=$((OLDSET + 1))
else
printf '\x00%s\x00' "shortcuts" > "${SCPATH}"
NEWSET=0
fi fi
{ addEntry
printf '\x00%s\x00' "${NEWSET}"
printf '\x02%s\x00%b' "appid" "${NOSTAIDVDFHEXFMT}"
printf '\x01%s\x00%s\x00' "AppName" "${NOSTAPPNAME}"
printf '\x01%s\x00%s\x00' "Exe" "${NOSTEXEPATH}"
printf '\x01%s\x00%s\x00' "StartDir" "${NOSTSTDIR}"
printf '\x01%s\x00%s\x00' "icon" "${NOSTICONPATH}"
printf '\x01%s\x00%s\x00' "ShortcutPath" ""
printf '\x01%s\x00%s\x00' "LaunchOptions" ""
printf '\x02%s\x00%b\x00\x00\x00' "IsHidden" "\x00"
printf '\x02%s\x00%b\x00\x00\x00' "AllowDesktopConfig" "\x00"
# These values are now stored in localconfig.vdf under the "Apps" section,
# under a block using the Non-Steam Game Signed 32bit AppID. (i.e., -223056321)
# This is handled by `updateLocalConfigAppsValue` below
#
# Unsure if required, but still write these to the shortcuts.vdf file for consistency
printf '\x02%s\x00%b\x00\x00\x00' "AllowOverlay" "\x00"
printf '\x02%s\x00%b\x00\x00\x00' "OpenVR" "\x00"
printf '\x02%s\x00\x00\x00\x00\x00' "Devkit"
printf '\x01%s\x00\x00' "DevkitGameID"
printf '\x02%s\x00\x00\x00\x00\x00' "DevkitOverrideAppID"
printf '\x02%s\x00\x00\x00\x00\x00' "LastPlayTime"
printf '\x01%s\x00\x00' "FlatpakAppID"
printf '\x00%s\x00' "tags"
printf '\x08\x08\x08\x08'
} >> "${SCPATH}"
# TODO: замень использование steamgriddb на steam так как сайт steamgriddb у многих без VPN не работает
# а пока просто блочим использование
export DOWNLOAD_STEAM_GRID="0"
if [[ "${DOWNLOAD_STEAM_GRID}" == "1" ]] ; then if [[ "${DOWNLOAD_STEAM_GRID}" == "1" ]] ; then
pw_start_progress_bar_block "${translations[Please wait. downloading covers for]} ${NOSTAPPNAME}" pw_start_progress_bar_block "${translations[Please wait. downloading covers for]} ${NOSTAPPNAME}"

@ -410,6 +410,7 @@ lsbash () {
else else
directory=$PWD directory=$PWD
fi fi
grep_find_file1 () { grep_find_file1 () {
find_file_old=$find_file find_file_old=$find_file
if [[ $grep_with_i == true ]] ; then if [[ $grep_with_i == true ]] ; then
@ -975,10 +976,25 @@ debug_timer () {
fi fi
} }
fix_icon_name_png () {
if [[ $1 =~ [\!\%\$\&\<] ]] ; then
local ICON_NAME_OLD=$1
local ICON_NAME_NEW=$ICON_NAME_OLD
local ICON_NAME_REGEX=(\! % \$ \& \<)
for i in "${ICON_NAME_REGEX[@]}" ; do
ICON_NAME_NEW="${ICON_NAME_NEW//$i/}"
done
sed -i "s|Icon=$ICON_NAME_OLD|Icon=$ICON_NAME_NEW|" "$2"
return 0
else
return 1
fi
}
# Поиск нужного .desktop файла по $portwine_exe (для показа в комментариях нужного времени) # Поиск нужного .desktop файла по $portwine_exe (для показа в комментариях нужного времени)
# Параллельное создание базы по времени после завершения приложения # Параллельное создание базы по времени после завершения приложения
search_desktop_file () { search_desktop_file () {
local desktop_file desktop_file_new line1 line2 FILE_SHA256SUM_ARRAY EXEC_DESKTOP BROKEN_LINE FILE_SHA256SUM_FOUND FILE_SHA256SUM_NOT_FOUND local desktop_file desktop_file_new line1 line2 FILE_SHA256SUM_ARRAY EXEC_DESKTOP ICON_NAME BROKEN_LINE FILE_SHA256SUM_FOUND FILE_SHA256SUM_NOT_FOUND
if [[ -z $FILE_SHA256SUM ]] ; then if [[ -z $FILE_SHA256SUM ]] ; then
read -r -a FILE_SHA256SUM_ARRAY < <(sha256sum "$portwine_exe") read -r -a FILE_SHA256SUM_ARRAY < <(sha256sum "$portwine_exe")
FILE_SHA256SUM=${FILE_SHA256SUM_ARRAY[0]} FILE_SHA256SUM=${FILE_SHA256SUM_ARRAY[0]}
@ -996,7 +1012,9 @@ search_desktop_file () {
EXEC_DESKTOP=${line1//Exec=env \"$PORT_SCRIPTS_PATH\/start.sh\" /} EXEC_DESKTOP=${line1//Exec=env \"$PORT_SCRIPTS_PATH\/start.sh\" /}
fi fi
fi fi
[[ $line1 =~ ^Icon= ]] && ICON_NAME=${line1//Icon=/}
done < "$desktop_file" done < "$desktop_file"
fix_icon_name_png "$ICON_NAME" "$desktop_file"
if [[ $portwine_exe == "${EXEC_DESKTOP//\"/}" ]] ; then if [[ $portwine_exe == "${EXEC_DESKTOP//\"/}" ]] ; then
DESKTOP_CORRECT_FILE="$desktop_file" DESKTOP_CORRECT_FILE="$desktop_file"
break break
@ -1607,7 +1625,7 @@ init_wine_ver () {
else else
if [[ -d "${PORT_WINE_PATH}/data/dist" ]] ; then if [[ -d "${PORT_WINE_PATH}/data/dist" ]] ; then
IFS=$'\n' IFS=$'\n'
for dist_dir in $(lsbash "${PORT_WINE_PATH}/data/dist/") ; do for dist_dir in $(ls -1 "${PORT_WINE_PATH}/data/dist") ; do
dist_dir_new=$(echo "${dist_dir}" | awk '$1=$1' | sed -e s/[[:blank:]]/_/g) dist_dir_new=$(echo "${dist_dir}" | awk '$1=$1' | sed -e s/[[:blank:]]/_/g)
if [[ ! -d "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}" ]] ; then if [[ ! -d "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}" ]] ; then
mv -- "${PORT_WINE_PATH}/data/dist/$dist_dir" "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}" mv -- "${PORT_WINE_PATH}/data/dist/$dist_dir" "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}"
@ -1615,7 +1633,7 @@ init_wine_ver () {
done done
IFS="$orig_IFS" IFS="$orig_IFS"
fi fi
if [[ -z $(lsbash "${PORT_WINE_PATH}/data/dist/" --grep "${PW_WINE_USE}") ]] ; then if [[ -z $(ls "${PORT_WINE_PATH}/data/dist/" | grep "${PW_WINE_USE}") ]] ; then
if [[ "$PW_WINE_USE" =~ PROTON_LG* ]] if [[ "$PW_WINE_USE" =~ PROTON_LG* ]]
then export PW_WINE_USE=PROTON_LG then export PW_WINE_USE=PROTON_LG
else export PW_WINE_USE=WINE_LG else export PW_WINE_USE=WINE_LG
@ -1632,20 +1650,20 @@ init_wine_ver () {
export WINELOADER="${WINEDIR}/bin/wine" export WINELOADER="${WINEDIR}/bin/wine"
export WINESERVER="${WINEDIR}/bin/wineserver" export WINESERVER="${WINEDIR}/bin/wineserver"
if [[ -d "${WINEDIR}/files" && ! -d "${WINEDIR}/dist" ]] ; then if [[ -d "${WINEDIR}/files" && ! -d "${WINEDIR}/dist" ]] ; then
for clear_dist_files in $(lsbash "$WINEDIR" | sed -r "s/^(files|version)$//g") ; do for clear_dist_files in $(ls "${WINEDIR}" | sed -r "s/^(files|version)$//g") ; do
rm -fr "${WINEDIR}/$clear_dist_files" rm -fr "${WINEDIR}/$clear_dist_files"
done done
mv -f "${WINEDIR}/files"/* "${WINEDIR}/" mv -f "${WINEDIR}/files"/* "${WINEDIR}/"
rm -fr "${WINEDIR}/files" rm -fr "${WINEDIR}/files"
elif [[ ! -d "${WINEDIR}/files" && -d "${WINEDIR}/dist" ]] ; then elif [[ ! -d "${WINEDIR}/files" && -d "${WINEDIR}/dist" ]] ; then
for clear_dist_files in $(lsbash "$WINEDIR" | sed -r "s/^(dist|version)$//g") ; do for clear_dist_files in $(ls "${WINEDIR}" | sed -r "s/^(dist|version)$//g") ; do
rm -fr "${WINEDIR}/$clear_dist_files" rm -fr "${WINEDIR}/$clear_dist_files"
done done
mv -f "${WINEDIR}/dist"/* "${WINEDIR}/" mv -f "${WINEDIR}/dist"/* "${WINEDIR}/"
rm -fr "${WINEDIR}/dist" rm -fr "${WINEDIR}/dist"
elif [[ -f "${WINEDIR}/proton_dist.tar" ]] ; then elif [[ -f "${WINEDIR}/proton_dist.tar" ]] ; then
unpack "${WINEDIR}/proton_dist.tar" "${WINEDIR}/" unpack "${WINEDIR}/proton_dist.tar" "${WINEDIR}/"
for clear_dist_files in $(lsbash "$WINEDIR" | sed -r "s/^(bin|lib|lib64|share|version)$//g") ; do for clear_dist_files in $(ls "${WINEDIR}" | sed -r "s/^(bin|lib|lib64|share|version)$//g") ; do
rm -fr "${WINEDIR}/$clear_dist_files" rm -fr "${WINEDIR}/$clear_dist_files"
done done
fi fi
@ -1934,7 +1952,7 @@ pw_kill_autostart () {
fi fi
done done
if [[ -n "$(lsbash "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/drive_c/ | grep -m 1 ".tmp")" ]] ; then if [[ -n "$(ls "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/drive_c/ | grep -m 1 ".tmp")" ]] ; then
rm -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/drive_c/*.tmp rm -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/drive_c/*.tmp
fi fi
@ -2025,8 +2043,8 @@ pw_download_libs () {
"${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz" ; then "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz" ; then
if unpack "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz" "${PORT_WINE_TMP_PATH}/" ; then if unpack "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz" "${PORT_WINE_TMP_PATH}/" ; then
try_remove_file "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz" try_remove_file "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz"
if lsbash "${PORT_WINE_TMP_PATH}" --grep libs_v --grep -v libs"${PW_LIBS_VER}" ; then if ls "${PORT_WINE_TMP_PATH}" | grep libs_v | grep -v libs"${PW_LIBS_VER}" ; then
for RM_LIBS in $(lsbash "${PORT_WINE_TMP_PATH}" --grep libs_v --grep -v libs"${PW_LIBS_VER}") for RM_LIBS in $(ls "${PORT_WINE_TMP_PATH}" | grep libs_v | grep -v libs"${PW_LIBS_VER}")
do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_LIBS}" do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_LIBS}"
done done
fi fi
@ -2176,9 +2194,9 @@ pw_check_and_download_plugins () {
try_remove_file "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz" try_remove_file "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz"
# TODO: drop clear prefix, and add update prefix from new plugins # TODO: drop clear prefix, and add update prefix from new plugins
pw_clear_pfx pw_clear_pfx
if lsbash "${PORT_WINE_TMP_PATH}" --grep plugins_v --grep -v "plugins${PW_PLUGINS_VER}" if ls "${PORT_WINE_TMP_PATH}" | grep plugins_v | grep -v "plugins${PW_PLUGINS_VER}"
then then
for RM_PLUGINS in $(lsbash "${PORT_WINE_TMP_PATH}" --grep plugins_v --grep -v "plugins${PW_PLUGINS_VER}") for RM_PLUGINS in $(ls "${PORT_WINE_TMP_PATH}" | grep plugins_v | grep -v "plugins${PW_PLUGINS_VER}")
do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_PLUGINS}" do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_PLUGINS}"
done done
fi fi
@ -2209,9 +2227,9 @@ pw_check_and_download_plugins () {
try_remove_file "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz" try_remove_file "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz"
# TODO: drop clear prefix, and add update prefix from new plugins # TODO: drop clear prefix, and add update prefix from new plugins
pw_clear_pfx pw_clear_pfx
if lsbash "${PORT_WINE_TMP_PATH}" --grep plugins_v --grep -v "plugins${PW_PLUGINS_VER}" if ls "${PORT_WINE_TMP_PATH}" | grep plugins_v | grep -v "plugins${PW_PLUGINS_VER}"
then then
for RM_PLUGINS in $(lsbash "${PORT_WINE_TMP_PATH}" --grep plugins_v --grep -v "plugins${PW_PLUGINS_VER}") for RM_PLUGINS in $(ls "${PORT_WINE_TMP_PATH}" | grep plugins_v | grep -v "plugins${PW_PLUGINS_VER}")
do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_PLUGINS}" do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_PLUGINS}"
done done
fi fi
@ -2338,7 +2356,7 @@ pw_init_db () {
# shellcheck source=/dev/null # shellcheck source=/dev/null
source "${PORTWINE_DB_FILE}" source "${PORTWINE_DB_FILE}"
if echo "${portwine_exe}" | grep "/prefixes/" &>/dev/null ; then if echo "${portwine_exe}" | grep "/prefixes/" &>/dev/null ; then
if [[ -z $(lsbash "${PORT_WINE_PATH}/prefixes/" --grep ^"${PW_PREFIX_NAME}"$) ]] \ if [[ -z $(ls "${PORT_WINE_PATH}/prefixes/" | grep -e ^"${PW_PREFIX_NAME}"$) ]] \
|| [[ -z $(grep -e ^"export PW_PREFIX_NAME=" "${PORTWINE_DB_FILE}" 2>/dev/null) ]] || [[ -z $(grep -e ^"export PW_PREFIX_NAME=" "${PORTWINE_DB_FILE}" 2>/dev/null) ]]
then then
PW_PREFIX_NAME=$(echo "${portwine_exe}" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}') PW_PREFIX_NAME=$(echo "${portwine_exe}" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}')
@ -2378,7 +2396,7 @@ pw_init_db () {
try_copy_file "${PW_FIND_DB_FILE}" "${portwine_exe}".ppdb try_copy_file "${PW_FIND_DB_FILE}" "${portwine_exe}".ppdb
PORTWINE_DB_FILE="${portwine_exe}".ppdb PORTWINE_DB_FILE="${portwine_exe}".ppdb
if echo "${portwine_exe}" | grep "/prefixes/" &>/dev/null ; then if echo "${portwine_exe}" | grep "/prefixes/" &>/dev/null ; then
if [[ -z $(lsbash "${PORT_WINE_PATH}/prefixes/" --grep ^"${PW_PREFIX_NAME}"$) ]] \ if [[ -z $(ls "${PORT_WINE_PATH}/prefixes/" | grep -e ^"${PW_PREFIX_NAME}"$) ]] \
|| [[ -z $(grep -e ^"export PW_PREFIX_NAME=" "${PORTWINE_DB_FILE}" 2>/dev/null) ]] || [[ -z $(grep -e ^"export PW_PREFIX_NAME=" "${PORTWINE_DB_FILE}" 2>/dev/null) ]]
then then
PW_PREFIX_NAME=$(echo "${portwine_exe}" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}') PW_PREFIX_NAME=$(echo "${portwine_exe}" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}')
@ -2427,7 +2445,7 @@ pw_init_db () {
if [[ "${PW_WINE_CPU_TOPOLOGY}" == "disabled" ]] && [[ -n "${WINE_CPU_TOPOLOGY}" ]] ; then if [[ "${PW_WINE_CPU_TOPOLOGY}" == "disabled" ]] && [[ -n "${WINE_CPU_TOPOLOGY}" ]] ; then
export PW_WINE_CPU_TOPOLOGY="${WINE_CPU_TOPOLOGY}" export PW_WINE_CPU_TOPOLOGY="${WINE_CPU_TOPOLOGY}"
fi fi
if lsbash "${PATH_TO_GAME}"/*_Data/Resources/ --grep "unity" &>/dev/null \ if ls "${PATH_TO_GAME}"/*_Data/Resources/ 2>/dev/null | grep "unity" &>/dev/null \
&& [[ "${PW_WINE_CPU_TOPOLOGY}" == "disabled" ]] \ && [[ "${PW_WINE_CPU_TOPOLOGY}" == "disabled" ]] \
&& [[ $(grep -c ^"processor" /proc/cpuinfo) -gt "8" ]] && [[ $(grep -c ^"processor" /proc/cpuinfo) -gt "8" ]]
then then
@ -2886,11 +2904,17 @@ edit_db_from_gui () {
then then
for mod_db in "$@" ; do for mod_db in "$@" ; do
proxy_mod_db="${!mod_db}" proxy_mod_db="${!mod_db}"
if [[ $proxy_mod_db =~ (${translations[Disabled]}|${translations[Disable]}) ]] ; then if (( ${#translations[@]} > 0 )); then
proxy_mod_db=disabled if [[ $proxy_mod_db =~ (${translations[Disabled]}|${translations[Disable]}) ]] ; then
elif [[ $proxy_mod_db =~ (${translations[Enabled]}|${translations[Enable]}) ]] ; then proxy_mod_db=disabled
proxy_mod_db=enabled elif [[ $proxy_mod_db =~ (${translations[Enabled]}|${translations[Enable]}) ]] ; then
proxy_mod_db=enabled
fi
fi fi
# Escaping backslashes and quotes for Windows paths
proxy_mod_db=$(echo "$proxy_mod_db" | sed 's/\\/\\\\\\\\/g; s/"/\\"/g')
if [[ $(<"${PORTWINE_DB_FILE}") =~ export\ ${mod_db}= ]] if [[ $(<"${PORTWINE_DB_FILE}") =~ export\ ${mod_db}= ]]
then sed -i "s|export ${mod_db}=.*|export ${mod_db}=\"$proxy_mod_db\"|g" "${PORTWINE_DB_FILE}" then sed -i "s|export ${mod_db}=.*|export ${mod_db}=\"$proxy_mod_db\"|g" "${PORTWINE_DB_FILE}"
else echo "export ${mod_db}=\"$proxy_mod_db\"" >> "${PORTWINE_DB_FILE}" else echo "export ${mod_db}=\"$proxy_mod_db\"" >> "${PORTWINE_DB_FILE}"
@ -2982,9 +3006,15 @@ pw_create_gui_png () {
edit_db_from_gui PORTPROTON_NAME FILE_DESCRIPTION edit_db_from_gui PORTPROTON_NAME FILE_DESCRIPTION
fi fi
resize_png "$portwine_exe" "${PORTPROTON_NAME}" "128" resize_png "$portwine_exe" "${PORTPROTON_NAME}" "48" "128"
PORTPROTON_NAME_PNG="${PORTPROTON_NAME// /_}" PORTPROTON_NAME_PNG="${PORTPROTON_NAME// /_}"
if [[ $PORTPROTON_NAME_PNG =~ [\!\%\$\&\<] ]] ; then
local ICON_NAME_REGEX=(\! % \$ \& \<)
for i in "${ICON_NAME_REGEX[@]}" ; do
PORTPROTON_NAME_PNG="${PORTPROTON_NAME_PNG//$i/}"
done
fi
if [[ -z "${PW_ICON_FOR_YAD}" ]] ; then if [[ -z "${PW_ICON_FOR_YAD}" ]] ; then
if [[ -n "$(file "${PORT_WINE_PATH}/data/img/${PORTPROTON_NAME_PNG}.png" | grep "${PW_RESIZE_TO} x ${PW_RESIZE_TO}")" ]] ; then if [[ -n "$(file "${PORT_WINE_PATH}/data/img/${PORTPROTON_NAME_PNG}.png" | grep "${PW_RESIZE_TO} x ${PW_RESIZE_TO}")" ]] ; then
export PW_ICON_FOR_YAD="${PORT_WINE_PATH}/data/img/${PORTPROTON_NAME_PNG}.png" export PW_ICON_FOR_YAD="${PORT_WINE_PATH}/data/img/${PORTPROTON_NAME_PNG}.png"
@ -3140,18 +3170,18 @@ start_portwine () {
var_winedlloverride_update "winegstreamer=" var_winedlloverride_update "winegstreamer="
fi fi
check_variables VKD3D_DEBUG none check_variables VKD3D_DEBUG "none"
check_variables VKD3D_SHADER_DEBUG none check_variables VKD3D_SHADER_DEBUG "none"
check_variables DXVK_LOG_LEVEL none check_variables DXVK_LOG_LEVEL "none"
check_variables DXVK_NVAPI_LOG_LEVEL none check_variables DXVK_NVAPI_LOG_LEVEL "none"
check_variables VK_LOADER_DEBUG none check_variables VK_LOADER_DEBUG "none"
check_variables VKBASALT_LOG_LEVEL none check_variables VKBASALT_LOG_LEVEL "none"
if [[ "${PW_LOG}" == 1 ]] \ if [[ "${PW_LOG}" == 1 ]] \
|| [[ -n "$PW_DEBUG" ]] || [[ -n "$PW_DEBUG" ]]
then then
export WINEDEBUG="+loaddll,+gstreamer" check_variables WINEDEBUG "+loaddll"
export WINE_MONO_TRACE="E:System.NotImplementedException" check_variables WINE_MONO_TRACE "E:System.NotImplementedException"
export VKBASALT_LOG_LEVEL="error" check_variables VKBASALT_LOG_LEVEL "error"
else else
export WINEDEBUG="-all" export WINEDEBUG="-all"
unset WINE_MONO_TRACE unset WINE_MONO_TRACE
@ -4368,6 +4398,35 @@ pw_yad_form_vulkan () {
fi fi
} }
steamplay_launch () {
if [[ -n "${portwine_exe:-}" ]]; then
cd "$(dirname "${portwine_exe}")"
export PORTWINE_DB_FILE="${portwine_exe}.ppdb"
[[ -f "${PORTWINE_DB_FILE}" ]] && source "${PORTWINE_DB_FILE}"
PORT_WINE_PREFIX="${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME:-DEFAULT}"
for path in "ProgramData" "users/Public" "users/steamuser"; do
mkdir -p "${PORT_WINE_PREFIX}/drive_c/${path}"
if [[ ! -L "${WINEPREFIX}/drive_c/${path}" ]]; then
mkdir -p "${WINEPREFIX}/drive_c/users/"
rm -rf "${WINEPREFIX}/drive_c/${path}"
ln -sr "${PORT_WINE_PREFIX}/drive_c/${path}" "${WINEPREFIX}/drive_c/${path}"
fi
done
if [[ -n "${PW_DLL_INSTALL:-}" ]] ; then
update_winetricks
PATH="${PATH}:${PW_PLUGINS_PATH}/portable/bin" LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PW_PLUGINS_PATH}/portable/lib/lib64:${PW_PLUGINS_PATH}/portable/lib/lib32" \
"${PORT_WINE_TMP_PATH}/winetricks" -q ${PW_DLL_INSTALL}
fi
[[ $PW_LOG != 1 ]] && debug_timer --start -s "PW_TIME_IN_GAME"
"${STEAM_COMPAT_TOOL_PATHS%%:*}/proton" "run" "${portwine_exe}" "$@"
if [[ $PW_LOG != 1 ]] && [[ -n $START_PW_TIME_IN_GAME ]] ; then
debug_timer --end -s "PW_TIME_IN_GAME"
PW_TIME_IN_GAME=$(( PW_TIME_IN_GAME / 1000 ))
search_desktop_file
fi
fi
}
portwine_launch () { portwine_launch () {
start_portwine start_portwine
unset PW_VD_TMP unset PW_VD_TMP
@ -6074,35 +6133,49 @@ resize_png () {
print_error "no argument specified for resize_png" print_error "no argument specified for resize_png"
return 1 return 1
else else
local RESIZE_FILE="$1" local RESIZE_FILE RESIZE_NAME_PNG resize_to resize_to_helper
local RESIZE_NAME_PNG="${2// /_}" RESIZE_FILE="$1"
local RESIZE_TO="$3" RESIZE_NAME_PNG="${2// /_}"
fi fi
if [[ -f "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}.png" ]] \ for resize_to in "${@:3}" ; do
|| [[ ! -f "${RESIZE_FILE}" ]] \ if [[ $resize_to == 128 ]]
|| [[ ! ${RESIZE_FILE,,} =~ .exe$ ]] then resize_to_helper=""
then else resize_to_helper="_$resize_to"
return 0
fi
try_remove_file "${PORT_WINE_PATH}/data/img/launcher.png"
try_remove_file "${PORT_WINE_PATH}/data/img/Launcher.png"
if check_flatpak ; then
if ! timeout 3 \
exe-thumbnailer --force-resize -s "$RESIZE_TO" "$(readlink -f "${RESIZE_FILE}")" "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}.png" \
&& [[ "$ALPINE_FP" != "1" ]]
then
print_error "exe-thumbnailer - broken!"
fi fi
else
print_warning "use portable exe-thumbnailer" if [[ $RESIZE_NAME_PNG =~ [\!\%\$\&\<] ]] ; then
env PYTHONPATH="${PW_PLUGINS_PATH}/portable/lib/python3.9/site-packages/" \ local ICON_NAME_REGEX=(\! % \$ \& \<)
LD_LIBRARY_PATH="${PW_PLUGINS_PATH}/portable/lib/lib64" \ for i in "${ICON_NAME_REGEX[@]}" ; do
"${PW_WINELIB}/runtime/files/bin/python3.9" \ RESIZE_NAME_PNG="${RESIZE_NAME_PNG//$i/}"
"${PW_PLUGINS_PATH}/portable/bin/exe-thumbnailer" --force-resize -s "$RESIZE_TO" "$(readlink -f "${RESIZE_FILE}")" "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}.png" done
fi fi
return 0
if [[ -f "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}${resize_to_helper}.png" ]] \
|| [[ ! -f "${RESIZE_FILE}" ]] \
|| [[ ! ${RESIZE_FILE,,} =~ .exe$ ]]
then
return 0
fi
try_remove_file "${PORT_WINE_PATH}/data/img/launcher.png"
try_remove_file "${PORT_WINE_PATH}/data/img/Launcher.png"
if check_flatpak ; then
if ! timeout 3 \
exe-thumbnailer --force-resize -s "$resize_to" "$(readlink -f "${RESIZE_FILE}")" "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}${resize_to_helper}.png" \
&& [[ "$ALPINE_FP" != "1" ]]
then
print_error "exe-thumbnailer - broken!"
fi
else
print_warning "use portable exe-thumbnailer"
env PYTHONPATH="${PW_PLUGINS_PATH}/portable/lib/python3.9/site-packages/" \
LD_LIBRARY_PATH="${PW_PLUGINS_PATH}/portable/lib/lib64" \
"${PW_WINELIB}/runtime/files/bin/python3.9" \
"${PW_PLUGINS_PATH}/portable/bin/exe-thumbnailer" --force-resize -s "$resize_to" "$(readlink -f "${RESIZE_FILE}")" "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}${resize_to_helper}.png"
fi
done
} }
# GUI CREATE SHORTCUT # GUI CREATE SHORTCUT
@ -6122,6 +6195,12 @@ portwine_create_shortcut () {
export name_desktop="$PW_NAME_DESKTOP_PROXY" export name_desktop="$PW_NAME_DESKTOP_PROXY"
[[ -z "${name_desktop_png}" ]] && name_desktop_png="${PORTPROTON_NAME// /_}" [[ -z "${name_desktop_png}" ]] && name_desktop_png="${PORTPROTON_NAME// /_}"
if [[ $name_desktop_png =~ [\!\%\$\&\<] ]] ; then
local ICON_NAME_REGEX=(\! % \$ \& \<)
for i in "${ICON_NAME_REGEX[@]}" ; do
name_desktop_png="${name_desktop_png//$i/}"
done
fi
OUTPUT=$("${pw_yad}" --title="${translations[Choices]}" --form \ OUTPUT=$("${pw_yad}" --title="${translations[Choices]}" --form \
--gui-type="settings-shortcut" \ --gui-type="settings-shortcut" \
@ -6168,7 +6247,7 @@ portwine_output_yad_shortcut () {
echo "Path=${PORT_SCRIPTS_PATH}/" echo "Path=${PORT_SCRIPTS_PATH}/"
echo "Icon=${PORT_WINE_PATH}/data/img/${name_desktop_png}.png" echo "Icon=${PORT_WINE_PATH}/data/img/${name_desktop_png}.png"
} >> "${PORT_WINE_PATH}/${name_desktop}.desktop" } >> "${PORT_WINE_PATH}/${name_desktop}.desktop"
chmod u+x "${PORT_WINE_PATH}/${name_desktop}.desktop" chmod +x "${PORT_WINE_PATH}/${name_desktop}.desktop"
if [[ "${PW_SHORTCUT_MENU}" == "TRUE" ]] ; then if [[ "${PW_SHORTCUT_MENU}" == "TRUE" ]] ; then
try_remove_file "${HOME}/.local/share/applications/${name_desktop}.desktop" try_remove_file "${HOME}/.local/share/applications/${name_desktop}.desktop"
@ -6287,7 +6366,7 @@ pw_auto_create_shortcut () {
print_info "Created link for: $link_name" print_info "Created link for: $link_name"
PORTPROTON_NAME="$link_name" PORTPROTON_NAME="$link_name"
export portwine_exe="$exe_path" export portwine_exe="$exe_path"
resize_png "$portwine_exe" "${PORTPROTON_NAME}" "128" resize_png "$portwine_exe" "${PORTPROTON_NAME}" "48" "128"
export PW_NO_RESTART_PPDB=1 export PW_NO_RESTART_PPDB=1
portwine_create_shortcut portwine_create_shortcut
fi fi
@ -6308,7 +6387,18 @@ portwine_change_shortcut () {
then PW_SHORTCUT_DESKTOP="TRUE" then PW_SHORTCUT_DESKTOP="TRUE"
else PW_SHORTCUT_DESKTOP="FALSE" else PW_SHORTCUT_DESKTOP="FALSE"
fi fi
PW_SHORTCUT_STEAM="FALSE" if [[ -n $PW_DELETE_STEAM ]]; then
source "${PORT_SCRIPTS_PATH}/add_in_steam.sh"
NOSTSHPATH="${PW_DELETE_SHORTCUT_STEAM[0]//#@_@#/ }"
NOSTAIDGRID=$(getAppId "${NOSTSHPATH}")
if [[ -n "${NOSTSHPATH}" ]] && [[ -n "${NOSTAIDGRID}" ]]; then
PW_SHORTCUT_STEAM="TRUE"
else
PW_SHORTCUT_STEAM="FALSE"
fi
else
PW_SHORTCUT_STEAM="FALSE"
fi
unset name_desktop unset name_desktop
create_name_desktop create_name_desktop
@ -6316,6 +6406,12 @@ portwine_change_shortcut () {
pw_create_gui_png pw_create_gui_png
[[ -z "${name_desktop_png}" ]] && name_desktop_png="${PORTPROTON_NAME// /_}" [[ -z "${name_desktop_png}" ]] && name_desktop_png="${PORTPROTON_NAME// /_}"
if [[ $name_desktop_png =~ [\!\%\$\&\<] ]] ; then
local ICON_NAME_REGEX=(\! % \$ \& \<)
for i in "${ICON_NAME_REGEX[@]}" ; do
name_desktop_png="${name_desktop_png//$i/}"
done
fi
OUTPUT=$("${pw_yad}" --title="${translations[Choices]}" --form \ OUTPUT=$("${pw_yad}" --title="${translations[Choices]}" --form \
--gui-type="settings-shortcut" \ --gui-type="settings-shortcut" \
@ -6334,6 +6430,7 @@ portwine_change_shortcut () {
PORTWINE_CHANGE_SHORTCUT=1 PORTWINE_CHANGE_SHORTCUT=1
if [[ $PW_YAD_OUT == 1 ]] ; then if [[ $PW_YAD_OUT == 1 ]] ; then
[[ "$PW_GUI_START" == "NOTEBOOK" ]] && unset PW_YAD_FORM_TAB [[ "$PW_GUI_START" == "NOTEBOOK" ]] && unset PW_YAD_FORM_TAB
PW_SHORTCUT_STEAM="FALSE"
portwine_delete_shortcut portwine_delete_shortcut
restart_pp restart_pp
fi fi
@ -6341,24 +6438,29 @@ portwine_change_shortcut () {
} }
portwine_search_shortcut () { portwine_search_shortcut () {
unset PW_DELETE_SHORTCUT_MENU PW_DELETE_SHORTCUT_DESKTOP unset PW_DELETE_SHORTCUT_MENU PW_DELETE_SHORTCUT_STEAM PW_DELETE_SHORTCUT_DESKTOP
PW_DELETE_MENU="$(grep -il "${portwine_exe}" "${HOME}/.local/share/applications"/*.desktop 2>/dev/null)" if [[ -n "${portwine_exe}" ]]; then
read -r -d '' -a PW_DELETE_SHORTCUT_MENU <<< "${PW_DELETE_SHORTCUT_MENU[*]} ${PW_DELETE_MENU// /#@_@#}" PW_DELETE_MENU="$(grep -il "${portwine_exe}" "${HOME}/.local/share/applications"/*.desktop 2>/dev/null)"
read -r -d '' -a PW_DELETE_SHORTCUT_MENU <<< "${PW_DELETE_SHORTCUT_MENU[*]} ${PW_DELETE_MENU// /#@_@#}"
PW_DELETE_PP="$(grep -il "${portwine_exe}" "${PORT_WINE_PATH}"/*.desktop 2>/dev/null)" PW_DELETE_PP="$(grep -il "${portwine_exe}" "${PORT_WINE_PATH}"/*.desktop 2>/dev/null)"
read -r -d '' -a PW_DELETE_SHORTCUT_MENU <<< "${PW_DELETE_SHORTCUT_MENU[*]} ${PW_DELETE_PP// /#@_@#}" read -r -d '' -a PW_DELETE_SHORTCUT_MENU <<< "${PW_DELETE_SHORTCUT_MENU[*]} ${PW_DELETE_PP// /#@_@#}"
if [[ -d "${HOME}/Desktop" ]] ; then PW_DELETE_STEAM="$(grep -il "${portwine_exe}" "${STEAM_SCRIPTS}"/*.sh 2>/dev/null)"
PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Desktop"/*.desktop 2>/dev/null)" read -r -d '' -a PW_DELETE_SHORTCUT_STEAM <<< "${PW_DELETE_SHORTCUT_STEAM[*]} ${PW_DELETE_STEAM// /#@_@#}"
read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}"
fi if [[ -d "${HOME}/Desktop" ]] ; then
if [[ -d "${HOME}/Рабочий стол" ]] ; then PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Desktop"/*.desktop 2>/dev/null)"
PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Рабочий стол"/*.desktop 2>/dev/null)" read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}"
read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}" fi
fi if [[ -d "${HOME}/Рабочий стол" ]] ; then
if [[ $(xdg-user-dir DESKTOP) ]] ; then PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Рабочий стол"/*.desktop 2>/dev/null)"
PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "$(xdg-user-dir DESKTOP)"/*.desktop 2>/dev/null)" read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}"
read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}" fi
if [[ $(xdg-user-dir DESKTOP) ]] ; then
PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "$(xdg-user-dir DESKTOP)"/*.desktop 2>/dev/null)"
read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}"
fi
fi fi
} }
@ -6371,6 +6473,11 @@ portwine_delete_shortcut () {
for delete_shortcut in "${PW_DELETE_SHORTCUT_MENU[@]}" "${PW_DELETE_SHORTCUT_DESKTOP[@]}" ; do for delete_shortcut in "${PW_DELETE_SHORTCUT_MENU[@]}" "${PW_DELETE_SHORTCUT_DESKTOP[@]}" ; do
rm -f "${delete_shortcut//#@_@#/ }" rm -f "${delete_shortcut//#@_@#/ }"
done done
if [[ "${PW_SHORTCUT_STEAM}" == "FALSE" ]] && [[ -n "${NOSTSHPATH}" ]] && [[ -n "${NOSTAIDGRID}" ]]; then
source "${PORT_SCRIPTS_PATH}/add_in_steam.sh"
removeNonSteamGame "${NOSTAIDGRID}" "${NOSTSHPATH}"
fi
} }
portwine_missing_shortcut () { portwine_missing_shortcut () {
@ -6965,7 +7072,7 @@ gui_edit_db_file () {
} }
gui_open_scripts_from_backup () { gui_open_scripts_from_backup () {
cd "${PORT_WINE_TMP_PATH}/scripts_backup/" || fatal [[ -d "${PORT_WINE_TMP_PATH}/scripts_backup/" ]] && cd "${PORT_WINE_TMP_PATH}/scripts_backup/" || cd "$HOME"
PW_SCRIPT_FROM_BACKUP=$("${pw_yad}" --file --width=650 --height=500 \ PW_SCRIPT_FROM_BACKUP=$("${pw_yad}" --file --width=650 --height=500 \
--window-icon="$PW_GUI_ICON_PATH/portproton.svg" --title "SCRIPTS FROM BACKUP" --file-filter="backup_scripts|scripts_v*.tar.gz" 2>/dev/null ) --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --title "SCRIPTS FROM BACKUP" --file-filter="backup_scripts|scripts_v*.tar.gz" 2>/dev/null )
YAD_STATUS="$?" YAD_STATUS="$?"

@ -3,16 +3,18 @@
#HogwartsLegacy.exe #HogwartsLegacy.exe
#Rating=1-5 #Rating=1-5
#####################examples########################### #####################examples###########################
if [[ "$LANGUAGE" == "ru" ]] ; then if [[ $(cat /proc/cpuinfo | grep umip) ]] ; then
export PW_COMMENT_DB="Если у вас игра не запускается, то необходимо добавить if [[ "$LANGUAGE" == "ru" ]] ; then
export PW_COMMENT_DB="Если у вас игра не запускается, то необходимо добавить
clearcpuid=514 в раздел GRUB_CMDLINE_LINUX_DEFAULT clearcpuid=514 в раздел GRUB_CMDLINE_LINUX_DEFAULT
в файле /etc/default/grub. Для упрощения можно использовать в файле /etc/default/grub. Для упрощения можно использовать
утилиту Grub Customizer" утилиту Grub Customizer"
else else
export PW_COMMENT_DB="If your game does not start, you need to add export PW_COMMENT_DB="If your game does not start, you need to add
clearcpuid=514 to the GRUB_CMDLINE_LINUX_DEFAULT section clearcpuid=514 to the GRUB_CMDLINE_LINUX_DEFAULT section
in the /etc/default/grub file. To simplify things, you can use in the /etc/default/grub file. To simplify things, you can use
Grub Customizer utility" Grub Customizer utility"
fi
fi fi
export PW_VULKAN_USE="2" export PW_VULKAN_USE="2"

@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Author: chal55rus
# type: games
# name: Fractured Online (ENG)
# image: fracturedonline
# info_en: Fractured Online is the first open-world sandbox MMORPG mixing action combat with fully interactable environments, appealing equally to lovers of competitive and cooperative gameplay. Jump right into the fray from day one. Defeat your enemies through your own skill and cleverness, not equipment or level. Gather resources, craft, trade and venture into legendary travels as a solitary hero, or start a settlement with your guild and grow it into the next empire.
# info_ru: Fractured Online — это первая массовая многопользовательская ролевая онлайн-игра с открытым миром, сочетающая динамичные сражения с полностью интерактивным окружением. Она одинаково понравится любителям соревновательного и кооперативного игрового процесса. С самого первого дня погрузитесь в бой. Побеждайте врагов благодаря собственным навыкам и смекалке, а не снаряжению или уровню. Собирайте ресурсы, создавайте предметы, торгуйте и отправляйтесь в легендарные путешествия в одиночку или создайте поселение со своей гильдией и превратите его в следующую империю.
########################################################################
export PW_PREFIX_NAME="FRACTURED_ONLINE"
export LAUNCH_PARAMETERS="/S"
export PW_AUTOINSTALL_EXE="${PW_USER_TEMP}/fractured-online-setup.exe"
export PORTWINE_CREATE_SHORTCUT_NAME="Fractured Online"
start_portwine
if try_download "https://assets.fracturedmmo.com/clients/3f990010d1afb2cabadc44c6c849116c/fractured-online-setup.exe" "${PW_AUTOINSTALL_EXE}" no_mirror
then
pw_start_progress_bar_install_game "Fractured Online."
pw_run "${PW_AUTOINSTALL_EXE}"
portwine_exe="$WINEPREFIX/drive_c/Program Files/Fractured Online/FracturedOnline.exe"
try_remove_file "${PW_AUTOINSTALL_EXE}"
try_remove_file "${portwine_exe}.ppdb"
kill_portwine
pw_stop_progress_bar
portwine_create_shortcut
fi
stop_portwine

@ -0,0 +1,25 @@
#!/usr/bin/env bash
# Author: chal55rus
# type: games
# name: Last Chaos
# image: lastchaos
# info_en: Last Chaos is a classic MMORPG with six classes, castle sieges, a Korean grind and kilometers of dungeons. The confrontation between Apollo and Eres is gaining momentum, so hurry up to take one of the sides.
# info_ru: Last Chaos классическая MMORPG с шестью классами, осадами замков, корейским гриндом и километрами подземелий. Противостояние Апполона и Эреса набирает обороты, так что спешите принять одну из сторон.
########################################################################
export PW_PREFIX_NAME="LAST_CHAOS"
export PW_AUTOINSTALL_EXE="${PW_USER_TEMP}/Last Chaos.zip"
export PORTWINE_CREATE_SHORTCUT_NAME="Last Chaos"
start_portwine
if try_download "https://last-chaos.ru/download/Last%20Chaos.zip" "${PW_AUTOINSTALL_EXE}" no_mirror
then
pw_start_progress_bar_install_game "Last Chaos."
"$pw_7z" x -y "${PW_AUTOINSTALL_EXE}" -o"${WINEPREFIX}/drive_c/Program Files/"
portwine_exe="${WINEPREFIX}/drive_c/Program Files/Last Chaos/LC.exe"
try_remove_file "${PW_AUTOINSTALL_EXE}"
try_remove_file "${portwine_exe}.ppdb"
kill_portwine
pw_stop_progress_bar
portwine_create_shortcut
fi
stop_portwine

@ -6,6 +6,11 @@ export url_site="https://linux-gaming.ru/portproton/"
export url_cloud="https://cloud.linux-gaming.ru/portproton" export url_cloud="https://cloud.linux-gaming.ru/portproton"
export url_git="https://git.linux-gaming.ru/CastroFidel/PortWINE" export url_git="https://git.linux-gaming.ru/CastroFidel/PortWINE"
######################################################################## ########################################################################
if [[ "${START_FROM_FLATPAK:-0}" == 1 ]] && [[ -z "${STEAM_COMPAT_DATA_PATH:-}" ]] && command -v "flatpak" &>/dev/null; then
unset START_FROM_FLATPAK
flatpak run ru.linux_gaming.PortProton "$@"
exit
fi
echo ' echo '
█░░ █ █▄░█ █░█ ▀▄▀ ▄▄ █▀▀ ▄▀█ █▀▄▀█ █ █▄░█ █▀▀ ░ █▀█ █░█ █░░ █ █▄░█ █░█ ▀▄▀ ▄▄ █▀▀ ▄▀█ █▀▄▀█ █ █▄░█ █▀▀ ░ █▀█ █░█
█▄▄ █ █░▀█ █▄█ █░█ ░░ █▄█ █▀█ █░▀░█ █ █░▀█ █▄█ ▄ █▀▄ █▄█ █▄▄ █ █░▀█ █▄█ █░█ ░░ █▄█ █▀█ █░▀░█ █ █░▀█ █▄█ ▄ █▀▄ █▄█
@ -96,7 +101,7 @@ fi
unset MANGOHUD MANGOHUD_DLSYM PW_NO_ESYNC PW_NO_FSYNC PW_VULKAN_USE WINEDLLOVERRIDES PW_NO_WRITE_WATCH PW_YAD_SET PW_ICON_FOR_YAD unset MANGOHUD MANGOHUD_DLSYM PW_NO_ESYNC PW_NO_FSYNC PW_VULKAN_USE WINEDLLOVERRIDES PW_NO_WRITE_WATCH PW_YAD_SET PW_ICON_FOR_YAD
unset PW_CHECK_AUTOINSTALL PW_VKBASALT_EFFECTS PW_VKBASALT_FFX_CAS PORTWINE_DB PORTWINE_DB_FILE RADV_PERFTEST unset PW_CHECK_AUTOINSTALL PW_VKBASALT_EFFECTS PW_VKBASALT_FFX_CAS PORTWINE_DB PORTWINE_DB_FILE RADV_PERFTEST
unset CHK_SYMLINK_FILE PW_MESA_GL_VERSION_OVERRIDE PW_VKD3D_FEATURE_LEVEL PATH_TO_GAME PW_START_DEBUG PORTPROTON_NAME PW_PATH unset CHK_SYMLINK_FILE PW_MESA_GL_VERSION_OVERRIDE PW_VKD3D_FEATURE_LEVEL PATH_TO_GAME PW_START_DEBUG PORTPROTON_NAME PW_PATH
unset PW_PREFIX_NAME WINEPREFIX VULKAN_MOD PW_WINE_VER PW_ADD_TO_ARGS_IN_RUNTIME PW_GAMEMODERUN_SLR PW_WINE_CPU_TOPOLOGY unset PW_PREFIX_NAME VULKAN_MOD PW_WINE_VER PW_ADD_TO_ARGS_IN_RUNTIME PW_GAMEMODERUN_SLR PW_WINE_CPU_TOPOLOGY
unset MANGOHUD_CONFIG FPS_LIMIT PW_WINE_USE WINEDLLPATH WINE WINEDIR WINELOADER WINESERVER PW_USE_RUNTIME PORTWINE_CREATE_SHORTCUT_NAME MIRROR unset MANGOHUD_CONFIG FPS_LIMIT PW_WINE_USE WINEDLLPATH WINE WINEDIR WINELOADER WINESERVER PW_USE_RUNTIME PORTWINE_CREATE_SHORTCUT_NAME MIRROR
unset PW_LOCALE_SELECT PW_SETTINGS_INDICATION PW_GUI_START PW_AUTOINSTALL_EXE NOSTSTDIR RADV_DEBUG PW_NO_AUTO_CREATE_SHORTCUT unset PW_LOCALE_SELECT PW_SETTINGS_INDICATION PW_GUI_START PW_AUTOINSTALL_EXE NOSTSTDIR RADV_DEBUG PW_NO_AUTO_CREATE_SHORTCUT
unset PW_TERM PW_EXEC_FROM_DESKTOP WEBKIT_DISABLE_DMABUF_RENDERER PW_AMD_VULKAN_USE PW_VK_ICD_FILENAMES LAUNCH_URI unset PW_TERM PW_EXEC_FROM_DESKTOP WEBKIT_DISABLE_DMABUF_RENDERER PW_AMD_VULKAN_USE PW_VK_ICD_FILENAMES LAUNCH_URI
@ -115,15 +120,14 @@ echo "" > "${PW_TMPFS_PATH}/tmp_yad_form"
echo "" > "${PW_TMPFS_PATH}/tmp_yad_form_vulkan" echo "" > "${PW_TMPFS_PATH}/tmp_yad_form_vulkan"
create_new_dir "${PORT_WINE_PATH}/data/dist" create_new_dir "${PORT_WINE_PATH}/data/dist"
pushd "${PORT_WINE_PATH}/data/dist/" 1>/dev/null || fatal IFS=$'\n'
for dist_dir in ./* ; do for dist_dir in $(ls -1 "${PORT_WINE_PATH}/data/dist") ; do
[[ -d "$dist_dir" ]] || continue dist_dir_new=$(echo "${dist_dir}" | awk '$1=$1' | sed -e s/[[:blank:]]/_/g)
dist_dir_new="${dist_dir//[[:blank:]]/_}"
if [[ ! -d "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}" ]] ; then if [[ ! -d "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}" ]] ; then
mv -- "${PORT_WINE_PATH}/data/dist/$dist_dir" "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}" mv -- "${PORT_WINE_PATH}/data/dist/$dist_dir" "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}"
fi fi
done done
popd 1>/dev/null || fatal IFS="$orig_IFS"
create_new_dir "${PORT_WINE_PATH}/data/prefixes/DEFAULT" create_new_dir "${PORT_WINE_PATH}/data/prefixes/DEFAULT"
create_new_dir "${PORT_WINE_PATH}/data/prefixes/DOTNET" create_new_dir "${PORT_WINE_PATH}/data/prefixes/DOTNET"
@ -163,7 +167,10 @@ export PW_WINELIB="${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}"
try_remove_dir "${PW_WINELIB}/var" try_remove_dir "${PW_WINELIB}/var"
install_ver="$(<"${PORT_WINE_TMP_PATH}/PortProton_ver")" install_ver="$(<"${PORT_WINE_TMP_PATH}/PortProton_ver")"
export install_ver export install_ver
scripts_install_ver="$(<"${PORT_WINE_TMP_PATH}/scripts_ver")" if [[ -f "${PORT_WINE_TMP_PATH}/scripts_ver" ]]
then scripts_install_ver="$(<"${PORT_WINE_TMP_PATH}/scripts_ver")"
else scripts_install_ver="2025"
fi
export scripts_install_ver export scripts_install_ver
export WINETRICKS_DOWNLOADER="curl" export WINETRICKS_DOWNLOADER="curl"
export USER_CONF="${PORT_WINE_PATH}/data/user.conf" export USER_CONF="${PORT_WINE_PATH}/data/user.conf"
@ -191,6 +198,12 @@ if [[ $TRANSLATIONS_VER != "$scripts_install_ver" ]] ; then
source "$PW_CACHE_LANG_PATH/$LANGUAGE" source "$PW_CACHE_LANG_PATH/$LANGUAGE"
fi fi
if [[ -n "${STEAM_COMPAT_DATA_PATH:-}" ]]; then
steamplay_launch "${@:2}"
exit
fi
unset WINEPREFIX
# check PortProton theme # check PortProton theme
if [[ -n "$GUI_THEME" ]] \ if [[ -n "$GUI_THEME" ]] \
&& [[ -f "$PW_GUI_THEMES_PATH/$GUI_THEME.pptheme" ]] && [[ -f "$PW_GUI_THEMES_PATH/$GUI_THEME.pptheme" ]]
@ -645,6 +658,12 @@ else
fi fi
[[ $line1 =~ ^Icon= ]] && PW_ICON_PATH["$AMOUNT_GENERATE_BUTTONS"]=${line1//Icon=/} [[ $line1 =~ ^Icon= ]] && PW_ICON_PATH["$AMOUNT_GENERATE_BUTTONS"]=${line1//Icon=/}
done < "$desktop_file" done < "$desktop_file"
if fix_icon_name_png "${PW_ICON_PATH["$AMOUNT_GENERATE_BUTTONS"]}" "$desktop_file" ; then
ICON_NAME_REGEX=(\! % \$ \& \<)
for i in "${ICON_NAME_REGEX[@]}" ; do
PW_ICON_PATH["$AMOUNT_GENERATE_BUTTONS"]="${PW_ICON_PATH["$AMOUNT_GENERATE_BUTTONS"]//$i/}"
done
fi
PW_ALL_DF["$AMOUNT_GENERATE_BUTTONS"]="$desktop_file_new" PW_ALL_DF["$AMOUNT_GENERATE_BUTTONS"]="$desktop_file_new"
# Для конвертации существующих .desktop файлов flatpak в натив и наоборот # Для конвертации существующих .desktop файлов flatpak в натив и наоборот
if [[ ${PW_NAME_D_ICON["$AMOUNT_GENERATE_BUTTONS"]} =~ ^"Exec=flatpak run ru.linux_gaming.PortProton " ]] ; then if [[ ${PW_NAME_D_ICON["$AMOUNT_GENERATE_BUTTONS"]} =~ ^"Exec=flatpak run ru.linux_gaming.PortProton " ]] ; then
@ -702,20 +721,6 @@ else
for dp in "${PW_AMOUNT_NEW_DESKTOP[@]}" "${PW_AMOUNT_OLD_DESKTOP[@]}" ; do for dp in "${PW_AMOUNT_NEW_DESKTOP[@]}" "${PW_AMOUNT_OLD_DESKTOP[@]}" ; do
PW_DESKTOP_FILES="${PW_ALL_DF[$dp]}" PW_DESKTOP_FILES="${PW_ALL_DF[$dp]}"
PW_DESKTOP_FILES_SHOW="$PW_DESKTOP_FILES" PW_DESKTOP_FILES_SHOW="$PW_DESKTOP_FILES"
PW_ICON_PATH[dp]=${PW_ICON_PATH[dp]%.png}
PW_NAME_D_ICON_NEW="${PW_NAME_D_ICON[dp]//\"/}"
PW_NAME_D_ICON_128="${PW_ICON_PATH[dp]}"
resize_png "$PW_NAME_D_ICON_NEW" "${PW_NAME_D_ICON_128//"${PORT_WINE_PATH}/data/img/"/}" "128"
if [[ $PW_DESKTOP_FILES =~ [\!\%\$\&\<] || ${PW_ICON_PATH[dp]} =~ [\!\%\$\&\<] ]] ; then
PW_DESKTOP_FILES_SHOW_REGEX=(\! % \$ \& \<)
for i in "${PW_DESKTOP_FILES_SHOW_REGEX[@]}" ; do
PW_DESKTOP_FILES_SHOW="${PW_DESKTOP_FILES_SHOW//$i/}"
PW_ICON_PATH[dp]="${PW_ICON_PATH[dp]//$i/}"
done
fi
PW_NAME_D_ICON_48="${PW_ICON_PATH[dp]}_48"
resize_png "$PW_NAME_D_ICON_NEW" "${PW_NAME_D_ICON_48//"${PORT_WINE_PATH}/data/img/"/}" "48"
if [[ $PW_DESKTOP_FILES =~ [\(\)\!\$\%\&\`\'\"\>\<\\\|\;] ]] ; then if [[ $PW_DESKTOP_FILES =~ [\(\)\!\$\%\&\`\'\"\>\<\\\|\;] ]] ; then
PW_DESKTOP_FILES_REGEX=(\( \) \! \$ % \& \` \' \" \> \< \\ \| \;) PW_DESKTOP_FILES_REGEX=(\( \) \! \$ % \& \` \' \" \> \< \\ \| \;)
@ -726,7 +731,19 @@ else
done done
fi fi
PW_GENERATE_BUTTONS+="--field= $(print_wrapped "${PW_DESKTOP_FILES_SHOW//".desktop"/""}" "25" "...")!${PW_NAME_D_ICON_48}.png!:FBTNR%@bash -c \"button_click --desktop "${PW_DESKTOP_FILES// /#@_@#}"\"%" if [[ $PW_DESKTOP_FILES_SHOW =~ [\!\%\$\&\<] ]] ; then
PW_DESKTOP_FILES_SHOW_REGEX=(\! % \$ \& \<)
for i in "${PW_DESKTOP_FILES_SHOW_REGEX[@]}" ; do
PW_DESKTOP_FILES_SHOW="${PW_DESKTOP_FILES_SHOW//$i/}"
done
fi
PW_ICON_PATH[dp]=${PW_ICON_PATH[dp]%.png}
PW_NAME_D_ICON_NEW="${PW_NAME_D_ICON[dp]//\"/}"
resize_png "$PW_NAME_D_ICON_NEW" "${PW_ICON_PATH[dp]//"${PORT_WINE_PATH}/data/img/"/}" "48" "128"
PW_GENERATE_BUTTONS+="--field= $(print_wrapped "${PW_DESKTOP_FILES_SHOW//".desktop"/""}" "25" "...")!${PW_ICON_PATH[dp]}_48.png!:FBTNR%@bash -c \"button_click --desktop "${PW_DESKTOP_FILES// /#@_@#}"\"%"
done done
if [[ $AMOUNT_GENERATE_BUTTONS == 1 ]] ; then if [[ $AMOUNT_GENERATE_BUTTONS == 1 ]] ; then

@ -4,9 +4,10 @@ credits_devel () { echo "
Boria138 Boria138
Vano Majukin Vano Majukin
Eljeyna Eljeyna
chal55rus minergenon (chal55rus)
SDR SDR
Mels Mels
alex2844
Cefeiko Cefeiko
Dezert1r Dezert1r
Taz_mania Taz_mania

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#Author: Castro-Fidel (linux-gaming.ru) #Author: Castro-Fidel (linux-gaming.ru)
#SCRIPTS_NEXT_VERSION=2385 #SCRIPTS_NEXT_VERSION=2388
#SCRIPTS_STABLE_VERSION=2385 #SCRIPTS_STABLE_VERSION=2388
######################################################################## ########################################################################
export AI_TOP_GAMES="PW_LGC PW_VKPLAY PW_EPIC PW_BATTLE_NET PW_WORLD_OF_SEA_BATTLE PW_RUSSIAN_FISHING PW_HO_YO_PLAY PW_FARLIGHT84 PW_WARFRAME PW_WGC PW_UBISOFT" export AI_TOP_GAMES="PW_LGC PW_VKPLAY PW_EPIC PW_BATTLE_NET PW_WORLD_OF_SEA_BATTLE PW_RUSSIAN_FISHING PW_HO_YO_PLAY PW_FARLIGHT84 PW_WARFRAME PW_WGC PW_UBISOFT"
# export PROTON_USE_XALIA="1" # export PROTON_USE_XALIA="1"
@ -55,9 +55,9 @@ export PW_VULKAN_USE="2"
export VKD3D_LIMIT_TESS_FACTORS="64" export VKD3D_LIMIT_TESS_FACTORS="64"
export DXVK_LEGACY_VER="1.6.1" export DXVK_LEGACY_VER="1.6.1"
export DXVK_STABLE_VER="1.10.3-28" export DXVK_STABLE_VER="1.10.3-28"
export DXVK_GIT_VER="2.5.2-1" export DXVK_GIT_VER="2.5.3-31"
export VKD3D_STABLE_VER="1.1-2602" export VKD3D_STABLE_VER="1.1-2602"
export VKD3D_GIT_VER="1.1-4326" export VKD3D_GIT_VER="1.1-4367"
###VKBASALT### ###VKBASALT###
export PW_VKBASALT_EFFECTS="Curves:cas" export PW_VKBASALT_EFFECTS="Curves:cas"
export PW_VKBASALT_FFX_CAS="0.50" export PW_VKBASALT_FFX_CAS="0.50"