Files
backup_script/tools/tools.sh
2026-04-29 20:08:41 +08:00

601 lines
25 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/system/bin/sh
# ============================================================
# SpeedBackup - Android 備份恢復腳本
# By @YAWAsau
# ============================================================
#
# 模組化結構 — 函數定義已移至 tools/core/
# core/config_mgmt.sh - 配置檔生成
# core/base_utils.sh - 基礎工具函數
# core/app_utils.sh - 應用/進程/權限管理
# core/backup_core.sh - 備份核心邏輯
# core/restore_core.sh - 恢復核心邏輯
# core/updater.sh - 更新/列表/WiFi/設備
#
# 本文件為執行入口,包含:
# L21-32 全局變量與初始檢查
# L33-43 模組載入
# L44-77 配置檔加載與語言設定
# L78-217 環境設置 (PATH/busybox/SHA/TMPDIR)
# L218-292 硬件信息/語言檢測
# L293-369 用戶檢測與環境別名
# L370-498 更新檢查流程
# L499-510 後台應用檢測
# L511-599 入口分發 (菜單/直接執行)
# ============================================================
if [ "$(whoami)" != root ]; then
echo "你是憨批不給Root用你媽 爬"
exit 1
fi
[[ -d /data/cache ]] && set -x 2> /data/cache/debug_output.log
shell_language="zh-TW"
MODDIR_NAME="${MODDIR##*/}"
tools_path="$MODDIR/tools"
script="${0##*/}"
backup_version="202508162209"
[[ $SHELL = *mt* ]] && echo "請勿使用MT管理器拓展包環境執行,請更換系統環境" && exit 2
# ======================== Section 2: 配置檔生成與加載 ========================
# --- Load core modules ---
core_path="$MODDIR/tools/core"
[[ ! -d $core_path ]] && core_path="${0%/*}/core"
. "$core_path/config_mgmt.sh"
. "$core_path/base_utils.sh"
. "$core_path/app_utils.sh"
. "$core_path/backup_core.sh"
. "$core_path/restore_core.sh"
. "$core_path/updater.sh"
# --- End module loading ---
if [[ ! -d $tools_path ]]; then
tools_path="${MODDIR%/*}/tools"
[[ ! -d $tools_path ]] && echo "$tools_path二進制目錄遺失" && EXIT="true"
fi
if [[ ! -f $conf_path ]]; then
if [[ $conf_path != *restore_settings.conf && $conf_path = *backup_settings.conf ]]; then
update_backup_settings_conf>"$conf_path"
else
if [[ $conf_path = *restore_settings.conf && $conf_path != *backup_settings.conf ]]; then
update_Restore_settings_conf>"$conf_path"
else
echo "$conf_path配置遺失" && exit 1
fi
fi
echo "因腳本找不到\n$conf_path\n故重新生成默認列表\n請重新配置後重新執行腳本" && exit 0
fi
[[ ! -f $conf_path ]] && echo "$conf_path遺失" && exit 2
. "$conf_path" &>/dev/null
# 加載後立即更新配置(補充新選項)
if [[ $conf_path != *restore_settings.conf && $conf_path = *backup_settings.conf ]]; then
update_backup_settings_conf>"$conf_path"
else
if [[ $conf_path = *restore_settings.conf && $conf_path != *backup_settings.conf ]]; then
update_Restore_settings_conf>"$conf_path"
else
echo "$conf_path配置遺失" && exit 1
fi
fi
case $Shell_LANG in
1) LANG="CN" ;;
0) LANG="TW" ;;
*) LANG="${LANG:="$(getprop "persist.sys.locale")"}" ;;
esac
# ======================== Section 3: 基礎工具函數 ========================
rgb_a="${rgb_a:=214}"
abi="$(getprop ro.product.cpu.abi)"
case $abi in
arm64*)
if [[ $(getprop ro.build.version.sdk) -lt 26 ]]; then
echoRgb "設備Android $(getprop ro.build.version.release)版本過低 請升級至Android 8+" "0"
exit 1
else
case $(getprop ro.build.version.sdk) in
26|27|28)
echoRgb "設備Android $(getprop ro.build.version.release)版本偏低,無法確定腳本能正確的使用" "0"
;;
esac
fi
;;
*)
echoRgb "未知的架構: $abi" "0"
exit 1
;;
esac
get_mv="$(which mv)"
PATH="/system/bin:/system/xbin:/data/adb/ksu/bin:/sbin/.magisk/busybox:/sbin/.magisk:/sbin:/system_ext/bin:/vendor/bin:/vendor/xbin:/data/data/com.omarea.vtools/files/toolkit:/data/user/0/com.termux/files/usr/bin"
if [[ -d $(magisk --path 2>/dev/null) ]]; then
PATH="$(magisk --path 2>/dev/null)/.magisk/busybox:$PATH"
else
[[ $(ksud -V 2>/dev/null) = "" ]] && echo "Magisk busybox Path does not exist"
fi
export PATH="$PATH"
filepath="/data/backup_tools"
busybox="$filepath/busybox"
busybox2="$tools_path/busybox"
#排除自身
exclude="
update
soc.json
classes.dex
Device_List"
if [[ ! -d $filepath ]]; then
mkdir -p "$filepath"
[[ $? = 0 ]] && echoRgb "設置busybox環境中"
fi
#刪除無效軟連結
find -L "$filepath" -maxdepth 1 -type l -exec rm -rf {} \;
if [[ -f $busybox && -f $busybox2 ]]; then
filesha256="$(sha256sum "$busybox" | cut -d" " -f1)"
filesha256_1="$(sha256sum "$busybox2" | cut -d" " -f1)"
if [[ $filesha256 != $filesha256_1 ]]; then
echoRgb "busybox sha256不一致 重新創立環境中"
rm -rf "$filepath"/*
fi
fi
find "$tools_path" -maxdepth 1 ! -path "$tools_path/tools.sh" -type f | egrep -v "$(echo $exclude | sed 's/ /\|/g')" | while read; do
File_name="${REPLY##*/}"
if [[ ! -f $filepath/$File_name ]]; then
cp -r "$REPLY" "$filepath"
chmod 0755 "$filepath/$File_name"
echoRgb "$File_name > $filepath/$File_name"
else
filesha256="$(sha256sum "$filepath/$File_name" | cut -d" " -f1)"
filesha256_1="$(sha256sum "$tools_path/$File_name" | cut -d" " -f1)"
if [[ $filesha256 != $filesha256_1 ]]; then
echoRgb "$File_name sha256不一致 重新創建"
cp -r "$REPLY" "$filepath"
chmod 0755 "$filepath/$File_name"
echoRgb "$File_name > $filepath/$File_name"
fi
fi
done
if [[ -f $busybox ]]; then
"$busybox" --list | while read; do
if [[ $REPLY != tar && $REPLY != bc && ! -f $filepath/$REPLY ]]; then
ln -fs "$busybox" "$filepath/$REPLY"
fi
done
fi
[[ ! -f $filepath/zstd ]] && echoRgb "$filepath缺少zstd" && exit 2
export PATH="$filepath:$PATH"
export TZ=Asia/Taipei
ln -fs "$tools_path/classes.dex" "$filepath/classes.dex"
export CLASSPATH="$filepath/classes.dex"
quit=0
while read -r file expected_hash; do
if [[ -f $tools_path/$file ]]; then
computed_hash="$(sha256sum "$tools_path/$file" | awk '{print $1}')"
if [[ $computed_hash = $expected_hash ]]; then
echoRgb "$file: 驗證通過"
else
echoRgb "$tools_path/$file: SHA-256 不一致\n -\"$computed_hash\""
quit=2
break
fi
else
echoRgb "⚠️ 檔案 $tools_path/$file 不存在"
quit=1
break
fi
done <<< "$(cat <<EOF
zstd ab32aecb389c3ba5c1f7ab05d5eb6a861bad80261fd14ef9a8f4c283ac48c22c
tar 3c605b1e9eb8283555225dcad4a3bf1777ae39c5f19a2c8b8943140fd7555814
classes.dex 63934f7d15de40f4b188672e36fe22a01b55abb235becee2c2738f29aaf8299b
bc b15d730591f6fb52af59284b87d939c5bea204f944405a3518224d8df788dc15
busybox 4d60ab3f5a59ebb2ca863f2f514e6924401b581e9b64f602665c008177626651
find 7fa812e58aafa29679cf8b50fc617ecf9fec2cfb2e06ea491e0a2d6bf79b903b
jq 4dd2d8a0661df0b22f1bb9a1f9830f06b6f3b8f7d91211a1ef5d7c4f06a8b4a5
keycheck 50645ee0e0d2a7d64fb4a1286446df7a4445f3d11aefd49eeeb88515b314c363
cmd 08da8ac23b6e99788fd3ce6c19c7b5a083b2ad48be35963a48d01d6ee7f3bb6d
EOF)"
if [[ $background_execution = 1 || $setDisplayPowerMode = 1 ]]; then
alias notification="app_process /system/bin com.xayah.dex.NotificationUtil notify -t 'SpeedBackup' "$@""
else
alias notification="&>/dev/null"
fi
if [[ $quit -ne 0 ]]; then
exit "$quit"
fi
TMPDIR="/data/local/tmp/SpeedBackup"
[[ ! -d $TMPDIR ]] && mkdir -p "$TMPDIR"
[[ -n $TMPDIR && $TMPDIR = /data/local/tmp/* ]] && rm -rf "$TMPDIR"/*
chmod 771 "$TMPDIR"
chown '2000:2000' "$TMPDIR"
if [[ $(which busybox) = "" ]]; then
echoRgb "環境變量中沒有找到busybox 請在tools內添加一個\narm64可用的busybox\n或是安裝搞機助手 scene或是Magisk busybox模塊...." "0"
exit 1
fi
if [[ $(which toybox | egrep -o "system") != system ]]; then
echoRgb "系統變量中沒有找到toybox" "0"
exit 1
fi
#下列為自定義函數
alias down="app_process /system/bin com.xayah.dex.HttpUtil get $@"
case $LANG in
*CN* | *cn*)
alias ts="app_process /system/bin com.xayah.dex.CCUtil t2s $@" ;;
*)
alias ts="app_process /system/bin com.xayah.dex.CCUtil s2t $@" ;;
esac
alias LS="toybox ls -Zd"
alias mv="$get_mv"
nskg=1
echo $$
kill_Serve
[[ -f /sys/block/sda/size ]] && ROM_TYPE="UFS" || ROM_TYPE="eMMC"
if [[ -f /proc/scsi/scsi ]]; then
UFS_MODEL="$(sed -n 3p /proc/scsi/scsi | awk '/Vendor/{print $2,$4}')"
else
if [[ $(cat "/sys/class/block/sda/device/inquiry" 2>/dev/null) != "" ]]; then
UFS_MODEL="$(cat "/sys/class/block/sda/device/inquiry")"
else
UFS_MODEL="unknown"
fi
fi
[[ $(egrep -w "$(getprop ro.product.model 2>/dev/null)" "$tools_path/Device_List" | awk -F'"' '{print $4}') != "" ]] && Device_name="$(egrep -w "$(getprop ro.product.model 2>/dev/null)" "$tools_path/Device_List" | awk -F'"' '{print $4}' | head -1)" || Device_name="$(getprop ro.product.model 2>/dev/null)"
if [[ $(su -v 2>/dev/null) != "" ]]; then
Manager_version="$(su -v 2>/dev/null)"
[[ $Manager_version = *KernelSU* ]] && ksu="ksu"
[[ $ksu = "" ]] && [[ -d /data/adb/ksu ]] && ksu="ksu"
else
if [[ -d /data/adb/ksu ]]; then
Manager_version=KernelSU
ksu="ksu"
fi
fi
Socname="$(getprop ro.soc.model)"
if [[ $Socname != "" ]]; then
if [[ -f $tools_path/soc.json ]]; then
jq -r --arg device "$Socname" '.[$device] | "處理器:\(.VENDOR) \(.NAME)"' "$tools_path/soc.json" &>/dev/null
if [[ $? = 0 ]]; then
DEVICE_NAME="$(jq -r --arg device "$Socname" '.[$device] | "處理器:\(.VENDOR) \(.NAME)"' "$tools_path/soc.json" 2>/dev/null)"
jq -r --arg device "$Socname" '.[$device] | "RAM:\(.MEMORY) \(.CHANNELS)"' "$tools_path/soc.json" &>/dev/null
if [[ $? = 0 ]]; then
RAMINFO="$(jq -r --arg device "$Socname" '.[$device] | "RAM:\(.MEMORY) \(.CHANNELS)"' "$tools_path/soc.json" 2>/dev/null)"
else
RAMINFO="RAM:null"
fi
else
DEVICE_NAME="處理器:null"
RAMINFO="RAM:null"
fi
else
DEVICE_NAME="處理器:null"
RAMINFO="RAM:null"
fi
else
DEVICE_NAME="處理器:null"
RAMINFO="RAM:null"
fi
echoRgb "---------------------SpeedBackup---------------------"
echoRgb "腳本路徑:$MODDIR\n -已開機:$(Show_boottime)\n -執行時間:$(date +"%Y-%m-%d %H:%M:%S")\n -busybox路徑:$(which busybox)\n -busybox版本:$(busybox | head -1 | cut -d' ' -f2)\n -腳本版本:$backup_version\n -管理器:$Manager_version\n -品牌:$(getprop ro.product.brand 2>/dev/null)\n -型號:$Device_name($(getprop ro.product.device 2>/dev/null))\n -閃存顆粒:$UFS_MODEL($ROM_TYPE)\n -$DEVICE_NAME\n -$RAMINFO\n -Android版本:$(getprop ro.build.version.release 2>/dev/null) SDK:$(getprop ro.build.version.sdk 2>/dev/null)\n -內核:$(uname -r)\n -Selinux狀態:$([[ $(getenforce) = Permissive ]] && echo "寬容" || echo "嚴格")\n -By@YAWAsau\n -Support: https://jq.qq.com/?_wv=1027&k=f5clPNC3"
case $MODDIR in
*Backup_*)
if [[ -f $MODDIR/app_details.json ]]; then
if [[ -d ${MODDIR%/*/*}/tools ]]; then
path_hierarchy="${MODDIR%/*/*}"
else
path_hierarchy="${MODDIR%/*}"
fi
else
if [[ -d ${MODDIR%/*}/tools ]]; then
path_hierarchy="${MODDIR%/*}"
else
[[ -d $MODDIR/tools ]] && path_hierarchy="$MODDIR"
fi
fi ;;
*) [[ -d $MODDIR/tools ]] && path_hierarchy="$MODDIR" ;;
esac
[[ $LANG = "" ]] && echoRgb "系統無參數語言獲取失敗\n -如果需要更改腳本語言請於$conf_path\n -Shell_LANG=填入對應數字" "0"
case $LANG in
*TW* | *tw* | *HK*)
Script_target_language="zh-TW" ;;
*CN* | *cn*)
Script_target_language="zh-CN" ;;
esac
echoRgb "$Script_target_language腳本"
# ======================== Section 4: 用戶檢測與環境別名 ========================
if [[ ! -f ${0%/*}/app_details.json ]]; then
if [[ $user = "" ]]; then
user_id="$(ls /data/user | tr ' ' '\n')"
if [[ $user_id != "" && $(ls /data/user | tr ' ' '\n' | wc -l) -gt 1 ]]; then
echo "$user_id" | while read ; do
[[ $REPLY = 0 ]] && echoRgb "主用戶:$REPLY" "2" || echoRgb "分身用戶:$REPLY" "2"
done
echoRgb "設備存在多用戶,選擇操作目標用戶"
if [[ $(echo "$user_id" | wc -l) = 2 ]]; then
user1="$(echo "$user_id" | sed -n '1p')"
user2="$(echo "$user_id" | sed -n '2p')"
case $Lo in
0|1)
echoRgb "音量上選擇用戶:$user1,音量下選擇用戶:$user2" "2"
Select_user="true"
get_version "$user1" "$user2" && user="$branch"
unset Select_user ;;
2)
Enter_options "輸入1選擇用戶:$user1 0用戶:$user2" "$user1" "$user2"
case $parameter in
0) user="$user2" ;;
1) user="$user1" ;;
esac ;;
esac
else
while true ;do
if [[ $option != "" ]]; then
user="$option"
break
else
echoRgb "請輸入需要操作目標分區" "1"
read option
fi
done
fi
else
user="0"
fi
else
user_id="$(ls /data/user | tr ' ' '\n')"
if [[ $user_id != "" && $(ls /data/user | tr ' ' '\n' | wc -l) -gt 1 ]]; then
echo "$user_id" | while read ; do
[[ $REPLY = 0 ]] && echoRgb "主用戶:$REPLY" "2" || echoRgb "分身用戶:$REPLY" "2"
done
else
echoRgb "主用戶:$user_id" "2"
fi
fi
else
case $(echo "${0%}") in
*zstd*) user="$(echo "${0%}" | sed 's/.*\/Backup_zstd_\([0-9]*\).*/\1/')" ;;
*tar*) user="$(echo "${0%}" | sed 's/.*\/Backup_tar_\([0-9]*\).*/\1/')" ;;
*) echoRgb "請勿修改備份資料夾名稱保持原本的Backup_壓縮算法名稱_使用者id" "0" && exit 2 ;;
esac
fi
[[ $user != 0 ]] && am start-user "$user"
path="/data/media/$user/Android"
path2="/data/user/$user"
path3="/data/user_de/$user"
[[ ! -d $path2 ]] && echoRgb "$user分區不存在請將上方提示的用戶id按照需求填入\n -$conf_path配置項user=,一次只能填寫一個" "0" && exit 2
echoRgb "當前操作為用戶$user"
export USER_ID="$user"
unset LD_LIBRARY_PATH
#因接收USER_ID環境變量問題故將函數放在此處
alias appinfo="app_process /system/bin com.xayah.dex.HiddenApiUtil getInstalledPackagesAsUser $USER_ID $@"
alias appinfo2="app_process /system/bin com.xayah.dex.HiddenApiUtil getPackageLabel $USER_ID $@"
alias appinfo3="app_process /system/bin com.xayah.dex.HiddenApiUtil getPackageArchiveInfo $@"
alias get_ssaid="app_process /system/bin com.xayah.dex.SsaidUtil get $USER_ID $@"
alias set_ssaid="app_process /system/bin com.xayah.dex.SsaidUtil set $USER_ID $@"
alias get_uid="app_process /system/bin com.xayah.dex.HiddenApiUtil getPackageUid $USER_ID $@"
alias get_Permissions="app_process /system/bin com.xayah.dex.HiddenApiUtil getRuntimePermissions $USER_ID $@"
alias Set_true_Permissions="app_process /system/bin com.xayah.dex.HiddenApiUtil grantRuntimePermission $USER_ID $@"
alias Set_false_Permissions="app_process /system/bin com.xayah.dex.HiddenApiUtil revokeRuntimePermission $USER_ID $@"
alias Set_Ops="app_process /system/bin com.xayah.dex.HiddenApiUtil setOpsMode $USER_ID $@"
alias setDisplay="app_process /system/bin com.xayah.dex.HiddenApiUtil setDisplayPowerMode $@"
find_tools_path="$(find "$path_hierarchy"/* -maxdepth 1 -name "tools" -type d ! -path "$path_hierarchy/tools")"
# ======================== Section 5: WiFi/腳本生成/重命名工具 ========================
# ======================== Section 6: 腳本更新邏輯 ========================
update_script
zipFile="$(ls -t /storage/emulated/0/Download/*.zip 2>/dev/null | head -1)"
if [[ $(unzip -l "$zipFile" 2>/dev/null | awk '{print $4}' | egrep -wo "^backup_settings.conf$") != "" ]]; then
update_script
else
zipFile="$(ls -t /storage/emulated/0/Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/*.zip 2>/dev/null | head -1)"
[[ $(unzip -l "$zipFile" 2>/dev/null | awk '{print $4}' | egrep -wo "^backup_settings.conf$") != "" ]] && update_script
fi
SDK_V="$(getprop ro.build.version.sdk)"
if [[ $SDK_V -lt 30 ]]; then
alias INSTALL="pm install --user $user -r -t >/dev/null"
alias create="pm install-create --user $user -tl"
elif [[ $SDK_V -gt 33 ]]; then
alias INSTALL="pm install -r --bypass-low-target-sdk-block -i com.android.vending --user $user -t >/dev/null"
alias create="pm install-create -i com.android.vending --bypass-low-target-sdk-block --user $user -t"
else
alias INSTALL="pm install -r -i com.android.vending --user $user -t >/dev/null"
alias create="pm install-create -i com.android.vending --user $user -t"
fi
#settings get system system_locales
Language="https://api.github.com/repos/YAWAsau/backup_script/releases/latest"
if [[ $path_hierarchy != "" && $Script_target_language != "" ]]; then
K=1
J="$(find "$path_hierarchy" -maxdepth 3 -name "tools.sh" -type f | wc -l)"
find "$path_hierarchy" -maxdepth 3 -name "tools.sh" -type f | while read ; do
unset shell_language
shell_language="$(awk -F= '/^shell_language=/ {gsub(/"/, "", $2); print $2}' "$REPLY")"
case $shell_language in
zh-CN|zh-TW)
if [[ $Script_target_language != $shell_language ]]; then
[[ $K = 1 ]] && echoRgb "腳本語言為$shell_language....轉換為$Script_target_language中,請稍後等待轉換...."
ts <"$REPLY">temp && cp temp "$REPLY" && rm temp
if [[ $? = 0 ]]; then
touch "$TMPDIR/0"
echo_log "$(echo "$REPLY" | sed "s|^$path_hierarchy/||")翻譯"
MODDIR="${0%/*}"
if [[ -f ${REPLY%/*/*}/backup_settings.conf ]]; then
update_backup_settings_conf>"${REPLY%/*/*}/backup_settings.conf"
ts <"${REPLY%/*/*}/backup_settings.conf">temp && cp temp "${REPLY%/*/*}/backup_settings.conf" && rm temp
echo_log "${REPLY%/*/*}/backup_settings.conf翻譯"
fi
if [[ -f ${REPLY%/*/*}/restore_settings.conf ]]; then
update_Restore_settings_conf>"${REPLY%/*/*}/restore_settings.conf"
ts <"${REPLY%/*/*}/restore_settings.conf">temp && cp temp "${REPLY%/*/*}/restore_settings.conf" && rm temp
echo_log "${REPLY%/*/*}/restore_settings.conf翻譯"
fi
sed "s/shell_language=\"$shell_language\"/shell_language=\"$Script_target_language\"/g" "$REPLY" > temp && cp temp "$REPLY" && rm temp
[[ $shell_language != $(awk -F= '/^shell_language=/ {gsub(/"/, "", $2); print $2}' "$REPLY") ]] && echoRgb "$(echo "$REPLY" | sed "s|^$path_hierarchy/||")變量修改成功" || echoRgb "$(echo "$REPLY" | sed "s|^$path_hierarchy/||")變量修改失敗" "0"
ts <"${REPLY%/*}/Device_List">temp && cp temp "${REPLY%/*}/Device_List" && rm temp
echo_log "${REPLY%/*}/Device_List翻譯"
[[ $K = 1 ]] && Rename_script
else
echoRgb "$REPLY ts進程出現錯誤" "0"
fi
K=$((K + 1))
fi ;;
esac
done
[[ -e $TMPDIR/0 ]] && rm "$TMPDIR/0" && echoRgb "轉換腳本完成,退出腳本重新執行即可使用" && exit 2
fi
#校驗選填是否正確
case $Lo in
0)
[[ $update != "" ]] && isBoolean "$update" "update" && update="$nsx" || {
echoRgb "自動更新腳本?\n -音量上更新,下不更新"
get_version "更新" "不更新" && update="$branch"
} ;;
1)
[[ $update = "" ]] && {
echoRgb "自動更新腳本?\n -音量上更新,下不更新"
get_version "更新" "不更新" && update="$branch"
} || isBoolean "$update" "update" && update="$nsx" ;;
2)
[[ $update = "" ]] && {
Enter_options "輸入1自動更新腳本輸入0不自動更新腳本" "更新" "不更新" && isBoolean "$parameter" "update" && update="$nsx"
} || {
isBoolean "$update" "update" && update="$nsx"
} ;;
*) echoRgb "$conf_path Lo=$Lo填寫錯誤正確值0 1 2" "0" && exit 2 ;;
esac
if [[ $update = true ]]; then
json="$(down "$Language")"
else
echoRgb "自動更新被關閉" "0"
fi
if [[ $json != "" ]]; then
tag="$(jq -r '.tag_name'<<< "$json" 2>/dev/null)"
if [[ $tag != "" && $backup_version != $tag ]]; then
if [[ $(expr "$(echo "$backup_version" | tr -d "a-zA-Z")" \> "$(echo "$tag" | tr -d "a-zA-Z")") -eq 0 ]]; then
download="$(jq -r '.assets[].browser_download_url'<<< "$json")"
case $cdn in
0) zip_url="$download" ;;
1) zip_url="https://ghfast.top/$download" ;;
2) zip_url="https://shrill-pond-3e81.hunsh.workers.dev/$download" ;;
*) echoRgb "$conf_path cdn=設置錯誤 範圍只能是0-2" && exit 2 ;;
esac
if [[ $(expr "$(echo "$backup_version" | tr -d "a-zA-Z")" \> "$(echo "$download" | tr -d "a-zA-Z")") -eq 0 ]]; then
echoRgb "發現新版本:$tag"
if [[ $update = true ]]; then
echoRgb "$(ts "更新日誌:\n$(down "$Language" | jq -r '.body')")"
case $Lo in
0|1)
echoRgb "是否更新腳本?\n -音量上更新,音量下不更新" "2"
get_version "更新" "不更新" && choose="$branch" ;;
2)
Enter_options "輸入1自動更新腳本輸入0不自動更新腳本" "更新" "不更新" && isBoolean "$parameter" "update" && update="$nsx" ;;
esac
if [[ $choose = true ]]; then
echoRgb "下載中.....耐心等待 如果下載失敗請掛飛機"
starttime1="$(date -u "+%s")"
down "$zip_url" >"$MODDIR/update.zip" &
wait
endtime 1
[[ ! -f $MODDIR/update.zip ]] && echoRgb "下載失敗" && exit 2
zipFile="$MODDIR/update.zip"
fi
else
echoRgb "$conf_path內update選項為0忽略更新僅提示更新" "0"
fi
fi
fi
fi
else
[[ $update = true ]] && echoRgb "更新獲取失敗" "0"
fi
update_script
# ======================== Section 7: 備份路徑/分區/APK/SSAID/權限 ========================
# ======================== Section 8: 數據備份與恢復核心 ========================
# ======================== Section 9: 應用列表管理與進程檢測 ========================
Background_application_list debug
pkgs="$(pm list packages --user "$user" | cut -f2 -d ':' | awk -v pkg="$(echo "$Backstage" | head -1)" '$1 == pkg {print $1}')"
if [[ $pkgs != "" ]]; then
echoRgb "後台應用獲取成功($pkgs)" "1"
[[ $(Process_Information "$pkgs") = "" ]] && echoRgb "應用pid獲取失敗" "0" || echoRgb "應用pid獲取成功$(Process_Information "$pkgs")" "1"
else
echoRgb "後台應用獲取失敗" "0" activity=false
fi
unset Backstage
# ======================== Section 10: 備份主流程 ========================
# ======================== Section 11: 恢復主流程 ========================
# ======================== Section 12: 應用列表生成 ========================
# ======================== Section 13: 入口分發 ========================
if [[ $0 = *backup.sh ]]; then
start=backup
else
[[ $0 = *recover.sh ]] && start=Restore
fi
if [[ $start != "" ]]; then
case $(grep -o 'background_execution=.*' "$conf_path" | awk -F '=' '{print $2}') in
0)
eval "$start" ;;
1)
{
eval "$start"
} & ;;
esac
else
if [[ -f $MODDIR/backup_settings.conf ]]; then
steps=(
"生成應用列表"
"備份應用"
"備份已更新應用"
"備份自定義資料夾"
"備份WiFi"
"殺死運行中腳本"
)
commands=(
"Getlist"
"backup"
"backup_update_apk"
"backup_media"
"wifi"
"echoRgb '等待腳本停止中,請稍後.....' && echoRgb '腳本終止'; exit"
)
elif [[ -f $MODDIR/restore_settings.conf ]]; then
steps=(
"重新生成應用列表"
"恢復備份"
"僅恢復包含ssaid應用(含數據)"
"僅恢復包含ssaid應用(不含數據)"
"恢復自定義資料夾"
"恢復wifi"
"壓縮檔完整性檢查"
"轉換文件夾名稱"
"殺死運行中腳本"
)
commands=(
"dumpname"
"Restore"
"ssaid_mode=true && Restore"
"ssaid_mode_1=true && Restore4"
"Restore3"
"recover_wifi \"$MODDIR/wifi\""
"check_file"
"convert"
"echoRgb '等待腳本停止中,請稍後.....' && echoRgb '腳本終止'; exit"
)
fi
echoRgb "請選擇要執行的操作:"
for i in "${!steps[@]}"; do
printf "%d) %s\n" "$((i+1))" "${steps[$i]}"
done
echo "x) 離開腳本"
echo -n "請輸入選項編號: "
read choice
case $choice in
x|X)
echoRgb "已退出腳本" "0"
exit 0 ;;
[1-9])
if (( choice >= 1 && choice <= ${#steps[@]} )); then
index=$((choice - 1))
echo "執行:${steps[$index]}"
background=$(grep -o 'background_execution=.*' "$conf_path" | awk -F '=' '{print $2}')
if [[ "$background" = "1" ]]; then
eval "${commands[$index]}" &
else
eval "${commands[$index]}"
fi
else
echoRgb "超出功能選項範圍1-${#steps[@]}" "0"
fi
;;
*)
echoRgb "輸入錯誤,請重新輸入有效的數字或輸入 x 離開。" "0" ;;
esac
fi