├── .gitattributes ├── .gitignore ├── META-INF └── com │ └── google │ └── android │ ├── update-binary │ └── updater-script ├── README.md ├── busybox-armeabi-v7a ├── busybox-x86 ├── customize.sh ├── mod-util.sh ├── module.prop ├── system └── bin │ └── module_manager ├── zip-armeabi-v7a └── zip-x86 /.gitattributes: -------------------------------------------------------------------------------- 1 | META-INF/** text eol=lf 2 | *.sh text eol=lf 3 | module_manager text eol=lf 4 | *.md text eol=lf 5 | *.prop text eol=lf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __MACOSX 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /META-INF/com/google/android/update-binary: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | 3 | ################# 4 | # Initialization 5 | ################# 6 | 7 | umask 022 8 | 9 | # echo before loading util_functions 10 | ui_print() { echo "$1"; } 11 | 12 | require_new_magisk() { 13 | ui_print "*******************************" 14 | ui_print " Please install Magisk > v23! " 15 | ui_print "*******************************" 16 | exit 1 17 | } 18 | 19 | ######################### 20 | # Load util_functions.sh 21 | ######################### 22 | 23 | OUTFD=$2 24 | ZIPFILE=$3 25 | 26 | mount /data 2>/dev/null 27 | 28 | [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk 29 | . /data/adb/magisk/util_functions.sh 30 | [ $MAGISK_VER_CODE -lt 23000 ] && require_new_magisk 31 | 32 | install_module 33 | exit 0 -------------------------------------------------------------------------------- /META-INF/com/google/android/updater-script: -------------------------------------------------------------------------------- 1 | #MAGISK 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Module Manager 2 | 3 | Terminal script to manage your magisk modules 4 | 5 | Note that this is only for magisk canary builds > v23 and < 24 beta 6 | Temporary workaround until custom repo support is added to magisk manager canary 7 | 8 | ### Usage 9 | ``` 10 | su 11 | module_manager 12 | ``` 13 | 14 | ### Download 15 | See [my website](https://zackptg5.com/android.php#mm) 16 | 17 | ### Changelog 18 | * v1.0 - 11/16/21 19 | * Initial Release 20 | * v1.1 - 11/17/21 21 | * Bug fix for self-updating module manager 22 | * Allow updating of existing magisk repo modules without needing to reinstall through module manager 23 | 24 | ### Support 25 | See [XDA Thread](https://forum.xda-developers.com/t/module-canary-module-manager.4362875) 26 | -------------------------------------------------------------------------------- /busybox-armeabi-v7a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zackptg5/Module-Manager/823a359a20dfbc8ac566da9167736b6a184578a3/busybox-armeabi-v7a -------------------------------------------------------------------------------- /busybox-x86: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zackptg5/Module-Manager/823a359a20dfbc8ac566da9167736b6a184578a3/busybox-x86 -------------------------------------------------------------------------------- /customize.sh: -------------------------------------------------------------------------------- 1 | echo "https://github.com/Zackptg5/Module-Manager" > $MODPATH/module_manager 2 | mv -f $MODPATH/busybox-$ABI32 $MODPATH/busybox 3 | mv -f $MODPATH/zip-$ABI32 $MODPATH/zip 4 | rm -f $MODPATH/busybox-* $MODPATH/zip-* 5 | set_perm_recursive $MODPATH/system 0 0 0755 0755 6 | set_perm $MODPATH/busybox 0 0 0755 7 | set_perm $MODPATH/zip 0 0 0755 8 | -------------------------------------------------------------------------------- /mod-util.sh: -------------------------------------------------------------------------------- 1 | ########################################################################################## 2 | # 3 | # Terminal Utility Functions 4 | # by veez21 5 | # 6 | ########################################################################################## 7 | 8 | # Versions 9 | MODUTILVER=v2.6.2 10 | MODUTILVCODE=262 11 | 12 | # Check A/B slot 13 | if [ -d /system_root ]; then 14 | isABDevice=true 15 | SYSTEM=/system_root/system 16 | SYSTEM2=/system 17 | CACHELOC=/data/cache 18 | else 19 | isABDevice=false 20 | SYSTEM=/system 21 | SYSTEM2=/system 22 | CACHELOC=/cache 23 | fi 24 | [ -z "$isABDevice" ] && { echo "Something went wrong!"; exit 1; } 25 | 26 | #=========================== Set Busybox up 27 | # Variables: 28 | # BBok - If busybox detection was ok (true/false) 29 | # _bb - Busybox binary directory 30 | # _bbname - Busybox name 31 | 32 | # set_busybox 33 | # alias busybox applets 34 | set_busybox() { 35 | if [ -x "$1" ]; then 36 | for i in $(${1} --list); do 37 | if [ "$i" != 'echo' ]; then 38 | alias "$i"="${1} $i" >/dev/null 2>&1 39 | fi 40 | done 41 | _busybox=true 42 | _bb=$1 43 | fi 44 | } 45 | _busybox=false 46 | if [ -n "$_bb" ]; then 47 | true 48 | elif [ -x $SYSTEM2/xbin/busybox ]; then 49 | _bb=$SYSTEM2/xbin/busybox 50 | elif [ -x $SYSTEM2/bin/busybox ]; then 51 | _bb=$SYSTEM2/bin/busybox 52 | else 53 | echo "! Busybox not detected" 54 | echo "Please install one (@osm0sis' busybox recommended)" 55 | false 56 | fi 57 | set_busybox $_bb 58 | [ $? -ne 0 ] && exit $? 59 | [ -n "$ANDROID_SOCKET_adbd" ] && alias clear='echo' 60 | _bbname="$($_bb | head -n1 | awk '{print $1,$2}')" 61 | BBok=true 62 | if [ "$_bbname" == "" ]; then 63 | _bbname="BusyBox not found!" 64 | BBok=false 65 | fi 66 | 67 | #=========================== Default Functions and Variables 68 | 69 | # Set perm 70 | set_perm() { 71 | chown $2:$3 $1 || return 1 72 | chmod $4 $1 || return 1 73 | (if [ -z $5 ]; then 74 | case $1 in 75 | *"/bin/"*) chcon 'u:object_r:system_file:s0' $1;; 76 | *"system/vendor/app/"*) chcon 'u:object_r:vendor_app_file:s0' $1;; 77 | *"system/vendor/etc/"*) chcon 'u:object_r:vendor_configs_file:s0' $1;; 78 | *"system/vendor/overlay/"*) chcon 'u:object_r:vendor_overlay_file:s0' $1;; 79 | *"system/vendor/"*) chcon 'u:object_r:vendor_file:s0' $1;; 80 | *) chcon 'u:object_r:system_file:s0' $1;; 81 | esac 82 | else 83 | chcon $5 $1 84 | fi) || return 1 85 | } 86 | 87 | # Set perm recursive 88 | set_perm_recursive() { 89 | find $1 -type d 2>/dev/null | while read dir; do 90 | set_perm $dir $2 $3 $4 $6 91 | done 92 | find $1 -type f -o -type l 2>/dev/null | while read file; do 93 | set_perm $file $2 $3 $5 $6 94 | done 95 | } 96 | 97 | # Mktouch 98 | mktouch() { 99 | mkdir -p ${1%/*} 2>/dev/null 100 | [ -z $2 ] && touch $1 || echo $2 > $1 101 | chmod 644 $1 102 | } 103 | 104 | # Grep prop 105 | grep_prop() { 106 | local REGEX="s/^$1=//p" 107 | shift 108 | local FILES=$@ 109 | [ -z "$FILES" ] && FILES='/system/build.prop' 110 | sed -n "$REGEX" $FILES 2>/dev/null | head -n 1 111 | } 112 | 113 | # Is mounted 114 | is_mounted() { 115 | grep -q " `readlink -f $1` " /proc/mounts 2>/dev/null 116 | return $? 117 | } 118 | 119 | # Abort 120 | abort() { 121 | echo "$1" 122 | exit 1 123 | } 124 | 125 | 126 | # Device Info 127 | # Variables: BRAND MODEL DEVICE API ABI ABI2 ABILONG ARCH 128 | BRAND=$(getprop ro.product.brand) 129 | MODEL=$(getprop ro.product.model) 130 | DEVICE=$(getprop ro.product.device) 131 | ROM=$(getprop ro.build.display.id) 132 | API=$(grep_prop ro.build.version.sdk) 133 | ABI=$(grep_prop ro.product.cpu.abi | cut -c-3) 134 | ABI2=$(grep_prop ro.product.cpu.abi2 | cut -c-3) 135 | ABILONG=$(grep_prop ro.product.cpu.abi) 136 | ARCH=arm 137 | ARCH32=arm 138 | IS64BIT=false 139 | if [ "$ABI" = "x86" ]; then ARCH=x86; ARCH32=x86; fi; 140 | if [ "$ABI2" = "x86" ]; then ARCH=x86; ARCH32=x86; fi; 141 | if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; ARCH32=arm; IS64BIT=true; fi; 142 | if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; ARCH32=x86; IS64BIT=true; fi; 143 | 144 | # Version Number 145 | VER=$(grep_prop version $MODDIR/module.prop) 146 | # Version Code 147 | REL=$(grep_prop versionCode $MODDIR/module.prop) 148 | # Author 149 | AUTHOR=$(grep_prop author $MODDIR/module.prop) 150 | # Mod Name/Title 151 | MODTITLE=$(grep_prop name $MODDIR/module.prop) 152 | 153 | # Colors 154 | G='\e[01;32m' # GREEN TEXT 155 | R='\e[01;31m' # RED TEXT 156 | Y='\e[01;33m' # YELLOW TEXT 157 | B='\e[01;34m' # BLUE TEXT 158 | V='\e[01;35m' # VIOLET TEXT 159 | Bl='\e[01;30m' # BLACK TEXT 160 | C='\e[01;36m' # CYAN TEXT 161 | W='\e[01;37m' # WHITE TEXT 162 | BGBL='\e[1;30;47m' # Background W Text Bl 163 | N='\e[0m' # How to use (example): echo "${G}example${N}" 164 | loadBar=' ' # Load UI 165 | # Remove color codes if -nc or in ADB Shell 166 | [ -n "$1" -a "$1" == "-nc" ] && shift && NC=true 167 | [ "$NC" -o -n "$ANDROID_SOCKET_adbd" ] && { 168 | G=''; R=''; Y=''; B=''; V=''; Bl=''; C=''; W=''; N=''; BGBL=''; loadBar='='; 169 | } 170 | 171 | # No. of characters in $MODTITLE, $VER, and $REL 172 | character_no=$(echo "$MODTITLE $VER $REL" | wc -c) 173 | 174 | # Divider 175 | div="${Bl}$(printf '%*s' "${character_no}" '' | tr " " "=")${N}" 176 | 177 | # title_div [-c] 178 | # based on $div with <title> 179 | title_div() { 180 | set +x 181 | [ "$1" == "-c" ] && local character_no=$2 && shift 2 182 | [ -z "$1" ] && { local message=; no=0; } || { local message="$@ "; local no=$(echo "$@" | wc -c); } 183 | [ $character_no -gt $no ] && local extdiv=$((character_no-no)) || { echo "Invalid!"; return; } 184 | echo "${W}$message${N}${Bl}$(printf '%*s' "$extdiv" '' | tr " " "=")${N}" 185 | set -x 2>>$VERLOG 186 | } 187 | 188 | # set_file_prop <property> <value> <prop.file> 189 | set_file_prop() { 190 | if [ -f "$3" ]; then 191 | if grep -q "$1=" "$3"; then 192 | sed -i "s/${1}=.*/${1}=${2}/g" "$3" 193 | else 194 | echo "$1=$2" >> "$3" 195 | fi 196 | else 197 | echo "$3 doesn't exist!" 198 | fi 199 | } 200 | 201 | # https://github.com/fearside/ProgressBar 202 | # ProgressBar <progress> <total> 203 | ProgressBar() { 204 | # Determine Screen Size 205 | if [[ "$COLUMNS" -le "57" ]]; then 206 | local var1=2 207 | local var2=20 208 | else 209 | local var1=4 210 | local var2=40 211 | fi 212 | # Process data 213 | local _progress=$(((${1}*100/${2}*100)/100)) 214 | local _done=$(((${_progress}*${var1})/10)) 215 | local _left=$((${var2}-$_done)) 216 | # Build progressbar string lengths 217 | local _done=$(printf "%${_done}s") 218 | local _left=$(printf "%${_left}s") 219 | 220 | # Build progressbar strings and print the ProgressBar line 221 | printf "\rProgress : ${BGBL}|${N}${_done// /${BGBL}$loadBar${N}}${_left// / }${BGBL}|${N} ${_progress}%%" 222 | } 223 | 224 | #https://github.com/fearside/SimpleProgressSpinner 225 | # Spinner <message> 226 | Spinner() { 227 | 228 | # Choose which character to show. 229 | case ${_indicator} in 230 | "|") _indicator="/";; 231 | "/") _indicator="-";; 232 | "-") _indicator="\\";; 233 | "\\") _indicator="|";; 234 | # Initiate spinner character 235 | *) _indicator="\\";; 236 | esac 237 | 238 | # Print simple progress spinner 239 | printf "\r${@} [${_indicator}]" 240 | } 241 | 242 | # cmd & spinner <message> 243 | e_spinner() { 244 | set +x 245 | PID=$! 246 | h=0; anim='-\|/'; 247 | while [ -d /proc/$PID ]; do 248 | h=$(((h+1)%4)) 249 | sleep 0.02 250 | printf "\r${@} [${anim:$h:1}]" 251 | done 252 | set -x 2>>$VERLOG 253 | } 254 | 255 | # test_connection 256 | # tests if there's internet connection 257 | test_connection() { 258 | ( 259 | if ping -q -c 1 -W 1 google.com >/dev/null 2>&1; then 260 | true 261 | elif ping -q -c 1 -W 1 baidu.com >/dev/null 2>&1; then 262 | true 263 | else 264 | false 265 | fi & e_spinner "Testing internet connection" 266 | ) && echo " - OK" || { echo " - Error"; false; } 267 | } 268 | 269 | 270 | # Log files will be uploaded to termbin.com 271 | # Logs included: VERLOG LOG oldVERLOG oldLOG 272 | upload_logs() { 273 | $BBok && { 274 | test_connection || exit 275 | echo "Uploading logs" 276 | [ -s $VERLOG ] && verUp=$(cat $VERLOG | nc termbin.com 9999) || verUp=none 277 | [ -s $oldVERLOG ] && oldverUp=$(cat $oldVERLOG | nc termbin.com 9999) || oldverUp=none 278 | [ -s $LOG ] && logUp=$(cat $LOG | nc termbin.com 9999) || logUp=none 279 | [ -s $oldLOG ] && oldlogUp=$(cat $oldLOG | nc termbin.com 9999) || oldlogUp=none 280 | [ -s $stdoutLOG ] && stdoutUp=$(cat $stdoutLOG | nc termbin.com 9999) || stdoutUp=none 281 | [ -s $oldstdoutLOG ] && oldstdoutUp=$(cat $oldstdoutLOG | nc termbin.com 9999) || oldstdoutUp=none 282 | echo -n "Link: " 283 | echo "$MODEL ($DEVICE) API $API\n$ROM\n$ID\n 284 | O_Verbose: $oldverUp 285 | Verbose: $verUp 286 | 287 | O_STDOUT: $oldstdoutUp 288 | STDOUT: $stdoutUp 289 | 290 | O_Log: $oldlogUp 291 | Log: $logUp" | nc termbin.com 9999 292 | } || echo "Busybox not found!" 293 | exit 294 | } 295 | 296 | # Print Random 297 | # Prints a message at random 298 | # CHANCES - no. of chances <integer> 299 | # TARGET - target value out of CHANCES <integer> 300 | prandom() { 301 | local CHANCES=2 302 | local TARGET=2 303 | [ "$1" == "-c" ] && { local CHANCES=$2; local TARGET=$3; shift 3; } 304 | [ "$((RANDOM%CHANCES+1))" -eq "$TARGET" ] && echo "$@" 305 | } 306 | 307 | # Print Center 308 | # Prints text in the center of terminal 309 | pcenter() { 310 | local CHAR=$(printf "$@" | sed 's|\\e[[0-9;]*m||g' | wc -m) 311 | local hfCOLUMN=$((COLUMNS/2)) 312 | local hfCHAR=$((CHAR/2)) 313 | local indent=$((hfCOLUMN-hfCHAR)) 314 | echo "$(printf '%*s' "${indent}" '') $@" 315 | } 316 | 317 | # Heading 318 | mod_head() { 319 | clear 320 | echo "$div" 321 | echo "${W}$MODTITLE $VER${N}(${Bl}$REL${N})" 322 | echo "by ${W}$AUTHOR${N}" 323 | echo "$div" 324 | echo "${W}$_bbname${N}" 325 | echo "${Bl}$_bb${N}" 326 | echo "$div" 327 | [ -s $LOG ] && echo "Enter ${W}logs${N} to upload logs" && echo $div 328 | } 329 | -------------------------------------------------------------------------------- /module.prop: -------------------------------------------------------------------------------- 1 | id=module_manager 2 | name=Module Manager 3 | version=v1.1 4 | versionCode=2 5 | author=Zackptg5 6 | description=Terminal script to manage your magisk modules 7 | -------------------------------------------------------------------------------- /system/bin/module_manager: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | # Terminal Magisk Mod Template 3 | # by veez21 @ xda-developers 4 | 5 | # Setup kill switch 6 | trap "exit 0" 10 7 | proc="$$" 8 | 9 | # Magisk Module ID ** 10 | ID="module_manager" 11 | 12 | # Detect root 13 | _name=$(basename $0) 14 | ls /data >/dev/null 2>&1 || { echo "$ID needs to run as root!"; echo "type 'su' then '$_name'"; exit 1; } 15 | 16 | # Magisk Mod Directory 17 | MOUNTPATH="/data/adb/modules" 18 | MODDIR="$MOUNTPATH/$ID" 19 | [ ! -d $MODDIR ] && { echo "Module not detected!"; exit 1; } 20 | 21 | # Set path to your busybox if applicable 22 | _bb=$MODDIR/busybox 23 | alias zip=$MODDIR/zip 24 | 25 | # Load mod-util.sh 26 | . $MODDIR/mod-util.sh || exit $? 27 | 28 | # Set Log Files 29 | mount -o remount,rw /cache 2>/dev/null 30 | mount -o rw,remount /cache 2>/dev/null 31 | # > Logs should go in this file 32 | LOG=/data/local/tmp/$ID.log 33 | oldLOG=/data/local/tmp/$ID-old.log 34 | # > Verbose output goes here 35 | VERLOG=/data/local/tmp/$ID-verbose.log 36 | oldVERLOG=/data/local/tmp/$ID-verbose-old.log 37 | stdoutLOG=$MODDIR/logs/$ID-STDOUT.log 38 | oldstdoutLOG=$MODDIR/logs/$ID-STDOUT-old.log 39 | 40 | # Start Logging verbosely 41 | mv -f $VERLOG $oldVERLOG 2>/dev/null; mv -f $LOG $oldLOG 2>/dev/null; mv -f $stdoutLOG $oldstdoutLOG 2>/dev/null 42 | # exec 3>&1 43 | # exec 1>$stdoutLOG 44 | set -x 2>$VERLOG 45 | 46 | # Main 47 | # > You can start your MOD here. 48 | # > You can add functions, variables & etc. 49 | # > Rather than editing the default vars above. 50 | quit() { 51 | rm -f $MODDIR/tmp* 52 | kill -10 $proc 53 | exit 0 54 | } 55 | 56 | mag_repo(){ 57 | echo "Generating list..." 58 | find $MOUNTPATH -mindepth 2 -maxdepth 2 -type f -name module_manager | cut -d / -f5 > $MODDIR/tmpm 59 | cp -f $MODDIR/tmpr $MODDIR/tmpmi 60 | while read -r line; do 61 | sed -i "/$line/d" $MODDIR/tmpmi 62 | done < $MODDIR/tmpm 63 | awk '{print NR ": " $s}' $MODDIR/tmpmi > $MODDIR/tmpm 64 | sed -i "1i0: None, go back to main menu" $MODDIR/tmpm 65 | rm -f $MODDIR/tmpmi 66 | echo "$div" 67 | echo -e "Which module do you want to install?\n" 68 | cat $MODDIR/tmpm 69 | while true; do 70 | read -r ichoice?'--> ' 71 | echo " " 72 | case $ichoice in 73 | 0) return 1;; 74 | q) quit;; 75 | *) [ "$(grep -w "$ichoice:" $MODDIR/tmpm 2>/dev/null)" ] && { export choice="https://github.com/Magisk-Modules-Repo/$(grep -w "$ichoice:" $MODDIR/tmpm | awk '{print $2}')/archive/master.zip"; return 0; } || echo "Invalid option: $ichoice! Try again";; 76 | esac 77 | done 78 | } 79 | 80 | install_module(){ 81 | local OPATH=$PWD ZIPFILE=$MODDIR/tmp.zip modname update 82 | if [ "$1" ]; then 83 | update=true 84 | modname=$2 85 | echo "$1" > $MODDIR/tmpi 86 | wget --no-check-certificate -qO $ZIPFILE "$1/archive/master.zip" 2>/dev/null 87 | else 88 | update=false 89 | echo "$div" 90 | echo "Type 'repo' if installing from Magisk Modules Repo" 91 | echo "Otherwise, paste the Module's Github URL" 92 | echo "Type '0' to go back to main menu" 93 | while true; do 94 | read -r choice?'--> ' 95 | echo " " 96 | case $choice in 97 | 0) return 0;; 98 | q) quit;; 99 | "repo") mag_repo && { rm -f $MODDIR/tmpm; break; } || return 0;; 100 | "https://github.com/"*|"https://www.github.com/"*) echo "$(echo $choice | sed 's|/$||')" > $MODDIR/tmpi; choice="$choice/archive/master.zip" 101 | wget --no-check-certificate -q --spider $choice 2>/dev/null && break || echo "URL doesn't exist! Try again";; 102 | *) echo "Invalid option! Try again";; 103 | esac 104 | done 105 | wget --no-check-certificate -qO $ZIPFILE $choice 2>/dev/null 106 | modname="$(unzip -ql $ZIPFILE | awk '{print $4}' | head -n3 | tail -n1 | rev | cut -d- -f2- | rev)" 107 | fi 108 | 109 | $update && echo "$div\nUpdating $modname...\n" || echo "$div\nInstalling $modname...\n" 110 | 111 | # Repack into normal magisk module zip 112 | unzip -q $ZIPFILE -d $MODDIR 113 | rm -f $ZIPFILE 114 | cd $MODDIR/$modname-master 115 | zip -0 -r -x ".git*" -q $ZIPFILE . 116 | cd $OPATH 117 | rm -rf $MODDIR/$modname-master 118 | 119 | # Install mod 120 | magisk --install-module $ZIPFILE 121 | rm -f $ZIPFILE 122 | mv -f $MODDIR/tmpi $MOUNTPATH\_update/$modname/module_manager 2>/dev/null 123 | $update && echo -e "\n$div\n$modname updated!" || echo -e "\n$div\n$modname installed!" 124 | } 125 | 126 | update_check() { 127 | clear 128 | echo "0: None, go back to main menu\n1: All list modules" > $MODDIR/tmpu 129 | local j=2 130 | for i in $(ls $MOUNTPATH 2>/dev/null); do 131 | if grep -q "$i" $MODDIR/tmpr || [ -f $MOUNTPATH/$i/module_manager ]; then 132 | echo "$j: $i" >> $MODDIR/tmpu 133 | j=$((j+1)) 134 | fi 135 | done 136 | while true; do 137 | echo "$div" 138 | echo "Update which module?" 139 | echo "$div" 140 | cat $MODDIR/tmpu 141 | while true; do 142 | read -r choice?'--> ' 143 | echo " " 144 | for i in $choice; do 145 | case $i in 146 | 0) break 3;; 147 | 1) choice="$(awk '{print $1}' $MODDIR/tmpu | sed -E -e '/^0:|^1:/d' -e 's/://' | tr '\n' ' ')"; break 2;; 148 | q) quit;; 149 | *) [ "$(grep -w "$i:" $MODDIR/tmpu 2>/dev/null)" ] && break 2 || echo "Invalid option: $i! Try again";; 150 | esac 151 | done 152 | done 153 | for ichoice in $choice; do 154 | local mod="$(grep -w "$ichoice:" $MODDIR/tmpu | awk '{print $2}')" 155 | [ -f $MOUNTPATH/$mod/module_manager ] && local modurl="$(cat $MOUNTPATH/$mod/module_manager)" || local modurl="https://github.com/Magisk-Modules-Repo/$mod" 156 | wget --no-check-certificate -qO $MODDIR/tmprop $modurl/raw/master/module.prop 2>/dev/null 157 | local new="$(grep_prop versionCode $MODDIR/tmprop)" old="$(grep_prop versionCode $MOUNTPATH/$mod/module.prop)" 158 | rm -f $MODDIR/tmprop 159 | if [ $new -gt $old ]; then 160 | touch $MOUNTPATH/$mod/update 161 | install_module "$modurl" "$mod" 162 | else 163 | echo -e "$mod is up to date\n" 164 | fi 165 | done 166 | done 167 | rm -f $MODDIR/tmpu 168 | clear 169 | } 170 | 171 | mod_head 172 | test_connection || quit "No network connection! Aborting!" 173 | ( 174 | echo "Downloading repo info..." & e_spinner 175 | wget --no-check-certificate -qO - "https://api.github.com/orgs/Magisk-Modules-Repo/repos?sort=full_name&per_page=100" | grep '"full_name":' | sed -r 's|.*/(.*)",|\1|g' > $MODDIR/tmpr 176 | wget --no-check-certificate -qO - "https://api.github.com/orgs/Magisk-Modules-Repo/repos?sort=full_name&per_page=100&page=2" | grep '"full_name":' | sed -r 's|.*/(.*)",|\1|g' >> $MODDIR/tmpr 177 | ) & e_spinner 178 | echo "" 179 | while true; do 180 | echo "$div" 181 | echo "Choose option:" 182 | echo "$div" 183 | echo "1: Check for Updates" 184 | echo "2: Install Module" 185 | echo "Type 'q' at any time to quit" 186 | while true; do 187 | read -r choice?'--> ' 188 | case $choice in 189 | 1|2) break;; 190 | q) quit;; 191 | *) echo "Invalid option! Try again";; 192 | esac 193 | done 194 | case $choice in 195 | 1) update_check;; 196 | 2) install_module; clear;; 197 | esac 198 | done 199 | -------------------------------------------------------------------------------- /zip-armeabi-v7a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zackptg5/Module-Manager/823a359a20dfbc8ac566da9167736b6a184578a3/zip-armeabi-v7a -------------------------------------------------------------------------------- /zip-x86: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zackptg5/Module-Manager/823a359a20dfbc8ac566da9167736b6a184578a3/zip-x86 --------------------------------------------------------------------------------