diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3b229933d8..76caa3adae 100755 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,8 +78,8 @@ jobs: cp -f build.tmp build.md get_update_json() { echo "{ - \"version\": \"$1\", - \"versionCode\": ${{ steps.next_ver_code.outputs.NEXT_VER_CODE}}, + \"version\": \"$1 (${{ steps.next_ver_code.outputs.NEXT_VER_CODE }})\", + \"versionCode\": ${{ steps.next_ver_code.outputs.NEXT_VER_CODE }}, \"zipUrl\": \"$2\", \"changelog\": \"https://raw.githubusercontent.com/$GITHUB_REPOSITORY/update/build.md\" }" diff --git a/CONFIG.md b/CONFIG.md index 678960a04b..0030e31995 100755 --- a/CONFIG.md +++ b/CONFIG.md @@ -14,19 +14,22 @@ There exists an example below with all defaults shown and all the keys explicitl ```toml parallel-jobs = 1 # amount of cores to use for parallel patching, if not set nproc is used +compression-level = 9 # module zip compression level +remove-rv-integrations-checks = true # remove checks from the revanced integrations + patches-source = "revanced/revanced-patches" # where to fetch patches bundle from. default: "revanced/revanced-patches" integrations-source = "revanced/revanced-integrations" # where to fetch integrations from. default: "revanced/revanced-integrations" cli-source = "j-hc/revanced-cli" # where to fetch cli from. default: "j-hc/revanced-cli" # options like cli-source can also set per app rv-brand = "ReVanced Extended" # rebrand from 'ReVanced' to something different. default: "ReVanced" -patches-version = "v2.160.0" # locks the patches version. default: latest available -integrations-version = "v0.95.0" # locks the integrations version. default: latest available +patches-version = "v2.160.0" # 'latest', 'dev', or a version number. default: "latest" +# integrations-version and cli-version can be also configured [Some-App] app-name = "SomeApp" # if set, release name becomes SomeApp instead of Some-App. default is same as table name, which is 'Some-App' here. enabled = true # whether to build the app. default: true -version = "auto" # 'auto', 'latest', 'beta' or a custom one e.g. '17.40.41'. default: auto +version = "auto" # 'auto', 'latest', 'beta' or a version number (e.g. '17.40.41'). default: auto # 'auto' option gets the latest possible version supported by all the included patches # 'latest' gets the latest stable without checking patches support. 'beta' gets the latest beta/alpha include-stock = true # includes stock apk in the module. default: true diff --git a/bin/dexlib2.jar b/bin/dexlib2.jar new file mode 100644 index 0000000000..07216e6913 Binary files /dev/null and b/bin/dexlib2.jar differ diff --git a/bin/paccer.jar b/bin/paccer.jar new file mode 100644 index 0000000000..4e18eb30c0 Binary files /dev/null and b/bin/paccer.jar differ diff --git a/build.sh b/build.sh index 7f67488b15..8308f64d08 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ set -euo pipefail shopt -s nullglob -trap "rm -rf temp/*tmp.* temp/*/*tmp.*; exit 130" INT +trap "rm -rf temp/*tmp.* temp/*/*tmp.* temp/*-temporary-files; exit 130" INT if [ "${1-}" = "clean" ]; then rm -rf temp build logs build.md @@ -20,14 +20,16 @@ COMPRESSION_LEVEL=$(toml_get "$main_config_t" compression-level) || COMPRESSION_ if ! PARALLEL_JOBS=$(toml_get "$main_config_t" parallel-jobs); then if [ "$OS" = Android ]; then PARALLEL_JOBS=1; else PARALLEL_JOBS=$(nproc); fi fi -DEF_PATCHES_VER=$(toml_get "$main_config_t" patches-version) || DEF_PATCHES_VER="" -DEF_INTEGRATIONS_VER=$(toml_get "$main_config_t" integrations-version) || DEF_INTEGRATIONS_VER="" -DEF_CLI_VER=$(toml_get "$main_config_t" cli-version) || DEF_CLI_VER="" +REMOVE_RV_INTEGRATIONS_CHECKS=$(toml_get "$main_config_t" remove-rv-integrations-checks) || REMOVE_RV_INTEGRATIONS_CHECKS="true" + +DEF_PATCHES_VER=$(toml_get "$main_config_t" patches-version) || DEF_PATCHES_VER="latest" +DEF_INTEGRATIONS_VER=$(toml_get "$main_config_t" integrations-version) || DEF_INTEGRATIONS_VER="latest" +DEF_CLI_VER=$(toml_get "$main_config_t" cli-version) || DEF_CLI_VER="latest" DEF_PATCHES_SRC=$(toml_get "$main_config_t" patches-source) || DEF_PATCHES_SRC="ReVanced/revanced-patches" DEF_INTEGRATIONS_SRC=$(toml_get "$main_config_t" integrations-source) || DEF_INTEGRATIONS_SRC="ReVanced/revanced-integrations" DEF_CLI_SRC=$(toml_get "$main_config_t" cli-source) || DEF_CLI_SRC="j-hc/revanced-cli" DEF_RV_BRAND=$(toml_get "$main_config_t" rv-brand) || DEF_RV_BRAND="ReVanced" -mkdir -p $TEMP_DIR $BUILD_DIR +mkdir -p "$TEMP_DIR" "$BUILD_DIR" if [ "${2-}" = "--config-update" ]; then config_update @@ -50,21 +52,11 @@ java --version >/dev/null || abort "\`openjdk 17\` is not installed. install it zip --version >/dev/null || abort "\`zip\` is not installed. install it with 'apt install zip' or equivalent" # ---------------- rm -rf revanced-magisk/bin/*/tmp.* -get_prebuilts +if [ "$(echo "$TEMP_DIR"/*-rv/changelog.md)" ]; then + : >"$TEMP_DIR"/*-rv/changelog.md || : +fi -set_prebuilts() { - local integrations_src=$1 patches_src=$2 cli_src=$3 integrations_ver=$4 patches_ver=$5 cli_ver=$6 - local patches_dir=${patches_src%/*} - local integrations_dir=${integrations_src%/*} - local cli_dir=${cli_src%/*} - cli_ver=${cli_ver#v} - integrations_ver="${integrations_ver#v}" - patches_ver="${patches_ver#v}" - app_args[cli]=$(find "${TEMP_DIR}/${cli_dir,,}-rv" -name "revanced-cli-${cli_ver:-*}-all.jar" -type f -print -quit 2>/dev/null) && [ "${app_args[cli]}" ] || return 1 - app_args[integ]=$(find "${TEMP_DIR}/${integrations_dir,,}-rv" -name "revanced-integrations-${integrations_ver:-*}.apk" -type f -print -quit 2>/dev/null) && [ "${app_args[integ]}" ] || return 1 - app_args[ptjar]=$(find "${TEMP_DIR}/${patches_dir,,}-rv" -name "revanced-patches-${patches_ver:-*}.jar" -type f -print -quit 2>/dev/null) && [ "${app_args[ptjar]}" ] || return 1 - app_args[ptjs]=$(find "${TEMP_DIR}/${patches_dir,,}-rv" -name "patches-${patches_ver:-*}.json" -type f -print -quit 2>/dev/null) && [ "${app_args[ptjs]}" ] || return 1 -} +get_prebuilts declare -A cliriplib idx=0 @@ -86,16 +78,14 @@ for table_name in $(toml_get_table_names); do cli_src=$(toml_get "$t" cli-source) || cli_src=$DEF_CLI_SRC cli_ver=$(toml_get "$t" cli-version) || cli_ver=$DEF_CLI_VER - if ! set_prebuilts "$integrations_src" "$patches_src" "$cli_src" "$integrations_ver" "$patches_ver" "$cli_ver"; then - if ! RVP="$(get_rv_prebuilts "$cli_src" "$cli_ver" "$integrations_src" "$integrations_ver" "$patches_src" "$patches_ver")"; then - abort "could not download rv prebuilts" - fi - read -r rv_cli_jar rv_integrations_apk rv_patches_jar rv_patches_json <<<"$RVP" - app_args[cli]=$rv_cli_jar - app_args[integ]=$rv_integrations_apk - app_args[ptjar]=$rv_patches_jar - app_args[ptjs]=$rv_patches_json + if ! RVP="$(get_rv_prebuilts "$cli_src" "$cli_ver" "$integrations_src" "$integrations_ver" "$patches_src" "$patches_ver")"; then + abort "could not download rv prebuilts" fi + read -r rv_cli_jar rv_integrations_apk rv_patches_jar rv_patches_json <<<"$RVP" + app_args[cli]=$rv_cli_jar + app_args[integ]=$rv_integrations_apk + app_args[ptjar]=$rv_patches_jar + app_args[ptjs]=$rv_patches_json if [[ -v cliriplib[${app_args[cli]}] ]]; then app_args[riplib]=${cliriplib[${app_args[cli]}]}; else if [[ $(java -jar "${app_args[cli]}" patch 2>&1) == *rip-lib* ]]; then cliriplib[${app_args[cli]}]=true @@ -106,7 +96,7 @@ for table_name in $(toml_get_table_names); do fi fi if [ "${app_args[riplib]}" = "true" ] && [ "$(toml_get "$t" riplib)" = "false" ]; then app_args[riplib]=false; fi - app_args[rv_brand]=$(toml_get "$t" rv-brand) || app_args[rv_brand]="$DEF_RV_BRAND" + app_args[rv_brand]=$(toml_get "$t" rv-brand) || app_args[rv_brand]=$DEF_RV_BRAND app_args[excluded_patches]=$(toml_get "$t" excluded-patches) || app_args[excluded_patches]="" if [ -n "${app_args[excluded_patches]}" ] && [[ ${app_args[excluded_patches]} != *'"'* ]]; then abort "patch names inside excluded-patches must be quoted"; fi @@ -176,14 +166,14 @@ for table_name in $(toml_get_table_names); do done wait rm -rf temp/tmp.* -if [ -z "$(ls -A1 ${BUILD_DIR})" ]; then abort "All builds failed."; fi +if [ -z "$(ls -A1 "${BUILD_DIR}")" ]; then abort "All builds failed."; fi log "\nInstall [Microg](https://github.com/ReVanced/GmsCore/releases) for non-root YouTube and YT Music APKs" log "Use [zygisk-detach](https://github.com/j-hc/zygisk-detach) to detach root ReVanced YouTube and YT Music from Play Store" log "\n[revanced-magisk-module](https://github.com/j-hc/revanced-magisk-module)\n" -log "$(cat $TEMP_DIR/*-rv/changelog.md)" +log "$(cat "$TEMP_DIR"/*-rv/changelog.md)" -SKIPPED=$(cat $TEMP_DIR/skipped 2>/dev/null || :) +SKIPPED=$(cat "$TEMP_DIR"/skipped 2>/dev/null || :) if [ -n "$SKIPPED" ]; then log "\nSkipped:" log "$SKIPPED" diff --git a/config.toml b/config.toml index 2a04c5ef81..a931daf514 100755 --- a/config.toml +++ b/config.toml @@ -1,4 +1,5 @@ enable-magisk-update = true # set this to false if you do not want to receive updates for the module in magisk app +parallel-jobs = 1 # add 'enabled = false' for not patching a specific app or remove it from the config # see https://github.com/j-hc/revanced-magisk-module/blob/main/CONFIG.md for more detailed explanations @@ -10,14 +11,14 @@ build-mode = "both" excluded-patches = "" included-patches = "" version = "auto" -archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.google.android.youtube" apkmirror-dlurl = "https://www.apkmirror.com/apk/google-inc/youtube" # fallback +# archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.google.android.youtube" [Music] build-mode = "both" -archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.google.android.apps.youtube.music" -apkmirror-dlurl = "https://www.apkmirror.com/apk/google-inc/youtube-music" arch = "both" +apkmirror-dlurl = "https://www.apkmirror.com/apk/google-inc/youtube-music" +# archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.google.android.apps.youtube.music" [Music-Extended] app-name = "Music" @@ -26,9 +27,9 @@ integrations-source = "inotia00/revanced-integrations" cli-source = "inotia00/revanced-cli" rv-brand = "ReVanced Extended" build-mode = "both" -archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.google.android.apps.youtube.music" -apkmirror-dlurl = "https://www.apkmirror.com/apk/google-inc/youtube-music" arch = "both" +apkmirror-dlurl = "https://www.apkmirror.com/apk/google-inc/youtube-music" +# archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.google.android.apps.youtube.music" [YouTube-Extended] app-name = "YouTube" @@ -37,26 +38,32 @@ integrations-source = "inotia00/revanced-integrations" cli-source = "inotia00/revanced-cli" rv-brand = "ReVanced Extended" build-mode = "both" -archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.google.android.youtube" apkmirror-dlurl = "https://www.apkmirror.com/apk/google-inc/youtube" +# archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.google.android.youtube" [Twitter] +enabled = false +apkmirror-dlurl = "https://www.apkmirror.com/apk/x-corp/twitter" build-mode = "apk" -archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.twitter.android" - -[Twitch] -archive-dlurl = "https://archive.org/download/jhc-apks/apks/tv.twitch.android.app" - -[TikTok] -archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.zhiliaoapp.musically" -included-patches = "'SIM spoof'" +dpi = "120-640dpi" +# archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.twitter.android" [Reddit-Extended] patches-source = "inotia00/revanced-patches" integrations-source = "inotia00/revanced-integrations" cli-source = "inotia00/revanced-cli" rv-brand = "ReVanced Extended" -archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.reddit.frontpage" +apkmirror-dlurl = "https://www.apkmirror.com/apk/redditinc/reddit/" +# archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.reddit.frontpage" + +[Twitch] +enabled = false +# archive-dlurl = "https://archive.org/download/jhc-apks/apks/tv.twitch.android.app" + +[TikTok] +enabled = false +# archive-dlurl = "https://archive.org/download/jhc-apks/apks/com.zhiliaoapp.musically" +included-patches = "'SIM spoof'" [Messenger] enabled = false diff --git a/revanced-magisk/customize.sh b/revanced-magisk/customize.sh index 86b7c94f96..28970d01f2 100755 --- a/revanced-magisk/customize.sh +++ b/revanced-magisk/customize.sh @@ -6,45 +6,58 @@ if [ -n "$MODULE_ARCH" ] && [ "$MODULE_ARCH" != "$ARCH" ]; then Your device: $ARCH Module: $MODULE_ARCH" fi - if [ "$ARCH" = "arm" ]; then ARCH_LIB=armeabi-v7a - alias cmpr='$MODPATH/bin/arm/cmpr' elif [ "$ARCH" = "arm64" ]; then ARCH_LIB=arm64-v8a - alias cmpr='$MODPATH/bin/arm64/cmpr' elif [ "$ARCH" = "x86" ]; then ARCH_LIB=x86 - alias cmpr='$MODPATH/bin/x86/cmpr' elif [ "$ARCH" = "x64" ]; then ARCH_LIB=x86_64 - alias cmpr='$MODPATH/bin/x64/cmpr' -else - abort "ERROR: unsupported arch: ${ARCH}" -fi +else abort "ERROR: unreachable: ${ARCH}"; fi +RVPATH=/data/adb/rvhc/${MODPATH##*/}.apk + set_perm_recursive "$MODPATH/bin" 0 0 0755 0777 if su -M -c true >/dev/null 2>/dev/null; then alias mm='su -M -c' -else - alias mm='nsenter -t1 -m' -fi +else alias mm='nsenter -t1 -m'; fi -mm grep "$PKG_NAME" /proc/mounts | while read -r line; do +mm grep -F "$PKG_NAME" /proc/mounts | while read -r line; do ui_print "* Un-mount" mp=${line#* } mp=${mp%% *} mm umount -l "${mp%%\\*}" done am force-stop "$PKG_NAME" +pmex() { + OP=$(pm "$@" 2>&1 &2; then + if pmex install-existing "$PKG_NAME" >&2; then + BASEPATH=$(pmex path "$PKG_NAME") || abort "ERROR: pm path failed $BASEPATH" + echo >&2 "'$BASEPATH'" + BASEPATH=${BASEPATH##*:} BASEPATH=${BASEPATH%/*} + if [ "${BASEPATH:1:4}" = data ]; then + if pmex uninstall -k --user 0 "$PKG_NAME" >&2; then + ui_print "* Cleared existing $PKG_NAME package" + else abort "ERROR: pm uninstall failed"; fi + else ui_print "* Installed stock $PKG_NAME package"; fi + fi +fi + +IS_SYS=false INS=true -if BASEPATH=$(pm path "$PKG_NAME"); then +if BASEPATH=$(pmex path "$PKG_NAME"); then + echo >&2 "'$BASEPATH'" BASEPATH=${BASEPATH##*:} BASEPATH=${BASEPATH%/*} - if [ "${BASEPATH:1:6}" = system ]; then - ui_print "* $PKG_NAME is a system app" - elif [ ! -d "${BASEPATH}/lib" ]; then - ui_print "* Invalid installation found. Uninstalling..." - pm uninstall -k --user 0 "$PKG_NAME" + if [ "${BASEPATH:1:4}" != data ]; then + ui_print "* $PKG_NAME is a system app." + IS_SYS=true elif [ ! -f "$MODPATH/$PKG_NAME.apk" ]; then ui_print "* Stock $PKG_NAME APK was not found" VERSION=$(dumpsys package "$PKG_NAME" | grep -m1 versionName) VERSION="${VERSION#*=}" @@ -57,7 +70,7 @@ if BASEPATH=$(pm path "$PKG_NAME"); then module: $PKG_VER " fi - elif cmpr "$BASEPATH/base.apk" "$MODPATH/$PKG_NAME.apk"; then + elif "${MODPATH:?}/bin/$ARCH/cmpr" "$BASEPATH/base.apk" "$MODPATH/$PKG_NAME.apk"; then ui_print "* $PKG_NAME is up-to-date" INS=false fi @@ -68,41 +81,58 @@ install() { abort "ERROR: Stock $PKG_NAME apk was not found" fi ui_print "* Updating $PKG_NAME to $PKG_VER" + VERIF_ADB=$(settings get global verifier_verify_adb_installs) settings put global verifier_verify_adb_installs 0 SZ=$(stat -c "%s" "$MODPATH/$PKG_NAME.apk") - if ! SES=$(pm install-create --user 0 -i com.android.vending -r -d -S "$SZ" 2>&1); then - ui_print "ERROR: install-create failed" - abort "$SES" - fi - SES=${SES#*[} SES=${SES%]*} - set_perm "$MODPATH/$PKG_NAME.apk" 1000 1000 644 u:object_r:apk_data_file:s0 - if ! op=$(pm install-write -S "$SZ" "$SES" "$PKG_NAME.apk" "$MODPATH/$PKG_NAME.apk" 2>&1); then - ui_print "ERROR: install-write failed" - abort "$op" - fi - if ! op=$(pm install-commit "$SES" 2>&1); then - if echo "$op" | grep -q INSTALL_FAILED_VERSION_DOWNGRADE; then - ui_print "* INSTALL_FAILED_VERSION_DOWNGRADE. Uninstalling..." - pm uninstall -k --user 0 "$PKG_NAME" - return 1 + for IT in 1 2; do + if ! SES=$(pmex install-create --user 0 -i com.android.vending -r -d -S "$SZ"); then + ui_print "ERROR: install-create failed" + settings put global verifier_verify_adb_installs "$VERIF_ADB" + abort "$SES" fi - ui_print "ERROR: install-commit failed" - abort "$op" - fi - settings put global verifier_verify_adb_installs 1 - if BASEPATH=$(pm path "$PKG_NAME"); then - BASEPATH=${BASEPATH##*:} BASEPATH=${BASEPATH%/*} - else - abort "ERROR: install $PKG_NAME manually and reflash the module" - fi -} -if [ $INS = true ]; then - if ! install; then - if ! install; then - abort + SES=${SES#*[} SES=${SES%]*} + set_perm "$MODPATH/$PKG_NAME.apk" 1000 1000 644 u:object_r:apk_data_file:s0 + if ! op=$(pmex install-write -S "$SZ" "$SES" "$PKG_NAME.apk" "$MODPATH/$PKG_NAME.apk"); then + ui_print "ERROR: install-write failed" + settings put global verifier_verify_adb_installs "$VERIF_ADB" + abort "$op" fi - fi -fi + if ! op=$(pmex install-commit "$SES"); then + if echo "$op" | grep -q INSTALL_FAILED_VERSION_DOWNGRADE; then + ui_print "* Handling INSTALL_FAILED_VERSION_DOWNGRADE.." + if [ "$IS_SYS" = true ]; then + mkdir -p /data/adb/rvhc/empty /data/adb/post-fs-data.d + SCNM="/data/adb/post-fs-data.d/$PKG_NAME-uninstall.sh" + echo "mount -o bind /data/adb/rvhc/empty $BASEPATH" >"$SCNM" + chmod +x "$SCNM" + ui_print "* Created the uninstall script." + ui_print "" + ui_print "* Reboot and reflash the module!" + abort + else + ui_print "* Uninstalling..." + if ! op=$(pmex uninstall -k --user 0 "$PKG_NAME"); then + ui_print "$op" + if [ $IT = 2 ]; then abort "ERROR: pm uninstall failed."; fi + fi + continue + fi + fi + ui_print "ERROR: install-commit failed" + settings put global verifier_verify_adb_installs "$VERIF_ADB" + abort "$op" + fi + if BASEPATH=$(pmex path "$PKG_NAME"); then + BASEPATH=${BASEPATH##*:} BASEPATH=${BASEPATH%/*} + else + settings put global verifier_verify_adb_installs "$VERIF_ADB" + abort "ERROR: install $PKG_NAME manually and reflash the module" + fi + break + done + settings put global verifier_verify_adb_installs "$VERIF_ADB" +} +if [ $INS = true ] && ! install; then abort; fi BASEPATHLIB=${BASEPATH}/lib/${ARCH} if [ -z "$(ls -A1 "$BASEPATHLIB")" ]; then @@ -133,6 +163,11 @@ nohup cmd package compile --reset "$PKG_NAME" >/dev/null 2>&1 & ui_print "* Cleanup" rm -rf "${MODPATH:?}/bin" "$MODPATH/$PKG_NAME.apk" +if [ "$KSU" ] && [ -d "/data/adb/modules/zygisk-assistant" ]; then + ui_print "* If you are using zygisk-assistant, you need to" + ui_print " give root permissions to $PKG_NAME" +fi + ui_print "* Done" ui_print " by j-hc (github.com/j-hc)" ui_print " " diff --git a/revanced-magisk/service.sh b/revanced-magisk/service.sh index 99a3a2ce92..aa40f267cc 100755 --- a/revanced-magisk/service.sh +++ b/revanced-magisk/service.sh @@ -3,42 +3,47 @@ MODDIR=${0%/*} RVPATH=/data/adb/rvhc/${MODDIR##*/}.apk . "$MODDIR/config" +err() { + [ ! -f "$MODDIR/err" ] && cp "$MODDIR/module.prop" "$MODDIR/err" + sed -i "s/^des.*/description=⚠️ Needs reflash: '${1}'/g" "$MODDIR/module.prop" +} + until [ "$(getprop sys.boot_completed)" = 1 ]; do sleep 1; done until [ -d "/sdcard/Android" ]; do sleep 1; done while - BASEPATH=$(pm path "$PKG_NAME") - svcl=$? - [ $svcl = 20 ] + BASEPATH=$(pm path "$PKG_NAME" 2>&1 "$MODDIR/log.txt" + ls -Zla "$BASEPATH/lib" >>"$MODDIR/log.txt" + else rm "$MODDIR/log.txt" >/dev/null 2>&1; fi + VERSION=$(dumpsys package "$PKG_NAME" | grep -m1 versionName) VERSION="${VERSION#*=}" + if [ "$VERSION" != "$PKG_VER" ] && [ "$VERSION" ]; then + err "version mismatch (installed:${VERSION}, module:$PKG_VER)" + return + fi + grep "$PKG_NAME" /proc/mounts | while read -r line; do + mp=${line#* } mp=${mp%% *} + umount -l "${mp%%\\*}" + done + if ! chcon u:object_r:apk_data_file:s0 "$RVPATH"; then + err "apk not found" + return + fi + mount -o bind "$RVPATH" "$BASEPATH/base.apk" + am force-stop "$PKG_NAME" + [ -f "$MODDIR/err" ] && mv -f "$MODDIR/err" "$MODDIR/module.prop" } -if [ $svcl != 0 ]; then - err "app not installed" - exit -fi -BASEPATH=${BASEPATH##*:} BASEPATH=${BASEPATH%/*} -if [ ! -d "$BASEPATH/lib" ]; then - err "zygote crashed (fix your ROM)" - exit -fi -VERSION=$(dumpsys package "$PKG_NAME" | grep -m1 versionName) VERSION="${VERSION#*=}" -if [ "$VERSION" != "$PKG_VER" ] && [ "$VERSION" ]; then - err "version mismatch (installed:${VERSION}, module:$PKG_VER)" - exit -fi -grep "$PKG_NAME" /proc/mounts | while read -r line; do - mp=${line#* } mp=${mp%% *} - umount -l "${mp%%\\*}" -done -if ! chcon u:object_r:apk_data_file:s0 "$RVPATH"; then - err "apk not found" - exit -fi -mount -o bind "$RVPATH" "$BASEPATH/base.apk" -am force-stop "$PKG_NAME" -[ -f "$MODDIR/err" ] && mv -f "$MODDIR/err" "$MODDIR/module.prop" +run diff --git a/revanced-magisk/uninstall.sh b/revanced-magisk/uninstall.sh index 7ed3fbe29b..57f75ff29e 100755 --- a/revanced-magisk/uninstall.sh +++ b/revanced-magisk/uninstall.sh @@ -1,6 +1,9 @@ #!/system/bin/sh { MODDIR=${0%/*} - rm "/data/adb/rvhc/${MODDIR##*/}".apk + . "$MODDIR/config" + + rm "/data/adb/rvhc/${MODDIR##*/}.apk" rmdir "/data/adb/rvhc" + rm "/data/adb/post-fs-data.d/$PKG_NAME-uninstall.sh" } & diff --git a/utils.sh b/utils.sh index 300bd3b95d..de70c83bc7 100755 --- a/utils.sh +++ b/utils.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash MODULE_TEMPLATE_DIR="revanced-magisk" -TEMP_DIR="temp" -BIN_DIR="bin" -BUILD_DIR="build" +CWD=$(pwd) +TEMP_DIR=${CWD}/"temp" +BIN_DIR=${CWD}/"bin" +BUILD_DIR=${CWD}/"build" if [ "${GITHUB_TOKEN-}" ]; then GH_HEADER="Authorization: token ${GITHUB_TOKEN}"; else GH_HEADER=; fi NEXT_VER_CODE=${NEXT_VER_CODE:-$(date +'%Y%m%d')} -REBUILD=${REBUILD:-false} OS=$(uname -o) toml_prep() { __TOML__=$(tr -d '\t\r' <<<"$1" | tr "'" '"' | grep -o '^[^#]*' | grep -v '^$' | sed -r 's/(\".*\")|\s*/\1/g; 1i []'); } @@ -37,6 +37,7 @@ abort() { get_rv_prebuilts() { local cli_src=$1 cli_ver=$2 integrations_src=$3 integrations_ver=$4 patches_src=$5 patches_ver=$6 + local integs_file="" pr "Getting prebuilts (${patches_src%/*})" >&2 local cl_dir=${patches_src%/*} cl_dir=${TEMP_DIR}/${cl_dir,,}-rv @@ -53,32 +54,72 @@ get_rv_prebuilts() { dir=${TEMP_DIR}/${dir,,}-rv [ -d "$dir" ] || mkdir "$dir" - local rv_rel="https://api.github.com/repos/${src}/releases/" - if [ "$ver" ]; then rv_rel+="tags/${ver}"; else rv_rel+="latest"; fi + local rv_rel="https://api.github.com/repos/${src}/releases" name_ver + if [ "$ver" = "dev" ]; then + name_ver="*-dev*" + elif [ "$ver" = "latest" ]; then + rv_rel+="/latest" + name_ver="*" + else + rv_rel+="/tags/${ver}" + name_ver="$ver" + fi - local resp asset url name file - resp=$(gh_req "$rv_rel" -) || return 1 - asset=$(jq -e -r ".assets[] | select(.name | endswith(\"$ext\"))" <<<"$resp") || return 1 - url=$(jq -r .url <<<"$asset") - name=$(jq -r .name <<<"$asset") - file="${dir}/${name}" - [ -f "$file" ] || REBUILD=true + local url file tag_name name + file=$(find "$dir" -name "revanced-${tag,,}-${name_ver#v}.${ext}" -type f 2>/dev/null) + if [ -z "$file" ]; then + local resp asset name + resp=$(gh_req "$rv_rel" -) || return 1 + if [ "$ver" = "dev" ]; then resp=$(jq -r '.[0]' <<<"$resp"); fi + tag_name=$(jq -r '.tag_name' <<<"$resp") + asset=$(jq -e -r ".assets[] | select(.name | endswith(\"$ext\"))" <<<"$resp") || return 1 + url=$(jq -r .url <<<"$asset") + name=$(jq -r .name <<<"$asset") + file="${dir}/${name}" + gh_dl "$file" "$url" >&2 || return 1 + if [ "$tag" = "Integrations" ]; then integs_file=$file; fi + echo "$tag: $(cut -d/ -f1 <<<"$src")/${name} " >>"${cl_dir}/changelog.md" + else + local for_err=$file + if [ "$ver" = "latest" ]; then + file=$(grep -v '/[^/]*dev[^/]*$' <<<"$file" | head -1) + else file=$(grep "/[^/]*${ver#v}[^/]*\$" <<<"$file" | head -1); fi + if [ -z "$file" ]; then abort "filter fail: '$for_err' with '$ver'"; fi + name=$(basename "$file") + tag_name=$(cut -d'-' -f3- <<<"$name") + tag_name=v${tag_name%.*} + fi - echo "$tag: $(cut -d/ -f5 <<<"$url")/${name} " >>"${cl_dir}/changelog.md" - gh_dl "$file" "$url" >&2 || return 1 echo -n "$file " if [ "$tag" = "Patches" ]; then - local tag_name - tag_name=$(jq -r '.tag_name' <<<"$resp") name="patches-${tag_name}.json" file="${dir}/${name}" - url=$(jq -e -r '.assets[] | select(.name | endswith("json")) | .url' <<<"$resp") || return 1 - gh_dl "$file" "$url" >&2 || return 1 + if [ ! -f "$file" ]; then + resp=$(gh_req "$rv_rel" -) || return 1 + if [ "$ver" = "dev" ]; then resp=$(jq -r '.[0]' <<<"$resp"); fi + url=$(jq -e -r '.assets[] | select(.name | endswith("json")) | .url' <<<"$resp") || return 1 + gh_dl "$file" "$url" >&2 || return 1 + echo -e "[Changelog](https://github.com/${src}/releases/tag/${tag_name})\n" >>"${cl_dir}/changelog.md" + fi echo -n "$file " - echo -e "[Changelog](https://github.com/${src}/releases/tag/${tag_name})\n" >>"${cl_dir}/changelog.md" fi done echo + + if [ "$integs_file" ] && [ "$REMOVE_RV_INTEGRATIONS_CHECKS" = true ]; then + if ! ( + mkdir -p "${integs_file}-zip" || return 1 + unzip -qo "${integs_file}" -d "${integs_file}-zip" || return 1 + cd "${integs_file}-zip" || return 1 + java -cp "${BIN_DIR}/paccer.jar:${BIN_DIR}/dexlib2.jar" com.jhc.Main "${integs_file}-zip/classes.dex" "${integs_file}-zip/classes-patched.dex" || return 1 + mv -f "${integs_file}-zip/classes-patched.dex" "${integs_file}-zip/classes.dex" || return 1 + rm "${integs_file}" || return 1 + zip -0rq "${integs_file}" . || return 1 + ) >&2; then + echo >&2 "Patching revanced-integrations failed" + fi + rm -r "${integs_file}-zip" || : + fi } get_prebuilts() { @@ -101,7 +142,7 @@ get_prebuilts() { config_update() { if [ ! -f build.md ]; then abort "build.md not available"; fi declare -A sources - : >$TEMP_DIR/skipped + : >"$TEMP_DIR"/skipped local conf="" # shellcheck disable=SC2154 conf+=$(sed '1d' <<<"$main_config_t") @@ -113,26 +154,34 @@ config_update() { enabled=$(toml_get "$t" enabled) || enabled=true if [ "$enabled" = false ]; then continue; fi PATCHES_SRC=$(toml_get "$t" patches-source) || PATCHES_SRC=$DEF_PATCHES_SRC - if [[ -v sources[$PATCHES_SRC] ]]; then - if [ "${sources[$PATCHES_SRC]}" = 1 ]; then + PATCHES_VER=$(toml_get "$t" patches-version) || PATCHES_VER=$DEF_PATCHES_VER + if [[ -v sources["$PATCHES_SRC/$PATCHES_VER"] ]]; then + if [ "${sources["$PATCHES_SRC/$PATCHES_VER"]}" = 1 ]; then conf+="$t" conf+=$'\n' fi else - sources[$PATCHES_SRC]=0 - if ! last_patches=$(gh_req "https://api.github.com/repos/${PATCHES_SRC}/releases/latest" - | - jq -e -r '.assets[] | select(.name | endswith("jar")) | .name'); then + sources["$PATCHES_SRC/$PATCHES_VER"]=0 + local rv_rel="https://api.github.com/repos/${PATCHES_SRC}/releases" + if [ "$PATCHES_VER" = "dev" ]; then + last_patches=$(gh_req "$rv_rel" - | jq -e -r '.[0]') + elif [ "$PATCHES_VER" = "latest" ]; then + last_patches=$(gh_req "$rv_rel/latest" -) + else + last_patches=$(gh_req "$rv_rel/tags/${ver}" -) + fi + + if ! last_patches=$(jq -e -r '.assets[] | select(.name | endswith("jar")) | .name' <<<"$last_patches"); then abort oops fi - cur_patches=$(sed -n "s/.*Patches: ${PATCHES_SRC%%/*}\/\(.*\)/\1/p" build.md | xargs) - if [ "$cur_patches" ] && [ "$last_patches" ]; then - if [ "${cur_patches}" != "$last_patches" ]; then - sources[$PATCHES_SRC]=1 + if [ "$last_patches" ]; then + if ! OP=$(grep "^Patches: ${PATCHES_SRC%%/*}/" build.md | grep "$last_patches"); then + sources["$PATCHES_SRC/$PATCHES_VER"]=1 prcfg=true conf+="$t" conf+=$'\n' else - echo "Patches: ${PATCHES_SRC%%/*}/${cur_patches} " >>$TEMP_DIR/skipped + echo "$OP" >>"$TEMP_DIR"/skipped fi fi fi @@ -146,6 +195,7 @@ _req() { if [ "$op" = - ]; then wget -nv -O "$op" "$@" "$ip" else + if [ -f "$op" ]; then return; fi local dlp dlp="$(dirname "$op")/tmp.$(basename "$op")" if [ -f "$dlp" ]; then @@ -200,36 +250,81 @@ isoneof() { return 1 } +merge_splits() { + local bundle=$1 output=$2 + pr "Merging splits" + gh_dl "$TEMP_DIR/apkeditor.jar" "https://github.com/REAndroid/APKEditor/releases/download/V1.3.9/APKEditor-1.3.9.jar" >/dev/null || return 1 + if ! OP=$(java -jar "$TEMP_DIR/apkeditor.jar" merge -i "${bundle}" -o "${bundle}.mzip" -clean-meta -f 2>&1); then + epr "$OP" + return 1 + fi + # this is required because of apksig + mkdir "${bundle}-zip" + unzip -qo "${bundle}.mzip" -d "${bundle}-zip" + cd "${bundle}-zip" || abort + zip -0rq "${bundle}.zip" . + cd "$CWD" || abort + # if building apk, sign the merged apk properly + if isoneof "module" "${build_mode_arr[@]}"; then + patch_apk "${bundle}.zip" "${output}" "--exclusive" "${args[cli]}" "${args[ptjar]}" + local ret=$? + else + cp "${bundle}.zip" "${output}" + local ret=$? + fi + rm -r "${bundle}-zip" "${bundle}.zip" "${bundle}.mzip" || : + return $ret +} + # -------------------- apkmirror -------------------- -dl_apkmirror() { - local url=$1 version=${2// /-} output=$3 arch=$4 dpi=$5 apkorbundle=APK - if [ "$arch" = "arm-v7a" ]; then arch="armeabi-v7a"; fi - local apparch resp node app_table dlurl="" +apk_mirror_search() { + local resp="$1" dpi="$2" arch="$3" apk_bundle="$4" + local apparch dlurl node app_table if [ "$arch" = all ]; then apparch=(universal noarch 'arm64-v8a + armeabi-v7a') else apparch=("$arch" universal noarch 'arm64-v8a + armeabi-v7a'); fi - url="${url}/${url##*/}-${version//./-}-release/" - resp=$(req "$url" -) || return 1 - node=$($HTMLQ "div.table-row.headerFont:nth-last-child(1)" -r "span:nth-child(n+3)" <<<"$resp") - if [ "$node" ]; then - for ((n = 1; n < 40; n++)); do - node=$($HTMLQ "div.table-row.headerFont:nth-last-child($n)" -r "span:nth-child(n+3)" <<<"$resp") - if [ -z "$node" ]; then break; fi - app_table=$($HTMLQ --text --ignore-whitespace <<<"$node") - if [ "$(sed -n 3p <<<"$app_table")" = "$apkorbundle" ] && { [ "$apkorbundle" = BUNDLE ] || - { [ "$apkorbundle" = APK ] && [ "$(sed -n 6p <<<"$app_table")" = "$dpi" ] && - isoneof "$(sed -n 4p <<<"$app_table")" "${apparch[@]}"; }; }; then - dlurl=$($HTMLQ --base https://www.apkmirror.com --attribute href "div:nth-child(1) > a:nth-child(1)" <<<"$node") - break + for ((n = 1; n < 40; n++)); do + node=$($HTMLQ "div.table-row.headerFont:nth-last-child($n)" -r "span:nth-child(n+3)" <<<"$resp") + if [ -z "$node" ]; then break; fi + app_table=$($HTMLQ --text --ignore-whitespace <<<"$node") + if [ "$(sed -n 3p <<<"$app_table")" = "$apk_bundle" ] && [ "$(sed -n 6p <<<"$app_table")" = "$dpi" ] && + isoneof "$(sed -n 4p <<<"$app_table")" "${apparch[@]}"; then + dlurl=$($HTMLQ --base https://www.apkmirror.com --attribute href "div:nth-child(1) > a:nth-child(1)" <<<"$node") + echo "$dlurl" + return 0 + fi + done + return 1 +} +dl_apkmirror() { + local url=$1 version=${2// /-} output=$3 arch=$4 dpi=$5 is_bundle=false + if [ -f "${output}.apkm" ]; then + is_bundle=true + else + if [ "$arch" = "arm-v7a" ]; then arch="armeabi-v7a"; fi + local resp node app_table dlurl="" + url="${url}/${url##*/}-${version//./-}-release/" + resp=$(req "$url" -) || return 1 + node=$($HTMLQ "div.table-row.headerFont:nth-last-child(1)" -r "span:nth-child(n+3)" <<<"$resp") + if [ "$node" ]; then + if ! dlurl=$(apk_mirror_search "$resp" "$dpi" "${arch}" "APK"); then + if ! dlurl=$(apk_mirror_search "$resp" "$dpi" "${arch}" "BUNDLE"); then + return 1 + else is_bundle=true; fi fi - done - [ -z "$dlurl" ] && return 1 - resp=$(req "$dlurl" -) + [ -z "$dlurl" ] && return 1 + resp=$(req "$dlurl" -) + fi + url=$(echo "$resp" | $HTMLQ --base https://www.apkmirror.com --attribute href "a.btn") || return 1 + url=$(req "$url" - | $HTMLQ --base https://www.apkmirror.com --attribute href "span > a[rel = nofollow]") || return 1 + fi + + if [ "$is_bundle" = true ]; then + req "$url" "${output}.apkm" + merge_splits "${output}.apkm" "${output}" + else + req "$url" "${output}" fi - url=$(echo "$resp" | $HTMLQ --base https://www.apkmirror.com --attribute href "a.btn") || return 1 - if [ "$apkorbundle" = BUNDLE ] && [[ $url != *"&forcebaseapk=true" ]]; then url="${url}&forcebaseapk=true"; fi - url=$(req "$url" - | $HTMLQ --base https://www.apkmirror.com --attribute href "span > a[rel = nofollow]") || return 1 - req "$url" "$output" } get_apkmirror_vers() { local vers apkm_resp @@ -312,8 +407,10 @@ patch_apk() { --keystore-entry-password=123456789 --keystore-password=123456789 --signer=jhc --keystore-entry-alias=jhc --options=options.json" if [ "$OS" = Android ]; then cmd+=" --custom-aapt2-binary=${AAPT2}"; fi pr "$cmd" - eval "$cmd" - [ -f "$patched_apk" ] + if eval "$cmd"; then [ -f "$patched_apk" ]; else + rm "$patched_apk" 2>/dev/null || : + return 1 + fi } check_sig() { @@ -327,7 +424,7 @@ check_sig() { build_rv() { eval "declare -A args=${1#*=}" - local version build_mode_arr pkg_name + local version="" pkg_name="" local mode_arg=${args[build_mode]} version_mode=${args[version]} local app_name=${args[app_name]} local app_name_l=${app_name,,} @@ -341,13 +438,15 @@ build_rv() { p_patcher_args+=("$(join_args "${args[excluded_patches]}" -e) $(join_args "${args[included_patches]}" -i)") [ "${args[exclusive_patches]}" = true ] && p_patcher_args+=("--exclusive") + local tried_dl=() for dl_p in archive apkmirror uptodown; do if [ -z "${args[${dl_p}_dlurl]}" ]; then continue; fi - if ! get_"${dl_p}"_resp "${args[${dl_p}_dlurl]}" || ! pkg_name=$(get_"${dl_p}"_pkg_name); then + if ! get_${dl_p}_resp "${args[${dl_p}_dlurl]}" || ! pkg_name=$(get_"${dl_p}"_pkg_name); then args[${dl_p}_dlurl]="" epr "ERROR: Could not find ${table} in ${dl_p}" continue fi + tried_dl+=("$dl_p") dl_from=$dl_p break done @@ -377,6 +476,15 @@ build_rv() { epr "empty version, not building ${table}." return 0 fi + + if [ "$mode_arg" = module ]; then + build_mode_arr=(module) + elif [ "$mode_arg" = apk ]; then + build_mode_arr=(apk) + elif [ "$mode_arg" = both ]; then + build_mode_arr=(apk module) + fi + pr "Choosing version '${version}' for ${table}" local version_f=${version// /} version_f=${version_f#v} @@ -385,6 +493,7 @@ build_rv() { for dl_p in archive apkmirror uptodown; do if [ -z "${args[${dl_p}_dlurl]}" ]; then continue; fi pr "Downloading '${table}' from ${dl_p}" + if ! isoneof $dl_p "${tried_dl[@]}"; then get_${dl_p}_resp "${args[${dl_p}_dlurl]}"; fi if ! dl_${dl_p} "${args[${dl_p}_dlurl]}" "$version" "$stock_apk" "$arch" "${args[dpi]}" "$get_latest_ver"; then epr "ERROR: Could not download '${table}' from ${dl_p} with version '${version}', arch '${arch}', dpi '${args[dpi]}'" continue @@ -406,13 +515,6 @@ build_rv() { p_patcher_args=("${p_patcher_args[@]//-[ei] ${microg_patch}/}") fi - if [ "$mode_arg" = module ]; then - build_mode_arr=(module) - elif [ "$mode_arg" = apk ]; then - build_mode_arr=(apk) - elif [ "$mode_arg" = both ]; then - build_mode_arr=(apk module) - fi local patcher_args patched_apk build_mode local rv_brand_f=${args[rv_brand],,} rv_brand_f=${rv_brand_f// /-} @@ -441,7 +543,7 @@ build_rv() { fi fi fi - if [ ! -f "$patched_apk" ] || [ "$REBUILD" = true ]; then + if [ "${NORB:-}" != true ] || [ ! -f "$patched_apk" ]; then if ! patch_apk "$stock_apk" "$patched_apk" "${patcher_args[*]}" "${args[cli]}" "${args[ptjar]}"; then epr "Building '${table}' failed!" return 0 @@ -449,12 +551,12 @@ build_rv() { fi if [ "$build_mode" = apk ]; then local apk_output="${BUILD_DIR}/${app_name_l}-${rv_brand_f}-v${version_f}-${arch_f}.apk" - cp -f "$patched_apk" "$apk_output" + mv -f "$patched_apk" "$apk_output" pr "Built ${table} (non-root): '${apk_output}'" continue fi local base_template - base_template=$(mktemp -d -p $TEMP_DIR) + base_template=$(mktemp -d -p "$TEMP_DIR") cp -a $MODULE_TEMPLATE_DIR/. "$base_template" local upj="${table,,}-update.json" @@ -468,14 +570,12 @@ build_rv() { "$base_template" local module_output="${app_name_l}-${rv_brand_f}-magisk-v${version_f}-${arch_f}.zip" - if [ ! -f "$module_output" ] || [ "$REBUILD" = true ]; then - pr "Packing module ${table}" - cp -f "$patched_apk" "${base_template}/base.apk" - if [ "${args[include_stock]}" = true ]; then cp -f "$stock_apk" "${base_template}/${pkg_name}.apk"; fi - pushd >/dev/null "$base_template" || abort "Module template dir not found" - zip -"$COMPRESSION_LEVEL" -FSqr "../../${BUILD_DIR}/${module_output}" . - popd >/dev/null || : - fi + pr "Packing module ${table}" + cp -f "$patched_apk" "${base_template}/base.apk" + if [ "${args[include_stock]}" = true ]; then cp -f "$stock_apk" "${base_template}/${pkg_name}.apk"; fi + pushd >/dev/null "$base_template" || abort "Module template dir not found" + zip -"$COMPRESSION_LEVEL" -FSqr "${BUILD_DIR}/${module_output}" . + popd >/dev/null || : pr "Built ${table} (root): '${BUILD_DIR}/${module_output}'" done } @@ -497,7 +597,7 @@ MODULE_ARCH=$ma" >"$1/config" module_prop() { echo "id=${1} name=${2} -version=v${3} +version=v${3} (${NEXT_VER_CODE}) versionCode=${NEXT_VER_CODE} author=j-hc description=${4}" >"${6}/module.prop"