diff --git a/easytier-contrib/easytier-magisk/action.sh b/easytier-contrib/easytier-magisk/action.sh index 599a1199..0f26a4fc 100644 --- a/easytier-contrib/easytier-magisk/action.sh +++ b/easytier-contrib/easytier-magisk/action.sh @@ -1,43 +1,74 @@ #!/data/adb/magisk/busybox sh MODDIR=${0%/*} MODULE_PROP="${MODDIR}/module.prop" +IP_RULE_SCRIPT="${MODDIR}/hotspot_iprule.sh" ET_STATUS="" REDIR_STATUS="" -# 更新module.prop文件中的description +IS_RUNNING=false + +# 确保辅助脚本有执行权限 +chmod +x "${IP_RULE_SCRIPT}" 2>/dev/null + +# 更新 module.prop 文件中的 description update_module_description() { local status_message=$1 - sed -i "/^description=/c\description=[状态]${status_message}" ${MODULE_PROP} + # 检查 module.prop 文件存在且 description 发生变化了再写入 + if [ -f "${MODULE_PROP}" ]; then + local current_desc=$(grep "^description=" "${MODULE_PROP}") + local new_desc="description=[状态] ${status_message}" + if [ "${current_desc}" != "${new_desc}" ]; then + sed -i "s#^description=.*#${new_desc}#" "${MODULE_PROP}" + fi + fi } - +# 判断程序启动状态 if [ -f "${MODDIR}/disable" ]; then - ET_STATUS="已关闭" -elif pgrep -f 'easytier-core' >/dev/null; then - if [ -f "${MODDIR}/config/command_args"]; then - ET_STATUS="主程序已开启(启动参数模式)" + IS_RUNNING=false + ET_STATUS="主程序已关闭" + +elif pgrep -f "${MODDIR}/easytier-core" >/dev/null; then + IS_RUNNING=true + if [ -f "${MODDIR}/config/command_args" ]; then + ET_STATUS="主程序正在运行(启动参数模式)" else - ET_STATUS="主程序已开启(配置文件模式)" + ET_STATUS="主程序正在运行(配置文件模式)" fi + +elif [ -z "$ET_STATUS" ]; then + # 既没 disable 也没运行,说明是异常停止或未启动 + ET_STATUS="主程序启动失败或未运行" fi -#ET_STATUS不存在说明开启模块未正常运行,不修改状态 -if [ -n "$ET_STATUS" ]; then - if [ -f "${MODDIR}/enable_IP_rule" ]; then - rm -f "${MODDIR}/enable_IP_rule" - ${MODDIR}/hotspot_iprule.sh del - REDIR_STATUS="转发已禁用" - echo "热点子网转发已禁用" - echo "[ET-NAT] IP rule disabled." >> "${MODDIR}/log.log" - else - touch "${MODDIR}/enable_IP_rule" - ${MODDIR}/hotspot_iprule.sh del - ${MODDIR}/hotspot_iprule.sh add_once - REDIR_STATUS="转发已激活" - echo "热点子网转发已激活,热点开启后将自动将热点加入转发网络(要求已配置本地网络cidr=参数)。转发规则将随着热点开关而自动开关。该状态将保持到转发被禁用为止。" - echo "[ET-NAT] IP rule enabled." >> "${MODDIR}/log.log" - fi - update_module_description "${ET_STATUS} | ${REDIR_STATUS}" +# 无论主程序是否运行,都允许切换“开关文件”的状态,以便下次生效 +if [ -f "${MODDIR}/enable_IP_rule" ]; then + rm -f "${MODDIR}/enable_IP_rule" + + "${IP_RULE_SCRIPT}" del >/dev/null 2>&1 + + REDIR_STATUS="转发已禁用" + echo "热点子网转发已禁用" + echo "[ET-NAT] Action: IP rule disabled." >> "${MODDIR}/log.log" else - echo "主程序未正常启动,请先检查配置文件" + touch "${MODDIR}/enable_IP_rule" + + if [ "$IS_RUNNING" = true ]; then + "${IP_RULE_SCRIPT}" del >/dev/null 2>&1 + "${IP_RULE_SCRIPT}" add_once + echo "转发规则将立即生效,无需重启" + else + echo "主程序未运行,转发规则将在下次启动时生效" + fi + + REDIR_STATUS="转发已激活" + echo "----------------------------------" + echo "热点子网转发已激活" + echo "热点开启后将自动将热点加入转发网络" + echo "需要在配置中提前配置好 cidr 参数" + echo "----------------------------------" + echo "[ET-NAT] Action: IP rule enabled." >> "${MODDIR}/log.log" fi + +sync +update_module_description "${ET_STATUS}| ${REDIR_STATUS}" \ No newline at end of file diff --git a/easytier-contrib/easytier-magisk/customize.sh b/easytier-contrib/easytier-magisk/customize.sh index 783d46fb..114e47de 100644 --- a/easytier-contrib/easytier-magisk/customize.sh +++ b/easytier-contrib/easytier-magisk/customize.sh @@ -5,12 +5,15 @@ LATESTARTSERVICE=true set_perm_recursive $MODPATH 0 0 0777 0777 -ui_print '安装完成' -ui_print '当前架构为' + $ARCH -ui_print '当前系统版本为' + $API -ui_print '安装目录为: /data/adb/modules/easytier_magisk' -ui_print '配置文件位置: /data/adb/modules/easytier_magisk/config/config.toml' -ui_print '如果需要自定义启动参数,可将 /data/adb/modules/easytier_magisk/config/command_args_sample 重命名为 command_args,并修改其中内容,使用自定义启动参数时会忽略配置文件' -ui_print '修改配置文件后在magisk app禁用应用再启动即可生效' -ui_print '点击操作按钮可启动/关闭热点子网转发,配合easytier的子网代理功能实现手机热点访问easytier网络' -ui_print '记得重启' +ui_print "系统架构为:$ARCH" +ui_print "系统 SDK 版本:$API" +ui_print "EasyTier 安装位置:/data/adb/modules/easytier_magisk" +ui_print "配置文件位置:/data/adb/modules/easytier_magisk/config/config.toml" +ui_print "如需使用启动参数模式,请将 /data/adb/modules/easytier_magisk/config/command_args_sample 重命名为 command_args,并修改其中的内容" +ui_print "config 目录中存在 command_args 文件时,模块会自动忽略 config.toml 文件" +ui_print "----------------------------------" +ui_print "注意!启动参数文件中不能存在 \" 和 ',配置文件则没有这个限制" +ui_print "----------------------------------" +ui_print "修改配置后无需重启设备,在 Magisk 中禁用 EasyTier 模块,等待 10 秒后重新启用即可让新配置生效" +ui_print "点击 Magisk 中模块左下角的“操作”按钮可以禁用或激活热点子网转发,使用该功能前需要在配置中提前配置好 cidr 参数" +ui_print "模块安装完成,重启设备生效" \ No newline at end of file diff --git a/easytier-contrib/easytier-magisk/easytier_core.sh b/easytier-contrib/easytier-magisk/easytier_core.sh index d4d845b2..acbbd242 100644 --- a/easytier-contrib/easytier-magisk/easytier_core.sh +++ b/easytier-contrib/easytier-magisk/easytier_core.sh @@ -2,64 +2,111 @@ MODDIR=${0%/*} CONFIG_FILE="${MODDIR}/config/config.toml" +COMMAND_ARGS="${MODDIR}/config/command_args" LOG_FILE="${MODDIR}/log.log" MODULE_PROP="${MODDIR}/module.prop" EASYTIER="${MODDIR}/easytier-core" + +# 处理获取到的设备型号中可能出现的空格 +BRAND=$(getprop ro.product.brand | tr ' ' '-') +MODEL=$(getprop ro.product.model | tr ' ' '-') +DEVICE_HOSTNAME="${BRAND}-${MODEL}" REDIR_STATUS="" -# 更新module.prop文件中的description +# 更新 module.prop 文件中的 description update_module_description() { local status_message=$1 - sed -i "/^description=/c\description=[状态]${status_message}" ${MODULE_PROP} + # 检查 module.prop 文件存在且 description 发生变化了再写入 + if [ -f "${MODULE_PROP}" ]; then + local current_desc=$(grep "^description=" "${MODULE_PROP}") + local new_desc="description=[状态] ${status_message}" + if [ "${current_desc}" != "${new_desc}" ]; then + sed -i "s#^description=.*#${new_desc}#" "${MODULE_PROP}" + fi + fi } -if [ -f "${MODDIR}/enable_IP_rule" ]; then - REDIR_STATUS="转发已激活" -else - REDIR_STATUS="转发已禁用" -fi - +# 检查并初始化 TUN 设备 if [ ! -e /dev/net/tun ]; then if [ ! -d /dev/net ]; then mkdir -p /dev/net fi - + ln -s /dev/tun /dev/net/tun fi while true; do - if ls $MODDIR | grep -q "disable"; then - update_module_description "关闭中 | ${REDIR_STATUS}" - if pgrep -f 'easytier-core' >/dev/null; then - echo "开关控制$(date "+%Y-%m-%d %H:%M:%S") 进程已存在,正在关闭 ..." - pkill easytier-core # 关闭进程 - fi + # 获取子网转发激活状态 + if [ -f "${MODDIR}/enable_IP_rule" ]; then + REDIR_STATUS="转发已激活" else - if ! pgrep -f 'easytier-core' >/dev/null; then - if [ ! -f "$CONFIG_FILE" ]; then - update_module_description "config.toml不存在" - sleep 3s - continue - fi + REDIR_STATUS="转发已禁用" + fi - # 如果 config 目录下存在 command_args 文件,则读取其中的内容作为启动参数 - if [ -f "${MODDIR}/config/command_args" ]; then - TZ=Asia/Shanghai ${EASYTIER} $(cat ${MODDIR}/config/command_args) --hostname "$(getprop ro.product.brand)-$(getprop ro.product.model)" > ${LOG_FILE} & - sleep 5s # 等待easytier-core启动完成 - update_module_description "主程序已开启(启动参数模式) | ${REDIR_STATUS}" - else - TZ=Asia/Shanghai ${EASYTIER} -c ${CONFIG_FILE} --hostname "$(getprop ro.product.brand)-$(getprop ro.product.model)" > ${LOG_FILE} & - sleep 5s # 等待easytier-core启动完成 - update_module_description "主程序已开启(配置文件模式) | ${REDIR_STATUS}" - fi - ip rule add from all lookup main - if ! pgrep -f 'easytier-core' >/dev/null; then - update_module_descriptio "主程序启动失败,请检查配置文件" - fi - else - echo "开关控制$(date "+%Y-%m-%d %H:%M:%S") 进程已存在" + # 检查模块是否被禁用 + if [ -f "${MODDIR}/disable" ]; then + update_module_description "主程序已关闭 | ${REDIR_STATUS}" + if pgrep -f "${EASYTIER}" >/dev/null; then + echo "开关控制 $(date "+%Y-%m-%d %H:%M:%S") 进程已存在,正在关闭" + pkill -f "${EASYTIER}" fi + sleep 10s + continue fi - sleep 3s # 暂停3秒后再次执行循环 -done + # 检查进程是否已经在运行 + if pgrep -f "${EASYTIER}" >/dev/null; then + sleep 10s + continue + fi + + # 检查配置文件是否存在 + if [ ! -f "${CONFIG_FILE}" ] && [ ! -f "${COMMAND_ARGS}" ]; then + update_module_description "缺少配置文件或启动参数文件" + sleep 10s + continue + fi + + # 如果 config 目录下存在 command_args 文件,则读取其中的内容作为启动参数 + if [ -f "${COMMAND_ARGS}" ]; then + # 启动参数模式 + CMD_CONTENT=$(tr '\r\n' ' ' < "${COMMAND_ARGS}") + + if echo "${CMD_CONTENT}" | grep -q "\-\-hostname"; then + FINAL_ARGS="${CMD_CONTENT}" + else + FINAL_ARGS="${CMD_CONTENT} --hostname ${DEVICE_HOSTNAME}" + fi + + TZ=Asia/Shanghai "${EASYTIER}" ${FINAL_ARGS} > "${LOG_FILE}" 2>&1 & + STR_MODE="启动参数模式" + + # 否则读取 config.toml 的内容作为启动参数 + else + # 配置文件模式 + if grep -q "^[[:space:]]*hostname[[:space:]]*=" "${CONFIG_FILE}"; then + TZ=Asia/Shanghai "${EASYTIER}" -c "${CONFIG_FILE}" > "${LOG_FILE}" 2>&1 & + else + TZ=Asia/Shanghai "${EASYTIER}" -c "${CONFIG_FILE}" --hostname "${DEVICE_HOSTNAME}" > "${LOG_FILE}" 2>&1 & + fi + + STR_MODE="配置文件模式" + fi + + # 等待进程启动 + sleep 5s + + # 启动后的扫尾工作 + if pgrep -f "${EASYTIER}" >/dev/null; then + + if ! ip rule show | grep -q "lookup main"; then + ip rule add from all lookup main + fi + + update_module_description "主程序正在运行(${STR_MODE})| ${REDIR_STATUS}" + else + update_module_description "主程序启动失败,请检查配置文件或启动参数" + fi + + sleep 10s +done \ No newline at end of file diff --git a/easytier-contrib/easytier-magisk/uninstall.sh b/easytier-contrib/easytier-magisk/uninstall.sh index c7d7cb27..36dca1a3 100644 --- a/easytier-contrib/easytier-magisk/uninstall.sh +++ b/easytier-contrib/easytier-magisk/uninstall.sh @@ -1,3 +1,5 @@ MODDIR=${0%/*} -pkill easytier-core # 结束 easytier-core 进程 -rm -rf $MODDIR/* \ No newline at end of file +pkill -f "${MODDIR}/easytier-core" + +# 使用 ${MODDIR:?} 确保变量非空,避免执行 rm -rf /* +rm -rf "${MODDIR:?}/"* \ No newline at end of file