diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 300c8a88..275e0033 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,9 +62,12 @@ jobs: fi mkdir -p download - ./scripts/build.sh --arch ${{ inputs.arch }} --release-type $RLS_TYPE --magisk-branch topjohnwu --magisk-ver stable $WITH_GAPPS --root-sol ${{ inputs.root }} --remove-amazon --compress-format zip - env: - API_KEY: ${{ secrets.API_KEY }} + + if [[ "${{ inputs.root_sol }}" == *Magisk* ]]; then + ./scripts/build_with_lspinit.sh --arch ${{ inputs.arch }} --release-type $RLS_TYPE --magisk-branch topjohnwu --magisk-ver stable $WITH_GAPPS --root-sol ${{ inputs.root }} --remove-amazon --compress-format 7zip + else + ./scripts/build_with_mount.sh --arch ${{ inputs.arch }} --release-type $RLS_TYPE --magisk-branch topjohnwu --magisk-ver stable $WITH_GAPPS --root-sol ${{ inputs.root }} --remove-amazon --compress-format 7zip + fi - name: Pass to Windows 💸 uses: actions/upload-artifact@v4 diff --git a/.github/workflows/comment_on_issues.yml b/.github/workflows/comment_on_issues.yml index a1a509d5..2006c00c 100644 --- a/.github/workflows/comment_on_issues.yml +++ b/.github/workflows/comment_on_issues.yml @@ -82,6 +82,7 @@ jobs: subprocess.call(["echo '{}={}' >> $GITHUB_ENV".format(name, value)], shell=True) if __name__ == '__main__': issues = 'false' + ismagisk = 'false' iscustom = 'true' errinfo = body = '' try: @@ -95,11 +96,14 @@ jobs: else: iscustom = 'false' errinfo = 'Argument is invaild, please update the body of the Issues' + if re.match(".*arch.*64.*release-type.*root-sol\smagisk.*magisk-branch.*magisk-ver.*compress-format.*", body): + ismagisk = 'true' except Exception as e: iscustom = 'false' errinfo = 'Issues Body error, {}.'.format(e) set_output('issues', issues) set_output('iscustom', iscustom) + set_output('ismagisk', ismagisk) set_output('errinfo', errinfo) set_output('body', body) @@ -183,13 +187,14 @@ jobs: - name: Build WSA id: wsa - if: env.iscustom == 'true' && success() + if: env.iscustom == 'true' && env.ismagisk == 'true' && success() run: | mkdir -p download - ./scripts/build.sh ${{ env.body }} - env: - API_KEY: ${{ secrets.API_KEY }} - + if [[ ${{ env.ismagisk }} == 'true' ]]; then + ./scripts/build_with_lspinit.sh ${{ env.body }} + else + ./scripts/build_with_mount.sh ${{ env.body }} + - name: Pass to Windows if: env.iscustom == 'true' && success() uses: actions/cache/save@v4 diff --git a/.github/workflows/custom_build.yml b/.github/workflows/custom_build.yml index fb92e0b3..96ae756d 100644 --- a/.github/workflows/custom_build.yml +++ b/.github/workflows/custom_build.yml @@ -1,5 +1,5 @@ name: Custom Build (for testing purpose) -run-name: WSA ${{ inputs.release_type }} ${{ inputs.arch }} with ${{ inputs.root_sol }} and ${{ inputs.gapps_brand }} as ${{ inputs.custom_model }} +run-name: WSA ${{ inputs.release_type }} ${{ inputs.arch }} with ${{ inputs.root_sol }} and ${{ inputs.gapps_brand }} on: workflow_dispatch: inputs: @@ -38,12 +38,6 @@ on: required: true options: ["Magisk Stable","Magisk Beta","Magisk Canary","Magisk Debug"] default: "Magisk Stable" - custom_model: - type: choice - description: Custom model - required: true - options: ["WSA Default", "Pixel 4a", "Pixel 4a (5G)", "Pixel 5", "Pixel 5a", "Pixel 6", "Pixel 6 Pro", "Pixel 6a", "Pixel 7", "Pixel 7 Pro", "Pixel 7a", "Pixel Tablet", "Pixel Fold"] - default: "Pixel 5" compression: type: choice description: Compression format. @@ -98,18 +92,19 @@ jobs: run: | declare -A opts=( ["RELEASE_TYPE,Retail"]="retail" ["RELEASE_TYPE,Release Preview"]="RP" ["RELEASE_TYPE,Insider Slow"]="WIS" ["RELEASE_TYPE,Insider Fast"]="WIF" ["RELEASE_TYPE,Insider Private"]="latest" ["ROOT_SOL,Magisk Official"]="topjohnwu" ["ROOT_SOL,Magisk Delta (HuskyDG)"]="HuskyDG" ["ROOT_SOL,Magisk Alpha (vvb2060)"]="vvb2060" ["ROOT_SOL,KernelSU"]="kernelsu" ["ROOT_SOL,Non-root"]="none" ["MAGISK_TYPE,Magisk Stable"]="stable" ["MAGISK_TYPE,Magisk Beta"]="beta" ["MAGISK_TYPE,Magisk Canary"]="canary" ["MAGISK_TYPE,Magisk Debug"]="debug" ["CUSTOM_MODEL,WSA Default"]="none" ["CUSTOM_MODEL,Pixel 4a"]="sunfish" ["CUSTOM_MODEL,Pixel 4a (5G)"]="bramble" ["CUSTOM_MODEL,Pixel 5"]="redfin" ["CUSTOM_MODEL,Pixel 5a"]="barbet" ["CUSTOM_MODEL,Pixel 6 Pro"]="raven" ["CUSTOM_MODEL,Pixel 6"]="oriole" ["CUSTOM_MODEL,Pixel 6a"]="bluejay" ["CUSTOM_MODEL,Pixel 7"]="panther" ["CUSTOM_MODEL,Pixel 7 Pro"]="cheetah" ["CUSTOM_MODEL,Pixel 7a"]="lynx" ["CUSTOM_MODEL,Pixel Tablet"]="tangorpro" ["CUSTOM_MODEL,Pixel Fold"]="felix" ["GAPPS_BRAND,MindTheGapps v13.0"]="--install-gapps" ) + mkdir -p download + echo -e "user_code=$(cat $GITHUB_EVENT_PATH | jq -r '.inputs.user_code')" > download/.ms_account + if [[ "${{ inputs.root_sol }}" == *Magisk* ]]; then MAGISK_BRANCH="${opts[ROOT_SOL,${{ inputs.root_sol }}]}" ROOT_SOL="magisk" + ./scripts/build_with_lspinit.sh --arch ${{ inputs.arch }} --release-type ${opts[RELEASE_TYPE,${{ inputs.release_type }}]} --magisk-branch "$MAGISK_BRANCH" --magisk-ver "${opts[MAGISK_TYPE,${{ inputs.magisk_channel }}]}" --root-sol $ROOT_SOL ${opts[GAPPS_BRAND,${{ inputs.gapps_brand }}]} ${opts[REMOVE_AMAZON,${{ inputs.remove_amazon }}]} else MAGISK_BRANCH="topjohnwu" ROOT_SOL="${opts[ROOT_SOL,${{ inputs.root_sol }}]}" + ./scripts/build_with_mount.sh --arch ${{ inputs.arch }} --release-type ${opts[RELEASE_TYPE,${{ inputs.release_type }}]} --magisk-branch "$MAGISK_BRANCH" --magisk-ver "${opts[MAGISK_TYPE,${{ inputs.magisk_channel }}]}" --root-sol $ROOT_SOL ${opts[GAPPS_BRAND,${{ inputs.gapps_brand }}]} ${opts[REMOVE_AMAZON,${{ inputs.remove_amazon }}]} fi - mkdir -p download - echo -e "user_code=$(cat $GITHUB_EVENT_PATH | jq -r '.inputs.user_code')" > download/.ms_account - ./scripts/build.sh --arch ${{ inputs.arch }} --release-type ${opts[RELEASE_TYPE,${{ inputs.release_type }}]} --magisk-branch "$MAGISK_BRANCH" --magisk-ver "${opts[MAGISK_TYPE,${{ inputs.magisk_channel }}]}" --root-sol $ROOT_SOL ${opts[GAPPS_BRAND,${{ inputs.gapps_brand }}]} ${opts[REMOVE_AMAZON,${{ inputs.remove_amazon }}]} - #--custom-model ${opts[CUSTOM_MODEL,${{ inputs.custom_model }}]} - name: Pass to Windows 💸 uses: actions/cache/save@v4 with: diff --git a/bin/EROFS/fuse.erofs b/bin/EROFS/fuse.erofs new file mode 100644 index 00000000..b06cecd8 Binary files /dev/null and b/bin/EROFS/fuse.erofs differ diff --git a/bin/EROFS/mkfs.erofs b/bin/EROFS/mkfs.erofs new file mode 100644 index 00000000..5770c0e7 Binary files /dev/null and b/bin/EROFS/mkfs.erofs differ diff --git a/installer/arm64/MakePri.ps1 b/installer/arm64/MakePri.ps1 index a45443af..6b68c72e 100644 --- a/installer/arm64/MakePri.ps1 +++ b/installer/arm64/MakePri.ps1 @@ -56,6 +56,8 @@ if (((Test-Path -Path $(Get-Content -Path .\filelist-pri.txt)) -eq $false).Count } } $ProjectXml.Save($AppxManifestFile) + Remove-Item 'pri' -Recurse -Force + Remove-Item 'xml' -Recurse -Force Remove-Item 'makepri.exe' -Force Remove-Item 'filelist-pri.txt' -Force Remove-Item $PSCommandPath -Force diff --git a/installer/x64/MakePri.ps1 b/installer/x64/MakePri.ps1 index b9abb1ea..938a7edf 100644 --- a/installer/x64/MakePri.ps1 +++ b/installer/x64/MakePri.ps1 @@ -46,6 +46,8 @@ $(Get-Item .\xml\* -Exclude "priconfig.xml" -Include "*.xml") | ForEach-Object { } $ProjectXml.Save($AppxManifestFile) +Remove-Item 'pri' -Recurse -Force +Remove-Item 'xml' -Recurse -Force Remove-Item 'filelist-pri.txt' -Force Remove-Item $PSCommandPath -Force exit 0 diff --git a/linker/libc.so b/linker/libc.so new file mode 100755 index 00000000..748c48ca Binary files /dev/null and b/linker/libc.so differ diff --git a/linker/libdl.so b/linker/libdl.so new file mode 100755 index 00000000..8b24897c Binary files /dev/null and b/linker/libdl.so differ diff --git a/linker/libm.so b/linker/libm.so new file mode 100755 index 00000000..7bf99e88 Binary files /dev/null and b/linker/libm.so differ diff --git a/linker/linker64 b/linker/linker64 new file mode 100755 index 00000000..894beae3 Binary files /dev/null and b/linker/linker64 differ diff --git a/scripts/build.sh b/scripts/build_with_lspinit.sh similarity index 86% rename from scripts/build.sh rename to scripts/build_with_lspinit.sh index ecac1d8a..399d3867 100755 --- a/scripts/build.sh +++ b/scripts/build_with_lspinit.sh @@ -81,22 +81,6 @@ MAGISK_VER_MAP=( "alpha" ) -# CUSTOM_MODEL_MAP=( -# "none" -# "sunfish" -# "bramble" -# "redfin" -# "barbet" -# "raven" -# "oriole" -# "bluejay" -# "panther" -# "cheetah" -# "lynx" -# "tangorpro" -# "felix" -# ) - ROOT_SOL_MAP=( "magisk" "kernelsu" @@ -197,7 +181,6 @@ check_list "$RELEASE_TYPE" "Release Type" "${RELEASE_TYPE_MAP[@]}" check_list "$MAGISK_BRANCH" "Magisk Branch" "${MAGISK_BRANCH_MAP[@]}" check_list "$MAGISK_VER" "Magisk Version" "${MAGISK_VER_MAP[@]}" check_list "$ROOT_SOL" "Root Solution" "${ROOT_SOL_MAP[@]}" -# check_list "$CUSTOM_MODEL" "Custom Model" "${CUSTOM_MODEL_MAP[@]}" check_list "$COMPRESS_FORMAT" "Compress Format" "${COMPRESS_FORMAT_MAP[@]}" # shellcheck disable=SC1091 @@ -257,7 +240,7 @@ update_ksu_zip_name() { echo "Generating WSA Download Links" python3 generateWSALinks.py "$ARCH" "$RELEASE_TYPE" "$DOWNLOAD_DIR" "$DOWNLOAD_WSA_CONF_NAME" || abort -if [ "$RELEASE_TYPE" == "latest" ]; then +if [ "$RELEASE_TYPE" = "latest" ]; then printf "%s\n" "$(curl -sL https://api.github.com/repos/bubbles-wow/WSA-Archive/releases/latest | jq -r '.assets[] | .browser_download_url')" >> "$DOWNLOAD_DIR/$DOWNLOAD_WSA_CONF_NAME" || abort printf " dir=%s\n" "$DOWNLOAD_DIR" >> "$DOWNLOAD_DIR/$DOWNLOAD_WSA_CONF_NAME" || abort printf " out=wsa-latest.zip\n" >> "$DOWNLOAD_DIR/$DOWNLOAD_WSA_CONF_NAME" || abort @@ -301,7 +284,7 @@ if [ "$ROOT_SOL" = "kernelsu" ]; then fi if [ "$HAS_GAPPS" ]; then update_gapps_files_name - python3 generateGappsLink.py "$ARCH" "$DOWNLOAD_DIR" "$DOWNLOAD_CONF_NAME" "$ANDROID_API" "$GAPPS_IMAGE_NAME" || abort + python3 generateAddonsLink.py "$ARCH" "$DOWNLOAD_DIR" "$DOWNLOAD_CONF_NAME" "$ANDROID_API" "$GAPPS_IMAGE_NAME" || abort fi if [ -f "$DOWNLOAD_DIR/$DOWNLOAD_CONF_NAME" ]; then echo "Downloading Artifacts" @@ -424,18 +407,42 @@ if [ "$REMOVE_AMAZON" ]; then fi echo "Removing signature and add scripts" -rm -rf "${WORK_DIR:?}"/wsa/"$ARCH"/\[Content_Types\].xml "$WORK_DIR/wsa/$ARCH/AppxBlockMap.xml" "$WORK_DIR/wsa/$ARCH/AppxSignature.p7x" "$WORK_DIR/wsa/$ARCH/AppxMetadata" || abort -cp "$vclibs_PATH" "$xaml_PATH" "$WORK_DIR/wsa/$ARCH" || abort -cp "$UWPVCLibs_PATH" "$xaml_PATH" "$WORK_DIR/wsa/$ARCH" || abort -cp "../installer/$ARCH/Install.ps1" "$WORK_DIR/wsa/$ARCH" || abort -cp "../installer/Run.bat" "$WORK_DIR/wsa/$ARCH" || abort -find "$WORK_DIR/wsa/$ARCH" -maxdepth 1 -mindepth 1 -printf "%P\n" >"$WORK_DIR/wsa/$ARCH/filelist.txt" || abort - +sudo rm -rf "${WORK_DIR:?}"/wsa/"$ARCH"/\[Content_Types\].xml "$WORK_DIR/wsa/$ARCH/AppxBlockMap.xml" "$WORK_DIR/wsa/$ARCH/AppxSignature.p7x" "$WORK_DIR/wsa/$ARCH/AppxMetadata" || abort +if [ "$ARCH" = "x64" ]; then + sudo rm -rf "$WORK_DIR/wsa/$ARCH/arm64/" || abort +else + sudo rm -rf "$WORK_DIR/wsa/$ARCH/amd64/" || abort +fi +mkdir "$WORK_DIR/wsa/$ARCH/uwp" +cp "$vclibs_PATH" "$xaml_PATH" "$WORK_DIR/wsa/$ARCH/uwp/" || abort +cp "$UWPVCLibs_PATH" "$xaml_PATH" "$WORK_DIR/wsa/$ARCH/uwp/" || abort cp "../xml/priconfig.xml" "$WORK_DIR/wsa/$ARCH/xml/" || abort -cp "../installer/$ARCH/MakePri.ps1" "$WORK_DIR/wsa/$ARCH" || abort +if [[ "$ROOT_SOL" = "none" ]] && [[ "$HAS_GAPPS" ]] && [[ "$REMOVE_AMAZON" ]]; then + sed -i -e 's@Start-Process\ "wsa://com.topjohnwu.magisk"@@g' "../installer/$ARCH/Install.ps1" + sed -i -e 's@Start-Process\ "wsa://com.android.vending"@@g' "../installer/$ARCH/Install.ps1" +else + if [[ "$ROOT_SOL" == "none" ]]; then + sed -i -e 's@Start-Process "wsa://com.topjohnwu.magisk"@@g' "../installer/$ARCH/Install.ps1" + elif [[ "$ROOT_SOL" = "kernelsu" ]]; then + sed -i -e 's@wsa://com.topjohnwu.magisk@https://github.com/YT-Advanced/WSA-Script/blob/HEAD/docs/Guides/KernelSU.md@g' "../installer/$ARCH/Install.ps1" + elif [[ "$MAGISK_BRANCH" = "HuskyDG" ]]; then + sed -i -e 's@com.topjohnwu.magisk@io.github.huskydg.magisk@g' "../installer/$ARCH/Install.ps1" + elif [[ "$MAGISK_BRANCH" = "vvb2060" ]]; then + sed -i -e 's@com.topjohnwu.magisk@io.github.vvb2060.magisk@g' "../installer/$ARCH/Install.ps1" + fi + if [[ -z "$HAS_GAPPS" ]] && [[ -z "$REMOVE_AMAZON" ]]; then + sed -i -e 's@com.android.vending@com.amazon.venezia@g' "../installer/$ARCH/Install.ps1" + elif [[ -z "$HAS_GAPPS" ]]; then + sed -i -e 's@Start-Process\ "wsa://com.android.vending"@@g' "../installer/$ARCH/Install.ps1" + fi +fi +cp "../installer/$ARCH/Install.ps1" "$WORK_DIR/wsa/$ARCH" || abort +find "$WORK_DIR/wsa/$ARCH" -not -path "*/uwp*" -not -path "*/pri*" -not -path "*/xml*" -printf "%P\n" | sed -e 's@/@\\@g' -e '/^$/d' > "$WORK_DIR/wsa/$ARCH/filelist.txt" || abort find "$WORK_DIR/wsa/$ARCH/pri" -printf "%P\n" | sed -e 's/^/pri\\/' -e '/^$/d' > "$WORK_DIR/wsa/$ARCH/filelist-pri.txt" || abort find "$WORK_DIR/wsa/$ARCH/xml" -printf "%P\n" | sed -e 's/^/xml\\/' -e '/^$/d' >> "$WORK_DIR/wsa/$ARCH/filelist-pri.txt" || abort -echo -e "Done\n" +cp "../installer/$ARCH/MakePri.ps1" "$WORK_DIR/wsa/$ARCH" || abort +cp ../installer/Run.bat "$WORK_DIR/wsa/$ARCH" || abort +echo -e "Remove signature and Add scripts done\n" if [[ "$ROOT_SOL" = "none" ]]; then name1="" diff --git a/scripts/build_with_mount.sh b/scripts/build_with_mount.sh new file mode 100755 index 00000000..3e415b07 --- /dev/null +++ b/scripts/build_with_mount.sh @@ -0,0 +1,766 @@ +#!/bin/bash +# +# This file is part of MagiskOnWSALocal. +# +# MagiskOnWSALocal is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# MagiskOnWSALocal is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with MagiskOnWSALocal. If not, see . +# +# Copyright (C) 2023 LSPosed Contributors +# + +# shellcheck disable=SC2034 +cd "$(dirname "$0")" || exit 1 +WORK_DIR=$(mktemp -d -t wsa-build-XXXXXXXXXX_) || exit 1 + +# lowerdir +ROOT_MNT_RO="$WORK_DIR/erofs" +VENDOR_MNT_RO="$ROOT_MNT_RO/vendor" +PRODUCT_MNT_RO="$ROOT_MNT_RO/product" +SYSTEM_EXT_MNT_RO="$ROOT_MNT_RO/system_ext" + +# upperdir +ROOT_MNT_RW="$WORK_DIR/upper" +VENDOR_MNT_RW="$ROOT_MNT_RW/vendor" +PRODUCT_MNT_RW="$ROOT_MNT_RW/product" +SYSTEM_EXT_MNT_RW="$ROOT_MNT_RW/system_ext" +SYSTEM_MNT_RW="$ROOT_MNT_RW/system" + +# merged +# shellcheck disable=SC2034 +ROOT_MNT="$WORK_DIR/system_root_merged" +SYSTEM_MNT="$ROOT_MNT/system" +VENDOR_MNT="$ROOT_MNT/vendor" +PRODUCT_MNT="$ROOT_MNT/product" +SYSTEM_EXT_MNT="$ROOT_MNT/system_ext" + +declare -A LOWER_PARTITION=(["zsystem"]="$ROOT_MNT_RO" ["vendor"]="$VENDOR_MNT_RO" ["product"]="$PRODUCT_MNT_RO" ["system_ext"]="$SYSTEM_EXT_MNT_RO") +declare -A UPPER_PARTITION=(["zsystem"]="$SYSTEM_MNT_RW" ["vendor"]="$VENDOR_MNT_RW" ["product"]="$PRODUCT_MNT_RW" ["system_ext"]="$SYSTEM_EXT_MNT_RW") +declare -A MERGED_PARTITION=(["zsystem"]="$ROOT_MNT" ["vendor"]="$VENDOR_MNT" ["product"]="$PRODUCT_MNT" ["system_ext"]="$SYSTEM_EXT_MNT") + +DOWNLOAD_DIR=../download +DOWNLOAD_WSA_CONF_NAME=wsa.list +DOWNLOAD_CONF_NAME=download.list +PYTHON_VENV_DIR="$(dirname "$PWD")/python3-env" +OUTPUT_DIR=../output +WSA_WORK_ENV="${WORK_DIR:?}/ENV" +touch "$WSA_WORK_ENV" +export WSA_WORK_ENV +abort() { + [ "$1" ] && echo -e "ERROR: $1" + echo "Build: an error has occurred, exit" + exit 1 +} +trap abort INT TERM + +default() { + ARCH=x64 + RELEASE_TYPE=retail + MAGISK_BRANCH=topjohnwu + MAGISK_VER=stable + ROOT_SOL=magisk + COMPRESS_FORMAT=zip +} + +vhdx_to_raw_img() { + qemu-img convert -q -f vhdx -O raw "$1" "$2" || return 1 + rm -f "$1" || return 1 +} + +ro_ext4_img_to_rw() { + resize_img "$1" "$(($(du --apparent-size -sB512 "$1" | cut -f1) * 2))"s || return 1 + e2fsck -fp -E unshare_blocks "$1" || return 1 + resize_img "$1" || return 1 + return 0 +} + +resize_img() { + sudo e2fsck -pf "$1" || return 1 + if [ "$2" ]; then + sudo resize2fs "$1" "$2" || return 1 + else + sudo resize2fs -M "$1" || return 1 + fi + return 0 +} + +mk_overlayfs() { + local context own + local workdir="$WORK_DIR/worker/$1" + local lowerdir="$2" + local upperdir="$3" + local merged="$4" + + echo "mk_overlayfs: label $1 + lowerdir=$lowerdir + upperdir=$upperdir + workdir=$workdir + merged=$merged" + case "$1" in + vendor) + context="u:object_r:vendor_file:s0" + own="0:2000" + ;; + system) + context="u:object_r:rootfs:s0" + own="0:0" + ;; + *) + context="u:object_r:system_file:s0" + own="0:0" + ;; + esac + sudo mkdir -p -m 755 "$workdir" "$upperdir" "$merged" || return 1 + sudo chown -R "$own" "$upperdir" "$workdir" "$merged" || return 1 + sudo setfattr -n security.selinux -v "$context" "$upperdir" || return 1 + sudo setfattr -n security.selinux -v "$context" "$workdir" || return 1 + sudo setfattr -n security.selinux -v "$context" "$merged" || return 1 + sudo mount -vt overlay overlay -olowerdir="$lowerdir",upperdir="$upperdir",workdir="$workdir" "$merged" || return 1 +} + +check_image_type() { + local type + type=$(blkid -o value -s TYPE "$1") + echo "$type" +} + +mk_erofs_umount() { + sudo "../bin/EROFS/mkfs.erofs" -zlz4hc -T1230768000 --chunksize=4096 --exclude-regex="lost+found" "$2".erofs "$1" || abort "Failed to make erofs image from $1" + sudo umount -v "$1" + sudo rm -f "$2" + sudo mv "$2".erofs "$2" +} + +# workaround for Debian +# In Debian /usr/sbin is not in PATH and some utilities in there are in use +[ -d /usr/sbin ] && export PATH="/usr/sbin:$PATH" +# In Debian /etc/mtab is not exist +[ -f /etc/mtab ] || sudo ln -s /proc/self/mounts /etc/mtab + +ARCH_MAP=( + "x64" + "arm64" +) + +RELEASE_TYPE_MAP=( + "retail" + "RP" + "WIS" + "WIF" + "latest" +) + +MAGISK_BRANCH_MAP=( + "topjohnwu" + "HuskyDG" + "vvb2060" +) + +MAGISK_VER_MAP=( + "stable" + "beta" + "canary" + "debug" + "release" + "delta" + "alpha" +) + +ROOT_SOL_MAP=( + "magisk" + "kernelsu" + "none" +) + +COMPRESS_FORMAT_MAP=( + "7z" + "zip" +) + +ARGUMENT_LIST=( + "arch:" + "release-type:" + "magisk-branch:" + "magisk-ver:" + "root-sol:" + "compress-format:" + "install-gapps" + "remove-amazon" +) + +default + +opts=$( + getopt \ + --longoptions "$(printf "%s," "${ARGUMENT_LIST[@]}")" \ + --name "$(basename "$0")" \ + --options "" \ + -- "$@" +) || abort "Failed to parse options, please check your input" + +eval set --"$opts" +while [[ $# -gt 0 ]]; do + case "$1" in + --arch ) ARCH="$2"; shift 2 ;; + --release-type ) RELEASE_TYPE="$2"; shift 2 ;; + --gapps-brand ) GAPPS_BRAND="$2"; shift 2 ;; + --root-sol ) ROOT_SOL="$2"; shift 2 ;; + --compress-format ) COMPRESS_FORMAT="$2"; shift 2 ;; + --install-gapps ) HAS_GAPPS="yes"; shift ;; + --remove-amazon ) REMOVE_AMAZON="yes"; shift ;; + --magisk-branch ) MAGISK_BRANCH="$2"; shift 2 ;; + --magisk-ver ) MAGISK_VER="$2"; shift 2 ;; + -- ) shift; break;; + esac +done + +check_list() { + local input=$1 + if [ -n "$input" ]; then + local name=$2 + shift + local arr=("$@") + local list_count=${#arr[@]} + for i in "${arr[@]}"; do + if [ "$input" == "$i" ]; then + echo "INFO: $name: $input" + break + fi + ((list_count--)) + if (("$list_count" <= 0)); then + abort "Invalid $name: $input" + fi + done + fi +} + +check_list "$ARCH" "Architecture" "${ARCH_MAP[@]}" +check_list "$RELEASE_TYPE" "Release Type" "${RELEASE_TYPE_MAP[@]}" +check_list "$MAGISK_BRANCH" "Magisk Branch" "${MAGISK_BRANCH_MAP[@]}" +check_list "$MAGISK_VER" "Magisk Version" "${MAGISK_VER_MAP[@]}" +check_list "$ROOT_SOL" "Root Solution" "${ROOT_SOL_MAP[@]}" +check_list "$COMPRESS_FORMAT" "Compress Format" "${COMPRESS_FORMAT_MAP[@]}" + +# shellcheck disable=SC1091 +[ -f "$PYTHON_VENV_DIR/bin/activate" ] && { + source "$PYTHON_VENV_DIR/bin/activate" || abort "Failed to activate virtual environment" +} +declare -A RELEASE_NAME_MAP=(["retail"]="Retail" ["latest"]="Insider Private" ["RP"]="Release Preview" ["WIS"]="Insider Slow" ["WIF"]="Insider Fast") +RELEASE_NAME=${RELEASE_NAME_MAP[$RELEASE_TYPE]} || abort + +echo -e "Build: RELEASE_TYPE=$RELEASE_NAME" + +WSA_ZIP_PATH=$DOWNLOAD_DIR/wsa-$RELEASE_TYPE.zip +VCLibs_PATH="$DOWNLOAD_DIR/Microsoft.VCLibs.140.00_$ARCH.appx" +UWPVCLibs_PATH="$DOWNLOAD_DIR/Microsoft.VCLibs.140.00.UWPDesktop_$ARCH.appx" +xaml_PATH="$DOWNLOAD_DIR/Microsoft.UI.Xaml.2.8_$ARCH.appx" +MAGISK_ZIP=magisk-$MAGISK_VER.zip +MAGISK_PATH=$DOWNLOAD_DIR/$MAGISK_ZIP +GAPPS_ZIP_NAME=MindTheGapps-$ARCH-13.0.zip +GAPPS_PATH=$DOWNLOAD_DIR/$GAPPS_ZIP_NAME +WSA_MAJOR_VER=0 + +getKernelVersion() { + local bintype kernel_string kernel_version + bintype="$(file -b "$1")" + if [[ $bintype == *"version"* ]]; then + readarray -td '' kernel_string < <(awk '{ gsub(/, /,"\0"); print; }' <<<"$bintype, ") + unset 'kernel_string[-1]' + for i in "${kernel_string[@]}"; do + if [[ $i == *"version"* ]]; then + IFS=" " read -r -a kernel_string <<<"$i" + kernel_version="${kernel_string[1]}" + fi + done + else + IFS=" " read -r -a kernel_string <<<"$(strings "$1" | grep 'Linux version')" + kernel_version="${kernel_string[2]}" + fi + IFS=" " read -r -a arr <<<"${kernel_version//-/ }" + printf '%s' "${arr[0]}" +} + +update_ksu_zip_name() { + KERNEL_VER="" + if [ -f "$WORK_DIR/wsa/$ARCH/Tools/kernel" ]; then + KERNEL_VER=$(getKernelVersion "$WORK_DIR/wsa/$ARCH/Tools/kernel") + fi + KERNELSU_ZIP_NAME=kernelsu-$ARCH-$KERNEL_VER.zip + KERNELSU_PATH=$DOWNLOAD_DIR/$KERNELSU_ZIP_NAME + KERNELSU_APK_PATH=$DOWNLOAD_DIR/KernelSU.apk + KERNELSU_INFO="$KERNELSU_PATH.info" +} + +update_gapps_zip_name() { + GAPPS_ZIP_NAME=MindTheGapps-$ARCH-13.0.zip + GAPPS_PATH=$DOWNLOAD_DIR/$GAPPS_ZIP_NAME +} + +echo "Generating WSA Download Links" +python3 generateWSALinks.py "$ARCH" "$RELEASE_TYPE" "$DOWNLOAD_DIR" "$DOWNLOAD_WSA_CONF_NAME" || abort + +if [ "$RELEASE_TYPE" == "latest" ]; then + printf "%s\n" "$(curl -sL https://api.github.com/repos/bubbles-wow/WSA-Archive/releases/latest | jq -r '.assets[] | .browser_download_url')" >> "$DOWNLOAD_DIR/$DOWNLOAD_WSA_CONF_NAME" || abort + printf " dir=%s\n" "$DOWNLOAD_DIR" >> "$DOWNLOAD_DIR/$DOWNLOAD_WSA_CONF_NAME" || abort + printf " out=wsa-latest.zip\n" >> "$DOWNLOAD_DIR/$DOWNLOAD_WSA_CONF_NAME" || abort + WSA_VER=$(curl -sL https://api.github.com/repos/bubbles-wow/WSA-Archive/releases/latest | jq -r '.tag_name') + WSA_MAJOR_VER=${WSA_VER:0:4} +else + # shellcheck disable=SC1090 + source "$WSA_WORK_ENV" || abort +fi + +if ! aria2c --no-conf --log-level=info --log="$DOWNLOAD_DIR/aria2_download.log" -x16 -s16 -j7 -m0 \ + --async-dns=false --check-integrity=true \ + -d"$DOWNLOAD_DIR" -i"$DOWNLOAD_DIR/$DOWNLOAD_WSA_CONF_NAME"; then + abort "We have encountered an error while downloading files." +fi + +echo "Extract WSA" +if [ -f "$WSA_ZIP_PATH" ]; then + if ! python3 extractWSA.py "$ARCH" "$WSA_ZIP_PATH" "$WORK_DIR" "$WSA_WORK_ENV"; then + abort "Unzip WSA failed, is the download incomplete?" + fi + echo -e "Extract done\n" + # shellcheck disable=SC1090 + source "$WSA_WORK_ENV" || abort +else + echo "The WSA zip package does not exist, is the download incomplete?" + exit 1 +fi + +if [ "$ROOT_SOL" = "magisk" ] || [ "$HAS_GAPPS" = "yes" ]; then + python3 generateMagiskLink.py "$MAGISK_BRANCH" "$MAGISK_VER" "$DOWNLOAD_DIR" "$DOWNLOAD_CONF_NAME" || abort +fi + +if [ "$ROOT_SOL" = "kernelsu" ]; then + update_ksu_zip_name + python3 generateKernelSULink.py "$ARCH" "$DOWNLOAD_DIR" "$DOWNLOAD_CONF_NAME" "$KERNEL_VER" "$KERNELSU_ZIP_NAME" || abort + # shellcheck disable=SC1090 + source "$WSA_WORK_ENV" || abort + # shellcheck disable=SC2153 + echo "KERNELSU_VER=$KERNELSU_VER" >"$KERNELSU_INFO" +fi +if [ "$HAS_GAPPS" = "yes" ]; then + update_gapps_zip_name + python3 generateGappsLink.py "$ARCH" "$DOWNLOAD_DIR" "$DOWNLOAD_CONF_NAME" "$GAPPS_ZIP_NAME" || abort +fi + +if [ -f "$DOWNLOAD_DIR/$DOWNLOAD_CONF_NAME" ]; then + echo "Downloading Artifacts" + if ! aria2c --no-conf --log-level=info --log="$DOWNLOAD_DIR/aria2_download.log" -x16 -s16 -j7 -m0 \ + --async-dns=false --check-integrity=true \ + -d"$DOWNLOAD_DIR" -i"$DOWNLOAD_DIR/$DOWNLOAD_CONF_NAME"; then + abort "We have encountered an error while downloading files." + fi +fi + +if [ "$HAS_GAPPS" = "yes" ] || [ "$ROOT_SOL" = "magisk" ]; then + echo "Extract Magisk" + if [ -f "$MAGISK_PATH" ]; then + MAGISK_VERSION_NAME="" + if ! python3 extractMagisk.py "$ARCH" "$MAGISK_PATH" "$WORK_DIR"; then + abort "Unzip Magisk failed, is the download incomplete?" + fi + # shellcheck disable=SC1090 + source "$WSA_WORK_ENV" || abort + sudo patchelf --set-interpreter "../linker/linker64" "$WORK_DIR/magisk/magiskpolicy" || abort + chmod +x "$WORK_DIR/magisk/magiskpolicy" || abort + else + echo "The Magisk zip package does not exist, rename it to magisk-debug.zip and put it in the download folder." + exit 1 + fi + echo -e "done\n" +fi + +if [ "$ROOT_SOL" = "kernelsu" ]; then + echo "Extracting KernelSU" + # shellcheck disable=SC1090 + source "${KERNELSU_INFO:?}" || abort + echo "WSA Kernel Version: $KERNEL_VER" + echo "KernelSU Version: $KERNELSU_VER" + if ! unzip "$KERNELSU_PATH" -d "$WORK_DIR/kernelsu"; then + abort "Unzip KernelSU failed, package is corrupted?" + fi + if [ "$ARCH" = "x64" ]; then + mv "$WORK_DIR/kernelsu/bzImage" "$WORK_DIR/kernelsu/kernel" + elif [ "$ARCH" = "arm64" ]; then + mv "$WORK_DIR/kernelsu/Image" "$WORK_DIR/kernelsu/kernel" + fi + echo "Integrate KernelSU" + mv "$WORK_DIR/wsa/$ARCH/Tools/kernel" "$WORK_DIR/wsa/$ARCH/Tools/kernel_origin" + cp "$WORK_DIR/kernelsu/kernel" "$WORK_DIR/wsa/$ARCH/Tools/kernel" +fi + +if [ "$HAS_GAPPS" = "yes" ]; then + update_gapps_zip_name + echo "Extract MindTheGapps" + mkdir -p "$WORK_DIR/gapps" || abort + if [ -f "$GAPPS_PATH" ]; then + if ! unzip "$GAPPS_PATH" "system/*" -d "$WORK_DIR/gapps"; then + abort "Unzip MindTheGapps failed, package is corrupted?" + fi + mv "$WORK_DIR/gapps/system/"* "$WORK_DIR/gapps" || abort + else + abort "The MindTheGapps zip package does not exist." + fi + echo -e "Extract done\n" +fi + +echo "Convert vhdx to RAW image" +vhdx_to_raw_img "$WORK_DIR/wsa/$ARCH/system_ext.vhdx" "$WORK_DIR/wsa/$ARCH/system_ext.img" || abort +vhdx_to_raw_img "$WORK_DIR/wsa/$ARCH/product.vhdx" "$WORK_DIR/wsa/$ARCH/product.img" || abort +vhdx_to_raw_img "$WORK_DIR/wsa/$ARCH/system.vhdx" "$WORK_DIR/wsa/$ARCH/system.img" || abort +vhdx_to_raw_img "$WORK_DIR/wsa/$ARCH/vendor.vhdx" "$WORK_DIR/wsa/$ARCH/vendor.img" || abort +echo -e "Convert vhdx to RAW image done\n" + +SYSTEMIMAGES_FILE_SYSTEM_TYPE=$(check_image_type "$WORK_DIR/wsa/$ARCH/system.img") +if [[ "$SYSTEMIMAGES_FILE_SYSTEM_TYPE" = "erofs" ]]; then + echo "Mount images" + sudo mkdir -p -m 755 "$ROOT_MNT_RO" || abort + sudo chown "0:0" "$ROOT_MNT_RO" || abort + sudo setfattr -n security.selinux -v "u:object_r:rootfs:s0" "$ROOT_MNT_RO" || abort + sudo "../bin/EROFS/fuse.erofs" "$WORK_DIR/wsa/$ARCH/system.img" "$ROOT_MNT_RO" || abort 1 + sudo "../bin/EROFS/fuse.erofs" "$WORK_DIR/wsa/$ARCH/vendor.img" "$VENDOR_MNT_RO" || abort 1 + sudo "../bin/EROFS/fuse.erofs" "$WORK_DIR/wsa/$ARCH/product.img" "$PRODUCT_MNT_RO" || abort 1 + sudo "../bin/EROFS/fuse.erofs" "$WORK_DIR/wsa/$ARCH/system_ext.img" "$SYSTEM_EXT_MNT_RO" || abort 1 + echo -e "done\n" + echo "Create overlayfs for EROFS" + mk_overlayfs system "$ROOT_MNT_RO" "$SYSTEM_MNT_RW" "$ROOT_MNT" || abort + mk_overlayfs vendor "$VENDOR_MNT_RO" "$VENDOR_MNT_RW" "$VENDOR_MNT" || abort + mk_overlayfs product "$PRODUCT_MNT_RO" "$PRODUCT_MNT_RW" "$PRODUCT_MNT" || abort + mk_overlayfs system_ext "$SYSTEM_EXT_MNT_RO" "$SYSTEM_EXT_MNT_RW" "$SYSTEM_EXT_MNT" || abort + echo -e "Create overlayfs for EROFS done\n" +elif [ "$SYSTEMIMAGES_FILE_SYSTEM_TYPE" = "ext4" ]; then + echo "Remove read-only flag for read-only EXT4 image" + ro_ext4_img_to_rw "$WORK_DIR/wsa/$ARCH/system_ext.img" || abort + ro_ext4_img_to_rw "$WORK_DIR/wsa/$ARCH/product.img" || abort + ro_ext4_img_to_rw "$WORK_DIR/wsa/$ARCH/system.img" || abort + ro_ext4_img_to_rw "$WORK_DIR/wsa/$ARCH/vendor.img" || abort + echo -e "Remove read-only flag for read-only EXT4 image done\n" + + echo "Calculate the required space" + EXTRA_SIZE=10240 + + SYSTEM_EXT_NEED_SIZE=$EXTRA_SIZE + if [ -d "$WORK_DIR/gapps/system_ext" ]; then + SYSTEM_EXT_NEED_SIZE=$((SYSTEM_EXT_NEED_SIZE + $(du --apparent-size -sB512 "$WORK_DIR/gapps/system_ext" | cut -f1))) + fi + + PRODUCT_NEED_SIZE=$EXTRA_SIZE + if [ -d "$WORK_DIR/gapps/product" ]; then + PRODUCT_NEED_SIZE=$((PRODUCT_NEED_SIZE + $(du --apparent-size -sB512 "$WORK_DIR/gapps/product" | cut -f1))) + fi + + SYSTEM_NEED_SIZE=$EXTRA_SIZE + if [ -d "$WORK_DIR/gapps" ]; then + SYSTEM_NEED_SIZE=$((SYSTEM_NEED_SIZE + $(du --apparent-size -sB512 "$WORK_DIR/gapps" | cut -f1) - PRODUCT_NEED_SIZE - SYSTEM_EXT_NEED_SIZE)) + fi + if [ "$ROOT_SOL" = "magisk" ]; then + if [ -d "$WORK_DIR/magisk" ]; then + MAGISK_SIZE=$(du --apparent-size -sB512 "$WORK_DIR/magisk/magisk" | cut -f1) + SYSTEM_NEED_SIZE=$((SYSTEM_NEED_SIZE + MAGISK_SIZE)) + fi + if [ -f "$MAGISK_PATH" ]; then + MAGISK_APK_SIZE=$(du --apparent-size -sB512 "$MAGISK_PATH" | cut -f1) + SYSTEM_NEED_SIZE=$((SYSTEM_NEED_SIZE + MAGISK_APK_SIZE)) + fi + fi + if [ -d "../$ARCH/system" ]; then + SYSTEM_NEED_SIZE=$((SYSTEM_NEED_SIZE + $(du --apparent-size -sB512 "../$ARCH/system" | cut -f1))) + fi + VENDOR_NEED_SIZE=$EXTRA_SIZE + echo -e "done\n" + echo "Expand images" + SYSTEM_EXT_IMG_SIZE=$(du --apparent-size -sB512 "$WORK_DIR/wsa/$ARCH/system_ext.img" | cut -f1) + PRODUCT_IMG_SIZE=$(du --apparent-size -sB512 "$WORK_DIR/wsa/$ARCH/product.img" | cut -f1) + SYSTEM_IMG_SIZE=$(du --apparent-size -sB512 "$WORK_DIR/wsa/$ARCH/system.img" | cut -f1) + VENDOR_IMG_SIZE=$(du --apparent-size -sB512 "$WORK_DIR/wsa/$ARCH/vendor.img" | cut -f1) + SYSTEM_EXT_TARGET_SIZE=$((SYSTEM_EXT_NEED_SIZE * 2 + SYSTEM_EXT_IMG_SIZE)) + PRODUCT_TAGET_SIZE=$((PRODUCT_NEED_SIZE * 2 + PRODUCT_IMG_SIZE)) + SYSTEM_TAGET_SIZE=$((SYSTEM_IMG_SIZE * 2)) + VENDOR_TAGET_SIZE=$((VENDOR_NEED_SIZE * 2 + VENDOR_IMG_SIZE)) + + resize_img "$WORK_DIR/wsa/$ARCH/system_ext.img" "$SYSTEM_EXT_TARGET_SIZE"s || abort + resize_img "$WORK_DIR/wsa/$ARCH/product.img" "$PRODUCT_TAGET_SIZE"s || abort + resize_img "$WORK_DIR/wsa/$ARCH/system.img" "$SYSTEM_TAGET_SIZE"s || abort + resize_img "$WORK_DIR/wsa/$ARCH/vendor.img" "$VENDOR_TAGET_SIZE"s || abort + + echo -e "Expand images done\n" + + echo "Mount images" + sudo mkdir "$ROOT_MNT" || abort + sudo mount -vo loop "$WORK_DIR/wsa/$ARCH/system.img" "$ROOT_MNT" || abort + sudo mount -vo loop "$WORK_DIR/wsa/$ARCH/vendor.img" "$VENDOR_MNT" || abort + sudo mount -vo loop "$WORK_DIR/wsa/$ARCH/product.img" "$PRODUCT_MNT" || abort + sudo mount -vo loop "$WORK_DIR/wsa/$ARCH/system_ext.img" "$SYSTEM_EXT_MNT" || abort + echo -e "done\n" +else + abort "Unknown file system type: $SYSTEMIMAGES_FILE_SYSTEM_TYPE" +fi + +if [ "$REMOVE_AMAZON" ]; then + echo "Remove Amazon Appstore" + rm -fv "$WORK_DIR/wsa/$ARCH/apex/mado_release.apex" + # Stub + find "${PRODUCT_MNT:?}"/{apex,etc/*permissions} 2>/dev/null | grep -e mado | sudo xargs rm -rfv + echo -e "done\n" +fi + +echo "Add device administration features" +sudo sed -i -e '/cts/a \ ' -e '/print/i \ ' "$VENDOR_MNT/etc/permissions/windows.permissions.xml" +sudo setfattr -n security.selinux -v "u:object_r:vendor_configs_file:s0" "$VENDOR_MNT/etc/permissions/windows.permissions.xml" || abort +echo -e "done\n" + +if [ "$ROOT_SOL" = 'magisk' ]; then + echo "Integrate Magisk" + sudo cp "$WORK_DIR/magisk/magisk/"* "$ROOT_MNT/debug_ramdisk/" + sudo cp "$MAGISK_PATH" "$ROOT_MNT/debug_ramdisk/stub.apk" || abort + sudo tee -a "$ROOT_MNT/debug_ramdisk/loadpolicy.sh" </dev/null || abort +#!/system/bin/sh +MAGISKTMP=/debug_ramdisk +export MAGISKTMP +mkdir -p /data/adb/magisk +cp \$MAGISKTMP/* /data/adb/magisk/ +sync +chmod -R 755 /data/adb/magisk +restorecon -R /data/adb/magisk +MAKEDEV=1 \$MAGISKTMP/magisk --preinit-device 2>&1 +RULESCMD="" +for r in \$MAGISKTMP/.magisk/preinit/*/sepolicy.rule; do + [ -f "\$r" ] || continue + RULESCMD="\$RULESCMD --apply \$r" +done +\$MAGISKTMP/magiskpolicy --live \$RULESCMD 2>&1 +EOF + sudo find "$ROOT_MNT/debug_ramdisk" -type f -exec chmod 0711 {} \; + sudo find "$ROOT_MNT/debug_ramdisk" -type f -exec chown root:root {} \; + sudo find "$ROOT_MNT/debug_ramdisk" -type f -exec setfattr -n security.selinux -v "u:object_r:magisk_file:s0" {} \; || abort + echo "/debug_ramdisk(/.*)? u:object_r:magisk_file:s0" | sudo tee -a "$VENDOR_MNT/etc/selinux/vendor_file_contexts" + echo '/data/adb/magisk(/.*)? u:object_r:magisk_file:s0' | sudo tee -a "$VENDOR_MNT/etc/selinux/vendor_file_contexts" + sudo LD_LIBRARY_PATH="../linker" "$WORK_DIR/magisk/magiskpolicy" --load "$VENDOR_MNT/etc/selinux/precompiled_sepolicy" --save "$VENDOR_MNT/etc/selinux/precompiled_sepolicy" --magisk || abort + NEW_INITRC_DIR=$SYSTEM_MNT/etc/init/hw + sudo tee -a "$SYSTEM_MNT/etc/init/hw/init.rc" </dev/null +on post-fs-data + mkdir /dev/debug_ramdisk_mirror + mount none /debug_ramdisk /dev/debug_ramdisk_mirror bind + mount none none /dev/debug_ramdisk_mirror private + mount tmpfs magisk /debug_ramdisk mode=0755 + copy /dev/debug_ramdisk_mirror/magisk64 /debug_ramdisk/magisk64 + chmod 0755 /debug_ramdisk/magisk64 + symlink ./magisk64 /debug_ramdisk/magisk + symlink ./magisk64 /debug_ramdisk/su + symlink ./magisk64 /debug_ramdisk/resetprop + start adbd + copy /dev/debug_ramdisk_mirror/magisk32 /debug_ramdisk/magisk32 + chmod 0755 /debug_ramdisk/magisk32 + copy /dev/debug_ramdisk_mirror/magiskinit /debug_ramdisk/magiskinit + chmod 0755 /debug_ramdisk/magiskinit + copy /dev/debug_ramdisk_mirror/magiskpolicy /debug_ramdisk/magiskpolicy + chmod 0755 /debug_ramdisk/magiskpolicy + mkdir /debug_ramdisk/.magisk + mkdir /debug_ramdisk/.magisk/mirror 0 + mkdir /debug_ramdisk/.magisk/block 0 + mkdir /debug_ramdisk/.magisk/worker 0 + copy /dev/debug_ramdisk_mirror/stub.apk /debug_ramdisk/stub.apk + chmod 0644 /debug_ramdisk/stub.apk + copy /dev/debug_ramdisk_mirror/loadpolicy.sh /debug_ramdisk/loadpolicy.sh + chmod 0755 /debug_ramdisk/loadpolicy.sh + umount /dev/debug_ramdisk_mirror + rmdir /dev/debug_ramdisk_mirror + exec u:r:magisk:s0 0 0 -- /system/bin/sh /debug_ramdisk/loadpolicy.sh + exec u:r:magisk:s0 0 0 -- /debug_ramdisk/magisk --post-fs-data + +on property:vold.decrypt=trigger_restart_framework + exec u:r:magisk:s0 0 0 -- /debug_ramdisk/magisk --service + +on nonencrypted + exec u:r:magisk:s0 0 0 -- /debug_ramdisk/magisk --service + +on property:sys.boot_completed=1 + exec u:r:magisk:s0 0 0 -- /debug_ramdisk/magisk --boot-complete + +on property:init.svc.zygote=stopped + exec u:r:magisk:s0 0 0 -- /debug_ramdisk/magisk --zygote-restart +EOF + + for i in "$NEW_INITRC_DIR"/*; do + if [[ "$i" =~ init.zygote.+\.rc ]]; then + echo "Inject zygote restart $i" + sudo awk -i inplace '{if($0 ~ /service zygote /){print $0;print " exec u:r:magisk:s0 0 0 -- /debug_ramdisk/magisk --zygote-restart";a="";next}} 1' "$i" + sudo setfattr -n security.selinux -v "u:object_r:system_file:s0" "$i" || abort + fi + done + echo -e "Integrate Magisk done\n" +elif [ "$ROOT_SOL" = "kernelsu" ]; then + echo "Copy KernelSU kernel" + cp "$WORK_DIR/kernelsu/kernel" "$WORK_DIR/wsa/$ARCH/Tools/kernel" + echo -e "Copy KernelSU kernel done\n" +fi + +echo "Permissions management Netfree and Netspark security certificates" +sudo cp -r "../cacerts/"* "$SYSTEM_MNT/etc/security/cacerts/" || abort +sudo chmod 0755 "$SYSTEM_MNT/etc/security/cacerts/" +find "../cacerts/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$SYSTEM_MNT/etc/security/cacerts/placeholder" -type f -exec chmod 0644 {} \; +find "../cacerts/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$SYSTEM_MNT/etc/security/cacerts/placeholder" -exec chown root:root {} \; +find "../cacerts/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$SYSTEM_MNT/etc/security/cacerts/placeholder" -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort +echo -e "Permissions management Netfree and Netspark security certificates done\n" + +if [ "$HAS_GAPPS" = "yes" ]; then + echo "Integrate GApps" + find "$WORK_DIR/gapps/" -mindepth 1 -type d -exec sudo chmod 0755 {} \; + find "$WORK_DIR/gapps/" -mindepth 1 -type d -exec sudo chown root:root {} \; + file_list="$(find "$WORK_DIR/gapps/" -mindepth 1 -type f)" + for file in $file_list; do + sudo chown root:root "$file" + sudo chmod 0644 "$file" + done + sudo cp --preserve=all -r "$WORK_DIR/gapps/system_ext/"* "$SYSTEM_EXT_MNT/" || abort + sudo cp --preserve=all -r "$WORK_DIR/gapps/product/"* "$PRODUCT_MNT" || abort + + find "$WORK_DIR/gapps/product/overlay" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/overlay/placeholder" -type f -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + find "$WORK_DIR/gapps/product/etc/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/etc/placeholder" -type d -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + find "$WORK_DIR/gapps/product/etc/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/etc/placeholder" -type f -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + #sudo setfattr -n security.selinux -v "u:object_r:system_file:s0" "$PRODUCT_MNT/framework" || abort + find "$WORK_DIR/gapps/product/app/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/app/placeholder" -type d -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + find "$WORK_DIR/gapps/product/priv-app/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/priv-app/placeholder" -type d -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + #find "$WORK_DIR/gapps/product/framework/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/framework/placeholder" -type d -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + find "$WORK_DIR/gapps/product/app/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/app/placeholder" -type f -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + find "$WORK_DIR/gapps/product/priv-app/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/priv-app/placeholder" -type f -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + #find "$WORK_DIR/gapps/product/framework/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/framework/placeholder" -type f -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + find "$WORK_DIR/gapps/system_ext/etc/permissions/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$SYSTEM_EXT_MNT/etc/permissions/placeholder" -type f -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + #sudo setfattr -n security.selinux -v "u:object_r:system_lib_file:s0" "$PRODUCT_MNT/lib" || abort + #find "$WORK_DIR/gapps/product/lib/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/lib/placeholder" -exec setfattr -n security.selinux -v "u:object_r:system_lib_file:s0" {} \; || abort + #find "$WORK_DIR/gapps/product/lib64/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$PRODUCT_MNT/lib64/placeholder" -type f -exec setfattr -n security.selinux -v "u:object_r:system_lib_file:s0" {} \; || abort + find "$WORK_DIR/gapps/system_ext/priv-app/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$SYSTEM_EXT_MNT/priv-app/placeholder" -type d -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + find "$WORK_DIR/gapps/system_ext/etc/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$SYSTEM_EXT_MNT/etc/placeholder" -type d -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + find "$WORK_DIR/gapps/system_ext/priv-app/" -maxdepth 1 -mindepth 1 -printf '%P\n' | xargs -I placeholder sudo find "$SYSTEM_EXT_MNT/priv-app/placeholder" -type f -exec setfattr -n security.selinux -v "u:object_r:system_file:s0" {} \; || abort + sudo LD_LIBRARY_PATH="../linker" "$WORK_DIR/magisk/magiskpolicy" --load "$VENDOR_MNT/etc/selinux/precompiled_sepolicy" --save "$VENDOR_MNT/etc/selinux/precompiled_sepolicy" "allow gmscore_app gmscore_app vsock_socket { create connect write read }" "allow gmscore_app device_config_runtime_native_boot_prop file read" "allow gmscore_app system_server_tmpfs dir search" "allow gmscore_app system_server_tmpfs file open" "allow gmscore_app system_server_tmpfs filesystem getattr" "allow gmscore_app gpu_device dir search" "allow gmscore_app media_rw_data_file filesystem getattr" || abort + echo -e "Integrate MindTheGapps done\n" +fi + +if [ "$HAS_GAPPS" = "yes" ]; then + echo "Fix MindTheGapps prop" + sudo python3 fixGappsProp.py "$ROOT_MNT" || abort + echo -e "Done\n" +fi + +sudo find "$ROOT_MNT" -not -type l -exec touch -amt 200901010000.00 {} \; + +if [ "$SYSTEMIMAGES_FILE_SYSTEM_TYPE" = "erofs" ]; then + echo "Create EROFS images" + mk_erofs_umount "$VENDOR_MNT" "$WORK_DIR/wsa/$ARCH/vendor.img" || abort + mk_erofs_umount "$PRODUCT_MNT" "$WORK_DIR/wsa/$ARCH/product.img" || abort + mk_erofs_umount "$SYSTEM_EXT_MNT" "$WORK_DIR/wsa/$ARCH/system_ext.img" || abort + mk_erofs_umount "$ROOT_MNT" "$WORK_DIR/wsa/$ARCH/system.img" || abort + echo -e "Create EROFS images done\n" + echo "Umount images" + sudo umount -v "$VENDOR_MNT_RO" + sudo umount -v "$PRODUCT_MNT_RO" + sudo umount -v "$SYSTEM_EXT_MNT_RO" + sudo umount -v "$ROOT_MNT_RO" + echo -e "done\n" +elif [ "$SYSTEMIMAGES_FILE_SYSTEM_TYPE" = "ext4" ]; then + echo "Umount images" + sudo find "$ROOT_MNT" -exec touch -hamt 200901010000.00 {} \; + sudo umount -v "$VENDOR_MNT" + sudo umount -v "$PRODUCT_MNT" + sudo umount -v "$SYSTEM_EXT_MNT" + sudo umount -v "$ROOT_MNT" + echo -e "done\n" + echo "Shrink images" + resize_img "$WORK_DIR/wsa/$ARCH/system.img" || abort + resize_img "$WORK_DIR/wsa/$ARCH/vendor.img" || abort + resize_img "$WORK_DIR/wsa/$ARCH/product.img" || abort + resize_img "$WORK_DIR/wsa/$ARCH/system_ext.img" || abort + echo -e "Shrink images done\n" +else + abort "Unknown file system type: $SYSTEMIMAGES_FILE_SYSTEM_TYPE" +fi + +echo "Convert images to vhdx" +qemu-img convert -q -f raw -o subformat=fixed -O vhdx "$WORK_DIR/wsa/$ARCH/system_ext.img" "$WORK_DIR/wsa/$ARCH/system_ext.vhdx" || abort +qemu-img convert -q -f raw -o subformat=fixed -O vhdx "$WORK_DIR/wsa/$ARCH/product.img" "$WORK_DIR/wsa/$ARCH/product.vhdx" || abort +qemu-img convert -q -f raw -o subformat=fixed -O vhdx "$WORK_DIR/wsa/$ARCH/system.img" "$WORK_DIR/wsa/$ARCH/system.vhdx" || abort +qemu-img convert -q -f raw -o subformat=fixed -O vhdx "$WORK_DIR/wsa/$ARCH/vendor.img" "$WORK_DIR/wsa/$ARCH/vendor.vhdx" || abort +rm -f "$WORK_DIR/wsa/$ARCH/"*.img || abort +echo -e "Convert images to vhdx done\n" + +echo "Remove signature and add scripts" +sudo rm -rf "${WORK_DIR:?}"/wsa/"$ARCH"/\[Content_Types\].xml "$WORK_DIR/wsa/$ARCH/AppxBlockMap.xml" "$WORK_DIR/wsa/$ARCH/AppxSignature.p7x" "$WORK_DIR/wsa/$ARCH/AppxMetadata" || abort +if [ "$ARCH" = "x64" ]; then + sudo rm -rf "$WORK_DIR/wsa/$ARCH/arm64/" || abort +else + sudo rm -rf "$WORK_DIR/wsa/$ARCH/amd64/" || abort +fi +mkdir "$WORK_DIR/wsa/$ARCH/uwp" +cp "$VCLibs_PATH" "$xaml_PATH" "$WORK_DIR/wsa/$ARCH/uwp/" || abort +cp "$UWPVCLibs_PATH" "$xaml_PATH" "$WORK_DIR/wsa/$ARCH/uwp/" || abort +cp "../xml/priconfig.xml" "$WORK_DIR/wsa/$ARCH/xml/" || abort +if [[ "$ROOT_SOL" = "none" ]] && [[ "$HAS_GAPPS" = "yes" ]] && [[ "$REMOVE_AMAZON" == "yes" ]]; then + sed -i -e 's@Start-Process\ "wsa://com.topjohnwu.magisk"@@g' "../installer/$ARCH/Install.ps1" + sed -i -e 's@Start-Process\ "wsa://com.android.vending"@@g' "../installer/$ARCH/Install.ps1" +else + if [[ "$ROOT_SOL" == "none" ]]; then + sed -i -e 's@Start-Process "wsa://com.topjohnwu.magisk"@@g' "../installer/$ARCH/Install.ps1" + elif [[ "$ROOT_SOL" = "kernelsu" ]]; then + sed -i -e 's@wsa://com.topjohnwu.magisk@https://github.com/YT-Advanced/WSA-Script/blob/HEAD/docs/Guides/KernelSU.md@g' "../installer/$ARCH/Install.ps1" + elif [[ "$MAGISK_BRANCH" = "HuskyDG" ]]; then + sed -i -e 's@com.topjohnwu.magisk@io.github.huskydg.magisk@g' "../installer/$ARCH/Install.ps1" + elif [[ "$MAGISK_BRANCH" = "vvb2060" ]]; then + sed -i -e 's@com.topjohnwu.magisk@io.github.vvb2060.magisk@g' "../installer/$ARCH/Install.ps1" + fi + if [[ "$HAS_GAPPS" != "yes" ]] && [[ "$REMOVE_AMAZON" != "yes" ]]; then + sed -i -e 's@com.android.vending@com.amazon.venezia@g' "../installer/$ARCH/Install.ps1" + elif [[ "$HAS_GAPPS" != "yes" ]]; then + sed -i -e 's@Start-Process\ "wsa://com.android.vending"@@g' "../installer/$ARCH/Install.ps1" + fi +fi +cp "../installer/$ARCH/Install.ps1" "$WORK_DIR/wsa/$ARCH" || abort +find "$WORK_DIR/wsa/$ARCH" -not -path "*/uwp*" -not -path "*/pri*" -not -path "*/xml*" -printf "%P\n" | sed -e 's@/@\\@g' -e '/^$/d' > "$WORK_DIR/wsa/$ARCH/filelist.txt" || abort +find "$WORK_DIR/wsa/$ARCH/pri" -printf "%P\n" | sed -e 's/^/pri\\/' -e '/^$/d' > "$WORK_DIR/wsa/$ARCH/filelist-pri.txt" || abort +find "$WORK_DIR/wsa/$ARCH/xml" -printf "%P\n" | sed -e 's/^/xml\\/' -e '/^$/d' >> "$WORK_DIR/wsa/$ARCH/filelist-pri.txt" || abort +cp "../installer/$ARCH/MakePri.ps1" "$WORK_DIR/wsa/$ARCH" || abort +cp ../installer/Run.bat "$WORK_DIR/wsa/$ARCH" || abort +echo -e "Remove signature and Add scripts done\n" + +echo "Generate info" +if [[ "$ROOT_SOL" = "none" ]]; then + name1="" +elif [ "$ROOT_SOL" = "magisk" ]; then + name1="-with-Magisk-$MAGISK_VERSION_NAME-$MAGISK_VER" +elif [ "$ROOT_SOL" = "kernelsu" ]; then + name1="-with-KernelSU-$KERNELSU_VER" +fi +if [ "$HAS_GAPPS" = "yes" ]; then + name2="-NoGApps" +else + name2=-Gapps-13.0 +fi +artifact_name=WSA_${WSA_VER}_${ARCH}_${WSA_REL}${name1}${name2} +if [ "$REMOVE_AMAZON" = "yes" ]; then + artifact_name+="-RemovedAmazon" + touch "$WORK_DIR/wsa/$ARCH/apex/.gitkeep" +fi +echo "$artifact_name" +echo -e "\nFinishing building...." +mkdir -p "$OUTPUT_DIR" +OUTPUT_PATH="${OUTPUT_DIR:?}/$artifact_name" +OUTPUT_PATH="${OUTPUT_DIR:?}/$artifact_name" +mv "$WORK_DIR/wsa/$ARCH" "$OUTPUT_PATH" +{ + echo "artifact=${artifact_name}" + echo "arch=${ARCH}" + echo "built=$(date -u +%Y%m%d%H%M%S)" + echo "file_ext=${COMPRESS_FORMAT}" +} >> "$GITHUB_OUTPUT" +echo -e "Done\n" diff --git a/scripts/extractMagisk.py b/scripts/extractMagisk.py index 577a096a..54e5f21d 100644 --- a/scripts/extractMagisk.py +++ b/scripts/extractMagisk.py @@ -80,3 +80,8 @@ def extract_as(zip, name, as_name, dir): extract_as(zip, f"lib/{ abi_map[arch][0] }/libinit-ld.so", "init-ld", "magisk") extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskinit", "magisk") extract_as(zip, f"lib/{ abi_map[host_abi][0] }/libmagiskboot.so", "magiskboot", "magisk") + + if f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so" in namelist: + extract_as(zip, f"lib/{ abi_map[host_abi][0] }/libmagiskpolicy.so", "magiskpolicy", "magisk") + else: + extract_as(zip, f"lib/{ abi_map[host_abi][0] }/libmagiskinit.so", "magiskpolicy", "magisk") diff --git a/scripts/fixGappsProp.py b/scripts/fixGappsProp.py index afc35b5a..300b7e20 100644 --- a/scripts/fixGappsProp.py +++ b/scripts/fixGappsProp.py @@ -40,21 +40,18 @@ def __iadd__(self, other: str) -> Prop: self[f".{len(self)}"] = other return self + new_props = { ("product", "brand"): "google", - ("system", "brand"): "google", ("product", "manufacturer"): "Google", - ("system", "manufacturer"): "Google", - ("build", "product"): sys.argv[2], - ("product", "name"): sys.argv[2], - ("system", "name"): sys.argv[2], - ("product", "device"): sys.argv[2], - ("system", "device"): sys.argv[2], - ("product", "model"): sys.argv[3], - ("system", "model"): sys.argv[3], - ("build", "flavor"): sys.argv[2] + "-user" + ("build", "product"): "redfin", + ("product", "name"): "redfin", + ("product", "device"): "redfin", + ("product", "model"): "Pixel 5", + ("build", "flavor"): "redfin-user" } + def description(sec: str, p: Prop) -> str: return f"{p[f'ro.{sec}.build.flavor']} {p[f'ro.{sec}.build.version.release_or_codename']} {p[f'ro.{sec}.build.id']} {p[f'ro.{sec}.build.version.incremental']} {p[f'ro.{sec}.build.tags']}" @@ -71,7 +68,7 @@ def fix_prop(sec, prop): with open(prop, 'r') as f: p = Prop(f) - p += "# extra props added by MagiskOnWSA and YT-Advanced/WSA-Script" + p += "# extra prop added by MagiskOnWSA" for k, v in new_props.items(): p[f"ro.{k[0]}.{k[1]}"] = v @@ -92,5 +89,5 @@ def fix_prop(sec, prop): sys_path = sys.argv[1] -for sec, prop in {"system": sys_path+"/system/build.prop", "vendor": sys_path+"/vendor/build.prop", "odm": sys_path+"/vendor/odm/etc/build.prop", "vendor_dlkm": sys_path+"/vendor/vendor_dlkm/etc/build.prop"}.items(): +for sec, prop in {"system": sys_path+"/system/build.prop", "product": sys_path+"/product/build.prop", "system_ext": sys_path+"/system_ext/build.prop", "vendor": sys_path+"/vendor/build.prop", "odm": sys_path+"/vendor/odm/etc/build.prop"}.items(): fix_prop(sec, prop) diff --git a/scripts/generateAddonsLink.py b/scripts/generateAddonsLink.py new file mode 100644 index 00000000..3d791bb6 --- /dev/null +++ b/scripts/generateAddonsLink.py @@ -0,0 +1,79 @@ +#!/usr/bin/python3 +# +# This file is part of MagiskOnWSALocal. +# +# MagiskOnWSALocal is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# MagiskOnWSALocal is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with MagiskOnWSALocal. If not, see . +# +# Copyright (C) 2024 LSPosed Contributors +# + +from datetime import datetime +import sys + +import requests +import json +import re +from pathlib import Path + + +class BearerAuth(requests.auth.AuthBase): + def __init__(self, token): + self.token = token + + def __call__(self, r): + r.headers["authorization"] = "Bearer " + self.token + return r + + +github_auth = None +if Path.cwd().joinpath('token').exists(): + with open(Path.cwd().joinpath('token'), 'r') as token_file: + github_auth = BearerAuth(token_file.read()) + print("Using token file for authentication", flush=True) +arch = sys.argv[1] +arg2 = sys.argv[2] +download_dir = Path.cwd().parent / "download" if arg2 == "" else Path(arg2) +tempScript = sys.argv[3] +android_api = sys.argv[4] +file_name = sys.argv[5] +print(f"Generating GApps download link: arch={arch}", flush=True) +abi_map = {"x64": "x86_64", "arm64": "arm64"} +android_api_map = {"33": "13.0", "34": "14.0"} +release = android_api_map[android_api] +res = requests.get(f"https://api.github.com/repos/LSPosed/WSA-Addon/releases/latest", auth=github_auth) +json_data = json.loads(res.content) +headers = res.headers +x_ratelimit_remaining = headers["x-ratelimit-remaining"] +if res.status_code == 200: + download_files = {} + assets = json_data["assets"] + for asset in assets: + if re.match(f'gapps.*{release}.*\.rc$', asset["name"]): + download_files[asset["name"]] = asset["browser_download_url"] + elif re.match(f'gapps.*{release}.*{abi_map[arch]}.*\.img$', asset["name"]): + download_files[asset["name"]] = asset["browser_download_url"] + with open(download_dir/tempScript, 'a') as f: + for key, value in download_files.items(): + print(f"download link: {value}\npath: {download_dir / key}\n", flush=True) + f.writelines(value + '\n') + f.writelines(f' dir={download_dir}\n') + f.writelines(f' out={key}\n') +elif res.status_code == 403 and x_ratelimit_remaining == '0': + message = json_data["message"] + print(f"Github API Error: {message}", flush=True) + ratelimit_reset = headers["x-ratelimit-reset"] + ratelimit_reset = datetime.fromtimestamp(int(ratelimit_reset)) + print( + f"The current rate limit window resets in {ratelimit_reset}", flush=True) + exit(1) diff --git a/scripts/generateGappsLink.py b/scripts/generateGappsLink.py index 3d791bb6..f144373d 100644 --- a/scripts/generateGappsLink.py +++ b/scripts/generateGappsLink.py @@ -26,54 +26,34 @@ import re from pathlib import Path - -class BearerAuth(requests.auth.AuthBase): - def __init__(self, token): - self.token = token - - def __call__(self, r): - r.headers["authorization"] = "Bearer " + self.token - return r - - -github_auth = None -if Path.cwd().joinpath('token').exists(): - with open(Path.cwd().joinpath('token'), 'r') as token_file: - github_auth = BearerAuth(token_file.read()) - print("Using token file for authentication", flush=True) arch = sys.argv[1] -arg2 = sys.argv[2] -download_dir = Path.cwd().parent / "download" if arg2 == "" else Path(arg2) +arg4 = sys.argv[2] +download_dir = Path.cwd().parent / "download" if arg4 == "" else Path(arg4) tempScript = sys.argv[3] -android_api = sys.argv[4] -file_name = sys.argv[5] -print(f"Generating GApps download link: arch={arch}", flush=True) +file_name = sys.argv[4] +print(f"Generating MindTheGapps download link: arch={arch}", flush=True) abi_map = {"x64": "x86_64", "arm64": "arm64"} -android_api_map = {"33": "13.0", "34": "14.0"} -release = android_api_map[android_api] -res = requests.get(f"https://api.github.com/repos/LSPosed/WSA-Addon/releases/latest", auth=github_auth) +res = requests.get(f"https://api.github.com/repos/YT-Advanced/MindTheGappsBuilder/releases/latest") json_data = json.loads(res.content) headers = res.headers x_ratelimit_remaining = headers["x-ratelimit-remaining"] if res.status_code == 200: - download_files = {} assets = json_data["assets"] for asset in assets: - if re.match(f'gapps.*{release}.*\.rc$', asset["name"]): - download_files[asset["name"]] = asset["browser_download_url"] - elif re.match(f'gapps.*{release}.*{abi_map[arch]}.*\.img$', asset["name"]): - download_files[asset["name"]] = asset["browser_download_url"] - with open(download_dir/tempScript, 'a') as f: - for key, value in download_files.items(): - print(f"download link: {value}\npath: {download_dir / key}\n", flush=True) - f.writelines(value + '\n') - f.writelines(f' dir={download_dir}\n') - f.writelines(f' out={key}\n') + if re.match(f'.*13\\.0\\.0.{abi_map[arch]}.*.zip$', asset["name"]): + link = asset["browser_download_url"] + break elif res.status_code == 403 and x_ratelimit_remaining == '0': message = json_data["message"] print(f"Github API Error: {message}", flush=True) ratelimit_reset = headers["x-ratelimit-reset"] ratelimit_reset = datetime.fromtimestamp(int(ratelimit_reset)) - print( - f"The current rate limit window resets in {ratelimit_reset}", flush=True) + print(f"The current rate limit window resets in {ratelimit_reset}", flush=True) exit(1) + +print(f"download link: {link}", flush=True) + +with open(download_dir/tempScript, 'a') as f: + f.writelines(f'{link}\n') + f.writelines(f' dir={download_dir}\n') + f.writelines(f' out={file_name}\n')