尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Grasscutter Tools 架构拆解:一条圣遗物命令从点击到落地的完整链路

Grasscutter Tools 架构拆解:一条圣遗物命令从点击到落地的完整链路 Grasscutter Tools 架构拆解一条圣遗物命令从点击到落地的完整链路【免费下载链接】grasscutter-toolsA cross-platform client that combines launcher, command generation, and mod management to easily play Grasscutter; 一个结合了启动器、命令生成、MOD管理等功能的跨平台客户端用于轻松游玩割草机。项目地址: https://gitcode.com/gh_mirrors/gr/grasscutter-toolsGrasscutter 私服玩家绕不开三个痛点每次都要手敲/give命令、在命令行里背物品 ID、手动解压 MOD 到指定目录。Grasscutter Tools 用 Tauri Vue3 把这三件事收进了一个跨平台图形客户端把启动器、命令生成、MOD 管理、管理员控制台编排进同一套界面。本文不按功能列表走而是从一条最日常的操作链路切入逐层拆开它的前后端设计。为什么不用 ElectronTauri 的取舍账选型这件事先看它放弃了什么。如果目标是快速包一个网页壳Electron 是零思考选项但它把整个 Chromium 塞进每个安装包一个静态工具动辄 80MB。Grasscutter Tools 的业务核心是文件扫描、压缩包解压、本地代理、HTTP 请求——全是系统级能力恰好是 Rust 的主场。用 Tauri前端保留 Vue 的开发体验后端让 Rust 直接碰文件系统和网络栈两边通过 IPC 传 JSON。维度Electron 方案Tauri 方案本项目的取舍安装包体积50–100MB内置 Chromium5–20MB复用系统 WebView文件操作Node 进程桥接多一层转发Rust 直接调用系统 APIwalkdir单线程遍历解压能力需引入第三方 JS 库Cargo 原生依赖 zip/unrar/sevenz-rust本地代理需要外部工具或重写hudsucker 内嵌可直接生成并注入 CA 证书内存占用常驻渲染进程 100MB单 WebView 实例明显更轻Cargo.toml 里的依赖清单直观说明了这套分工tauri负责应用壳与 IPCreqwest负责异步 HTTPwalkdir做递归目录遍历hudsucker rcgen rustls-pemfile拼出一套本地 HTTPS 代理sysproxy操作系统级代理设置。# src-tauri/Cargo.toml —— 后端依赖的核心分工 [dependencies] tauri { version 1.2.4, features [api-all, updater] } reqwest { version 0.11, features [json, native-tls] } walkdir 2 zip 0.6.4 unrar 0.4.4 sevenz-rust 0.2.2 hudsucker { version 0.19.0, features [rustls-client] } rcgen { version 0.10, features [x509-parser] } sysproxy 0.2每个库都对应一个明确的系统职责没有为框架感凑依赖。核心链路拆解从点击执行到命令落地的全过程拿圣遗物页面做标本。用户在左侧点一套圣遗物选部位花/羽/沙/杯/冠、主属性、最多 4 个副词条、档次和等级然后点执行。整条链路如下UI 状态收集 → 模板拼装命令文本 → 前端 token 校验 → HTTP 请求插件接口 → 服务端执行 → 消息回显在src/views/artifact/index.vue里命令不是拼死的字符串而是响应式 computed// src/views/artifact/index.vue —— 命令模板与参数映射 const command computed( () /give artifact.itemIds[position.value] // 圣遗物套装 ID lv${artifact.levels[position.value]} // 等级滑块上限 20 x${num.value} // 数量 artifact.mainstats[position.value] // 主属性 ID Object.entries(groupBy(artifact.substats[position.value], itemId)) .map(([k, v]) k , v.length) // 副词条按 ID 聚合成 id,次数 .join( ) )所有交互控件的状态被折叠成一行/give ...文本随每次调整实时刷新。点击执行后调用playerCommand走src/http/api.ts// src/http/api.ts —— 命令经 HTTP 发送到 Grasscutter 服务端 export function playerCommand(command: string) { if (!checkToken()) return // 未认证则拦截并跳转设置页 return request.get(/plugin/player/command?command${command}) }一个细节值得注意playerCommand发送前先做 token 校验未认证直接拦截并跳转设置页。这说明命令生成与命令执行被刻意解耦——模板逻辑是纯前端能力执行权限则交给服务端插件把关前后端职责切得很干净。关键实现细节三个藏着技术量的角落1. MOD 目录扫描用合并 MOD 规则规避重复解析MOD 管理页需要把本地 MOD 文件夹渲染成卡片列表。Rust 端用walkdir递归目录但真正的难点在区分两种 MOD 形态——独立 MOD 与合并 MOD。合并 MOD 以merged.ini标识若其子目录还嵌套了独立 MOD就要跳过外层只取里层否则会重复展示。file.rs用is_deep_merge判断目录下还有没有独立的 ini这套判定逻辑避免了卡片重复也保证了启用/停用重命名DISABLED_前缀时元数据不被破坏。同时get_mod_list会顺带扫描目录下的 png/jpg/jpeg/jfif 图片作为本地预览图通过convertFileSrc转成可访问 URL——绕过 WebView 的文件访问限制这是 Tauri 生态里标准的资源暴露姿势。2. 内嵌 HTTPS 代理自签 CA 与三平台注入连接私服时玩家可能遇到加密通信问题项目直接内置了一个本地代理。proxy.rs用rcgen生成自签 CA启动时调用sysproxy把系统代理指向127.0.0.1:port代理用hudsucker处理请求。CA 注入是三套完全不同的系统命令Windows 走certutil -user -addstore rootmacOS 走security add-trusted-certLinux 靠update-ca-certificates。同一函数名用#[cfg(target_os)]拆成三份实现编译期就完成平台分流。// src-tauri/src/cmd/proxy.rs —— 按平台编译的 CA 注入 #[cfg(target_os windows)] pub fn install_ca() - ResultString, Boxdyn Error { let path_crt get_ca_path_with(cert.crt)?.display().to_string(); let cmd_str /c certutil -user -addstore root .to_string() path_crt; let output Command::new(cmd).arg(cmd_str).output()?; Ok(String::from_utf8_lossy(output.stdout).to_string()) } #[cfg(target_os linux)] pub fn install_ca() - ResultString, Boxdyn Error { // 复制到 /usr/local/share/ca-certificates 后执行 update-ca-certificates ... }3. 下载即解压压缩格式的分派处理在线 MOD 下载完成后cmd.rs里的download命令根据扩展名分派解压逻辑zip走zip::ZipArchiverar走unrar7z走sevenz_rust解压后自动写入modinfo.json保存元数据。下载、解压、写元数据三段串成一个原子操作用户看到的是拖进列表即装好。工程化与稳定性跨平台、多语言与错误面跨平台差异收敛文件路径统一用path.replace(/\\/g, /)归一化代理与系统命令按平台条件编译启动器通过run_jar/run_program拉起服务端进程屏蔽了系统差异。错误处理分层Rust 端统一wrap_result!宏把ResultT, E转成可序列化的字符串错误前端用showSuccessMsg/$message回显用户拿到的不是堆栈而是可读提示。国际化结构界面文案走src/i18n/locales/下的 13 个语言 JSON游戏数据圣遗物、任务、怪物名走src/i18n/data/按语言分目录两者分离可独立更新。src/ ├── i18n/ │ ├── locales/ # 13 种界面语言 JSON │ └── data/ # 游戏数据本地化en/zh-CN/... ├── views/ │ ├── artifact/ # 圣遗物命令生成 │ ├── mod/ # MOD 下载与本地管理 │ └── quest/ # 任务/场景/传送 ├── http/ # 服务端插件接口封装 └── utils/ # invoke、存储、消息封装 src-tauri/src/ ├── cmd/ │ ├── file.rs # MOD 扫描、解压、重命名 │ ├── http.rs # reqwest 封装支持代理 │ ├── proxy.rs # 本地 HTTPS 代理与 CA │ └── system.rs # 进程拉起、luac 执行 └── cmd.rs # Tauri 命令注册与错误包装后端命令集中在cmd.rs通过#[tauri::command]宏暴露给前端一个文件就是一张完整的 IPC 接口清单审查权限边界非常方便。开放问题与展望坦诚说几个债客观看项目还有几处值得改进的地方代理实现的安全取舍http.rs中danger_accept_invalid_certs(true)关闭了证书校验这在本地私服场景可接受但说明代理链路整体信任面偏宽后续应把跳过校验收敛为可配置项。下载无进度与断点download是一次性拉完整字节流reqwest未接进度回调大 MOD 文件缺少断点续传与文章常讲的分片下载尚有距离。前端 bundle 膨胀风险monaco-editor被引入作为依赖体积不菲对一个小工具而言值得评估按需加载。数据同步缺失目前无云同步机制配置与 MOD 列表都停留在本机多设备迁移成本高。未来方向其实已经在代码里露了苗头execute_luac命令的存在说明系统预留了 LUA 脚本执行能力插件化是自然延伸updaterfeature 已启用自动更新链路是通的。相比口号式的路线图这几个落点更值得关注——把代理信任模型收紧、给下载加进度、让脚本能力变成开放的插件边界项目就能从好用跨到可扩展。毕竟把复杂的私服操作压缩成一次点击靠的不是界面堆砌而是前后端职责的清晰切分Rust 管住文件与网络Vue 管住交互与状态/give那行命令只是这两层之间最薄的那层纸。【免费下载链接】grasscutter-toolsA cross-platform client that combines launcher, command generation, and mod management to easily play Grasscutter; 一个结合了启动器、命令生成、MOD管理等功能的跨平台客户端用于轻松游玩割草机。项目地址: https://gitcode.com/gh_mirrors/gr/grasscutter-tools创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表