diff --git a/magisk_module_files/action.sh b/magisk_module_files/action.sh index 4907728..bf4ddac 100644 --- a/magisk_module_files/action.sh +++ b/magisk_module_files/action.sh @@ -91,10 +91,96 @@ PlayIntegrityFix() { build_json "$PIF_LIST" >"$CWD_PIF" ;; *) - ui_print " - Non BETA module detected, Downloading PIF.json in order to pass integrity…" + ui_print " - Non BETA module detected" + ui_print " - Do you wan't to download the PIF.json from GitHub? (chiteroman/PlayIntegrityFix)" - # Download the PIF.json file - download_file "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/module/pif.json" "$CWD_PIF" + # Ask whether to download PIF.json from chiteroman's GitHub or build one yourself + volume_key_event_setval "DOWNLOAD_PIF_GITHUB" true false "DOWNLOAD_PIF_GITHUB" + + # Either download the PIF.json from chiteroman's GitHub or build one yourself + if boolval "$DOWNLOAD_PIF_GITHUB"; then + download_file "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/module/pif.json" "$CWD_PIF" + else + # Download Generic System Image (GSI) HTML + ui_print " - Scalping Google's latest Pixel Beta Release…" + + # Download Generic System Image (GSI) HTML + download_file https://developer.android.com/topic/generic-system-image/releases DL_GSI_HTML + + # Extract release date from the text closest to the "(Beta)" string and convert to YYYY-MM-DD format + RELEASE_DATE="$(date -D '%B %e, %Y' -d "$(grep -m1 -o 'Date:.*' DL_GSI_HTML | cut -d\ -f2-4)" '+%Y-%m-%d')" + + # Extract the release version from the link closest to the "(Beta)" string + RELEASE_VERSION="$(awk '/\(Beta\)/ {flag=1} /versions/ && flag {print; flag=0}' DL_GSI_HTML | grep -o '/versions/[0-9]*' | sed 's/\/versions\///')" + + # Extract the build ID from the text closest to the "(Beta)" string + ID="$(awk '/\(Beta\)/ {flag=1} /Build:/ && flag {print; flag=0}' DL_GSI_HTML | grep -o 'Build: [A-Z0-9.]*' | sed 's/Build: //')" + + # Extract the incremental value (based on the ID) + INCREMENTAL="$(grep -o "$ID-[0-9]*-" DL_GSI_HTML | sed "s/$ID-//g" | sed 's/-//g' | head -n1)" + + # Download the OTA Image Download page + download_file "https://developer.android.com/about/versions/$RELEASE_VERSION/download-ota" DL_OTA_HTML + + # Build lists of supported models and products from the OTA Image Download page + MODEL_LIST="$(grep -A1 'tr id=' DL_OTA_HTML | grep '' | sed -e 's/<[^>]*>//g' | sed 's/^[ \t]*//g' | tr -d '\r' | paste -sd, -)" + PRODUCT_LIST="$(grep -o 'ota/[^-]*' DL_OTA_HTML | sed 's/ota\///g' | paste -sd, -)" + + # Create the custom list using awk for better handling of the comma-separated values + # model (product) + DEVICE_LIST="$(printf "%s\n%s" "$MODEL_LIST" "$PRODUCT_LIST" | awk -F, ' +NR==1 { + split($0, models, ",") + n = NF +} +NR==2 { + split($0, products, ",") + for (i=1; i<=n; i++) { + if (models[i] != "" && products[i] != "") { + if (i > 1) printf "\n" + printf "%s (%s)", models[i], products[i] + } + } +}')" + + # Show a list of device with proper format + ui_print " - Supported Devices:" + for i in $(seq 1 "$(echo "$DEVICE_LIST" | wc -l)"); do + echo " - $(echo "$DEVICE_LIST" | sed -n "${i}p")" + done + + # Use volume key events to select a device by product name + volume_key_event_setoption "PRODUCT" "$(echo "$PRODUCT_LIST" | tr ',' ' ')" "SELECTED_PRODUCT" + + # Get the device MODEL name from PRODUCT name, using DEVICE_LIST + SELECTED_MODEL=$(echo "$DEVICE_LIST" | grep "($SELECTED_PRODUCT)" | sed 's/ *(.*)//') + + # Display the selected device + ui_print " - Selected: $SELECTED_MODEL ($SELECTED_PRODUCT)" + + # Remove the beta (_*) from PRODUCT name + SELECTED_PRODUCT_NAME=${SELECTED_PRODUCT%_*} + + # Build security patch from OTA release date + SECURITY_PATCH_DATE="${RELEASE_DATE%-*}"-05 + + # List of properties to include in the PIF.json file + PIF_LIST="MODEL MANUFACTURER DEVICE_INITIAL_SDK_INT FINGERPRINT SECURITY_PATCH" + + # Build properties + MODEL="$SELECTED_MODEL" + MANUFACTURER="Google" + DEVICE_INITIAL_SDK_INT=$(grep_prop "ro.product.first_api_level" "$SYSPROP_CONTENT") + [ -z "$DEVICE_INITIAL_SDK_INT" ] && DEVICE_INITIAL_SDK_INT=$(grep_prop "ro.product.build.version.sdk" "$SYSPROP_CONTENT") + FINGERPRINT="google/$SELECTED_PRODUCT/$SELECTED_PRODUCT_NAME:$RELEASE_VERSION/$ID/$INCREMENTAL:user/release-keys" + SECURITY_PATCH="$SECURITY_PATCH_DATE" + + # Build the JSON object + build_json "$PIF_LIST" >"$CWD_PIF" + + # Clean the downloaded files + rm -f DL_*_HTML + fi ;; esac diff --git a/magisk_module_files/service.sh b/magisk_module_files/service.sh index 0c0764d..3a93540 100644 --- a/magisk_module_files/service.sh +++ b/magisk_module_files/service.sh @@ -108,7 +108,7 @@ EOF echo "$function_map" | while IFS=: read -r safe_var prop_type comparison; do eval "local safe_val=\$SAFE_$safe_var" - if boolval "$safe_val"; then + if ! boolval "$safe_val"; then ui_print " - Safe Mode was manually disabled for \"SAFE_$safe_var\" !" else case "$prop_type" in diff --git a/magisk_module_files/util_functions.sh b/magisk_module_files/util_functions.sh index fe15f86..b8ff75a 100644 --- a/magisk_module_files/util_functions.sh +++ b/magisk_module_files/util_functions.sh @@ -42,25 +42,39 @@ grep_prop() { # Usage: boolval "value" || echo $? boolval() { case "$(printf "%s" "${1:-}" | tr '[:upper:]' '[:lower:]')" in - 1 | true | on | enabled) return 1 ;; # Truely - 0 | false | off | disabled) return 0 ;; # Falsely + 1 | true | on | enabled) return 0 ;; # Truely + 0 | false | off | disabled) return 1 ;; # Falsely *) return 0 ;; # Everything else esac } -# Function which checks if either it should download a file using curl or wget, then download the file +# Function to download a file using curl or wget with retry mechanism download_file() { url="$1" file="$2" + retries=5 - # Check whether curl or wget is available, then download the file - if command -v curl >/dev/null 2>&1; then - curl -sL -o "$file" "$url" - elif command -v wget >/dev/null 2>&1; then - wget -qO "$file" "$url" - else - abort " ! curl or wget not found, unable to download file" - fi + # Try download with either curl or wget + while [ $retries -gt 0 ]; do + if command -v curl >/dev/null 2>&1; then + if curl -sL --connect-timeout 10 -o "$file" "$url"; then + return 0 + fi + elif command -v wget >/dev/null 2>&1; then + if wget -qO "$file" "$url" --timeout=10; then + return 0 + fi + else + abort " ! curl or wget not found, unable to download file" + fi + + retries=$((retries - 1)) + [ $retries -gt 0 ] && sleep 5 + done + + # If we get here, all attempts failed + rm -f "$file" + abort " ! Download failed after $retries attempts" } # Function to handle volume key events and set variables. @@ -75,7 +89,7 @@ volume_key_event_setval() { echo " * [ VOL- ] = [ NO ] *" echo " * [ POWR ] = [ CANCEL ] *" echo " *********************************" - echo " * Chose your selection for \"$option_name\" !" + echo " * Choose your value for \"$option_name\" !" echo " *********************************" while :; do @@ -94,6 +108,9 @@ volume_key_event_setval() { elif echo "$keys" | grep -q 'POWER'; then abort "Power key detected! Canceling…" fi + + # Wait some time before checking again + sleep 0.3 done } @@ -103,18 +120,27 @@ volume_key_event_setoption() { options_list=$2 # Space-separated list of options result_var=$3 + # Shift to remove the first three arguments (option_name, options_list, result_var) + shift 1 + echo " *********************************" echo " * [ VOL+ ] = [ CONFIRM ] *" echo " * [ VOL- ] = [ NEXT OPTION ] *" echo " * [ POWR ] = [ CANCEL ] *" echo " *********************************" - echo " * Choose your selection for \"$option_name\" !" + echo " * Choose your value for \"$option_name\" !" echo " *********************************" - # Sanitize the options list - options_list=$(echo "$options_list" | tr -s ' ') # Ensure no extra spaces - set -- $options_list # This sets the options as positional parameters ($1, $2, ..., $N) - total_options=$# # Number of options + # Sanitize the options list (ensure no extra spaces) + options_list=$(echo "$options_list" | tr -s ' ') + + # Store the original positional parameters in a temporary variable + original_options="$*" + + # Set the options as positional parameters ($1, $2, ..., $N) + set -- $(echo "$options_list") + + total_options=$# # Number of options # If only one option is available, automatically select it if [ "$total_options" -eq 1 ]; then @@ -123,15 +149,21 @@ volume_key_event_setoption() { fi # Display the options once - for i in $(seq 1 $total_options); do - eval "option=\$$i" # Get the i-th positional parameter - ui_print " - [$i] $option" - done + # i=1 + # while [ $# -gt 0 ]; do + # option="$1" + # ui_print " - [$i] $option" + # shift + # i=$((i + 1)) + # done selected_option=1 + # Restore the original positional parameters + set -- $original_options + # Display the initially selected option - current_option=$(eval echo "\$$selected_option") + eval "current_option=\$${selected_option}" ui_print " > $current_option" # Loop to capture key events and update selection @@ -150,10 +182,22 @@ volume_key_event_setoption() { if [ "$selected_option" -gt "$total_options" ]; then selected_option=1 # Wrap around to the first option fi - current_option=$(eval echo "\$$selected_option") + + # Use shift to get the selected option + set -- $original_options # Reset positional parameters + i=1 + while [ $i -lt $selected_option ]; do + shift + i=$((i + 1)) + done + current_option="$1" + ui_print " > $current_option" elif echo "$keys" | grep -q 'POWER'; then abort "Power key detected, Cancelling…" fi + + # Wait some time before checking again + sleep 0.3 done }