mirror of
https://github.com/SpotX-Official/SpotX-Bash.git
synced 2026-08-09 17:41:07 +10:00
Compare commits
9
Commits
8a2e356e8d
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a68b29fd9d | ||
|
|
307db7769d | ||
|
|
73b74cbd65 | ||
|
|
03207b6117 | ||
|
|
b6df3cdcc5 | ||
|
|
876e4dc0cd | ||
|
|
f4b9f7d20f | ||
|
|
852acb2acb | ||
|
|
7f190c6660 |
@@ -12,7 +12,7 @@
|
||||
<center>
|
||||
<h4 align="center">Adblock for the Spotify desktop client on Linux & macOS</h4>
|
||||
<p align="center">
|
||||
<strong>Latest supported version:</strong> 1.2.94.583.g60394bd5
|
||||
<strong>Latest supported version:</strong> 1.2.95.453.g0eeebbed
|
||||
</p>
|
||||
</center>
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
buildVer="1.2.94.583.g60394bd5"
|
||||
rollbackVer="1.2.93.667.g7b5cc0ce"
|
||||
buildVer="1.2.95.453.g0eeebbed"
|
||||
rollbackVer="1.2.94.583.g60394bd5"
|
||||
|
||||
latestB_X="4881"
|
||||
latestB_A="4872"
|
||||
rollbackB_X="2388"
|
||||
rollbackB_A="2385"
|
||||
latestB_X="3672"
|
||||
latestB_A="3672"
|
||||
rollbackB_X="4881"
|
||||
rollbackB_A="4872"
|
||||
|
||||
clr='\033[0m'
|
||||
green='\033[0;32m'
|
||||
@@ -47,45 +47,45 @@ show_help() {
|
||||
}
|
||||
|
||||
latestA_X=$(printf "%s" \
|
||||
"eyJpc3MiOiJzY2RuLXVybC1zaWduZXIiLCJleHAiOjE3ODY4MDk0ODgsIm5iZiI6" \
|
||||
"MTc4NDIxNzQ4OCwicGF0aCI6Ii91cGdyYWRlL2NsaWVudC9vc3gteDg2XzY0L3Nw" \
|
||||
"b3RpZnktYXV0b3VwZGF0ZS0xLjIuOTQuNTgzLmc2MDM5NGJkNS00ODgxLnRieiJ9" \
|
||||
".kxtysiyM75Sk0uZ2wZjnWnDrf40Hhjw8qUkW_Ott7-aa-Z3BEmRO7px-QDf25Of" \
|
||||
"fox48sICQGMnbTdw-ysa0G3XRqeHqfwnvH_LI4Y2kB2hG-Lv3DHAnVQMY7W9vZR1" \
|
||||
"syDeM94UOe6M6SGNDMquAh0LbbPg-TwNhiXWgGBdCK5BxPTirN0ABK3XYKTfkreK" \
|
||||
"UYVC7MsODGWRRypMmJuO36dUvY8UCmptQ0r_cJVuXTZWmS2FiB1mouKYMXxRBh4v" \
|
||||
"eJvXV8v-gCKePxFTV5wIBBVaioNjlNSUnphKlwoibRswnWVE1tmxDjVsYcl3Wpn-" \
|
||||
"GsP5spgl8Q6hDnWljPFEz1w")
|
||||
"eyJpc3MiOiJzY2RuLXVybC1zaWduZXIiLCJleHAiOjE3ODg1NjYyOTMsIm5iZiI6" \
|
||||
"MTc4NTk3NDI5MywicGF0aCI6Ii91cGdyYWRlL2NsaWVudC9vc3gteDg2XzY0L3Nw" \
|
||||
"b3RpZnktYXV0b3VwZGF0ZS0xLjIuOTUuNDUzLmcwZWVlYmJlZC0zNjcyLnRieiJ9" \
|
||||
".FQBMTRH3659zzbVTZn-IqCqpqBJwyd7h3l33pZ8gYrO-ko8cmdS0w2bxzO46h9n" \
|
||||
"7lV-ES8-aVXyzt0S57c8T3eNGkgz049amd-AgMJrtMSnhpGkmxnrzNwPUtvwWZUd" \
|
||||
"HqH4edpN2WYHqSmclz8Xt82FY2FeKkfzF-pE0RzJEBVdW3ZXqvQcPNtO_0az4LGW" \
|
||||
"qjbA7ZKd404-AGzBqrvJ7G_48XttT8xndYkVT2dTuNypZPoYzFCQ5Oh4I5XudlLB" \
|
||||
"uztQkf9kweo3LLwgfy1k2wlj012Iqiz7WUDofHLzYSTjR_1FA4JDGCAH5E_Uoaa6" \
|
||||
"Nnq-EChcnipD5WLpUon6AWQ")
|
||||
latestA_A=$(printf "%s" \
|
||||
"eyJpc3MiOiJzY2RuLXVybC1zaWduZXIiLCJleHAiOjE3ODY4MDk0ODgsIm5iZiI6" \
|
||||
"MTc4NDIxNzQ4OCwicGF0aCI6Ii91cGdyYWRlL2NsaWVudC9vc3gtYXJtNjQvc3Bv" \
|
||||
"dGlmeS1hdXRvdXBkYXRlLTEuMi45NC41ODMuZzYwMzk0YmQ1LTQ4NzIudGJ6In0." \
|
||||
"dgikJbvCtP540BHTmB-PCnZR7bagMsocETWW64nGYaJiz_dOxNqszB2MkBDPaboQ" \
|
||||
"LJpPtyocB92z-gVpbZeQNTkaK0jYBp4yIzF5RBk6AUMQNmnKkmTaggELxtit0euc" \
|
||||
"bT0_ieDyqTl3tskBo68rrw1ifNnwZVRPsy07dL_RYQrY3meXuQqf8r0KxhqTysgj" \
|
||||
"1pN7OQwO_sAS8WpNpZZ1vIeTMVf9ZQGmqh19Bx6dbCcDgrzTPgG7BrRHtcOa6tXG" \
|
||||
"WbfqVVyKVYSwDNVazIRR4NAjK4n0mfy_7t5r3eVfe04JTITNo0yX_kbybLMReRCh" \
|
||||
"lACVioAhwrvZWfirYjK8jw")
|
||||
"eyJpc3MiOiJzY2RuLXVybC1zaWduZXIiLCJleHAiOjE3ODg1NjYyOTMsIm5iZiI6" \
|
||||
"MTc4NTk3NDI5MywicGF0aCI6Ii91cGdyYWRlL2NsaWVudC9vc3gtYXJtNjQvc3Bv" \
|
||||
"dGlmeS1hdXRvdXBkYXRlLTEuMi45NS40NTMuZzBlZWViYmVkLTM2NzIudGJ6In0." \
|
||||
"fRBIOAjThS9W-m_0EEw7oxd2tpIViU26gBsVdScwrnaT1XtJxhLp28bP26kd6pF4" \
|
||||
"DsFxz5lmb5UogRCMhjdLMVvwUrJlMYR_IDKOkWxiOzFXG-CBEBCbylkm-hT5JG85" \
|
||||
"fy7u5ZtXq-fUiyl5VEchP1vYH8JMZiHHC4i2V1SM9O1ExOeqxNccu_4m29Hh4gFK" \
|
||||
"5qPIMnlD8egTqy_wstsZa7M5sHkmdjsJ4-SXxGy87ONtnbO9UxPOEQYemNOf9Zqq" \
|
||||
"iGRs10px09Mb4Mk-ZnBiLl9jhLrTsVHSnBHr4Alet1D7kcMmxRnFxkBAeUHCaTw3" \
|
||||
"xUtqn8T49yF538bgsKK5kw")
|
||||
rollbackA_X=$(printf "%s" \
|
||||
"eyJpc3MiOiJzY2RuLXVybC1zaWduZXIiLCJleHAiOjE3ODY4MDU4ODQsIm5iZiI6" \
|
||||
"MTc4NDIxMzg4NCwicGF0aCI6Ii91cGdyYWRlL2NsaWVudC9vc3gteDg2XzY0L3Nw" \
|
||||
"b3RpZnktYXV0b3VwZGF0ZS0xLjIuOTMuNjY3Lmc3YjVjYzBjZS0yMzg4LnRieiJ9" \
|
||||
".TImdHMAe0XIJldwwf_pHsz4K-C-dcaYg2cJqrXZovmmB8WRxRCPvYwSJnduwGi8" \
|
||||
"Y-aiEMTqnLul0DF0AquzXFRpu8u1aX9lET64wv9PYdUZ7ijBCskNWIZKL8uyf5WN" \
|
||||
"eJeA2qNMXxdwQtwX2bYwCCcwpq13Fi6iIjSHo5tnexz1vgmujHd-4PW4nfqE6SPV" \
|
||||
"I2gLbvTAmtlgpvFkO8dSPbDEzMb-mGSD2H_qRdfmAbD6bdhyljwHG3ZJeMwGsdc3" \
|
||||
"Vffh-GSjMG5viu3nbEXo6KXj2yzAUg1GOhpNefTPTTXkaGFUqeqi7KtNMQVLkyz7" \
|
||||
"n49X1xTa1tK-50c2Gyv5HPw")
|
||||
"eyJpc3MiOiJzY2RuLXVybC1zaWduZXIiLCJleHAiOjE3ODg0Mzg0ODksIm5iZiI6" \
|
||||
"MTc4NTg0NjQ4OSwicGF0aCI6Ii91cGdyYWRlL2NsaWVudC9vc3gteDg2XzY0L3Nw" \
|
||||
"b3RpZnktYXV0b3VwZGF0ZS0xLjIuOTQuNTgzLmc2MDM5NGJkNS00ODgxLnRieiJ9" \
|
||||
".VjPA-sh1Tjg72unZXmb-Mn-NRL64czXwOMkQzy0IN6gsRaYrwqsIXAMPldiJHgo" \
|
||||
"SSp6HtSBkepcI9bagoM6US0rT9FEDkrjUn03kp4wl0tHxyahfDVFCbAMskc5VCVf" \
|
||||
"yb1LK_GhNX2bvzTz9lLq1tSlNXclQNQB-NH21IfnvUViNF6-eXoTkvPSMNsLNg-n" \
|
||||
"t8kOePUNm1ypOZ4SgJxxUyz4QaIftyvIH-7PEeyrbgIyKYukEB8RbtjjPlH3DfUi" \
|
||||
"lmYMaJKOuDz2dww_r-4nPMIdCABdwyPj7RzZ1Yx5wMGVpAVpbNYg5nqRrTOs2PxO" \
|
||||
"lmmjgMDdLBfx6PKz1eww6Xw")
|
||||
rollbackA_A=$(printf "%s" \
|
||||
"eyJpc3MiOiJzY2RuLXVybC1zaWduZXIiLCJleHAiOjE3ODY4MDU4ODMsIm5iZiI6" \
|
||||
"MTc4NDIxMzg4MywicGF0aCI6Ii91cGdyYWRlL2NsaWVudC9vc3gtYXJtNjQvc3Bv" \
|
||||
"dGlmeS1hdXRvdXBkYXRlLTEuMi45My42NjcuZzdiNWNjMGNlLTIzODUudGJ6In0." \
|
||||
"gzHERnomKyNB7L2bZjz3wOt_W6NoDPk-bHvNQRsWecdinnv1mXchC92ICK8dBJeh" \
|
||||
"W2yfoFb-GaANn1Ky48Eie5FeO_rE0C8Y1u6FJnPbz9qgvFEx_2ebVF3c6cPF5hag" \
|
||||
"i3b3pCjsvWbYVsi4tPIJaJ3S7WX_mmg-KiVeseUFDvEOvdT_Rf_H0YM2hNwGdjhw" \
|
||||
"74y0O2H_a-4jgG2qSSMBByI5ldfdypm_S-GiH7uIajNtHEmxt-XpoeHbbnunKoMy" \
|
||||
"XCpCq1x1j1FYrMfNaWFkJtf7LEY2STMa33lXoIEnkxmW1VwwKkywoLBlsfxFE0a0" \
|
||||
"0wFx8b66ioOoAGY07D8wFg")
|
||||
"eyJpc3MiOiJzY2RuLXVybC1zaWduZXIiLCJleHAiOjE3ODg0Mzg0ODksIm5iZiI6" \
|
||||
"MTc4NTg0NjQ4OSwicGF0aCI6Ii91cGdyYWRlL2NsaWVudC9vc3gtYXJtNjQvc3Bv" \
|
||||
"dGlmeS1hdXRvdXBkYXRlLTEuMi45NC41ODMuZzYwMzk0YmQ1LTQ4NzIudGJ6In0." \
|
||||
"Ch1itbFNAno5o7YDJ_Eh2ZjHuA12PIvkWrBIJmbHAH6AqdUXC2gbD4znygHVWtPn" \
|
||||
"wc74tChZKO_-a79N0v3d26P6_rjPUir3hbtRn09YFzd4Tz4IZXHKY_bGg8YZI4rO" \
|
||||
"0pijbtgVQ1dnLOG90aTROC8jCSpwj4dBmzEBwKgE68J_n5sEJJMxNNHCzpV5P-mC" \
|
||||
"MHQiardZdR1zShvBy6d4CSzcaIiTZFTfeCnnyc8eyV9cY2wf18f4uEDgaZs90KKd" \
|
||||
"J-MpU41Anjpa5yk2SUVsTSHJsKbR4s4vbW25jw2Z5rlfBJsegbxLuNAu00t9Y14R" \
|
||||
"8eXZeGV3NgCrQCddw1sIzA")
|
||||
|
||||
while getopts ':BcdefF:hilopP:SvV:-:' flag; do
|
||||
case "${flag}" in
|
||||
@@ -107,7 +107,7 @@ while getopts ':BcdefF:hilopP:SvV:-:' flag; do
|
||||
noexp) excludeExp='true' ;;
|
||||
oldui) oldUi='true' ;;
|
||||
premium) paidPremium='true' ;;
|
||||
rollback) [[ "${platformType}" == "macOS" ]] && rollback='true'; installMac='true' ;;
|
||||
rollback) [[ "${platformType}" == "macOS" ]] && { rollback='true'; installMac='true'; } ;;
|
||||
skipcodesign) [[ "${platformType}" == "macOS" ]] && skipCodesign='true' ;;
|
||||
stable) [[ "${platformType}" == "Linux" ]] && stableVar='true' ;;
|
||||
uninstall) uninstallSpotx='true' ;;
|
||||
@@ -486,9 +486,22 @@ run_prepare() {
|
||||
}
|
||||
|
||||
check_write_permission() {
|
||||
local target_user="${SUDO_USER:-$(id -un)}"
|
||||
local writePath
|
||||
[[ "${platformType}" == "Linux" && -z "${SPOTX_BUILD_MODE}" ]] && ((EUID == 0)) && {
|
||||
stagedInstall='true'
|
||||
protectedInstall='true'
|
||||
}
|
||||
for path_to_check in "$@"; do
|
||||
[[ ! -w "${path_to_check}" ]] && {
|
||||
[[ -d "${path_to_check}" ]] && writePath="${path_to_check}" || writePath="${path_to_check%/*}"
|
||||
[[ ! -w "${path_to_check}" ]] && stagedInstall='true'
|
||||
[[ ! -w "${writePath}" ]] && {
|
||||
stagedInstall='true'
|
||||
protectedInstall='true'
|
||||
((EUID == 0)) && continue
|
||||
command -v sudo >/dev/null || {
|
||||
echo -e "\n${red}Error:${clr} sudo command not found. Install sudo or run this script as root.\n" >&2
|
||||
exit 1
|
||||
}
|
||||
sudo -n true 2>/dev/null || {
|
||||
echo -e "${yellow}Warning:${clr} SpotX-Bash does not have write permission in client directory.\nRequesting sudo permission..." >&2
|
||||
sudo -v || {
|
||||
@@ -496,17 +509,172 @@ check_write_permission() {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
sudo chown -R "${target_user}" "${path_to_check}"
|
||||
sudo chmod -R u+rwX,go-w "${path_to_check}"
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
sudo_run() {
|
||||
if ((EUID == 0)) || [[ -z "${protectedInstall+x}" ]]; then
|
||||
command "$@"
|
||||
else
|
||||
sudo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
protected_stage_copy() {
|
||||
local source="${1}" destination="${2}"
|
||||
sudo_run cat -- "${source}" > "${destination}" || {
|
||||
rm -f -- "${destination}"
|
||||
return 1
|
||||
}
|
||||
chmod 600 "${destination}"
|
||||
}
|
||||
|
||||
protected_stage_prepare() {
|
||||
targetAppBinary="${appBinary}"
|
||||
targetAppBak="${appBak}"
|
||||
targetXpuiPath="${xpuiPath}"
|
||||
targetXpuiSpa="${xpuiSpa}"
|
||||
targetXpuiBak="${xpuiBak}"
|
||||
linux_working_dir
|
||||
appPath="${workDir}/client"
|
||||
appBinary="${appPath}/spotify"
|
||||
appBak="${appBinary}.bak"
|
||||
xpuiPath="${appPath}/Apps"
|
||||
xpuiBak="${xpuiPath}/xpui.bak"
|
||||
xpuiDir="${xpuiPath}/xpui"
|
||||
xpuiSpa="${xpuiPath}/xpui.spa"
|
||||
dwpPanelSectionJs="${xpuiDir}/dwp-panel-section.js"
|
||||
homeHptoJs="${xpuiDir}/home-hpto.js"
|
||||
homeV2Js="${xpuiDir}/home-v2.js"
|
||||
indexHtml="${xpuiDir}/index.html"
|
||||
vendorXpuiJs="${xpuiDir}/vendor~xpui.js"
|
||||
xpuiCss="${xpuiDir}/xpui.css"
|
||||
xpuiDesktopModalsJs="${xpuiDir}/xpui-desktop-modals.js"
|
||||
xpuiJs="${xpuiDir}/xpui.js"
|
||||
xpuiSnapshotJs="${xpuiDir}/xpui-snapshot.js"
|
||||
mkdir -p "${xpuiPath}" || exit 1
|
||||
protected_stage_copy "${targetAppBinary}" "${appBinary}" || exit 1
|
||||
protected_stage_copy "${targetXpuiSpa}" "${xpuiSpa}" || exit 1
|
||||
[[ -f "${targetAppBak}" ]] && protected_stage_copy "${targetAppBak}" "${appBak}"
|
||||
[[ -f "${targetXpuiBak}" ]] && protected_stage_copy "${targetXpuiBak}" "${xpuiBak}"
|
||||
}
|
||||
|
||||
protected_prepare_file() {
|
||||
local source="${1}" destination="${2}" reference="${3}" tempFile
|
||||
tempFile=$(sudo_run mktemp "${destination}.spotx.XXXXXXXX") || return 1
|
||||
sudo_run cp -a -- "${reference}" "${tempFile}" &&
|
||||
sudo_run cp -- "${source}" "${tempFile}" &&
|
||||
sudo_run chown --reference="${reference}" "${tempFile}" &&
|
||||
sudo_run chmod --reference="${reference}" "${tempFile}" &&
|
||||
sudo_run touch -r "${reference}" "${tempFile}" || {
|
||||
sudo_run rm -f -- "${tempFile}"
|
||||
return 1
|
||||
}
|
||||
printf '%s\n' "${tempFile}"
|
||||
}
|
||||
|
||||
protected_save_destination() {
|
||||
local destination="${1}" tempFile
|
||||
[[ -e "${destination}" ]] || return 0
|
||||
tempFile=$(sudo_run mktemp "${destination}.spotx-rollback.XXXXXXXX") || return 1
|
||||
sudo_run cp -a -- "${destination}" "${tempFile}" || {
|
||||
sudo_run rm -f -- "${tempFile}"
|
||||
return 1
|
||||
}
|
||||
printf '%s\n' "${tempFile}"
|
||||
}
|
||||
|
||||
protected_restore_destination() {
|
||||
local backup="${1}" destination="${2}" existed="${3}"
|
||||
[[ "${existed}" ]] && sudo_run mv -f -- "${backup}" "${destination}" || sudo_run rm -f -- "${destination}"
|
||||
}
|
||||
|
||||
protected_remove_files() {
|
||||
local file
|
||||
for file in "$@"; do
|
||||
[[ -n "${file}" ]] && sudo_run rm -f -- "${file}"
|
||||
done
|
||||
}
|
||||
|
||||
protected_commit() {
|
||||
local uninstall="${1:-}" appFile spaFile appBakFile='' xpuiBakFile=''
|
||||
local appRollback='' spaRollback='' appBakRollback='' xpuiBakRollback=''
|
||||
local appExisted='' spaExisted='' appBakExisted='' xpuiBakExisted=''
|
||||
local appBakReference="${targetAppBinary}" xpuiBakReference="${targetXpuiSpa}"
|
||||
[[ -f "${appBinary}" && -f "${xpuiSpa}" ]] || return 1
|
||||
unzip -tqq "${xpuiSpa}" || return 1
|
||||
appFile=$(protected_prepare_file "${appBinary}" "${targetAppBinary}" "${targetAppBinary}") || return 1
|
||||
spaFile=$(protected_prepare_file "${xpuiSpa}" "${targetXpuiSpa}" "${targetXpuiSpa}") || {
|
||||
sudo_run rm -f -- "${appFile}"
|
||||
return 1
|
||||
}
|
||||
[[ -z "${uninstall}" ]] && {
|
||||
[[ -e "${targetAppBak}" ]] && appBakReference="${targetAppBak}"
|
||||
[[ -e "${targetXpuiBak}" ]] && xpuiBakReference="${targetXpuiBak}"
|
||||
appBakFile=$(protected_prepare_file "${appBak}" "${targetAppBak}" "${appBakReference}") || {
|
||||
sudo_run rm -f -- "${appFile}" "${spaFile}"
|
||||
return 1
|
||||
}
|
||||
xpuiBakFile=$(protected_prepare_file "${xpuiBak}" "${targetXpuiBak}" "${xpuiBakReference}") || {
|
||||
sudo_run rm -f -- "${appFile}" "${spaFile}" "${appBakFile}"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
[[ -e "${targetAppBinary}" ]] && appExisted='true'
|
||||
[[ -e "${targetXpuiSpa}" ]] && spaExisted='true'
|
||||
[[ -e "${targetAppBak}" ]] && appBakExisted='true'
|
||||
[[ -e "${targetXpuiBak}" ]] && xpuiBakExisted='true'
|
||||
{
|
||||
appRollback=$(protected_save_destination "${targetAppBinary}") &&
|
||||
spaRollback=$(protected_save_destination "${targetXpuiSpa}")
|
||||
[[ "${uninstall}" ]] || {
|
||||
appBakRollback=$(protected_save_destination "${targetAppBak}") &&
|
||||
xpuiBakRollback=$(protected_save_destination "${targetXpuiBak}")
|
||||
}
|
||||
} || {
|
||||
protected_remove_files "${appFile}" "${spaFile}" "${appBakFile}" "${xpuiBakFile}"
|
||||
protected_remove_files "${appRollback}" "${spaRollback}" "${appBakRollback}" "${xpuiBakRollback}"
|
||||
return 1
|
||||
}
|
||||
{
|
||||
{ [[ "${uninstall}" ]] || sudo_run mv -f -- "${appBakFile}" "${targetAppBak}"; } &&
|
||||
{ [[ "${uninstall}" ]] || sudo_run mv -f -- "${xpuiBakFile}" "${targetXpuiBak}"; } &&
|
||||
sudo_run mv -f -- "${appFile}" "${targetAppBinary}" &&
|
||||
sudo_run mv -f -- "${spaFile}" "${targetXpuiSpa}"
|
||||
} || {
|
||||
protected_restore_destination "${appRollback}" "${targetAppBinary}" "${appExisted}"
|
||||
protected_restore_destination "${spaRollback}" "${targetXpuiSpa}" "${spaExisted}"
|
||||
[[ "${uninstall}" ]] || protected_restore_destination "${appBakRollback}" "${targetAppBak}" "${appBakExisted}"
|
||||
[[ "${uninstall}" ]] || protected_restore_destination "${xpuiBakRollback}" "${targetXpuiBak}" "${xpuiBakExisted}"
|
||||
protected_remove_files "${appFile}" "${spaFile}" "${appBakFile}" "${xpuiBakFile}"
|
||||
return 1
|
||||
}
|
||||
protected_remove_files "${appRollback}" "${spaRollback}" "${appBakRollback}" "${xpuiBakRollback}"
|
||||
[[ "${uninstall}" ]] && sudo_run rm -f -- "${targetAppBak}" "${targetXpuiBak}"
|
||||
return 0
|
||||
}
|
||||
|
||||
atomic_copy() {
|
||||
local source="${1}" destination="${2}" tempFile result
|
||||
copyTempDir=$(mktemp -d "${destination}.spotx.XXXXXXXX") || return 1
|
||||
tempFile="${copyTempDir}/${destination##*/}"
|
||||
cp "${source}" "${tempFile}" && mv -f "${tempFile}" "${destination}"
|
||||
result=$?
|
||||
rm -rf "${copyTempDir}" 2>/dev/null
|
||||
[[ ! -d "${copyTempDir}" ]] && unset copyTempDir
|
||||
return "${result}"
|
||||
}
|
||||
|
||||
backup_spotx() {
|
||||
atomic_copy "${xpuiSpa}" "${xpuiBak}" && atomic_copy "${appBinary}" "${appBak}" && return 0
|
||||
rm -f "${appBak}" "${xpuiBak}" 2>/dev/null
|
||||
return 1
|
||||
}
|
||||
|
||||
uninstall_spotx() {
|
||||
rm -f "${appBinary}" 2>/dev/null
|
||||
mv -f "${appBak}" "${appBinary}"
|
||||
rm -f "${xpuiSpa}" 2>/dev/null
|
||||
mv -f "${xpuiBak}" "${xpuiSpa}"
|
||||
atomic_copy "${appBak}" "${appBinary}" && atomic_copy "${xpuiBak}" "${xpuiSpa}" || return 1
|
||||
rm -f "${appBak}" "${xpuiBak}" 2>/dev/null
|
||||
rm -rf "${xpuiDir}" 2>/dev/null
|
||||
}
|
||||
|
||||
@@ -517,12 +685,23 @@ run_uninstall_check() {
|
||||
exit 1
|
||||
}
|
||||
check_write_permission "${appPath}" "${appBinary}" "${xpuiPath}" "${xpuiSpa}"
|
||||
[[ "${platformType}" == "Linux" && "${stagedInstall}" ]] && protected_stage_prepare
|
||||
[[ "${cleanAB}" ]] && {
|
||||
echo -e "${yellow}Warning:${clr} SpotX-Bash has detected abnormal behavior.\nClient reinstallation may be required...\n" >&2
|
||||
rm -f "${appBak}" 2>/dev/null
|
||||
rm -f "${xpuiBak}" 2>/dev/null
|
||||
[[ "${platformType}" == "Linux" && "${stagedInstall}" ]] && sudo_run rm -f -- "${targetAppBak}" "${targetXpuiBak}"
|
||||
} || {
|
||||
uninstall_spotx
|
||||
uninstall_spotx || {
|
||||
echo -e "\n${red}Error:${clr} Failed to restore client. Backups were preserved.\n" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "${platformType}" == "Linux" && "${stagedInstall}" ]] && {
|
||||
protected_commit 'true' || {
|
||||
echo -e "\n${red}Error:${clr} Failed to restore client. Original files restored.\n" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
printf "\xE2\x9C\x94\x20\x46\x69\x6E\x69\x73\x68\x65\x64\x20\x75\x6E\x69\x6E\x73\x74\x61\x6C\x6C\n\n"
|
||||
exit 0
|
||||
@@ -584,7 +763,33 @@ sudo_check() {
|
||||
}
|
||||
}
|
||||
|
||||
linux_working_dir() { [[ -d "/tmp" ]] && workDir="/tmp" || workDir="$HOME"; }
|
||||
cleanup_temp_dirs() {
|
||||
[[ -n "${macInstallOld:-}" && -d "${macInstallOld}" && "${macInstallOld%/*}" == "${installPath:-}" && "${macInstallOld##*/}" == .spotx-previous.* ]] && {
|
||||
[[ "${macInstallOldMoved:-}" && -z "${macInstallCommitted:-}" && ! -e "${appPath:-}" ]] && mv -- "${macInstallOld}" "${appPath}"
|
||||
[[ -z "${macInstallOldMoved:-}" && -d "${macInstallOld}" ]] && rm -rf -- "${macInstallOld}"
|
||||
[[ "${macInstallCommitted:-}" && -d "${macInstallOld}" ]] && rm -rf -- "${macInstallOld}"
|
||||
}
|
||||
[[ -n "${macInstallTemp:-}" && -d "${macInstallTemp}" && "${macInstallTemp%/*}" == "${installPath:-}" && "${macInstallTemp##*/}" == .spotx-install.* ]] && rm -rf -- "${macInstallTemp}"
|
||||
[[ -n "${macDownloadPath:-}" && -f "${macDownloadPath}" && "${macDownloadPath%/*}" == "${HOME}/Downloads" && "${macDownloadPath##*/}" == "${fileVar:-}" ]] && rm -f -- "${macDownloadPath}"
|
||||
[[ -n "${workDir:-}" && -d "${workDir}" && "${workDir##*/}" == spotx-bash.* ]] && rm -rf -- "${workDir}"
|
||||
[[ -n "${copyTempDir:-}" && -d "${copyTempDir}" && "${copyTempDir##*/}" == *.spotx.* ]] && rm -rf -- "${copyTempDir}"
|
||||
[[ -n "${spaTempDir:-}" && -d "${spaTempDir}" && "${spaTempDir##*/}" == .spotx-spa.* ]] && rm -rf -- "${spaTempDir}"
|
||||
[[ "${xpuiTempCreated:-}" && -n "${xpuiDir:-}" && -d "${xpuiDir}" && "${xpuiDir##*/}" == "xpui" ]] && rm -rf -- "${xpuiDir}"
|
||||
}
|
||||
|
||||
linux_working_dir() {
|
||||
local tempBase="${TMPDIR:-/tmp}"
|
||||
[[ -n "${workDir:-}" && -d "${workDir}" && "${workDir##*/}" == spotx-bash.* ]] && return
|
||||
[[ "${tempBase}" == /* && -d "${tempBase}" && -w "${tempBase}" ]] || tempBase="/tmp"
|
||||
workDir=$(mktemp -d "${tempBase%/}/spotx-bash.XXXXXXXX") || {
|
||||
echo -e "${red}Error:${clr} Failed to create temporary working directory.\n" >&2
|
||||
exit 1
|
||||
}
|
||||
chmod 700 "${workDir}" || {
|
||||
echo -e "${red}Error:${clr} Failed to secure temporary working directory.\n" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
linux_deb_install() {
|
||||
sudo_check
|
||||
@@ -630,6 +835,7 @@ linux_deb_install() {
|
||||
}
|
||||
|
||||
macos_client_install() {
|
||||
local downloadPath="${HOME}/Downloads/${fileVar}" stagedApp
|
||||
[[ ! -w "${installPath}" ]] && {
|
||||
echo -e "${red}Error:${clr} SpotX-Bash does not have write permission in ${installOutput}.\nConfirm permissions or set custom install path to writable directory.\n" >&2
|
||||
exit 1
|
||||
@@ -648,22 +854,54 @@ macos_client_install() {
|
||||
"alHZyIWeChFT0F0UjRXQDJWeWNTW" \
|
||||
| rev | base64 --decode | base64 --decode)
|
||||
eval "${mc01}"; eval "${mc02}"
|
||||
tar -tf "$HOME/Downloads/${fileVar}" >/dev/null 2>&1 || {
|
||||
rm "$HOME/Downloads/${fileVar}" 2>/dev/null
|
||||
tar -tf "${downloadPath}" >/dev/null 2>&1 || {
|
||||
rm "${downloadPath}" 2>/dev/null
|
||||
echo -e "\n${red}Error:${clr} Downloaded client archive is corrupt or incomplete. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
macDownloadPath="${downloadPath}"
|
||||
printf "\xE2\x9C\x94\x20\x44\x6F\x77\x6E\x6C\x6F\x61\x64\x65\x64\x20\x61\x6E\x64\x20\x69\x6E\x73\x74\x61\x6C\x6C\x69\x6E\x67\x20\x53\x70\x6F\x74\x69\x66\x79\n"
|
||||
rm -rf "${appPath}" 2>/dev/null
|
||||
mkdir -p "${appPath}"
|
||||
tar -xpf "$HOME/Downloads/${fileVar}" -C "${appPath}" && unset notInstalled versionFailed || {
|
||||
rm "$HOME/Downloads/${fileVar}" 2>/dev/null
|
||||
macInstallTemp=$(mktemp -d "${installPath}/.spotx-install.XXXXXXXX") || {
|
||||
rm "${downloadPath}" 2>/dev/null
|
||||
echo -e "\n${red}Error:${clr} Client install failed. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
stagedApp="${macInstallTemp}/Spotify.app"
|
||||
mkdir -p "${stagedApp}" &&
|
||||
tar -xpf "${downloadPath}" -C "${stagedApp}" &&
|
||||
[[ -x "${stagedApp}/Contents/MacOS/Spotify" ]] &&
|
||||
[[ -f "${stagedApp}/Contents/Info.plist" ]] &&
|
||||
[[ -f "${stagedApp}/Contents/Resources/Apps/xpui.spa" ]] || {
|
||||
rm "${downloadPath}" 2>/dev/null
|
||||
echo -e "\n${red}Error:${clr} Client install failed. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ -e "${appPath}" ]] && {
|
||||
macInstallOld=$(mktemp -d "${installPath}/.spotx-previous.XXXXXXXX") || {
|
||||
rm "${downloadPath}" 2>/dev/null
|
||||
echo -e "\n${red}Error:${clr} Client install failed. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
rmdir "${macInstallOld}" && macInstallOldMoved='true' && mv "${appPath}" "${macInstallOld}" || {
|
||||
rm "${downloadPath}" 2>/dev/null
|
||||
echo -e "\n${red}Error:${clr} Client install failed. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
mv "${stagedApp}" "${appPath}" && macInstallCommitted='true' || {
|
||||
[[ -n "${macInstallOld:-}" && -d "${macInstallOld}" && ! -e "${appPath}" ]] && mv "${macInstallOld}" "${appPath}"
|
||||
rm "${downloadPath}" 2>/dev/null
|
||||
echo -e "\n${red}Error:${clr} Client install failed. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
rm -rf "${macInstallTemp}"
|
||||
[[ ! -d "${macInstallTemp}" ]] && unset macInstallTemp
|
||||
[[ -n "${macInstallOld:-}" ]] && rm -rf "${macInstallOld}"
|
||||
[[ -z "${macInstallOld:-}" || ! -d "${macInstallOld}" ]] && unset macInstallOld macInstallOldMoved macInstallCommitted
|
||||
printf "\xE2\x9C\x94\x20\x49\x6E\x73\x74\x61\x6C\x6C\x65\x64\x20\x69\x6E\x20'"${installOutput}"'\n"
|
||||
rm "$HOME/Downloads/${fileVar}"
|
||||
rm "${downloadPath}" && unset macDownloadPath
|
||||
clientVer=$(echo "${fileVar}" | perl -ne '/te-(.*)\..*\./ && print "$1"')
|
||||
unset notInstalled versionFailed
|
||||
}
|
||||
|
||||
run_install_check() {
|
||||
@@ -673,6 +911,20 @@ run_install_check() {
|
||||
}
|
||||
}
|
||||
|
||||
macos_codesign() {
|
||||
/usr/bin/xattr -cr "${appPath}" 2>/dev/null || {
|
||||
echo -e "\n${red}Error:${clr} Failed to clear Spotify security attributes. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "${skipCodesign}" ]] && return
|
||||
codesign -f --deep -s - "${appPath}" >/dev/null 2>&1 &&
|
||||
codesign --verify --deep --strict "${appPath}" >/dev/null 2>&1 || {
|
||||
echo -e "\n${red}Error:${clr} Failed to codesign Spotify. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
printf "\xE2\x9C\x94\x20\x43\x6F\x64\x65\x73\x69\x67\x6E\x65\x64\x20\x53\x70\x6F\x74\x69\x66\x79\n"
|
||||
}
|
||||
|
||||
run_cache_check() {
|
||||
[[ "${clearCache}" ]] && {
|
||||
[[ -n "${cachePath}" && -d "${cachePath}" ]] && {
|
||||
@@ -688,6 +940,7 @@ run_cache_check() {
|
||||
|
||||
final_setup_check() {
|
||||
[[ "${notInstalled}" ]] && { echo -e "${red}Error:${clr} Client not found\n" >&2; exit 1; }
|
||||
[[ ! -f "${appBinary}" || ! -s "${appBinary}" || ! -r "${appBinary}" || ! -x "${appBinary}" ]] && { echo -e "${red}Error:${clr} Client executable not found or invalid.\nReinstall client then try again.\n" >&2; exit 1; }
|
||||
[[ ! -f "${xpuiSpa}" ]] && { echo -e "${red}Error:${clr} Detected a modified client installation!\nReinstall client then try again.\n" >&2; exit 1; }
|
||||
[[ "${clientVer}" ]] && (($(ver "${clientVer}") < $(ver "1.1.59.710"))) && { echo -e "${red}Error:${clr} ${clientVer} not supported by SpotX-Bash\n" >&2; exit 1; }
|
||||
}
|
||||
@@ -696,42 +949,51 @@ perlVar() {
|
||||
local A=("$@")
|
||||
for cmd in "${A[@]}"; do
|
||||
IFS='&' read -r -a a <<< "${cmd}"
|
||||
local f="${a[4]}"
|
||||
local p="${!f}"
|
||||
[[ ! -f "${p}" && "${debug}" && "${devMode}" && "${t}" ]] && {
|
||||
echo -e "${red}Error:${clr} ${a[0]} invalid entry"
|
||||
continue
|
||||
}
|
||||
{ { [[ -z "${a[5]}" ]] || (( $(ver "${clientVer}") >= $(ver "${a[5]}") )); } &&
|
||||
{ [[ -z "${a[6]}" ]] || (( $(ver "${clientVer}") <= $(ver "${a[6]}") )); } &&
|
||||
{ [[ -z "${a[7]}" ]] || [[ "${a[7]}" =~ (^|\|)"${platformType}"($|\|) ]]; } &&
|
||||
{ [[ -z "${a[8]}" ]] || [[ "${a[8]}" =~ (^|\|)"${archVar}"($|\|) ]]; }
|
||||
} && perlvar "${xpuiSpa}"
|
||||
} || continue
|
||||
local f="${a[4]}"
|
||||
local p="${!f}"
|
||||
[[ ! -f "${p}" ]] && {
|
||||
[[ "${debug}" && "${devMode}" && "${t}" ]] && echo -e "${red}Error:${clr} ${a[0]} invalid entry"
|
||||
continue
|
||||
}
|
||||
perlvar "${xpuiSpa}"
|
||||
done
|
||||
}
|
||||
|
||||
xpui_detect() {
|
||||
[[ (-f "${appBak}" || -f "${xpuiBak}") && "${cleanAB}" ]] && {
|
||||
rm -f "${appBak}" 2>/dev/null; rm -f "${xpuiBak}" 2>/dev/null
|
||||
cp "${xpuiSpa}" "${xpuiBak}"; cp "${appBinary}" "${appBak}"
|
||||
backup_spotx || {
|
||||
echo -e "\n${red}Error:${clr} Failed to create client backup. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
printf "\xE2\x9C\x94\x20\x43\x72\x65\x61\x74\x65\x64\x20\x62\x61\x63\x6B\x75\x70\n"
|
||||
return
|
||||
}
|
||||
[[ (-f "${appBak}" || -f "${xpuiBak}") && "${forceSpotx}" ]] && {
|
||||
[[ -f "${appBak}" ]] && { rm -f "${appBinary}"; cp "${appBak}" "${appBinary}"; }
|
||||
[[ -f "${xpuiBak}" ]] && { rm -f "${xpuiSpa}"; cp "${xpuiBak}" "${xpuiSpa}"; }
|
||||
{ [[ ! -f "${appBak}" ]] || atomic_copy "${appBak}" "${appBinary}"; } &&
|
||||
{ [[ ! -f "${xpuiBak}" ]] || atomic_copy "${xpuiBak}" "${xpuiSpa}"; } || {
|
||||
echo -e "\n${red}Error:${clr} Failed to restore client backup. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
printf "\xE2\x9C\x94\x20\x44\x65\x74\x65\x63\x74\x65\x64\x20\x26\x20\x72\x65\x73\x74\x6F\x72\x65\x64\x20\x62\x61\x63\x6B\x75\x70\n"
|
||||
return
|
||||
}
|
||||
[[ (-f "${appBak}" || -f "${xpuiBak}") && -z "${forceSpotx+x}" ]] && {
|
||||
rm -rf "${xpuiDir}" 2>/dev/null
|
||||
xpuiSkip='true'
|
||||
printf "\xE2\x9C\x94\x20\x44\x65\x74\x65\x63\x74\x65\x64\x20\x62\x61\x63\x6B\x75\x70\n"
|
||||
echo -e "\n${yellow}Warning:${clr} SpotX-Bash has already been installed." >&2
|
||||
echo -e "Use the '-f' flag to force SpotX-Bash to run.\n" >&2
|
||||
return
|
||||
}
|
||||
cp "${xpuiSpa}" "${xpuiBak}"
|
||||
cp "${appBinary}" "${appBak}"
|
||||
backup_spotx || {
|
||||
echo -e "\n${red}Error:${clr} Failed to create client backup. Exiting...\n" >&2
|
||||
exit 1
|
||||
}
|
||||
printf "\xE2\x9C\x94\x20\x43\x72\x65\x61\x74\x65\x64\x20\x62\x61\x63\x6B\x75\x70\n"
|
||||
}
|
||||
|
||||
@@ -788,7 +1050,9 @@ snapshot_check() {
|
||||
}
|
||||
|
||||
xpui_open() {
|
||||
rm -rf "${xpuiDir}" 2>/dev/null
|
||||
mkdir -p "${xpuiDir}"
|
||||
xpuiTempCreated='true'
|
||||
unzip -qq "${xpuiSpa}" -d "${xpuiDir}" || {
|
||||
rm -rf "${xpuiDir}" 2>/dev/null
|
||||
echo -e "\n${red}Error:${clr} Failed to unpack xpui.spa. Reinstall client. Exiting...\n" >&2
|
||||
@@ -826,6 +1090,7 @@ xpui_open() {
|
||||
run_core_start() {
|
||||
final_setup_check
|
||||
check_write_permission "${appPath}" "${appBinary}" "${xpuiPath}" "${xpuiSpa}"
|
||||
[[ "${platformType}" == "Linux" && "${stagedInstall}" ]] && protected_stage_prepare
|
||||
xpui_detect
|
||||
[[ "${xpuiSkip}" ]] && { printf "\xE2\x9C\x94\x20\x46\x69\x6E\x69\x73\x68\x65\x64\n\n"; exit 0; }
|
||||
xpui_open
|
||||
@@ -882,20 +1147,40 @@ run_patches() {
|
||||
}
|
||||
|
||||
run_finish() {
|
||||
local spaTemp
|
||||
echo -e "\n//# SpotX was here" >> "${xpuiJs}"
|
||||
rm -f "${xpuiSpa}"
|
||||
(cd "${xpuiDir}" && zip -qq -r ../xpui.spa .) || {
|
||||
echo -e "\n${red}Error:${clr} Failed to repackage client." >&2
|
||||
echo -e "Spotify is now in a broken state. Please reinstall client.\n" >&2
|
||||
spaTempDir=$(mktemp -d "${xpuiPath}/.spotx-spa.XXXXXXXX") || {
|
||||
uninstall_spotx && \
|
||||
echo -e "\n${red}Error:${clr} Failed to create temporary SPA directory. Original client restored.\n" >&2 || \
|
||||
echo -e "\n${red}Error:${clr} Failed to create temporary SPA directory or restore client. Backups were preserved.\n" >&2
|
||||
exit 1
|
||||
}
|
||||
rm -rf "${xpuiDir}"
|
||||
[[ "${platformType}" == "macOS" ]] && {
|
||||
[[ "${skipCodesign}" ]] && /usr/bin/xattr -cr "${appPath}" 2>/dev/null || {
|
||||
/usr/bin/xattr -cr "${appPath}" 2>/dev/null
|
||||
codesign -f --deep -s - "${appPath}" 2>/dev/null
|
||||
printf "\xE2\x9C\x94\x20\x43\x6F\x64\x65\x73\x69\x67\x6E\x65\x64\x20\x53\x70\x6F\x74\x69\x66\x79\n"
|
||||
spaTemp="${spaTempDir}/xpui.spa"
|
||||
(cd "${xpuiDir}" && zip -qq -r "${spaTemp}" .) &&
|
||||
unzip -tqq "${spaTemp}" &&
|
||||
mv -f "${spaTemp}" "${xpuiSpa}" || {
|
||||
rm -rf "${spaTempDir}" 2>/dev/null
|
||||
uninstall_spotx && {
|
||||
echo -e "\n${red}Error:${clr} Failed to repackage client." >&2
|
||||
echo -e "Original client restored.\n" >&2
|
||||
} || {
|
||||
echo -e "\n${red}Error:${clr} Failed to repackage or restore client." >&2
|
||||
echo -e "Backups were preserved.\n" >&2
|
||||
}
|
||||
exit 1
|
||||
}
|
||||
rm -rf "${spaTempDir}" 2>/dev/null
|
||||
[[ ! -d "${spaTempDir}" ]] && unset spaTempDir
|
||||
rm -rf "${xpuiDir}"
|
||||
unset xpuiTempCreated
|
||||
[[ "${platformType}" == "Linux" && "${stagedInstall}" ]] && protected_commit || {
|
||||
[[ "${platformType}" == "Linux" && "${stagedInstall}" ]] && {
|
||||
echo -e "\n${red}Error:${clr} Failed to install patched client. Original files restored.\n" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
[[ "${platformType}" == "macOS" ]] && {
|
||||
macos_codesign
|
||||
}
|
||||
}
|
||||
|
||||
@@ -927,7 +1212,7 @@ freeEx=(
|
||||
'hideDlQual&(\(.,..jsxs\)\(.{1,3}|(.\(\).|..)createElement\(.{1,4}),\{(filterMatchQuery|filter:.,title|(variant:"viola",semanticColor:"textSubdued"|..:"span",variant:.{3,6}mesto,color:.{3,6}),htmlFor:"desktop.settings.downloadQuality.+?).{1,6}get\("desktop.settings.downloadQuality.title.+?(children:.{1,2}\(.,.\).+?,|\(.,.\){3,4},|,.\)}},.\(.,.\)\),)&&&xpuiJs&1.1.59.710&1.2.29.605'
|
||||
'hideUpgradeButton&(return|.=.=>)"free"===(.+?)(return|.=.=>)"premium"===&$1"premium"===$2$3"free"===&g&xpuiJs&1.1.59.710&1.1.92.647'
|
||||
'hideUpgradeButton2&(?|(===")free(")|(")free("===))&$1premium$2&g&xpuiJs&1.2.55.235'
|
||||
'hptoEnabled&hptoEnabled:!\K0&1&s&xpuiJs'
|
||||
'hptoEnabled&hptoEnabled:!\K0&1&s&xpuiJs&&1.2.94.583'
|
||||
'hptoShown&isHptoShown:!\K0&1&gs&homeHptoJs&1.1.85.884&1.2.20.1218'
|
||||
'hptoShown2&(ADS_PREMIUM,isPremium:)\w(.*?ADS_HPTO_HIDDEN,isHptoHidden:)\w&$1true$2true&&xpuiJs&1.2.21.1104'
|
||||
'payloadS&\x3F\x70\x61\x79\x6C\x6F\x61\x64&\x00\x00\x00\x00\x00\x00\x00\x00&gs&appBinary&1.2.53.437&1.2.93.667'
|
||||
@@ -950,8 +1235,8 @@ newUiEx=(
|
||||
'enableNavAltExperiment&Enable the new home structure and navigation",values:.,default:\K..DISABLED&true&&xpuiJs&1.1.94.864&1.1.96.785'
|
||||
'enableNavAltExperiment2&Enable the new home structure and navigation",values:.,default:.\K.DISABLED&.ENABLED_CENTER&&xpuiJs&1.1.97.956&1.2.2.582'
|
||||
'enablePanelSizeCoordination&Enable Panel Size Coordination between the left sidebar, the main view and the right sidebar",default:\K!.(?=})&true&s&xpuiJs&1.2.7.1264&1.2.50.335'
|
||||
'enableRightSidebar&Enable the view on the right sidebar",default:\K!1&true&s&xpuiJs&1.1.98.683&1.2.23.1125&1.2.93.667'
|
||||
'enableRightSidebarLyrics&Show lyrics in the right sidebar",default:\K!1&true&s&xpuiJs&1.2.0.1165'
|
||||
'enableRightSidebar&Enable the view on the right sidebar",default:\K!1&true&s&xpuiJs&1.1.98.683&1.2.93.667'
|
||||
'enableRightSidebarLyrics&Show lyrics in the right sidebar",default:\K!1&true&s&xpuiJs&1.2.0.1165&1.2.94.583'
|
||||
'enableYLXSidebar&Enable Your Library X view of the left sidebar",default:\K!1&true&s&xpuiJs&1.1.97.962&1.2.13.661'
|
||||
)
|
||||
podEx=(
|
||||
@@ -967,7 +1252,7 @@ lyricsBgEx=(
|
||||
)
|
||||
aoEx=(
|
||||
'aboutSpotX&((..createElement|children:\(.{1,7}\))\(.{1,7},\{source:).{1,7}get\("about.copyright",.\),paragraphClassName:("[^"]+"|.)(?=\}\))&$1"<h3>About SpotX / SpotX-Bash</h3><br><details><summary><svg xmlns='\''http://www.w3.org/2000/svg'\'' width='\''20'\'' height='\''20'\'' viewBox='\''0 0 24 24'\''><path d='\''M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z'\'' fill='\''#fff'\''/></svg> Github</summary><a href='\''https://github.com/SpotX-Official/SpotX'\''>SpotX \(Windows\)</a><br><a href='\''https://github.com/SpotX-Official/SpotX-Bash'\''>SpotX-Bash \(Linux/macOS\)</a><br><br/></details><details><summary><svg xmlns='\''http://www.w3.org/2000/svg'\'' width='\''20'\'' height='\''20'\'' viewBox='\''0 0 24 24'\''><path id='\''telegram-1'\'' d='\''M18.384,22.779c0.322,0.228 0.737,0.285 1.107,0.145c0.37,-0.141 0.642,-0.457 0.724,-0.84c0.869,-4.084 2.977,-14.421 3.768,-18.136c0.06,-0.28 -0.04,-0.571 -0.26,-0.758c-0.22,-0.187 -0.525,-0.241 -0.797,-0.14c-4.193,1.552 -17.106,6.397 -22.384,8.35c-0.335,0.124 -0.553,0.446 -0.542,0.799c0.012,0.354 0.25,0.661 0.593,0.764c2.367,0.708 5.474,1.693 5.474,1.693c0,0 1.452,4.385 2.209,6.615c0.095,0.28 0.314,0.5 0.603,0.576c0.288,0.075 0.596,-0.004 0.811,-0.207c1.216,-1.148 3.096,-2.923 3.096,-2.923c0,0 3.572,2.619 5.598,4.062Zm-11.01,-8.677l1.679,5.538l0.373,-3.507c0,0 6.487,-5.851 10.185,-9.186c0.108,-0.098 0.123,-0.262 0.033,-0.377c-0.089,-0.115 -0.253,-0.142 -0.376,-0.064c-4.286,2.737 -11.894,7.596 -11.894,7.596Z'\'' fill='\''#fff'\''/></svg> Telegram</summary><a href='\''https://t.me/spotify_windows_mod'\''>SpotX Channel</a><br><a href='\''https://t.me/SpotxCommunity'\''>SpotX Community</a><br><br/></details><details><summary><svg xmlns='\''http://www.w3.org/2000/svg'\'' width='\''20'\'' height='\''20'\'' viewBox='\''0 0 24 24'\''><path d='\''M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm1.25 17c0 .69-.559 1.25-1.25 1.25-.689 0-1.25-.56-1.25-1.25s.561-1.25 1.25-1.25c.691 0 1.25.56 1.25 1.25zm1.393-9.998c-.608-.616-1.515-.955-2.551-.955-2.18 0-3.59 1.55-3.59 3.95h2.011c0-1.486.829-2.013 1.538-2.013.634 0 1.307.421 1.364 1.226.062.847-.39 1.277-.962 1.821-1.412 1.343-1.438 1.993-1.432 3.468h2.005c-.013-.664.03-1.203.935-2.178.677-.73 1.519-1.638 1.536-3.022.011-.924-.284-1.719-.854-2.297z'\'' fill='\''#fff'\''/></svg> FAQ</summary><a href='\''https://te.legra.ph/SpotX-FAQ-09-19'\''>Windows</a><br><a href='\''https://github.com/SpotX-Official/SpotX-Bash/wiki/SpotX%E2%80%90Bash-FAQ'\''>Linux/macOS</a></details><br><h4>DISCLAIMER</h4>SpotX is a modified version of the official Spotify\x26reg; client, provided \x26quot;as is\x26quot; for the purpose of evaluation at user'\''s own risk. Source code for SpotX is available separately and free of charge under open source software license agreements. SpotX is not affiliated with Spotify\x26reg;, Spotify AB or Spotify Group.<br><br>Spotify\x26reg; is a registered trademark of Spotify Group."&&xpuiDesktopModalsJs&1.1.79.763'
|
||||
'allowSwitchingBetweenHomeAdsAndHpto&opposed to only showing the legacy HPTO format.",default:\K!.(?=})&false&s&xpuiJs&1.2.34.783'
|
||||
'allowSwitchingBetweenHomeAdsAndHpto&opposed to only showing the legacy HPTO format.",default:\K!.(?=})&false&s&xpuiJs&1.2.34.783&1.2.94.583'
|
||||
'betamaxFilterNegativeDuration&for duration that is negative",default:\K!.(?=})&false&s&xpuiJs&1.1.59.001&1.2.93.667'
|
||||
'bGabo&\x00\K\x67(?=\x61\x62\x6F\x2D\x72\x65\x63\x65\x69\x76\x65\x72\x2D\x73\x65\x72\x76\x69\x63\x65\x2F\x70)&\x00&g&appBinary&1.1.84.716'
|
||||
'bLogic&\x00\K\x61(?=\x64\x2D\x6C\x6F\x67\x69\x63\x2F\x73)&\x00&&appBinary&1.1.70.610&1.2.28.581'
|
||||
@@ -998,11 +1283,13 @@ aoEx=(
|
||||
'enableFraudLoadSignals&Enable user fraud signals emitted on page load",default:\K!.(?=})&false&s&xpuiJs&1.2.22.975&1.2.62.580'
|
||||
'enableHomeAds&Enable Fist Impression Takeover ads on Home Page",default:\K!.(?=})&false&s&xpuiJs&1.2.31.1205&1.2.84.477'
|
||||
'enableHomeAdStaticBanner&Enables temporary home banner, static version",default:\K!.(?=})&false&s&xpuiJs&1.2.25.1009&1.2.53.440'
|
||||
'enableHpto&Hpto announcements on Home",default:\K!.(?=})&false&s&xpuiJs&1.2.65.255'
|
||||
'enableHpto&Hpto announcements on Home",default:\K!.(?=})&false&s&xpuiJs&1.2.65.255&1.2.94.583'
|
||||
'enableHptoLayoutRewrite&Enable the new HomeAdCard flexbox layout rewrite",default:\K!.(?=})&false&s&xpuiJs&1.2.92.0'
|
||||
'enableHptoLocationRefactor&Enable new permanent location for HPTO iframe to HptoHtml.js",default:\K!.(?=})&false&s&xpuiJs&1.2.1.958&1.2.20.1218'
|
||||
'enableImageOptimizationSentrySpanMeasurement&Sentry image resource span attributes for image optimization rollout measurement",default:\K!.(?=})&false&s&xpuiJs&1.2.94.0'
|
||||
'enableInAppMessaging&Enables quicksilver in-app messaging modal",default:\K!.(?=})&false&s&xpuiJs&1.1.70.610'
|
||||
'enableInteractionLogger&Enables the old interaction logger",default:\K!.(?=})&false&s&xpuiJs&1.2.41.434&1.2.64.408'
|
||||
'enableLeaderboardEmptySlotHandling&Config for clearing the current leaderboard ad and hiding the leaderboard container when the ad slot returns an empty response",default:\K!.(?=})&true&s&xpuiJs&1.2.95.200'
|
||||
'enableLeavebehindsMockData&Use the mock endpoint to fetch Leavebehinds from AP4P",default:\K!.(?=})&false&s&xpuiJs&1.2.30.1135'
|
||||
'enableNewAdsNpv&Enable showing new ads NPV",default:\K!.(?=})&false&s&xpuiJs&1.2.18.997&1.2.50.335'
|
||||
'enableNewAdsNpvCanvasAds&Enable Canvas ads for new ads NPV",default:\K!.(?=})&false&s&xpuiJs&1.2.28.581&1.2.51.345'
|
||||
@@ -1015,8 +1302,10 @@ aoEx=(
|
||||
'enablePodcastSponsoredContent&Enable sponsored content information for podcasts",default:\K!.(?=})&false&s&xpuiJs&1.2.30.1135&1.2.50.335'
|
||||
'enablePromotions&Enables promotions on home",default:\K!.(?=})&false&s&xpuiJs&1.2.38.720&1.2.45.454'
|
||||
'enableSaxLeaderboardAds&Enable SAX Leaderboard Ad Format",default:\K!.(?=})&false&s&xpuiJs&1.2.62.575&1.2.82.428'
|
||||
'enableSentryReactRouterV6Routing&Sentry React Router v6 route instrumentation for Web Player SPA transactions",default:\K!.(?=})&false&s&xpuiJs&1.2.94.0'
|
||||
'enableShowLeavebehindConsolidation&Enable show leavebehinds consolidated experience",default:\K!.(?=})&false&s&xpuiJs&1.2.23.1114&1.2.93.667'
|
||||
'enableSponsoredPlaylistEsperantoMigration&Enable esperanto Migration for Sponsored Playlist Ad Formats",default:\K!.(?=})&false&s&xpuiJs&1.2.32.985&1.2.50.335'
|
||||
'enableSponsoredPlaylistHorizontalVideo&horizontal video layout for sponsored playlist headers on desktop",default:\K!.(?=})&false&s&xpuiJs&1.2.95.200'
|
||||
'enableSurveyAds&Enable Spotify Brand Lift .SBL. Surveys in the NPV",default:\K!.(?=})&false&s&xpuiJs&1.2.43.420&1.2.63.394'
|
||||
'enableUnderAgeBlockingModal&Enables the underage blocking modal for accounts in blocked/pending disabled state",default:\K!.(?=})&false&s&xpuiJs&1.2.78.397'
|
||||
'enableUserFraudCanvas&Enable user fraud Canvas Fingerprinting",default:\K!.(?=})&false&s&xpuiJs&1.2.13.656&1.2.63.394'
|
||||
@@ -1093,6 +1382,7 @@ expEx=(
|
||||
'enableEightShortcuts&Increase max number of shortcuts on home to 8",default:\K!1&true&s&xpuiJs&1.2.26.1180&1.2.45.454'
|
||||
'enableEncoreCards&all cards throughout app to be Encore Cards",default:\K!1&true&s&xpuiJs&1.2.21.1104&1.2.33.1042'
|
||||
'enableEncorePlaybackButtons&Use Encore components in playback control components",default:\K!1&true&s&xpuiJs&1.2.20.1210&1.2.43.420'
|
||||
'enableEntityHeaderNew&Enable the new entity header design",default:\K!.(?=})&true&s&xpuiJs&1.2.95.200'
|
||||
'enableEqualizer&audio equalizer for Desktop and Web Player",default:\K!1&true&s&xpuiJs&1.1.88.595'
|
||||
'enableExcludeTrackFromTasteProfile&option to exclude track from taste profile via context menu",default:\K!1&true&s&xpuiJs&1.2.73.451'
|
||||
'enableExtraTracklistColumns&extra tracklist columns",default:\K!1&true&s&xpuiJs&1.2.44.405&1.2.71.421'
|
||||
@@ -1121,7 +1411,7 @@ expEx=(
|
||||
'enableMoreLikeThisPlaylist&More Like This playlist for playlists the user cannot edit",default:\K!1&true&s&xpuiJs&1.2.32.985&1.2.73.474'
|
||||
'enableNearbyJams&support for Nearby Jams feature in the Device Picker",default:\K!1&true&s&xpuiJs&1.2.52.442'
|
||||
'enableNewArtistEventsPage&Display the new Artist events page",default:\K!1&true&s&xpuiJs&1.2.18.997&1.2.32.997'
|
||||
'enableNewConcertFeed&Enables new concert feed experience",default:\K!1&true&s&xpuiJs&1.2.37.701&1.2.42.290&1.2.50.335'
|
||||
'enableNewConcertFeed&Enables new concert feed experience",default:\K!1&true&s&xpuiJs&1.2.37.701&1.2.50.335'
|
||||
'enableNewConcertLocationExperience&new concert location experience modal selector.",default:\K!1&true&s&xpuiJs&1.2.34.783&1.2.42.290'
|
||||
'enableNewEntityHeaders&New Entity Headers",default:\K!1&true&s&xpuiJs&1.2.15.826&1.2.28.0'
|
||||
'enableNewEpisodes&new episodes view",default:\K!1&true&s&xpuiJs&1.1.84.716&1.2.62.580'
|
||||
@@ -1144,13 +1434,14 @@ expEx=(
|
||||
'enablePlaybackBarAnimation&animation of the playback bar",default:\K!1&true&s&xpuiJs&1.2.34.783&1.2.82.428'
|
||||
'enablePlaylistCreationFlow&new playlist creation flow in Web Player and DesktopX",default:\K!1&true&s&xpuiJs&1.1.70.610&1.1.93.896'
|
||||
'enablePlaylistPermissionsProd&Playlist Permissions flows for Prod",default:\K!.(?=})&true&s&xpuiJs&1.1.75.572&1.2.50.335'
|
||||
'enablePlaylistReleaseDateColumn&Enables the release date column in playlist tracklists",default:\K!.(?=})&true&s&xpuiJs&1.2.95.200'
|
||||
'enablePodcastChaptersInNpv&showing podcast chapters in NPV",default:\K!.(?=})&true&s&xpuiJs&1.2.22.975&1.2.50.335'
|
||||
'enablePodcastChapterPage&the podcast chapter entity page",default:\K!.(?=})&true&s&xpuiJs&1.2.85.504&1.2.93.667'
|
||||
'enablePodcastDescriptionAutomaticLinkification&Linkifies anything looking like a url in a podcast description.",default:\K!1&true&s&xpuiJs&1.2.19.937'
|
||||
'enablePremiumUserForMiniPlayer&premium user flag for mini player",default:\K!1&true&s&xpuiJs&1.2.32.985'
|
||||
'enablePrereleaseRadar&Show a curated list of upcoming albums to a user",default:\K!1&true&s&xpuiJs&1.2.39.578&1.2.45.454'
|
||||
'enableProfileVisibilityControls&profile visibility controls in the settings . profile page",default:\K!1&true&s&xpuiJs&1.2.74.462&1.2.85.519'
|
||||
'enableProgressBarEpisodeChapters&pisode chapters markers in the progress bar",default:\K!1&true&s&xpuiJs&1.2.68.525&1.2.74&1.2.74.477'
|
||||
'enableProgressBarEpisodeChapters&pisode chapters markers in the progress bar",default:\K!1&true&s&xpuiJs&1.2.68.525&1.2.74.477'
|
||||
'enableProgressBarRefactorWithChapters&refactored ProgressBar implementation with chapter support",default:\K!1&true&s&xpuiJs&1.2.74.462&1.2.82.428'
|
||||
'enableQueueOnRightPanel&Enable Queue on the right panel.",default:\K!.(?=})&true&s&xpuiJs&1.2.26.1180&1.2.61.443'
|
||||
'enableQueueOnRightPanelAnimations&animations for Queue on the right panel.",default:\K!.(?=})&true&s&xpuiJs&1.2.32.985&1.2.50.335'
|
||||
@@ -1190,6 +1481,7 @@ expEx=(
|
||||
'enableTiltable3DArtwork&tiltable 3D parallax effect on artwork .Cinema Mode and Cover Art Modal.",default:\K!1&true&s&xpuiJs&1.2.76.256'
|
||||
'enableTogglePlaylistColumns&ability to toggle playlist column visibility",default:\K!1&true&s&xpuiJs&1.2.17.832&1.2.66.447'
|
||||
'enableTracklistColumnsSorting&column reordering functionality in tracklists",default:\K!1&true&s&xpuiJs&1.2.69.448'
|
||||
'enableTranscriptTextSelection&text selection and copy in episode transcripts on desktop",default:\K!.(?=})&true&s&xpuiJs&1.2.95.200'
|
||||
'enableUserCommentsForEpisodes&user comments for podcast episodes",default:\K!1&true&s&xpuiJs&1.2.49.439'
|
||||
'enableUserCreatedArtwork&user created artworks for playlists",default:\K!1&true&s&xpuiJs&1.2.34.783&1.2.40.599'
|
||||
'enableUserProfileEdit&editing of user.s own profile in Web Player and DesktopX",default:\K!1&true&s&xpuiJs&1.1.87.612&1.2.25.1011'
|
||||
@@ -1208,7 +1500,7 @@ expEx=(
|
||||
'enableYLXPrereleaseAlbums&album pre-releases in YLX",default:\K!1&true&s&xpuiJs&1.2.32.985'
|
||||
'enableYLXPrereleaseAudiobooks&audiobook pre-releases in YLX",default:\K!1&true&s&xpuiJs&1.2.32.985&1.2.47.366'
|
||||
'enableYLXPrereleases&album pre-releases in YLX",default:\K!1&true&s&xpuiJs&1.2.31.1205&1.2.31.1205'
|
||||
'enableYlxReverseSorting&Enable reverse sort direction in Your Library",default:\K!1&true&s&xpuiJs&1.2.60.564'
|
||||
'enableYlxReverseSorting&Enable reverse sort direction in Your Library",default:\K!1&true&s&xpuiJs&1.2.60.564&1.2.94.583'
|
||||
'enableYLXTypeaheadSearch&jump to the first matching item",default:\K!1&true&s&xpuiJs&1.2.13.656'
|
||||
'enableZoomSettingsUIDesktop&zoom settings from the settings page on Desktop",default:\K!1&true&s&xpuiJs&1.2.17.832&1.2.53.437'
|
||||
'isVideoQualityEnabled&video quality settings and the in-player quality picker",default:\K!1&true&s&xpuiJs&1.2.84.194'
|
||||
@@ -1225,6 +1517,9 @@ premiumExpEx=(
|
||||
'enableYourSoundCapsuleModal&showing a modal on desktop to users who have clicked on a Your Sound Capsule share link",default:\K!1&true&s&xpuiJs&1.2.38.720'
|
||||
)
|
||||
|
||||
trap cleanup_temp_dirs EXIT
|
||||
trap 'exit 130' HUP INT TERM
|
||||
|
||||
run_prepare
|
||||
run_uninstall_check
|
||||
run_interactive_check
|
||||
|
||||
Reference in New Issue
Block a user