", html_string) 22 | html_string = re.sub(r"", "
", html_string) 23 | return html_string 24 | 25 | def convert_file(self, markdown_file: str) -> str: 26 | markdown_string = open(markdown_file, "r").read() 27 | html_string = core_converter.markdown(markdown_string) 28 | html_string = self.filter_html_tags(html_string) 29 | return html_string 30 | 31 | def convert_string(self, markdown_string: str) -> str: 32 | html_string = core_converter.markdown(markdown_string) 33 | html_string = self.filter_html_tags(html_string) 34 | return html_string 35 | 36 | def create_page(self, title: str, html_content: str) -> str: 37 | response = self.telegraph.create_page( 38 | title, 39 | html_content=html_content, 40 | author_name=self.author_name, 41 | author_url=self.author_url 42 | ) 43 | return response['url'] 44 | 45 | def create_page_from_file(self, title: str, markdown_file: str) -> str: 46 | html_content = self.convert_file(markdown_file) 47 | return self.create_page(title, html_content) 48 | 49 | def create_page_from_string(self, title: str, markdown_string: str) -> str: 50 | html_string = self.convert_string(markdown_string) 51 | return self.create_page(title, html_content=html_string) 52 | -------------------------------------------------------------------------------- /telegram-script/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | telegraph 3 | gh-md-to-html[offline_conversion] -------------------------------------------------------------------------------- /utils.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | MODULE_TEMPLATE_DIR="revanced-magisk" 4 | CWD=$(pwd) 5 | TEMP_DIR=${CWD}/"temp" 6 | BIN_DIR=${CWD}/"bin" 7 | BUILD_DIR=${CWD}/"build" 8 | 9 | if [ "${GITHUB_TOKEN-}" ]; then GH_HEADER="Authorization: token ${GITHUB_TOKEN}"; else GH_HEADER=; fi 10 | NEXT_VER_CODE=${NEXT_VER_CODE:-$(date +'%Y%m%d')} 11 | OS=$(uname -o) 12 | 13 | toml_prep() { __TOML__=$(tr -d '\t\r' <<<"$1" | tr "'" '"' | grep -o '^[^#]*' | grep -v '^$' | sed -r 's/(\".*\")|\s*/\1/g; 1i []'); } 14 | toml_get_table_names() { 15 | local tn 16 | tn=$(grep -x '\[.*\]' <<<"$__TOML__" | tr -d '[]') || return 1 17 | if [ "$(sort <<<"$tn" | uniq -u | wc -l)" != "$(wc -l <<<"$tn")" ]; then 18 | abort "ERROR: Duplicate tables in TOML" 19 | fi 20 | echo "$tn" 21 | } 22 | toml_get_table() { sed -n "/\[${1}]/,/^\[.*]$/p" <<<"$__TOML__" | sed '${/^\[/d;}'; } 23 | toml_get() { 24 | local table=$1 key=$2 val 25 | val=$(grep -m 1 "^${key}=" <<<"$table") && sed -e "s/^\"//; s/\"$//" <<<"${val#*=}" 26 | } 27 | 28 | pr() { echo -e "\033[0;32m[+] ${1}\033[0m"; } 29 | epr() { 30 | echo >&2 -e "\033[0;31m[-] ${1}\033[0m" 31 | if [ "${GITHUB_REPOSITORY-}" ]; then echo -e "::error::utils.sh [-] ${1}\n"; fi 32 | } 33 | abort() { 34 | epr "ABORT: ${1-}" 35 | exit 1 36 | } 37 | 38 | get_rv_prebuilts() { 39 | local cli_src=$1 cli_ver=$2 integrations_src=$3 integrations_ver=$4 patches_src=$5 patches_ver=$6 40 | local integs_file="" 41 | pr "Getting prebuilts (${patches_src%/*})" >&2 42 | local cl_dir=${patches_src%/*} 43 | cl_dir=${TEMP_DIR}/${cl_dir,,}-rv 44 | [ -d "$cl_dir" ] || mkdir "$cl_dir" 45 | for src_ver in "$cli_src CLI $cli_ver" "$integrations_src Integrations $integrations_ver" "$patches_src Patches $patches_ver"; do 46 | set -- $src_ver 47 | local src=$1 tag=$2 ver=${3-} ext 48 | if [ "$tag" = "CLI" ] || [ "$tag" = "Patches" ]; then 49 | ext="jar" 50 | elif [ "$tag" = "Integrations" ]; then 51 | ext="apk" 52 | else abort unreachable; fi 53 | local dir=${src%/*} 54 | dir=${TEMP_DIR}/${dir,,}-rv 55 | [ -d "$dir" ] || mkdir "$dir" 56 | 57 | local rv_rel="https://api.github.com/repos/${src}/releases" name_ver 58 | if [ "$ver" = "dev" ]; then 59 | name_ver="*-dev*" 60 | elif [ "$ver" = "latest" ]; then 61 | rv_rel+="/latest" 62 | name_ver="*" 63 | else 64 | rv_rel+="/tags/${ver}" 65 | name_ver="$ver" 66 | fi 67 | 68 | local url file tag_name name 69 | file=$(find "$dir" -name "revanced-${tag,,}-${name_ver#v}.${ext}" -type f 2>/dev/null) 70 | if [ -z "$file" ]; then 71 | local resp asset name 72 | resp=$(gh_req "$rv_rel" -) || return 1 73 | if [ "$ver" = "dev" ]; then resp=$(jq -r '.[0]' <<<"$resp"); fi 74 | tag_name=$(jq -r '.tag_name' <<<"$resp") 75 | asset=$(jq -e -r ".assets[] | select(.name | endswith(\"$ext\"))" <<<"$resp") || return 1 76 | url=$(jq -r .url <<<"$asset") 77 | name=$(jq -r .name <<<"$asset") 78 | file="${dir}/${name}" 79 | gh_dl "$file" "$url" >&2 || return 1 80 | if [ "$tag" = "Integrations" ]; then integs_file=$file; fi 81 | echo "$tag: $(cut -d/ -f1 <<<"$src")/${name} " >>"${cl_dir}/changelog.md" 82 | else 83 | local for_err=$file 84 | if [ "$ver" = "latest" ]; then 85 | file=$(grep -v '/[^/]*dev[^/]*$' <<<"$file" | head -1) 86 | else file=$(grep "/[^/]*${ver#v}[^/]*\$" <<<"$file" | head -1); fi 87 | if [ -z "$file" ]; then abort "filter fail: '$for_err' with '$ver'"; fi 88 | name=$(basename "$file") 89 | tag_name=$(cut -d'-' -f3- <<<"$name") 90 | tag_name=v${tag_name%.*} 91 | fi 92 | 93 | echo -n "$file " 94 | if [ "$tag" = "Patches" ]; then 95 | name="patches-${tag_name}.json" 96 | file="${dir}/${name}" 97 | if [ ! -f "$file" ]; then 98 | resp=$(gh_req "$rv_rel" -) || return 1 99 | if [ "$ver" = "dev" ]; then resp=$(jq -r '.[0]' <<<"$resp"); fi 100 | url=$(jq -e -r '.assets[] | select(.name | endswith("json")) | .url' <<<"$resp") || return 1 101 | gh_dl "$file" "$url" >&2 || return 1 102 | echo -e "[Changelog](https://github.com/${src}/releases/tag/${tag_name})\n" >>"${cl_dir}/changelog.md" 103 | fi 104 | echo -n "$file " 105 | fi 106 | done 107 | echo 108 | 109 | if [ "$integs_file" ]; then 110 | if ! ( 111 | mkdir -p "${integs_file}-zip" || return 1 112 | unzip -qo "${integs_file}" -d "${integs_file}-zip" || return 1 113 | cd "${integs_file}-zip" || return 1 114 | 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 115 | mv -f "${integs_file}-zip/classes-patched.dex" "${integs_file}-zip/classes.dex" || return 1 116 | rm "${integs_file}" || return 1 117 | zip -0rq "${integs_file}" . || return 1 118 | ) >&2; then 119 | echo >&2 "Patching revanced-integrations failed" 120 | fi 121 | rm -r "${integs_file}-zip" || : 122 | 123 | fi 124 | } 125 | 126 | get_prebuilts() { 127 | APKSIGNER="${BIN_DIR}/apksigner.jar" 128 | if [ "$OS" = Android ]; then 129 | local arch 130 | if [ "$(uname -m)" = aarch64 ]; then arch=arm64; else arch=arm; fi 131 | HTMLQ="${BIN_DIR}/htmlq/htmlq-${arch}" 132 | AAPT2="${BIN_DIR}/aapt2/aapt2-${arch}" 133 | else 134 | HTMLQ="${BIN_DIR}/htmlq/htmlq-x86_64" 135 | fi 136 | mkdir -p ${MODULE_TEMPLATE_DIR}/bin/arm64 ${MODULE_TEMPLATE_DIR}/bin/arm ${MODULE_TEMPLATE_DIR}/bin/x86 ${MODULE_TEMPLATE_DIR}/bin/x64 137 | gh_dl "${MODULE_TEMPLATE_DIR}/bin/arm64/cmpr" "https://github.com/j-hc/cmpr/releases/latest/download/cmpr-arm64-v8a" 138 | gh_dl "${MODULE_TEMPLATE_DIR}/bin/arm/cmpr" "https://github.com/j-hc/cmpr/releases/latest/download/cmpr-armeabi-v7a" 139 | gh_dl "${MODULE_TEMPLATE_DIR}/bin/x86/cmpr" "https://github.com/j-hc/cmpr/releases/latest/download/cmpr-x86" 140 | gh_dl "${MODULE_TEMPLATE_DIR}/bin/x64/cmpr" "https://github.com/j-hc/cmpr/releases/latest/download/cmpr-x86_64" 141 | } 142 | 143 | config_update() { 144 | if [ ! -f build.md ]; then abort "build.md not available"; fi 145 | declare -A sources 146 | : >"$TEMP_DIR"/skipped 147 | local conf="" 148 | # shellcheck disable=SC2154 149 | conf+=$(sed '1d' <<<"$main_config_t") 150 | conf+=$'\n' 151 | local prcfg=false 152 | for table_name in $(toml_get_table_names); do 153 | if [ -z "$table_name" ]; then continue; fi 154 | t=$(toml_get_table "$table_name") 155 | enabled=$(toml_get "$t" enabled) || enabled=true 156 | if [ "$enabled" = false ]; then continue; fi 157 | PATCHES_SRC=$(toml_get "$t" patches-source) || PATCHES_SRC=$DEF_PATCHES_SRC 158 | PATCHES_VER=$(toml_get "$t" patches-version) || PATCHES_VER=$DEF_PATCHES_VER 159 | if [[ -v sources["$PATCHES_SRC/$PATCHES_VER"] ]]; then 160 | if [ "${sources["$PATCHES_SRC/$PATCHES_VER"]}" = 1 ]; then 161 | conf+="$t" 162 | conf+=$'\n' 163 | fi 164 | else 165 | sources["$PATCHES_SRC/$PATCHES_VER"]=0 166 | local rv_rel="https://api.github.com/repos/${PATCHES_SRC}/releases" 167 | if [ "$PATCHES_VER" = "dev" ]; then 168 | last_patches=$(gh_req "$rv_rel" - | jq -e -r '.[0]') 169 | elif [ "$PATCHES_VER" = "latest" ]; then 170 | last_patches=$(gh_req "$rv_rel/latest" -) 171 | else 172 | last_patches=$(gh_req "$rv_rel/tags/${ver}" -) 173 | fi 174 | 175 | if ! last_patches=$(jq -e -r '.assets[] | select(.name | endswith("jar")) | .name' <<<"$last_patches"); then 176 | abort oops 177 | fi 178 | if [ "$last_patches" ]; then 179 | if ! OP=$(grep "^Patches: ${PATCHES_SRC%%/*}/" build.md | grep "$last_patches"); then 180 | sources["$PATCHES_SRC/$PATCHES_VER"]=1 181 | prcfg=true 182 | conf+="$t" 183 | conf+=$'\n' 184 | else 185 | echo "$OP" >>"$TEMP_DIR"/skipped 186 | fi 187 | fi 188 | fi 189 | done 190 | if [ "$prcfg" = true ]; then echo "$conf"; fi 191 | } 192 | 193 | _req() { 194 | local ip="$1" op="$2" 195 | shift 2 196 | if [ "$op" = - ]; then 197 | wget -nv -O "$op" "$@" "$ip" 198 | else 199 | if [ -f "$op" ]; then return; fi 200 | local dlp 201 | dlp="$(dirname "$op")/tmp.$(basename "$op")" 202 | if [ -f "$dlp" ]; then 203 | while [ -f "$dlp" ]; do sleep 1; done 204 | return 205 | fi 206 | wget -nv -O "$dlp" "$@" "$ip" || return 1 207 | mv -f "$dlp" "$op" 208 | fi 209 | } 210 | req() { _req "$1" "$2" --header="User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:108.0) Gecko/20100101 Firefox/108.0"; } 211 | gh_req() { _req "$1" "$2" --header="$GH_HEADER"; } 212 | gh_dl() { 213 | if [ ! -f "$1" ]; then 214 | pr "Getting '$1' from '$2'" 215 | _req "$2" "$1" --header="$GH_HEADER" --header="Accept: application/octet-stream" 216 | fi 217 | } 218 | 219 | log() { echo -e "$1 " >>"build.md"; } 220 | get_largest_ver() { 221 | local vers m 222 | vers=$(tee) 223 | m=$(head -1 <<<"$vers") 224 | if ! semver_validate "$m"; then echo "$m"; else sort -rV <<<"$vers" | head -1; fi 225 | } 226 | semver_validate() { 227 | local a="${1%-*}" 228 | local ac="${a//[.0-9]/}" 229 | [ ${#ac} = 0 ] 230 | } 231 | get_patch_last_supported_ver() { 232 | local inc_sel exc_sel vs 233 | inc_sel=$(list_args "$2" | sed 's/.*/\.name == &/' | paste -sd '~' | sed 's/~/ or /g' || :) 234 | exc_sel=$(list_args "$3" | sed 's/.*/\.name != &/' | paste -sd '~' | sed 's/~/ and /g' || :) 235 | inc_sel=${inc_sel:-false} 236 | if [ "$4" = false ]; then inc_sel="${inc_sel} or .use==true"; fi 237 | if ! vs=$(jq -e -r ".[] 238 | | select(.compatiblePackages // [] | .[] | .name==\"${1}\") 239 | | select(${inc_sel}) 240 | | select(${exc_sel:-true}) 241 | | .compatiblePackages[].versions // []" "$5"); then 242 | abort "error in jq query" 243 | fi 244 | tr -d ' ,\t[]"' <<<"$vs" | sort -u | grep -v '^$' | get_largest_ver || : 245 | } 246 | 247 | isoneof() { 248 | local i=$1 v 249 | shift 250 | for v; do [ "$v" = "$i" ] && return 0; done 251 | return 1 252 | } 253 | 254 | merge_splits() { 255 | local bundle=$1 output=$2 256 | pr "Merging splits" 257 | 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 258 | if ! OP=$(java -jar "$TEMP_DIR/apkeditor.jar" merge -i "${bundle}" -o "${bundle}.mzip" -clean-meta -f 2>&1); then 259 | epr "$OP" 260 | return 1 261 | fi 262 | # this is required because of apksig 263 | mkdir "${bundle}-zip" 264 | unzip -qo "${bundle}.mzip" -d "${bundle}-zip" 265 | cd "${bundle}-zip" || abort 266 | zip -0rq "${bundle}.zip" . 267 | cd "$CWD" || abort 268 | # if building apk, sign the merged apk properly 269 | if isoneof "module" "${build_mode_arr[@]}"; then 270 | patch_apk "${bundle}.zip" "${output}" "--exclusive" "${args[cli]}" "${args[ptjar]}" 271 | local ret=$? 272 | else 273 | cp "${bundle}.zip" "${output}" 274 | local ret=$? 275 | fi 276 | rm -r "${bundle}-zip" "${bundle}.zip" "${bundle}.mzip" || : 277 | return $ret 278 | } 279 | 280 | # -------------------- apkmirror -------------------- 281 | apk_mirror_search() { 282 | local resp="$1" dpi="$2" arch="$3" apk_bundle="$4" 283 | local apparch dlurl node app_table 284 | if [ "$arch" = all ]; then 285 | apparch=(universal noarch 'arm64-v8a + armeabi-v7a') 286 | else apparch=("$arch" universal noarch 'arm64-v8a + armeabi-v7a'); fi 287 | for ((n = 1; n < 40; n++)); do 288 | node=$($HTMLQ "div.table-row.headerFont:nth-last-child($n)" -r "span:nth-child(n+3)" <<<"$resp") 289 | if [ -z "$node" ]; then break; fi 290 | app_table=$($HTMLQ --text --ignore-whitespace <<<"$node") 291 | if [ "$(sed -n 3p <<<"$app_table")" = "$apk_bundle" ] && [ "$(sed -n 6p <<<"$app_table")" = "$dpi" ] && 292 | isoneof "$(sed -n 4p <<<"$app_table")" "${apparch[@]}"; then 293 | dlurl=$($HTMLQ --base https://www.apkmirror.com --attribute href "div:nth-child(1) > a:nth-child(1)" <<<"$node") 294 | echo "$dlurl" 295 | return 0 296 | fi 297 | done 298 | return 1 299 | } 300 | dl_apkmirror() { 301 | local url=$1 version=${2// /-} output=$3 arch=$4 dpi=$5 is_bundle=false 302 | if [ -f "${output}.apkm" ]; then 303 | is_bundle=true 304 | else 305 | if [ "$arch" = "arm-v7a" ]; then arch="armeabi-v7a"; fi 306 | local resp node app_table dlurl="" 307 | url="${url}/${url##*/}-${version//./-}-release/" 308 | resp=$(req "$url" -) || return 1 309 | node=$($HTMLQ "div.table-row.headerFont:nth-last-child(1)" -r "span:nth-child(n+3)" <<<"$resp") 310 | if [ "$node" ]; then 311 | if ! dlurl=$(apk_mirror_search "$resp" "$dpi" "${arch}" "APK"); then 312 | if ! dlurl=$(apk_mirror_search "$resp" "$dpi" "${arch}" "BUNDLE"); then 313 | return 1 314 | else is_bundle=true; fi 315 | fi 316 | [ -z "$dlurl" ] && return 1 317 | resp=$(req "$dlurl" -) 318 | fi 319 | url=$(echo "$resp" | $HTMLQ --base https://www.apkmirror.com --attribute href "a.btn") || return 1 320 | url=$(req "$url" - | $HTMLQ --base https://www.apkmirror.com --attribute href "span > a[rel = nofollow]") || return 1 321 | fi 322 | 323 | if [ "$is_bundle" = true ]; then 324 | req "$url" "${output}.apkm" 325 | merge_splits "${output}.apkm" "${output}" 326 | else 327 | req "$url" "${output}" 328 | fi 329 | } 330 | get_apkmirror_vers() { 331 | local vers apkm_resp 332 | apkm_resp=$(req "https://www.apkmirror.com/uploads/?appcategory=${__APKMIRROR_CAT__}" -) 333 | vers=$(sed -n 's;.*Version:\(.*\) .*;\1;p' <<<"$apkm_resp") 334 | if [ "$__AAV__" = false ]; then 335 | local IFS=$'\n' 336 | vers=$(grep -iv "\(beta\|alpha\)" <<<"$vers") 337 | local v r_vers=() 338 | for v in $vers; do 339 | grep -iq "${v} \(beta\|alpha\)" <<<"$apkm_resp" || r_vers+=("$v") 340 | done 341 | echo "${r_vers[*]}" 342 | else 343 | echo "$vers" 344 | fi 345 | } 346 | get_apkmirror_pkg_name() { sed -n 's;.*id=\(.*\)" class="accent_color.*;\1;p' <<<"$__APKMIRROR_RESP__"; } 347 | get_apkmirror_resp() { 348 | __APKMIRROR_RESP__=$(req "${1}" -) 349 | __APKMIRROR_CAT__="${1##*/}" 350 | } 351 | 352 | # -------------------- uptodown -------------------- 353 | get_uptodown_resp() { 354 | __UPTODOWN_RESP__=$(req "${1}/versions" -) 355 | __UPTODOWN_RESP_PKG__=$(req "${1}/download" -) 356 | } 357 | get_uptodown_vers() { $HTMLQ --text ".version" <<<"$__UPTODOWN_RESP__"; } 358 | dl_uptodown() { 359 | local uptodown_dlurl=$1 version=$2 output=$3 arch=$4 _dpi=$5 is_latest=$6 360 | local url 361 | if [ "$is_latest" = false ]; then 362 | url=$(grep -F "${version}" -B 2 <<<"$__UPTODOWN_RESP__" | head -1 | sed -n 's;.*data-url=".*download\/\(.*\)".*;\1;p') || return 1 363 | url="/$url" 364 | else url=""; fi 365 | if [ "$arch" != all ]; then 366 | local app_code data_version files node_arch content resp 367 | if [ "$is_latest" = false ]; then 368 | resp=$(req "${1}/download${url}" -) 369 | else resp="$__UPTODOWN_RESP_PKG__"; fi 370 | app_code=$($HTMLQ "#detail-app-name" --attribute code <<<"$resp") 371 | data_version=$($HTMLQ "button.button:nth-child(2)" --attribute data-version <<<"$resp") 372 | files=$(req "${uptodown_dlurl%/*}/app/${app_code}/version/${data_version}/files" - | jq -r .content) 373 | for ((n = 1; n < 40; n++)); do 374 | node_arch=$($HTMLQ ".content > p:nth-child($n)" --text <<<"$files" | xargs) || return 1 375 | if [ -z "$node_arch" ]; then return 1; fi 376 | if [ "$node_arch" != "$arch" ]; then continue; fi 377 | content=$($HTMLQ "div.variant:nth-child($((n + 1)))" <<<"$files") 378 | url=$(sed -n "s;.*'.*android\/post-download\/\(.*\)'.*;\1;p" <<<"$content" | head -1) 379 | url="/$url" 380 | break 381 | done 382 | fi 383 | url="https://dw.uptodown.com/dwn/$(req "${uptodown_dlurl}/post-download${url}" - | sed -n 's;.*class="post-download" data-url="\(.*\)".*;\1;p')" || return 1 384 | req "$url" "$output" 385 | } 386 | get_uptodown_pkg_name() { $HTMLQ --text "tr.full:nth-child(1) > td:nth-child(3)" <<<"$__UPTODOWN_RESP_PKG__"; } 387 | 388 | # -------------------- archive -------------------- 389 | dl_archive() { 390 | local url=$1 version=$2 output=$3 arch=$4 391 | local path version=${version// /} 392 | path=$(grep "${version_f#v}-${arch// /}" <<<"$__ARCHIVE_RESP__") || return 1 393 | req "${url}/${path}" "$output" 394 | } 395 | get_archive_resp() { 396 | local r 397 | r=$(req "$1" -) 398 | if [ -z "$r" ]; then return 1; else __ARCHIVE_RESP__=$(sed -n 's;^/dev/null || : 413 | return 1 414 | fi 415 | } 416 | 417 | check_sig() { 418 | local file=$1 pkg_name=$2 419 | local sig 420 | if grep -q "$pkg_name" sig.txt; then 421 | sig=$(java -jar "$APKSIGNER" verify --print-certs "$file" | grep ^Signer | grep SHA-256 | tail -1 | awk '{print $NF}') 422 | grep -qFx "$sig $pkg_name" sig.txt 423 | fi 424 | } 425 | 426 | build_rv() { 427 | eval "declare -A args=${1#*=}" 428 | local version pkg_name 429 | local mode_arg=${args[build_mode]} version_mode=${args[version]} 430 | local app_name=${args[app_name]} 431 | local app_name_l=${app_name,,} 432 | app_name_l=${app_name_l// /-} 433 | local table=${args[table]} 434 | local dl_from=${args[dl_from]} 435 | local arch=${args[arch]} 436 | local arch_f="${arch// /}" 437 | 438 | local p_patcher_args=() 439 | p_patcher_args+=("$(join_args "${args[excluded_patches]}" -e) $(join_args "${args[included_patches]}" -i)") 440 | [ "${args[exclusive_patches]}" = true ] && p_patcher_args+=("--exclusive") 441 | 442 | local tried_dl=() 443 | for dl_p in archive apkmirror uptodown; do 444 | if [ -z "${args[${dl_p}_dlurl]}" ]; then continue; fi 445 | if ! get_${dl_p}_resp "${args[${dl_p}_dlurl]}" || ! pkg_name=$(get_"${dl_p}"_pkg_name); then 446 | args[${dl_p}_dlurl]="" 447 | epr "ERROR: Could not find ${table} in ${dl_p}" 448 | continue 449 | fi 450 | tried_dl+=("$dl_p") 451 | dl_from=$dl_p 452 | break 453 | done 454 | if [ -z "$pkg_name" ]; then 455 | epr "empty pkg name, not building ${table}." 456 | return 0 457 | fi 458 | local get_latest_ver=false 459 | if [ "$version_mode" = auto ]; then 460 | if ! version=$(get_patch_last_supported_ver "$pkg_name" \ 461 | "${args[included_patches]}" "${args[excluded_patches]}" "${args[exclusive_patches]}" "${args[ptjs]}"); then 462 | exit 1 463 | elif [ -z "$version" ]; then get_latest_ver=true; fi 464 | elif isoneof "$version_mode" latest beta; then 465 | get_latest_ver=true 466 | p_patcher_args+=("-f") 467 | else 468 | version=$version_mode 469 | p_patcher_args+=("-f") 470 | fi 471 | if [ $get_latest_ver = true ]; then 472 | if [ "$version_mode" = beta ]; then __AAV__="true"; else __AAV__="false"; fi 473 | pkgvers=$(get_"${dl_from}"_vers) 474 | version=$(get_largest_ver <<<"$pkgvers") || version=$(head -1 <<<"$pkgvers") 475 | fi 476 | if [ -z "$version" ]; then 477 | epr "empty version, not building ${table}." 478 | return 0 479 | fi 480 | 481 | if [ "$mode_arg" = module ]; then 482 | build_mode_arr=(module) 483 | elif [ "$mode_arg" = apk ]; then 484 | build_mode_arr=(apk) 485 | elif [ "$mode_arg" = both ]; then 486 | build_mode_arr=(apk module) 487 | fi 488 | 489 | pr "Choosing version '${version}' for ${table}" 490 | local version_f=${version// /} 491 | version_f=${version_f#v} 492 | local stock_apk="${TEMP_DIR}/${pkg_name}-${version_f}-${arch_f}.apk" 493 | if [ ! -f "$stock_apk" ]; then 494 | for dl_p in archive apkmirror uptodown; do 495 | if [ -z "${args[${dl_p}_dlurl]}" ]; then continue; fi 496 | pr "Downloading '${table}' from ${dl_p}" 497 | if ! isoneof $dl_p "${tried_dl[@]}"; then get_${dl_p}_resp "${args[${dl_p}_dlurl]}"; fi 498 | if ! dl_${dl_p} "${args[${dl_p}_dlurl]}" "$version" "$stock_apk" "$arch" "${args[dpi]}" "$get_latest_ver"; then 499 | epr "ERROR: Could not download '${table}' from ${dl_p} with version '${version}', arch '${arch}', dpi '${args[dpi]}'" 500 | continue 501 | fi 502 | break 503 | done 504 | if [ ! -f "$stock_apk" ]; then return 0; fi 505 | fi 506 | if ! check_sig "$stock_apk" "$pkg_name"; then 507 | abort "apk signature mismatch '$stock_apk'" 508 | fi 509 | log "${table}: ${version}" 510 | 511 | p_patcher_args+=("-m ${args[integ]}") 512 | local microg_patch 513 | microg_patch=$(jq -r ".[] | select(.compatiblePackages // [] | .[] | .name==\"${pkg_name}\") | .name" "${args[ptjs]}" | grep -i "gmscore\|microg" || :) 514 | if [ -n "$microg_patch" ] && [[ ${p_patcher_args[*]} =~ $microg_patch ]]; then 515 | epr "You cant include/exclude microg patches as that's done by rvmm builder automatically." 516 | p_patcher_args=("${p_patcher_args[@]//-[ei] ${microg_patch}/}") 517 | fi 518 | 519 | local patcher_args patched_apk build_mode 520 | local rv_brand_f=${args[rv_brand],,} 521 | rv_brand_f=${rv_brand_f// /-} 522 | for build_mode in "${build_mode_arr[@]}"; do 523 | patcher_args=("${p_patcher_args[@]}") 524 | pr "Building '${table}' in '$build_mode' mode" 525 | if [ -n "$microg_patch" ]; then 526 | patched_apk="${TEMP_DIR}/${app_name_l}-${rv_brand_f}-${version_f}-${arch_f}-${build_mode}.apk" 527 | if [ "$build_mode" = apk ]; then 528 | patcher_args+=("-i \"${microg_patch}\"") 529 | elif [ "$build_mode" = module ]; then 530 | patcher_args+=("-e \"${microg_patch}\"") 531 | fi 532 | else 533 | patched_apk="${TEMP_DIR}/${app_name_l}-${rv_brand_f}-${version_f}-${arch_f}.apk" 534 | fi 535 | if [ "${args[riplib]}" = true ]; then 536 | patcher_args+=("--rip-lib x86_64 --rip-lib x86") 537 | if [ "$build_mode" = module ]; then 538 | patcher_args+=("--rip-lib arm64-v8a --rip-lib armeabi-v7a --unsigned") 539 | else 540 | if [ "$arch" = "arm64-v8a" ]; then 541 | patcher_args+=("--rip-lib armeabi-v7a") 542 | elif [ "$arch" = "arm-v7a" ]; then 543 | patcher_args+=("--rip-lib arm64-v8a") 544 | fi 545 | fi 546 | fi 547 | if [ "${NORB:-}" != true ] || [ ! -f "$patched_apk" ]; then 548 | if ! patch_apk "$stock_apk" "$patched_apk" "${patcher_args[*]}" "${args[cli]}" "${args[ptjar]}"; then 549 | epr "Building '${table}' failed!" 550 | return 0 551 | fi 552 | fi 553 | if [ "$build_mode" = apk ]; then 554 | local apk_output="${BUILD_DIR}/${app_name_l}-${rv_brand_f}-v${version_f}-${arch_f}.apk" 555 | mv -f "$patched_apk" "$apk_output" 556 | pr "Built ${table} (non-root): '${apk_output}'" 557 | continue 558 | fi 559 | local base_template 560 | base_template=$(mktemp -d -p "$TEMP_DIR") 561 | cp -a $MODULE_TEMPLATE_DIR/. "$base_template" 562 | local upj="${table,,}-update.json" 563 | 564 | module_config "$base_template" "$pkg_name" "$version" "$arch" 565 | module_prop \ 566 | "${args[module_prop_name]}" \ 567 | "${app_name} ${args[rv_brand]}" \ 568 | "$version" \ 569 | "${app_name} ${args[rv_brand]} Magisk module" \ 570 | "https://raw.githubusercontent.com/${GITHUB_REPOSITORY-}/update/${upj}" \ 571 | "$base_template" 572 | 573 | local module_output="${app_name_l}-${rv_brand_f}-magisk-v${version_f}-${arch_f}.zip" 574 | pr "Packing module ${table}" 575 | cp -f "$patched_apk" "${base_template}/base.apk" 576 | if [ "${args[include_stock]}" = true ]; then cp -f "$stock_apk" "${base_template}/${pkg_name}.apk"; fi 577 | pushd >/dev/null "$base_template" || abort "Module template dir not found" 578 | zip -"$COMPRESSION_LEVEL" -FSqr "${BUILD_DIR}/${module_output}" . 579 | popd >/dev/null || : 580 | pr "Built ${table} (root): '${BUILD_DIR}/${module_output}'" 581 | done 582 | } 583 | 584 | list_args() { tr -d '\t\r' <<<"$1" | tr -s ' ' | sed 's/" "/"\n"/g' | sed 's/\([^"]\)"\([^"]\)/\1'\''\2/g' | grep -v '^$' || :; } 585 | join_args() { list_args "$1" | sed "s/^/${2} /" | paste -sd " " - || :; } 586 | 587 | module_config() { 588 | local ma="" 589 | if [ "$4" = "arm64-v8a" ]; then 590 | ma="arm64" 591 | elif [ "$4" = "arm-v7a" ]; then 592 | ma="arm" 593 | fi 594 | echo "PKG_NAME=$2 595 | PKG_VER=$3 596 | MODULE_ARCH=$ma" >"$1/config" 597 | } 598 | module_prop() { 599 | echo "id=${1} 600 | name=${2} 601 | version=v${3} 602 | versionCode=${NEXT_VER_CODE} 603 | author=j-hc 604 | description=${4}" >"${6}/module.prop" 605 | 606 | if [ "$ENABLE_MAGISK_UPDATE" = true ]; then echo "updateJson=${5}" >>"${6}/module.prop"; fi 607 | } 608 | --------------------------------------------------------------------------------