.
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Magisk模块在线更新模板
2 |
3 | 这是一个`适配 Magisk的versionCode大于等于24000`的模块在线更新(updateJson)**模板**
4 |
5 |
6 |
7 |
8 |
9 | [简体中文](README.md) · [English](README_English.md)(English暂未上线)
10 |
11 |
12 |
13 |
14 |
15 | ## **使用方法**
16 |
17 | ### **一、了解相关文件**
18 |
19 | | 文件 | 类型 | 功能 |
20 | | :--------: | :-----: | :----: |
21 | | .github/workflows/release.yml | 文件 | 工作流文件|
22 | | module_files | 文件夹 | 存放您模块的相关文件 |
23 | | module.json | 文件 | Magisk检测模块更新的依赖文件 |
24 | | module.md | 文件 | Magisk模块检测到更新,点击
更新后,将会弹出更新日志 |
25 |
26 | ### **二、适配您的模块**
27 |
28 | 1. **复制文件**:将您的**模块文件夹**复制到**仓库根目录**,像案例中module_files文件夹一样。如果您有您的想法,请遵循您的想法
29 | 2. **修改[.github/workflows/release.yml](https://github.com/zjw2017/MagiskModule_OnlineUpdate/blob/main/.github/workflows/release.yml)**:根据**注释**修改相关代码
30 |
31 | ```yaml
32 | # 本仓库的模块文件名为module_files,下文的url已写入相关文件,可供参考
33 | # 下文所有"- name:"的后面的文案均为步骤名,可自行修改
34 | # release为工作流名,可自行修改
35 | name: release
36 | on:
37 | push:
38 | # 根据以下链接定制您的触发条件
39 | # https://docs.github.com/zh/actions/using-workflows/triggering-a-workflow
40 | # https://docs.github.com/zh/actions/using-workflows/events-that-trigger-workflows
41 | # https://docs.github.com/zh/actions/managing-workflow-runs/skipping-workflow-runs
42 | branches:
43 | - main
44 | workflow_dispatch:
45 | jobs:
46 | build:
47 | runs-on: ubuntu-latest
48 | steps:
49 | - uses: actions/checkout@main
50 | - name: 1. 准备文件
51 | run: |
52 | echo "version=$(jq -r .version $GITHUB_WORKSPACE/module.json)" >> $GITHUB_ENV
53 | echo "versionCode=$(jq -r .versionCode $GITHUB_WORKSPACE/module.json)" >> $GITHUB_ENV
54 | # ModuleFolderName的变量值需要修改为您模块文件夹的名字
55 | echo "ModuleFolderName=module_files" >> $GITHUB_ENV
56 | # 此处可根据您的需求添加您需要的shell语句
57 | - name: 2. 制作模块
58 | run: |
59 | mkdir -p "$GITHUB_WORKSPACE"/GithubRelease
60 | echo "version=$version" >>$GITHUB_WORKSPACE/$ModuleFolderName/module.prop
61 | echo "versionCode=$versionCode" >>$GITHUB_WORKSPACE/$ModuleFolderName/module.prop
62 | cd $GITHUB_WORKSPACE/$ModuleFolderName
63 | zip -q -r $ModuleFolderName.zip *
64 | mv $GITHUB_WORKSPACE/$ModuleFolderName/$ModuleFolderName.zip "$GITHUB_WORKSPACE"/GithubRelease
65 | cd "$GITHUB_WORKSPACE"
66 | touch file.md
67 | echo "$ModuleFolderName.zip" > file.md
68 | - name: 3.上传到Github Release
69 | uses: ncipollo/release-action@main
70 | with:
71 | artifacts: ${{ github.workspace }}/GithubRelease/*
72 | name: "${{ env.ModuleFolderName }} ${{ env.version }}"
73 | # name后面的是Github Release的标题,可自行修改
74 | # tag若涉及version和versionCode,请按照${{ env.version }}这个格式来写
75 | tag: "${{ env.version }}"
76 | bodyFile: "${{ github.workspace }}/file.md"
77 | allowUpdates: true
78 | artifactErrorsFailBuild: true
79 | makeLatest: true
80 | - name: 4. 更新下载链接
81 | run: |
82 | # 请在引号内自行更新您的Github账号信息
83 | git config --global user.email "30484319+zjw2017@users.noreply.github.com"
84 | # 请在引号内自行更新您的Github账号信息
85 | git config --global user.name "柚稚的孩纸"
86 | sed -i '4d' $GITHUB_WORKSPACE/module.json
87 | # OWNER、REPO、version分别是用户名、仓库名、版本号,根据自身来修改
88 | browser_download_url=$(
89 | curl -L \
90 | -H "Accept: application/vnd.github+json" \
91 | -H "Authorization: Bearer ${{ github.token }}" \
92 | -H "X-GitHub-Api-Version: 2022-11-28" \
93 | "https://api.github.com/repos/OWNER/REPO/releases/tags/$version" | jq -r .assets[].browser_download_url | cut -d'"' -f2
94 | )
95 | # 作用是自动更新下载地址,因中国大陆地区问题,添加了代理头(https://ghproxy.com/)
96 | # 如您的地区可以访问Github相关网站,可以删掉代理头,如
97 | # sed -i '3a "zipUrl": "'"$browser_download_url"'",' $GITHUB_WORKSPACE/module.json
98 | sed -i '3a "zipUrl": "https://ghproxy.com/'"$browser_download_url"'",' $GITHUB_WORKSPACE/module.json
99 | jq . $GITHUB_WORKSPACE/module.json > $GITHUB_WORKSPACE/new.json
100 | rm -rf $GITHUB_WORKSPACE/module.json && mv $GITHUB_WORKSPACE/new.json $GITHUB_WORKSPACE/module.json
101 | git add ./module.json
102 | # 引号内为提交信息,可根据需要自行修改
103 | if git commit -m "v$version"; then
104 | git push
105 | fi
106 | ```
107 |
108 | 3. **修改[module.md](https://github.com/zjw2017/MagiskModule_OnlineUpdate/blob/main/module.md)**:文件名可**自定义修改**。模块的**更新日志**,语法为`Markdown`
109 | 4. **修改[module.json](https://github.com/zjw2017/MagiskModule_OnlineUpdate/blob/main/module.json)**:**文件名**需要**与`.github/workflows/release.yml`中第5行文件名一致**。我们需要修改第**2、3、5**行。
110 |
111 | 变量:类型
112 | - version:string
113 | - versionCode:int
114 | - changelog:url
115 | > 补充说明:url为`module.md`的[链接](https://github.com/zjw2017/MagiskModule_OnlineUpdate/blob/main/module.md),只需要填写一次即可。如果是中国大陆地区,可在上一步中文件的链接前面加代理头(比如[https://ghproxy.com](https://ghproxy.com/))。如您的地区可以访问Github相关网站,可以删掉代理头
116 |
117 | 5. **修改模块的`module.prop`以支持在线更新**:格式如下。参数顺序可以打乱,但
118 |
119 | **updateJson行**下面的**空行**务必**不能删除**
120 |
121 | ```text
122 | id=
123 | name=
124 | author=
125 | description=
126 | updateJson=
127 |
128 | ```
129 |
130 | > 补充说明:url为`module.json`的[链接](https://github.com/zjw2017/MagiskModule_OnlineUpdate/blob/main/module.json),只需要填写一次即可。如果是中国大陆地区,可在上一步中文件的链接前面加代理头(比如[https://ghproxy.com](https://ghproxy.com/))。如您的地区可以访问Github相关网站,可以删掉代理头
131 |
132 | 6. 替换模块文件夹中的META-INF
133 |
134 | > 原因是**支持在线更新的模块的META-INF会在刷入时被Magisk替换为默认的update-binary**,所以请**不要自定义/META-INF/com/google/android/update-binary文件**。若您**没有修改**过此文件,此步骤**可跳过**
135 |
136 | 7. 发起Action构建,完成发布
137 |
138 | ### 三、授予Workflow权限
139 | 打开项目页的**Settings**,点击**左侧菜单栏**中的**Actions**,点击**展开菜单**中的**General**,找到**Workflow permissions**,点击**Read and write permissions**,点击**Workflow permissions下方的第一个Save按钮**
140 |
141 | ### 四、了解项目机制
142 | 本项目利用了**Github Actions**,设计了两种触发方式:**更新.json文件**和**手动触发**。
143 |
144 | 当您完成代码提交和模块迭代后,就要在 **.json文件** 中配置**版本号**来告知您的用户有新版本,同时,您可以在 **.md文件** 中使用`Markdown`语法书写此次的**更新日志**。不同于系统更新,日志不会叠加。所以您的用户只会看到最新版本的更新日志(除非您更新时保留上次的日志)。
145 |
146 | 到此,模块的迭代、版本号的更替、更新日志的书写都已经完成,接下来的一切交给**Github Actions**。
147 |
148 | **Github Actions**做第一步就是读取 **.json文件** 中的**版本号**信息,将其输出到`module.prop`,这也是为什么前文的`module.prop`中为什么**updateJson行下面的空行不能删除**和**不需要书写版本号**的奥秘。第二步,将模块文件压缩为**zip格式**。第三步,将**模块文件上传**至**Github Release**。第四步,**更新.json文件**中的**下载地址**,并根据**预留的Github账户信息**将含有**新版本链接**的.json**文件**推送到**您的仓库**。
149 |
150 | 做完了这些,您的用户就可以在**Magisk**的**模块**选项卡中检测到新版本并安装到设备上。
151 |
152 | ### 五、结语
153 | 欢迎大家用来适配自己的模块,同时也期待能有专业人员共同改进本项目,感谢大家!
154 |
--------------------------------------------------------------------------------
/module.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "versionCode": 30,
4 | "zipUrl": "https://ghproxy.com/https://github.com/zjw2017/MagiskModule_OnlineUpdate/releases/download/3/module_files.zip",
5 | "changelog": "https://ghproxy.com/https://github.com/zjw2017/MagiskModule_OnlineUpdate/blob/main/module.md"
6 | }
7 |
--------------------------------------------------------------------------------
/module.md:
--------------------------------------------------------------------------------
1 | # 更新日志
2 | - Hello,World!
--------------------------------------------------------------------------------
/module_files/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 v20.4+! "
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 20400 ] && require_new_magisk
31 |
32 | install_module
33 | exit 0
34 |
--------------------------------------------------------------------------------
/module_files/META-INF/com/google/android/updater-script:
--------------------------------------------------------------------------------
1 | #MAGISK
2 |
--------------------------------------------------------------------------------
/module_files/action.sh:
--------------------------------------------------------------------------------
1 | #!/system/bin/sh
2 | MODDIR=${0%/*}
3 | echo hello
--------------------------------------------------------------------------------
/module_files/customize.sh:
--------------------------------------------------------------------------------
1 | SKIPUNZIP=0
2 | . "$MODPATH"/util_functions.sh
3 | # 通用部分
4 | # SKIPUNZIP: 解压方式。0=自动,1=手动
5 | # MODPATH (path): 当前模块的安装目录
6 | # TMPDIR (path): 可以存放临时文件的目录
7 | # ZIPFILE (path): 当前模块的安装包文件
8 | # ARCH (string): 设备的 CPU 构架,有如下几种arm, arm64, x86, or x64
9 | # IS64BIT (bool): 是否是 64 位设备
10 | # API (int): 当前设备的 Android API 版本 (如: Android 14.0 上为 34)
11 |
12 | # For Magisk
13 | # MAGISK_VER (string): 当前安装的 Magisk 的版本字符串 (如: 27.0)
14 | # MAGISK_VER_CODE (int): 当前安装的 Magisk 的版本代码 (如: 27000)
15 | # BOOTMODE (bool): 如果模块被安装在 Magisk 应用程序中则值为true
16 |
17 | # For KernelSU
18 | # KSU (bool): 标记此脚本运行在 KernelSU 环境下,此变量的值将永远为 true,你可以通过它区分 Magisk。
19 | # KSU_VER (string): KernelSU 当前的版本名字 (如: v0.7.6)
20 | # KSU_VER_CODE (int): KernelSU 用户空间当前的版本号 (如: 11434)
21 | # KSU_KERNEL_VER_CODE (int): KernelSU 内核空间当前的版本号 (如: 11434)
22 | # BOOTMODE (bool): 此变量在 KernelSU 中永远为 true
23 |
24 | if [[ "$KSU" == "true" ]]; then
25 | ui_print "- KernelSU 用户空间版本号: $KSU_VER_CODE"
26 | ui_print "- KernelSU 内核空间版本号: $KSU_KERNEL_VER_CODE"
27 | if [ "$KSU_KERNEL_VER_CODE" -lt 11089 ]; then
28 | ui_print "*********************************************"
29 | ui_print "! 请安装 KernelSU 管理器 v0.6.2 或更高版本"
30 | abort "*********************************************"
31 | fi
32 | elif [[ "$APATCH" == "true" ]]; then
33 | ui_print "- APatch 版本名: $APATCH_VER"
34 | ui_print "- APatch 版本号: $APATCH_VER_CODE"
35 | else
36 | ui_print "- Magisk 版本名: $MAGISK_VER"
37 | ui_print "- Magisk 版本号: $MAGISK_VER_CODE"
38 | if [ "$MAGISK_VER_CODE" -lt 26000 ]; then
39 | ui_print "*********************************************"
40 | ui_print "! 请安装 Magisk 26.0+"
41 | abort "*********************************************"
42 | fi
43 | fi
44 |
45 | rm -rf /data/system/package_cache
46 |
47 | if [[ $KSU == true ]] || [[ $APATCH == true ]]; then
48 | replace() {
49 | if [[ "$1" == "file" ]]; then
50 | remove "$1" "$2"
51 | elif [[ "$1" == "directory" ]]; then
52 | dir="$2"
53 | dir="${dir%/*}"
54 | setfattr -n trusted.overlay.opaque -v y "$MODPATH""$dir"
55 | fi
56 | }
57 | remove() {
58 | mknod "$MODPATH""$2" c 0 0
59 | }
60 | else
61 | replace() {
62 | mkdir -p "$MODPATH""$2"
63 | if [[ "$1" == "file" ]]; then
64 | rm -rf "$MODPATH""$2"
65 | touch "$MODPATH""$2"
66 | chown root:root "$MODPATH""$2"
67 | chmod 0644 "$MODPATH""$2"
68 | elif [[ "$1" == "directory" ]]; then
69 | touch "$MODPATH""$2"/.replace
70 | chown root:root "$MODPATH""$2"/.replace
71 | chmod 0644 "$MODPATH""$2"/.replace
72 | fi
73 | }
74 | remove() {
75 | replace "$1" "$2"
76 | }
77 | fi
78 |
79 | # 用法: 函数名 类型 地址
80 | # 函数名: replace 或 (推荐使用) remove
81 | # replace 功能: 替换掉系统的某个目录,使其成为空目录
82 | # replace 可用类型为 file 或 directory
83 | # remove 功能: 删掉系统原来目录某个文件或者文件夹
84 | # remove 可用类型为 file 或 directory
85 | # 地址: 你要替换的地址
86 | # 例子:
87 | # remove file /system/product/app/AnalyticsCore/AnalyticsCore.apk
88 | # remove directory /system/product/app/AnalyticsCore
89 | # replace directory /system/product/app/AnalyticsCore
90 | # replace file /system/product/app/AnalyticsCore/AnalyticsCore.apk
91 |
92 | # 设置权限函数
93 | # set_perm_recursive <目录> <所有者> <用户组> <目录权限> <文件权限> <上下文> (默认值是: u:object_r:system_file:s0)
94 | # set_perm_recursive "$MODPATH"/system/lib 0 0 0755 0644
95 | # set_perm <文件名> <所有者> <用户组> <文件权限> <上下文> (默认值是: u:object_r:system_file:s0)
96 | # set_perm "$MODPATH"/system/bin/app_process32 0 2000 0755 u:object_r:zygote_exec:s0
97 | # set_perm "$MODPATH"/system/bin/dex2oat 0 2000 0755 u:object_r:dex2oat_exec:s0
98 | # set_perm "$MODPATH"/system/lib/libart.so 0 0 0644
99 |
--------------------------------------------------------------------------------
/module_files/module.prop:
--------------------------------------------------------------------------------
1 | id=
2 | name=
3 | author=
4 | description=
5 | updateJson=https://ghproxy.com/https://github.com/zjw2017/MagiskModule_OnlineUpdate/blob/main/module.json
6 |
--------------------------------------------------------------------------------
/module_files/post-fs-data.sh:
--------------------------------------------------------------------------------
1 | #!/system/bin/sh
2 | MODDIR=${0%/*}
--------------------------------------------------------------------------------
/module_files/service.sh:
--------------------------------------------------------------------------------
1 | #!/system/bin/sh
2 | MODDIR=${0%/*}
3 |
--------------------------------------------------------------------------------
/module_files/system.prop:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zjw2017/MagiskModule_OnlineUpdate/50461f19b2d0ca3a25421cbb16ba8a5a16cf0eeb/module_files/system.prop
--------------------------------------------------------------------------------
/module_files/system/placeholder:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zjw2017/MagiskModule_OnlineUpdate/50461f19b2d0ca3a25421cbb16ba8a5a16cf0eeb/module_files/system/placeholder
--------------------------------------------------------------------------------
/module_files/uninstall.sh:
--------------------------------------------------------------------------------
1 | #!/system/bin/sh
2 | MODDIR=${0%/*}
3 | rm -rf "$MODDIR"
4 | rm -rf /data/system/package_cache
5 |
--------------------------------------------------------------------------------
/module_files/util_functions.sh:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2068
2 | # shellcheck disable=SC2086
3 | # shellcheck disable=SC2124
4 | # shellcheck disable=SC2148
5 | # shellcheck disable=SC2155
6 | # shellcheck disable=SC2162
7 |
8 | ui_print() {
9 | echo "$1"
10 | }
11 |
12 | abort() {
13 | ui_print "$1"
14 | [ ! -z $MODPATH ] && rm -rf $MODPATH
15 | rm -rf $TMPDIR
16 | exit 1
17 | }
18 |
19 | grep_prop() {
20 | local REGEX="s/^$1=//p"
21 | shift
22 | local FILES=$@
23 | [ -z "$FILES" ] && FILES='/system/build.prop'
24 | cat $FILES 2>/dev/null | dos2unix | sed -n "$REGEX" | head -n 1
25 | }
26 |
27 | grep_get_prop() {
28 | local result=$(grep_prop $@)
29 | if [ -z "$result" ]; then
30 | # Fallback to getprop
31 | getprop "$1"
32 | else
33 | echo $result
34 | fi
35 | }
36 |
37 | set_perm() {
38 | chown $2:$3 $1 || return 1
39 | chmod $4 $1 || return 1
40 | local CON=$5
41 | [ -z $CON ] && CON=u:object_r:system_file:s0
42 | chcon $CON $1 || return 1
43 | }
44 |
45 | set_perm_recursive() {
46 | find $1 -type d 2>/dev/null | while read dir; do
47 | set_perm $dir $2 $3 $4 $6
48 | done
49 | find $1 -type f -o -type l 2>/dev/null | while read file; do
50 | set_perm $file $2 $3 $5 $6
51 | done
52 | }
53 |
--------------------------------------------------------------------------------