让你的UFI-TOOls彻底属于你:老款中兴5G随身WIFI第三方web绿化教程

引言

这是一个第三方web项目,适用于中兴f50、u30、v50等设备,推广很多,本教程旨在让你获得此工具的完整控制能力,不再为频繁的更新弹窗和骚扰信息所困扰,享受属于自己的宁静

目录

    1. 绿化目标
    1. 环境准备(Android Studio + Node)
    1. 拉源码
    1. 关掉默认上报(最核心)
    1. 关掉远程消息/外链资源(让前端离线化)
    1. 移除 customHead 脚本执行入口(堵住“可下发前端逻辑”的口子)
    1. 更新链路自控(禁用 force、固定资源服务器/直接禁用在线更新)
    1. 去掉强制条款弹窗(可选)
    1. 重新打包前端资源到 APK
    1. 编译 APK
    1. 验证:我真的自由了吗?

1. 绿化目标(你最终要达成什么)

对“绿化/自控版”的定义很简单:任何“会联网、会更新、会执行外部内容、会强制弹窗”的能力,都变成“你可选择、可关闭、可审计”。

本文最终效果(建议抓包验证):

  1. 不再每 5 小时向 api.kanokano.cn 上报 uuid / 机型 / 版本 / root 状态
  2. 不再从远端拉“系统消息/公告”
  3. customHead 不再执行 <script>(外链、内联都不执行)
  4. 更新不再因为文件名带 force 就“强制不是最新”(你可以选择干掉/弱化)
  5. “用户协议”弹窗不再作为使用门槛(可选)

2. 环境准备(Android Studio + Node)

2.1 你需要安装

  • Android Studio(或命令行 Gradle)
  • Node.js(用于把 app/frontEnd/public 打包进 app/src/main/assets
  • Git(可选,但强烈建议)

2.2 关键目录说明(别改错地方)

UFI-Tools 的 Web 前端不是“运行时在线拉的”,而是 build 后塞进 APK 的 assets

  • 源码前端:app/frontEnd/public/
  • build 输出(APK 里用的):app/src/main/assets/
  • build 脚本:app/frontEnd/build.js

所以:你改了 public 里的 JS/HTML,必须 npm run build 才会进 APK。


3. 拉源码

(如果你只是本地临时改改,也可以不推自己的仓库)

git clone https://github.com/kanoqwq/UFI-TOOLS.git cd UFI-TOOLS 

删除.git文件夹 后续如需自己维护,可以重新git init 然后推到自己的远程仓库

4. 关掉不必要的信息上报

你也不喜欢你的设备使用情况被视奸吧

4.1 先确认:上报在什么地方?

上报实现在:

  • app/src/main/java/com/minikano/f50_sms/utils/KanoReport.kt

你会看到:

  • 目标:https://api.***.cn/ufi_tools_report/report
  • header:token: ****
  • JSON:uuid / device_name / app_ver / firmware_ver / is_root

触发点在:

  • app/src/main/java/com/minikano/f50_sms/ADBService.kt

它每 5 小时执行一次:

handler.postDelayed(this, TimeUnit.HOURS.toMillis(5))

并且 ADBService 会被开机自启启动(所以会被认为“没打开同意也在跑”):

  • app/src/main/java/com/minikano/f50_sms/BootReceiver.kt
context.startForegroundService(Intent(context, ADBService::class.java))

4.2 推荐改法:只断触发点(改动小、不容易编译炸)

文件:app/src/main/java/com/minikano/f50_sms/ADBService.kt

找到:

executor.execute(runnableRPT)

改成(注释掉):

// executor.execute(runnableRPT)

这样做的好处:

  • KanoReport.kt 你可以暂时不动
  • 上报不会再被周期性触发
  • 不影响其它模块编译

4.3 更彻底(进阶):保留 runnableRPT,但不再外连

如果你想保留“周期任务框架”但不想外连,改成只注释上报调用即可:

// reportToServer()

5. 关掉远程消息推送

用于处理"放在错误的地方的开发者消息",比如小作文指责某些产品或者是无端弹出的收款码,尽管这听起来很荒谬,但的确发生过,所以我们选择眼不见心不烦的修改方法

5.1 关闭“系统消息/公告拉取”

文件:app/frontEnd/public/script/main.js

里面有一段“获取消息”的逻辑,关键点是硬编码了远端:

const api ='https://api.kanokano.cn/ufi_tools_report'// fetch(`${KANO_baseURL}/proxy/--${api}/get_message/${uuid}`)

最简单做法:直接禁用 initMessage() 调用。

做法:

  1. 搜索 initMessage()
  2. 把调用注释掉:
// initMessage()

这一步建议直接做

6. 移除 customHead 脚本执行入口(很关键)

diy绿化版本的另一个重点就是把“可执行外部脚本”的入口堵住:你可以允许 CSS,但不要让 <script> 自动跑。

6.1 先确认:customHead 到底做了什么?

文件:app/frontEnd/public/script/main.js(开头附近有 //customHead

它会把后端返回的 HTML 解析后塞进 <head>,并且会执行脚本:

doc.querySelectorAll('script').forEach(scriptEl=>{const newScript = document.createElement('script');if(scriptEl.src) newScript.src = scriptEl.src;// 外链脚本else newScript.textContent = scriptEl.textContent;// 内联脚本 document.head.appendChild(newScript);})

6.2 绿化推荐改法 A:直接禁用 customHead

文件:app/frontEnd/public/script/main.js

把 customHead 整段 IIFE 注释掉即可(它本来就是一个独立块)。

6.3 绿化推荐改法 B:保留 style/link/meta,但丢弃 script

如果你确实想保留“自定义样式”,那就只保留:

doc.querySelectorAll('style, link, meta').forEach(...)

script 部分改成“直接忽略”:

doc.querySelectorAll('script').forEach(()=>{// do nothing})
不要指望“正则过滤危险关键字”来保留 script:你很难过滤干净,实际上想绕过很容易,后风险可想而知。

6.4 后端建议一起收口(避免未来又被接回来)

customHead 的后端接口在:

文件:app/src/main/java/com/minikano/f50_sms/modules/plugins/pluginsModule.kt

  • POST /api/set_custom_head:把 text 存到 SharedPreferences
  • GET /api/get_custom_head:读出来给前端

如果你选择彻底删除 customHead 功能,建议把这两个路由也删掉。

(不想删也行——但删掉更“干净”,以后不会被 UI/插件又用起来。)


7. 更新链路自控(禁用 force + 自建资源服务器/禁用在线更新)

我爱用哪个版本,你管得着吗?

7.1 禁用“force”对更新判断的影响

文件:app/frontEnd/public/script/main.js

你会看到类似逻辑:

if(name.includes('force')){ isLatest =false;}

如果你不希望文件名影响“是否必须更新”,直接注释掉这一段即可。

7.2 资源服务器(插件/OTA)由你决定

后端有“资源服务器”概念,默认是:

文件:app/src/main/java/com/minikano/f50_sms/configs/AppMeta.kt

var GLOBAL_SERVER_URL ="https://pan.****.cn"

并且提供 API 可在运行时修改:

文件:app/src/main/java/com/minikano/f50_sms/modules/config/configModule.kt

  • GET /api/get_res_server
  • POST /api/set_res_server(body 里传 res_server

想完全自控有两条路:

  1. 你自建一个兼容的资源服务器(需要能提供 /api/fs/list 这类接口,项目用的是 alist 风格)
  2. 你直接禁用插件商店/在线 OTA(不依赖任何外部)

如果你只是想“不要默认连外网”,最简单是:把 res_server 改成你内网的服务或一个不可达地址,然后只用你自己手动安装的 APK。


8. 去掉强制条款弹窗

很多人都很反感“必须同意/必须输入确认文字”这种流氓条款,作为极客,我们完全可以把它删掉。

8.1 它是怎么判断“是否已同意”的?

后端把同意状态放在 SharedPreferences

  • POST /api/accept_terms:把 isReadUseTerms=true 写入
  • GET /api/version_info:返回 accept_terms

前端通过 getTermsAcceptance() 去读 version_info,不通过就弹窗:

文件:app/frontEnd/public/script/requests.js

constgetTermsAcceptance=async()=>{const res =await(awaitfetchWithTimeout(`${KANO_baseURL}/version_info`)).json()ACCEPT_TERMS= res.accept_terms && res.accept_terms.toString()=='true'returnACCEPT_TERMS}

8.2 绿化做法 A:前端不再弹(最简单)

文件:app/frontEnd/public/script/main.js

搜索 initTerms(),把它的调用注释掉:

// initTerms()

(这样不会再弹窗拦路。)

8.3 绿化做法 B:后端默认视为已同意(更“彻底”)

如果你想让 version_info 永远返回 accept_terms=true,可以在初始化时把默认值改成 true:

文件:app/src/main/java/com/minikano/f50_sms/configs/AppMeta.kt

把:

isReadUseTerms = prefs.getString("isReadUseTerms","false").toBoolean()

改成:

isReadUseTerms = prefs.getString("isReadUseTerms","true").toBoolean()

9. 重新打包前端资源到 APK(很关键)

前面我们改的是:

  • app/frontEnd/public/script/main.js
  • app/frontEnd/public/script/requests.js

这些改动 不会自动进 APK,必须跑前端 build:

cd app/frontEnd npminstall# 生产:会混淆 main.js/requests.js 并复制到 app/src/main/assets/npm run build # 如果你想调试(不混淆,方便看代码)npm run debug 

成功后你会看到:

  • app/src/main/assets/ 里对应的文件被更新

10. 编译 APK

10.1 Android Studio 方式

打开项目根目录 UFI-TOOLS/

  1. Gradle Sync
  2. Build -> Build APK(s)

10.2 命令行方式

在项目根目录执行:

./gradlew assembleDebug 

生成的 APK 通常在类似路径(按 Gradle 配置为准):

app/build/outputs/apk/debug/ 

11. 验证:我的ufi-tools实现自托管了吗?

建议你做两个验证:

11.1 抓包验证(推荐)

把设备连上网,打开/运行你编译的版本,观察:

  • 是否还有 api.???cn 的请求
  • 是否还有周期性 POST(等一会儿/看日志/看计划任务)

11.2 日志验证(更直观)

KanoReport.ktADBService.kt 里有 log tag,你可以:

  • 看 logcat
  • 或者临时在关键分支加日志确认“触发点已断”

最后:

当一个工具同时具备 稳定标识上报可下发前端内容并执行更新链路可控 这些能力时——
哪怕它“当前看起来没出事”“我们相信开发者”,你也在被动承担一笔信任成本


绿化版的意义,就是把这笔成本降到最低:外连由你决定,逻辑由你审计,更新由你掌握,功能由你开发
开源的魅力就在于每个人都可以对项目进行审查、贡献,按照自己的喜好删删改改

欢迎star或者fork原项目,按照你的想法diy更好用的随身wifi管理工具

Read more

Clawdbot直连Qwen3-32B教程:Webhook事件通知与外部系统自动触发实践

Clawdbot直连Qwen3-32B教程:Webhook事件通知与外部系统自动触发实践 1. 为什么需要直连Qwen3-32B?从被动响应到主动协同 你有没有遇到过这样的场景:用户在聊天界面提问后,系统只是简单返回答案,但后续该做什么——比如创建工单、同步客户信息、触发审批流程——还得手动操作?Clawdbot + Qwen3-32B 的直连方案,正是为了解决这个“最后一公里”问题。 它不只是把大模型接入聊天框,而是让AI真正成为业务流程的“触发器”。当Qwen3-32B在对话中识别出关键意图(例如“我要报修”“申请延期”“查询合同编号”),Clawdbot能立刻通过Webhook,把结构化事件推送给CRM、OA、ERP等任何支持HTTP接收的系统。整个过程无需中间数据库、不依赖定时轮询、没有消息队列配置负担——纯HTTP,轻量、可靠、可追溯。 更重要的是,这套方案用的是你私有部署的Qwen3-32B(320亿参数版本),所有对话数据不出内网,推理结果由Ollama本地托管,安全可控。而Clawdbot作为智能网关,既承担了协议转换(WebSocket ↔ HTTP)、上下

前端小白别慌:3分钟搞定页面插图(附避坑指南+性能彩蛋)

前端小白别慌:3分钟搞定页面插图(附避坑指南+性能彩蛋)

前端小白别慌:3分钟搞定页面插图(附避坑指南+性能彩蛋) * 前端小白别慌:3分钟搞定页面插图(附避坑指南+性能彩蛋) * 为啥前端连个图片都插不明白? * 浏览器加载一张图背后到底在偷偷干啥? * img 标签真就万能了吗? * 响应式图片怎么搞才不被设计师追着骂? * 懒加载、WebP、CDN——这些词听着高大上,其实你早就用过 * 图片加载失败时别让页面变"裂图坟场" * 别再一股脑扔高清大图了,用户流量不是大风刮来的 * 你以为写个 src 就完事了?SEO 和无障碍访问正在偷笑 * 开发时本地图片路径乱成一锅粥?模块化方案来救场 * Webpack/Vite 里图片到底该放哪?public 还是 assets? * 用 CSS 背景图还是 HTML img?这事儿得看场合 * 移动端图片模糊到像开了十级美颜?分辨率适配讲清楚 * 别让图片拖垮首屏速度,Lighthouse 分数掉得比工资还快 * 设计师给的图太大?教你几招无损压缩还不背锅

SpringBoot+Vue 农商对接系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】

SpringBoot+Vue 农商对接系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】

摘要 随着乡村振兴战略的深入推进,农产品产销对接成为促进农村经济发展的关键环节。传统农商对接模式存在信息不对称、交易效率低、资源整合不足等问题,亟需通过数字化手段构建高效、透明的对接平台。农商对接系统平台旨在整合农产品生产端与销售端资源,通过线上化交易流程降低中间成本,提升农产品流通效率。该系统聚焦于解决小农户与大市场之间的连接难题,为农产品供需双方提供精准匹配、订单管理、物流跟踪等一站式服务。关键词:乡村振兴、农产品产销、数字化平台、资源整合、供需匹配。 该系统基于SpringBoot+Vue的前后端分离架构开发,后端采用SpringBoot框架实现RESTful API接口,提供用户管理、商品管理、订单管理、数据分析等功能模块。前端使用Vue.js框架构建响应式界面,结合Element UI组件库提升用户体验。数据库采用MySQL存储结构化数据,通过Redis缓存高频访问数据以提升系统性能。系统支持多角色权限控制(农户、采购商、管理员),并集成第三方支付接口与物流查询接口,实现交易闭环。关键词:SpringBoot、Vue.js、MySQL、权限控制、接口集成。 数据表结构说

conda环境怎么配?Hunyuan-MT-7B-WEBUI依赖管理揭秘

conda环境怎么配?Hunyuan-MT-7B-WEBUI依赖管理揭秘 你有没有遇到过这样的情况:下载好 Hunyuan-MT-7B-WEBUI 镜像,兴冲冲启动 Jupyter,双击运行 1键启动.sh,结果终端突然跳出一长串红色报错——ModuleNotFoundError: No module named 'transformers'、ImportError: cannot import name 'AutoTokenizer',甚至更糟的 CUDA version mismatch?别急,这不是模型坏了,也不是你操作错了,而是conda 环境没配对。 这恰恰是绝大多数用户卡在“最后一公里”的真实写照。镜像文档里那句轻描淡写的“运行 1键启动.sh”,背后其实藏着一套精心设计、层层校验的依赖管理体系。它不靠魔法,也不靠运气,而是一套可复现、可调试、可迁移的工程实践。本文就带你一层层剥开