Introduction

The VPN Share Tool is a cross-platform distributed utility designed to safely and easily share remote or local network resources across multiple devices on the same local network.

The Problem

When working in teams, developers often connect to corporate VPNs or staging networks to access internal testing sites, staging environments, databases, or APIs. However:

  1. Connecting multiple devices (e.g., test mobile devices, tablets, additional testing laptops) to the same corporate VPN simultaneously can be restricted, expensive, or complex.
  2. Sharing a temporary resource hosted on a developer's localhost with another local testing machine is tedious.

The Solution

The VPN Share Tool solves this by allowing one machine—which has access to the VPN or local resource—to serve as a localized proxy.

  • It exposes the resource securely over the local network using HTTP/HTTPS.
  • Other devices on the same network can access the shared resource without needing to run the VPN client themselves.
  • It automatically handles URL rewrites and captures debug traffic.

Key Features

  • Zero Configuration Discovery: The client application automatically discovers the registry server on the local subnet without manual IP input.
  • HTTPS and SSL/TLS Support: Connections to discovery and shared proxies are secured with custom certificate authority (CA) certificates.
  • Embedded Request Debugger: Built-in web dashboard at /debug/ to view and inspect all proxied HTTP requests and responses in real-time.
  • Anti-Phishing & Content Rewriter: Rewrites hyperlinks, absolute assets, redirects, and injects customized client-side helpers (like CAPTCHA solving hooks) so proxied resources render correctly.
  • Auto-Reconnecting Live Logs: Real-time traffic log streams to a centralized admin registry.

Architecture

The VPN Share Tool is split into a desktop client application and a discovery server registry.

High-Level Overview

The system consists of two primary applications:

  1. Client Application (vpn-share-tool): A desktop GUI application that users interact with to share URLs and view available services.
  2. Discovery Server (discovery): A central (or local) registry server that tracks active client instances and facilitates service discovery.
graph TD
    Client1[vpn-share-tool Client 1] -- TCP 45679 Registration --> Server[Discovery Server]
    Client2[vpn-share-tool Client 2] -- TCP 45679 Registration --> Server
    Browser[Admin Browser] -- HTTPS 8080 Dashboard --> Server

Key Components

1. Client Application (cmd/vpn-share-tool)

  • Role: The main user-facing tool. It acts as both a proxy server (forwarding traffic) and a client (consuming services).
  • Technology:
    • Go (Golang) for backend logic.
    • Fyne for the cross-platform desktop GUI (Windows, Linux, macOS).
  • Core Logic (core/):
    • Proxy Engine: Manages HTTP/HTTPS proxies. It can rewrite URLs and modify content (e.g., injecting scripts) to ensure proxied sites work correctly.
    • Local API Server: Each client starts a local HTTP server (defaulting to port 10081+) to handle internal commands and status updates.
    • Registration Manager: Automatically finds the Discovery Server on the network and registers the client's presence.
  • Web Interface:
    • Debug Dashboard (core/debug_web): A built-in web interface (Vue.js) for inspecting captured requests and debugging proxy traffic (HAR support).

2. Discovery Server (cmd/discovery)

  • Role: Maintains a registry of all active vpn-share-tool instances on the network.
  • Technology: Go.
  • Communication:
    • TCP (Port 45679): Custom protocol for client registration and heartbeats. Handles TLS encryption.
    • HTTP/HTTPS (Port 8080): Provides a web dashboard and API for viewing active instances and configuring global settings.
  • Web Interface:
    • Discovery Dashboard (discovery_web): A Vue.js-based admin panel to view active servers, shared proxies, and logs.

3. Build System (dev/)

  • Tooling: A custom Go-based CLI tool wrapped by dev.fish.
  • Capabilities:
    • Builds Go binaries for multiple platforms (Windows, Linux, Android).
    • Compiles Vue.js frontends (npm run build) and embeds them into Go binaries.
    • Handles CA certificate generation and injection.

Data Flow & Communication

  1. Startup & Discovery:

    • When the Client starts, it scans the local subnet (sending TCP probes) or uses fallback IPs to find the Discovery Server.
    • Upon connection, it performs a TCP Handshake (TLS-secured) to register its IP and API port.
    • It maintains a persistent Heartbeat connection.
  2. Sharing a Resource:

    • User inputs a URL in the GUI.
    • The core/proxy module creates a local HTTP listener.
    • Traffic to this listener is proxied to the target URL, potentially with header/body modifications.
  3. Log Streaming:

    • Clients stream internal logs to the Discovery Server via a WebSocket connection (/upload-logs).
    • Admins can view these logs in real-time on the Discovery Dashboard, which also connects via WebSocket.
    • The server maintains a memory buffer (last 1000 lines) for initial state on connection.
  4. Updates:

    • The system supports auto-updates. Clients query the Discovery Server for the latest version and can trigger remote updates.

Getting Started

This guide explains how to set up the development environment, build the projects, and run the applications.

Prerequisites

  • Go: version 1.24.0 or higher.
  • Node.js & npm: version 20 or higher (required to build the web interfaces).
  • Rust: (optional) if compiling or checking FFI components under rustlib.

Development Environment Setup

  1. Clone the Repository:

    git clone https://github.com/soda92/vpn-share-tool.git
    cd vpn-share-tool
    
  2. Generate Development Certificates: Before compiling, you need to generate self-signed TLS certificates for development:

    go run ./dev certs
    

    This will create a certs/ folder with ca.crt, ca.key, server.crt, and server.key.

  3. Install Frontend Dependencies: Install npm dependencies for both web dashboards:

    # Request Debugger frontend
    cd core/debug_web
    npm install
    cd ../..
    
    # Discovery Dashboard frontend
    cd discovery_web
    npm install
    cd ..
    

Building the Applications

You can compile all components using the custom development CLI tool:

  • Build the Desktop GUI Application:

    go run ./dev build
    

    This builds the Vue frontend and compiles the final Go binary to cmd/vpn-share-tool/vpn-share-tool.

  • Build the Discovery Server:

    go run ./dev build server
    

    This builds the server dashboard frontend and compiles the server binary to dist/discovery.

  • Build for Windows (Cross-compilation via Docker/fyne-cross):

    go run ./dev build windows
    
  • Build Linux FFI Shared Library (for Flutter):

    go run ./dev build linux-so
    

Running the Applications

  1. Start the Discovery Server:

    # Run the server binary
    ./dist/discovery
    

    By default, it will listen for client connections on TCP port 45679 and host the web dashboard on port 8080.

  2. Start the Client Application:

    # Run the desktop app using the dev CLI
    go run ./dev run
    

    The client will boot up the cross-platform GUI, search for the local discovery server on your subnet, and establish a secure registration.

Windows Updater Architecture & Release Guide

To solve Windows file-locking issues, anti-virus alerts, and package size overhead, the auto-update pipeline uses a dedicated, lightweight console-based updater separate from the main application.


1. How the Updater Works (Architecture)

The update flow is split into a two-step bootstrap process to cleanly replace locked files:

sequenceDiagram
    participant App as Main App (vpn-share-tool)
    participant Server as Discovery Server
    participant Updater as Updater (updater.exe)

    App->>Server: 1. Check updates (/latest-app-version)
    Server-->>App: New version available (e.g., v40b)
    App->>Server: 2. Download updater (/latest-version)
    Server-->>App: Returns updater.exe
    App->>Updater: 3. Launch updater.exe & self-terminate
    Note over Updater: 4. Wait for main app to exit
    Updater->>Server: 5. Download app ZIP (/latest-app-version?format=zip)
    Server-->>Updater: Returns vpn-share-tool-app_v40b.zip
    Updater->>Updater: 6. Unzip & overwrite vpn-share-tool.exe
    Updater->>App: 7. Launch updated vpn-share-tool.exe
    Note over Updater: 8. Exit

Modes of Operation

  1. Bootstrap Mode: When the updater is executed with the name vpn-share-tool.exe (such as when legacy clients directly replace their main executable with the updater file), it copies itself to updater.exe, spawns updater.exe --source vpn-share-tool.exe, and exits immediately.
  2. Upgrade Mode: Running as updater.exe with a --source flag, it waits for the main application process to exit and release file locks, downloads the zip release of the actual application, extracts/overwrites the target binary, and restarts the application.

2. Updater vs. Main App Differences

FeatureMain Application (vpn-share-tool)Updater (updater.exe)
RoleGUI proxy sharing & client dashboardLightweight binary replacement agent
InterfaceFyne Desktop GUI (Interactive)Console (CLI outputs, progress bars)
Size~64 MB~6.5 MB
Go Versiongo >= 1.25 (Required by Sentry)go 1.24 / pure Go
CGOEnabled (OpenGL / graphics drivers)Disabled (CGO_ENABLED=0)
Release Filevpn-share-tool-app_vXX.zipvpn-share-tool_vXX.exe, vpn-share-tool_vXX.zip

3. Build & Release Commands

All compilation and publishing tasks are managed by the custom development CLI (go run ./dev).

A. The Updater Binary

To build and release updates to the updater binary itself (e.g., when improving the updater's unzip logic):

  1. Build:

    go run ./dev build updater
    

    This reads the current version from Release.toml and compiles dist/updater.exe (~6.5MB) using compile-time optimization and version injection flags (-trimpath and -ldflags="-s -w -X main.UpdaterVersion=vXX"). This ensures the updater knows its own version and avoids infinite update loops.

  2. Release:

    go run ./dev release-windows --updater
    

    Copies the updater executable and its ZIP package (renamed to vpn-share-tool_vXX.exe and vpn-share-tool_vXX.zip) to the Samba share path. No hash (.sha256) files are uploaded to maintain backwards compatibility with legacy client versions (e.g., 37b).

B. The Main Application

To build and release updates to the main application:

  1. Build:

    • Local build (using local mingw-w64 toolchain):
      go run ./dev build windows --local
      
    • Container build (using fyne-cross Docker image):
      go run ./dev build windows
      

    This bumps the version count, embeds frontend assets, and generates the application executable.

  2. Release:

    go run ./dev release-windows
    

    Compresses the application into vpn-share-tool-app_vXX.zip and uploads it to the Samba share alongside its .sha256 integrity verification file. Only the .zip archive is uploaded for the app to optimize network traffic and disk usage on the share.


4. Client Transition & Backwards Compatibility Guide

With the removal of the separate updater.exe from the new client updating flow, we transition clients in two steps to maintain compatibility with all client eras (Extremely Old e.g. v37b, Medium-Old e.g. v38 - v40c, and New client versions):

Era 1: Extremely Old Clients (e.g., v37b)

  • Behavior: These clients check /latest-version?format=zip directly for the main application update.
  • Transition: When we serve vpn-share-tool_vXX.zip (containing the updater compiled as vpn-share-tool.exe), these clients download it and overwrite themselves. On startup, the updater detects it is named vpn-share-tool.exe and enters Bootstrap Mode, copying itself to updater.exe, spawning it, and exiting. The spawned updater.exe then downloads and installs vpn-share-tool-app_vXX.zip (the new app).

Era 2: Medium-Old Clients (e.g., v38 - v40c)

  • Behavior: These clients query /latest-app-version for the app update, but download updater.exe from /latest-version to apply it.
  • Transition Step 1 (Upgrade Clients): Publish the new client version using the vpn-share-tool-app_vXX.zip naming pattern (e.g., vpn-share-tool-app_v40d.zip). Medium-old clients' updater.exe will download, extract, and successfully upgrade them to v40d. Once upgraded, no active clients use updater.exe anymore; they all update directly via update.bat.
  • Transition Step 2 (Stop Using -app Suffix): Once all clients run v40d or newer, subsequent versions (e.g., v41a) can be published directly as the base package vpn-share-tool_v41a.zip. The discovery server will fall back to match both -app and base package patterns for /latest-app-version, updating the clients successfully.

项目介绍

VPN Share Tool 是一个跨平台的分布式实用工具,旨在安全、轻松地在同一局域网(LAN)内的多个设备之间共享远程或本地网络资源。

解决的问题

在团队协作中,开发人员经常需要连接到公司 VPN 或特定的测试网络,以访问内部测试网站、预发环境、数据库或 API。然而,这面临着以下问题:

  1. 同时将多个设备(如测试手机、平板电脑、其他开发机)连接到同一个公司 VPN 可能受到限制,且过程繁琐或费用昂贵。
  2. 开发人员要在本地测试机之间临时共享运行在 localhost 上的资源十分麻烦。

解决方案

VPN Share Tool 通过让一台拥有 VPN 或本地资源访问权限的机器充当本地代理来解决此问题:

  • 它通过 HTTP/HTTPS 安全地在局域网内暴露资源。
  • 同一网络中的其他设备无需运行 VPN 客户端即可直接访问共享资源。
  • 自动处理 URL 重写,并捕获调试流量。

核心特性

  • 零配置发现:客户端能够自动在局域网网段中扫描并发现注册服务(Discovery Server),无需手动输入 IP。
  • HTTPS 与 SSL/TLS 支持:与注册中心和共享代理的连接使用自定义证书颁发机构(CA)证书进行安全加密。
  • 内置请求调试器:内置基于 Vue.js 的 Web 控制台(可通过 /debug/ 访问),用于实时查看、过滤和拦截代理的 HTTP 请求与响应(支持 HAR 导出与对比)。
  • 防钓鱼与内容重写:自动重写超链接、静态资源绝对路径、重定向地址,并能注入自定义客户端脚本(如验证码自动求解钩子),以确保被代理的网站能正常渲染和交互。
  • 自动重连实时日志:实时日志流能够持久化推送到集中的管理中心。

系统架构

VPN Share Tool 由桌面客户端应用程序和注册中心服务组成。

高层视图

系统包含两个主要应用程序:

  1. 客户端应用程序 (vpn-share-tool):一个桌面 GUI 应用程序,用户可通过它共享 URL 并查看可用服务。
  2. 注册服务 (discovery):一个中央(或本地)注册服务器,用于追踪活跃的客户端实例并协助服务发现。
graph TD
    Client1[vpn-share-tool Client 1] -- TCP 45679 注册 --> Server[Discovery Server]
    Client2[vpn-share-tool Client 2] -- TCP 45679 注册 --> Server
    Browser[Admin Browser] -- HTTPS 8080 控制台 --> Server

核心组件

1. 客户端应用程序 (cmd/vpn-share-tool)

  • 角色:主要的用户交互工具。它既是代理服务器(转发流量),也是客户端(消费服务)。
  • 技术栈
    • Go (Golang) 用于编写后端核心逻辑。
    • Fyne 用于编写跨平台的桌面 GUI(支持 Windows, Linux, macOS)。
  • 核心逻辑 (core/)
    • 代理引擎 (Proxy Engine):管理 HTTP/HTTPS 代理。它能够重写 URL 并修改响应内容(例如注入 JS 脚本)以确保代理页面功能正常。
    • 本地 API 服务:每个客户端启动一个本地 HTTP 服务(默认端口 10081+)来处理内部控制命令和状态更新。
    • 注册管理器 (Registration Manager):自动在网络中发现注册服务器(Discovery Server)并注册当前客户端。
  • Web 界面
    • 调试控制台 (core/debug_web):内置的网页端交互界面(Vue.js),用于审查捕获到的请求并调试代理流量(支持 HAR 导出与对比)。

2. 注册服务 (cmd/discovery)

  • 角色:维护局域网内所有活跃 vpn-share-tool 客户端的实例注册表。
  • 技术栈:Go。
  • 通信协议
    • TCP (端口 45679):用于客户端注册和心跳检测的自定义协议,使用 TLS 加密。
    • HTTP/HTTPS (端口 8080):提供 Web 仪表盘和 API,用于查看活跃的客户端以及配置全局属性。
  • Web 界面
    • 注册中心控制台 (discovery_web):基于 Vue.js 的管理面板,展示活跃的服务器、共享的代理以及实时日志。

3. 构建系统 (dev/)

  • 工具链:包装在 dev.fish 中的自定义 Go 编写的 CLI 开发命令工具。
  • 功能
    • 交叉编译构建多个平台(Windows, Linux, Android)的 Go 二进制文件。
    • 自动编译 Vue.js 前端代码(npm run build)并将资源静态嵌入到 Go 二进制文件中。
    • 处理 CA 证书的生成和分发注入。

数据流与通信机制

  1. 启动与发现

    • 客户端启动时,会自动扫描本地子网(发送 TCP 探测)或使用硬编码的备用 IP 来寻找注册服务服务器。
    • 连接成功后,它执行 TCP 握手(基于 TLS)注册自己的 IP 和 API 端口。
    • 它与服务端保持一条持久的 心跳 (Heartbeat) 连接。
  2. 共享资源

    • 用户在客户端 GUI 中输入需要代理的 URL。
    • core/proxy 模块创建一个本地 HTTP 监听端口。
    • 该端口的流量被代理转发到目标 URL,其间可能会经过请求头或响应体的重写修改。
  3. 日志推流

    • 客户端通过 WebSocket 连接(/upload-logs)向注册中心服务器推流本地日志。
    • 管理员可以通过注册中心控制台(同样通过 WebSocket 协议连接)实时查阅这些汇总日志。
    • 注册中心保持 1000 行的日志内存缓冲区,方便新建立连接的控制台查看初始状态。
  4. 系统更新

    • 系统支持自动升级。客户端定期从注册中心获取最新版本信息,并可触发远程自动更新。

快速开始

本指南将介绍如何设置本地开发环境、构建项目并运行应用程序。

前置环境要求

  • Go:版本 1.24.0 或更高。
  • Node.js & npm:版本 20 或更高(用于编译 Web 前端资源)。
  • Rust:(可选)如果你需要编译或调试 rustlib 目录下的 FFI 组件。

开发环境搭建

  1. 克隆仓库

    git clone https://github.com/soda92/vpn-share-tool.git
    cd vpn-share-tool
    
  2. 生成开发证书: 在编译之前,你需要生成开发用的自签名 TLS 证书:

    go run ./dev certs
    

    这将在 certs/ 目录下生成 ca.crtca.keyserver.crtserver.key

  3. 安装前端依赖: 分别在两个 Web 前端项目中安装 npm 依赖包:

    # 请求调试器前端 (Request Debugger)
    cd core/debug_web
    npm install
    cd ../..
    
    # 注册中心管理台前端 (Discovery Dashboard)
    cd discovery_web
    npm install
    cd ..
    

编译项目

你可以使用内置的命令行开发工具(dev CLI)完成各项编译操作:

  • 构建桌面 GUI 应用程序

    go run ./dev build
    

    这会先编译 Vue 前端资源,然后将其打包嵌入最终的 Go 二进制文件中,输出至 cmd/vpn-share-tool/vpn-share-tool

  • 构建注册服务 (Discovery Server)

    go run ./dev build server
    

    这会编译管理台前端资源并编译服务端的二进制文件,输出至 dist/discovery

  • 构建 Windows 安装包 (在 Linux Docker 环境下交叉编译)

    go run ./dev build windows
    
  • 构建 Linux FFI 共享库 (供 Flutter FFI 绑定调用)

    go run ./dev build linux-so
    

运行项目

  1. 启动注册服务器 (Discovery Server)

    # 启动服务端
    ./dist/discovery
    

    默认情况下,它将在 TCP 45679 端口监听客户端握手,并在 8080 端口托管 Web 管理后台。

  2. 启动桌面客户端

    # 使用开发命令行启动桌面 GUI
    go run ./dev run
    

    客户端将启动跨平台 GUI 窗口,并自动开始在子网内广播扫描注册服务器建立安全配对连接。

Windows 更新程序 (Updater) 架构与发布指南

为了解决 Windows 文件锁占用、杀毒软件误报以及包体体积过大的问题,自动更新流程采用了一个独立的、轻量级的 控制台更新程序 (Console Updater),与主程序完全分离。


1. 更新程序工作原理 (系统架构)

更新流程采用 两步引导程序 (Bootstrap Process) 来安全地替换被锁定的可执行文件:

sequenceDiagram
    participant App as 主程序 (vpn-share-tool)
    participant Server as 注册发现服务器
    participant Updater as 更新程序 (updater.exe)

    App->>Server: 1. 检查主程序更新 (/latest-app-version)
    Server-->>App: 返回有新版本可用 (例如 v40b)
    App->>Server: 2. 下载更新器程序 (/latest-version)
    Server-->>App: 返回 updater.exe
    App->>Updater: 3. 启动 updater.exe 并自杀退出
    Note over Updater: 4. 等待主程序进程退出以释放文件锁
    Updater->>Server: 5. 下载主程序压缩包 (/latest-app-version?format=zip)
    Server-->>Updater: 返回 vpn-share-tool-app_v40b.zip
    Updater->>Updater: 6. 解压并覆盖 vpn-share-tool.exe
    Updater->>App: 7. 启动更新后的 vpn-share-tool.exe
    Note over Updater: 8. 退出

运行模式

  1. 引导模式 (Bootstrap Mode):如果更新器本身以 vpn-share-tool.exe 命运行(例如旧版本客户端直接用更新器文件覆盖主程序的情况),它会复制自身到 updater.exe,启动子进程 updater.exe --source vpn-share-tool.exe,然后立即退出。
  2. 升级模式 (Upgrade Mode):以 updater.exe 文件运行并带有 --source 参数。它会等待主程序释放文件锁,下载主程序的 ZIP 压缩包进行解压和覆盖,最后重新拉起主程序。

2. 更新程序与主程序的区别

特性主程序 (vpn-share-tool)更新程序 (updater.exe)
角色代理资源共享与客户端 GUI 交互面板轻量级文件替换代理
界面Fyne 桌面 GUI (交互式)控制台 (命令行输出与进度条)
大小约 64 MB约 6.5 MB
Go 版本go >= 1.25 (Sentry 库依赖)go 1.24 / 纯 Go 标准库
CGO开启 (包含 OpenGL 图形驱动依赖)关闭 (CGO_ENABLED=0)
发布包vpn-share-tool-app_vXX.zipvpn-share-tool_vXX.exe, vpn-share-tool_vXX.zip

3. 构建与发布命令

所有的编译与分发操作均由自定义开发命令行工具 (go run ./dev) 统一管理。

A. 更新器 (Updater) 自身

用于编译和发布更新器本身的修改(例如修改了解压逻辑或命令行交互):

  1. 构建

    go run ./dev build updater
    

    该命令会从 Release.toml 读取当前版本,应用 -trimpath-ldflags="-s -w -X main.UpdaterVersion=vXX" 编译参数,进行编译优化并动态注入版本号,在 dist/ 目录下生成约 6.5MB 的 updater.exe。这能确保更新程序明确知道自身的版本,避免陷入无限更新循环。

  2. 发布

    go run ./dev release-windows --updater
    

    将更新程序可执行文件及 ZIP 包(重命名为 vpn-share-tool_vXX.exevpn-share-tool_vXX.zip)拷贝到共享目录。此处不上传 .sha256 校验文件,以确保旧版本(如 37b)客户端可以顺利下载并直接引导升级。

B. 主程序 (Main Application)

用于编译和发布主程序的业务更新:

  1. 构建

    • 本地构建(使用本地 mingw-w64 交叉编译工具链):
      go run ./dev build windows --local
      
    • 容器构建(使用 fyne-cross Docker 镜像):
      go run ./dev build windows
      

    构建过程会自动累加版本号,编译打包前端静态资源并嵌入二进制中。

  2. 发布

    go run ./dev release-windows
    

    将主程序打包成 vpn-share-tool-app_vXX.zip 并上传至共享目录,同时写入用于校验文件完整性的 .sha256 文件。主程序只发布 ZIP 格式,以大幅节省共享目录存储空间并降低网络带宽消耗。


4. 客户端迁移与后向兼容指南

随着新版本客户端移除了独立的 updater.exe,并改回直接使用 update.bat 的逻辑,我们需要分两步进行平滑迁移,以保证与各个历史版本(极旧版本如 v37b,中代版本如 v38 - v40c 以及全新版本客户端)的完全兼容:

阶段一:极旧版本客户端(例如 v37b

  • 行为:这些客户端直接向 /latest-version?format=zip 请求主程序的更新包。
  • 迁移逻辑:当它们下载到 vpn-share-tool_vXX.zip(实际为重命名为 vpn-share-tool.exe 的更新器程序)并解压运行时,更新器会检测到自身文件名不是 updater,从而进入引导模式 (Bootstrap Mode):复制自身到 updater.exe 并启动子进程,随后由该子进程请求 /latest-app-version 并下载解压 vpn-share-tool-app_vXX.zip(新版主程序)覆盖自身。

阶段二:中代版本客户端(如 v38 - v40c

  • 行为:这些客户端向 /latest-app-version 请求主程序更新,但会通过下载 /latest-version (即 updater.exe) 来执行覆盖安装。
  • 迁移步骤 1 (全网客户端换代):发布带有 -app 后缀的新主程序包(如 vpn-share-tool-app_v40d.zip)。中代客户端的 updater.exe 会自动下载、解压并将其升级至 v40d。在此次升级后,全网已无存活的使用 updater.exe 的客户端,后续全部切换至 update.bat 直更逻辑。
  • 迁移步骤 2 (回归标准包名):在全网客户端均升级至 v40d 或更高版本后,后续的新版本(如 v41a)可以直接发布为标准包名 vpn-share-tool_v41a.zip。注册发现服务器会自动应用回退匹配机制,当客户端请求 /latest-app-version 时会同时检索 -app 和标准包名,返回最新版本。