Compare commits

..

53 Commits

111 changed files with 1990 additions and 1402 deletions

View File

@@ -26,7 +26,7 @@ If applicable, add screenshots to help explain your problem.
**Information**
- OS: [e.g. macOS]
- Clash Nyanpasu Version: [e.g. 1.3.4]
- Clash Verge Version: [e.g. 1.3.4]
- Clash Core: [e.g. Clash or Clash Meta]
**Additional context**

View File

@@ -1,92 +0,0 @@
name: Alpha CI
on:
workflow_dispatch:
inputs:
debug:
type: boolean
default: false
env:
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: short
jobs:
release:
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-20.04, macos-latest]
runs-on: ${{ matrix.os }}
if: startsWith(github.repository, 'zzzgydi')
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: "16"
cache: "yarn"
- name: Delete current release assets
if: startsWith(matrix.os, 'ubuntu-')
uses: mknejp/delete-release-assets@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag: alpha
fail-if-no-assets: false
fail-if-no-release: false
assets: |
*.zip
*.gz
*.AppImage
*.deb
*.dmg
*.msi
*.sig
- name: Install Dependencies (ubuntu only)
if: startsWith(matrix.os, 'ubuntu-')
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf openssl
- name: Yarn install and check
run: |
yarn install --network-timeout 1000000 --frozen-lockfile
yarn run check
- name: Tauri build
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tagName: alpha
releaseName: "Clash Verge Alpha"
releaseBody: "Alpha Version (include debug)"
releaseDraft: false
prerelease: true
includeDebug: ${{ github.event.inputs.debug }}
- name: Portable Bundle
if: startsWith(matrix.os, 'windows-')
run: |
yarn build
yarn run portable
env:
TAG_NAME: alpha
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
VITE_WIN_PORTABLE: 1

View File

@@ -1,98 +0,0 @@
name: Release CI
on:
workflow_dispatch:
push:
tags:
- v**
env:
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: short
jobs:
release:
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
if: startsWith(github.repository, 'zzzgydi')
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: "16"
cache: "yarn"
- name: Install Dependencies (ubuntu only)
if: startsWith(matrix.os, 'ubuntu-')
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf openssl
- name: Yarn install and check
run: |
yarn install --network-timeout 1000000 --frozen-lockfile
yarn run check
- name: Tauri build
uses: tauri-apps/tauri-action@v0
# enable cache even though failed
# continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tagName: v__VERSION__
releaseName: "Clash Verge v__VERSION__"
releaseBody: "More new features are now supported."
releaseDraft: false
prerelease: true
- name: Portable Bundle
if: startsWith(matrix.os, 'windows-')
# rebuild with env settings
run: |
yarn build
yarn run portable
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
VITE_WIN_PORTABLE: 1
release-update:
needs: release
runs-on: ubuntu-latest
if: |
startsWith(github.repository, 'zzzgydi') &&
startsWith(github.ref, 'refs/tags/v')
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: "16"
cache: "yarn"
- name: Yarn install
run: yarn install --network-timeout 1000000 --frozen-lockfile
- name: Release updater file
run: yarn run updater
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -24,7 +24,7 @@ jobs:
os: ubuntu-22.04
runs-on: ${{ matrix.targets.os }}
if: startsWith(github.repository, 'zzzgydi')
if: startsWith(github.repository, 'wonfen')
steps:
- name: Checkout repository
uses: actions/checkout@v2

View File

@@ -17,10 +17,10 @@ jobs:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
if: startsWith(github.repository, 'keiko233')
if: startsWith(github.repository, 'wonfen')
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
@@ -31,7 +31,7 @@ jobs:
workspaces: src-tauri
- name: Install Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "20"
@@ -45,7 +45,7 @@ jobs:
if: startsWith(matrix.os, 'ubuntu-')
uses: mknejp/delete-release-assets@v1
with:
token: ${{ secrets.GH_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
tag: dev
fail-if-no-assets: false
fail-if-no-release: false
@@ -57,6 +57,8 @@ jobs:
*.dmg
*.msi
*.sig
*.exe
*.json
- name: Install Dependencies (Ubuntu Only)
if: startsWith(matrix.os, 'ubuntu-')
@@ -72,12 +74,12 @@ jobs:
- name: Tauri build
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tagName: dev
releaseName: "Clash Nyanpasu Dev"
releaseName: "Clash Verge Dev"
releaseBody: "More new features are now supported."
releaseDraft: false
prerelease: true
@@ -87,7 +89,6 @@ jobs:
- name: Portable Bundle
if: matrix.os == 'windows-latest'
run: |
pnpm build -f default-meta
pnpm portable
env:
TAG_NAME: dev

View File

@@ -17,7 +17,7 @@ jobs:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
if: startsWith(github.repository, 'zzzgydi')
if: startsWith(github.repository, 'wonfen')
steps:
- name: Checkout repository
uses: actions/checkout@v2

View File

@@ -3,8 +3,8 @@ name: Release Build
on:
workflow_dispatch:
push:
branches:
- main
tags:
- v**
env:
CARGO_INCREMENTAL: 0
@@ -13,14 +13,15 @@ env:
jobs:
release:
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
if: startsWith(github.repository, 'keiko233')
if: startsWith(github.repository, 'wonfen')
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
@@ -31,7 +32,7 @@ jobs:
workspaces: src-tauri
- name: Install Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "20"
@@ -55,12 +56,12 @@ jobs:
- name: Tauri build
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tagName: v__VERSION__
releaseName: "Clash Nyanpasu v__VERSION__"
releaseName: "Clash Verge v__VERSION__"
releaseBody: "More new features are now supported."
releaseDraft: false
prerelease: false
@@ -70,7 +71,6 @@ jobs:
- name: Portable Bundle
if: matrix.os == 'windows-latest'
run: |
pnpm build -f default-meta
pnpm portable
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -79,16 +79,17 @@ jobs:
VITE_WIN_PORTABLE: 1
release-update:
needs: release
needs: [release]
runs-on: ubuntu-latest
if: |
startsWith(github.repository, 'keiko233')
startsWith(github.repository, 'wonfen') &&
startsWith(github.ref, 'refs/tags/v')
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "20"

View File

@@ -28,14 +28,14 @@ env:
jobs:
release:
runs-on: ${{ github.event.inputs.os }}
if: startsWith(github.repository, 'zzzgydi')
if: startsWith(github.repository, 'wonfen')
steps:
- name: System Version
run: |
echo ${{ github.event.inputs.os }}
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
@@ -46,7 +46,7 @@ jobs:
workspaces: src-tauri
- name: Install Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "16"
cache: "yarn"

View File

@@ -5,7 +5,8 @@ on: workflow_dispatch
jobs:
release-update:
runs-on: ubuntu-latest
if: startsWith(github.repository, 'zzzgydi')
if: |
startsWith(github.repository, 'wonfen')
steps:
- name: Checkout repository
uses: actions/checkout@v3
@@ -13,13 +14,18 @@ jobs:
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: "16"
cache: "yarn"
node-version: "20"
- name: Yarn install
run: yarn install --network-timeout 1000000 --frozen-lockfile
- uses: pnpm/action-setup@v2
name: Install pnpm
with:
version: 8
run_install: false
- name: Pnpm install
run: pnpm i
- name: Release updater file
run: yarn run updater
run: pnpm updater
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,25 +1,51 @@
<h1 align="center">
<img src="./src/assets/image/logo.png" alt="Clash" width="128" />
<br>
Clash Nyanpasu
Clash Verge
<br>
</h1>
<h3 align="center">
A <a href="https://github.com/Dreamacro/clash">Clash</a> GUI based on <a href="https://github.com/tauri-apps/tauri">tauri</a>.
A 接盘 Clash Meta GUI based on <a href="https://github.com/tauri-apps/tauri">tauri</a>.
</h3>
## Features
- Full `clash` config supported, Partial `clash premium` config supported.
- Profiles management and enhancement (by yaml and Javascript). [Doc](https://github.com/keiko233/clash-nyanpasu/wiki/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97)
- Since the clash core has been removed. The project no longer maintains the clash core, but only the Clash Meta core.
- Profiles management and enhancement (by yaml and Javascript). [Doc](https://github.com/wonfen/clash-verge-rev/wiki/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97)
- Simple UI and supports custom theme color.
- Built-in support [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta) core.
- System proxy setting and guard.
#### TG Group: [@clash_verge_rev](https://t.me/clash_verge_rev)
## Promotion
[狗狗加速 —— 技术流机场 Doggygo VPN](https://狗狗加速.com)
- 高性能海外机场,免费试用,优惠套餐,解锁流媒体,全球首家支持 Hysteria 协议。
- 使用 Clash Verge 专属邀请链接注册送 3 天,每天 1G 流量免费试用https://verge.狗狗加速.com/#/register?code=oaxsAGo6
- Clash Verge 专属 8 折优惠码: verge20 (仅有 500 份)
- 优惠套餐每月仅需 15.8 元160G 流量,年付 8 折
- 海外团队,无跑路风险,高达 50% 返佣
- 集群负载均衡设计,高速专线(兼容老客户端)极低延迟无视晚高峰4K 秒开
- 全球首家 Hysteria 协议机场,现已上线更快的 `Hysteria2` 协议(Clash Verge 客户端最佳搭配)
- 解锁流媒体及 ChatGPT
- 官网https://狗狗加速.com
## Preview
![preview](./docs/preview.gif)
## Install
Download from [release](https://github.com/keiko233/clash-nyanpasu/releases). Supports Windows x64, Linux x86_64 and macOS 11+
Download from [release](https://github.com/wonfen/clash-verge-rev/releases). Supports Windows x64, Linux x86_64 and macOS 11+
- [Windows x64](https://github.com/wonfen/clash-verge-rev/releases/download/v1.4.0/Clash.Verge_1.4.0_x64_zh-CN.msi)
- [macOS intel](https://github.com/wonfen/clash-verge-rev/releases/download/v1.4.0/Clash.Verge_1.4.0_x64.dmg)
- [macOS arm](https://github.com/wonfen/clash-verge-rev/releases/download/v1.4.0/Clash.Verge_1.4.0_aarch64.dmg)
- [Linux AppImage](https://github.com/wonfen/clash-verge-rev/releases/download/v1.4.0/clash-verge_1.4.0_amd64.AppImage)
- [Linux deb](https://github.com/wonfen/clash-verge-rev/releases/download/v1.4.0/clash-verge_1.4.0_amd64.deb)
Or you can build it yourself. Supports Windows, Linux and macOS 10.15+
@@ -27,9 +53,9 @@ Notes: If you could not start the app on Windows, please check that you have [We
### FAQ
#### 1. **macOS** "Clash Nyanpasu" is damaged and can't be opened
#### 1. **macOS** "Clash Verge" is damaged and can't be opened
open the terminal and run `sudo xattr -r -d com.apple.quarantine /Applications/Clash\ Nyanpasu.app`
open the terminal and run `sudo xattr -r -d com.apple.quarantine /Applications/Clash\ Verge.app`
## Development
@@ -39,7 +65,7 @@ You should install Rust and Nodejs, see [here](https://tauri.app/v1/guides/getti
pnpm i
```
Then download the clash binary... Or you can download it from [clash premium release](https://github.com/Dreamacro/clash/releases/tag/premium) and rename it according to [tauri config](https://tauri.studio/docs/api/config/#tauri.bundle.externalBin).
Then download the clash binary... Or you can download it from [clash meta release](https://github.com/MetaCubeX/Clash.Meta/releases) and rename it according to [tauri config](https://tauri.studio/docs/api/config/#tauri.bundle.externalBin).
```shell
# force update to latest version
@@ -77,8 +103,9 @@ Issue and PR welcome!
## Acknowledgement
Clash Nyanpasu was based on or inspired by these projects and so on:
Clash Verge rev was based on or inspired by these projects and so on:
- [keiko233/clash-nyanpasu](https://github.com/keiko233/clash-nyanpasu): A Clash Verge variant.
- [zzzgydi/clash-verge](https://github.com/zzzgydi/clash-verge): A Clash GUI based on tauri. Supports Windows, macOS and Linux.
- [tauri-apps/tauri](https://github.com/tauri-apps/tauri): Build smaller, faster, and more secure desktop applications with a web frontend.
- [Dreamacro/clash](https://github.com/Dreamacro/clash): A rule-based tunnel in Go.

View File

@@ -1,23 +1,39 @@
## v1.4.1
### Features
- update clash meta core to newest 虚空终端(2023.11.23)
- delete clash core UI
- improve UI
- change Logo to original
---
## v1.4.0
### Features
- Default use Meta Core.
- Support copy PowerShell, CMD and sh env command.
- Add Upload Traffic, Download Traffic and Active Connections to ConnectionsPage.
- SettingPage use Grid layout.
- Import LoadingButton & use when Download Profile.
- New default theme color.
- Add Nyanpasu Element. (Logo designer [@ReallySnow](https://github.com/ReallySnow))
- Default enable unified-delay & tcp-concurrent.
- Use Meta Country.mmdb.
- Disable IPv6 by default.
- Add Material You element.
- Add Router switch transition.
- update clash meta core to newest 虚空终端
- delete clash core, no longer maintain
- merge Clash nyanpasu changes
- remove delay display different color
- use Meta Country.mmdb
- update dependencies
- small changes here and there
---
## v1.3.8
### Features
- update clash meta core
- add default valid keys
- adjust the delay display interval and color
### Bug Fixes
- Fix touchpad scrolling causes blank area to appear.
- fix connections page undefined exception
---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/preview.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 MiB

View File

@@ -1,6 +1,6 @@
{
"name": "clash-nyanpasu",
"version": "1.4.0",
"name": "clash-verge",
"version": "1.4.1",
"license": "GPL-3.0",
"scripts": {
"dev": "tauri dev -f default-meta",
@@ -42,6 +42,7 @@
"react-virtuoso": "^3.1.3",
"recoil": "^0.7.6",
"snarkdown": "^2.0.0",
"tar": "^6.2.0",
"swr": "^1.3.0"
},
"devDependencies": {

81
pnpm-lock.yaml generated
View File

@@ -80,6 +80,9 @@ dependencies:
swr:
specifier: ^1.3.0
version: 1.3.0(react@18.2.0)
tar:
specifier: ^6.2.0
version: 6.2.0
devDependencies:
"@actions/github":
@@ -2180,6 +2183,14 @@ packages:
fsevents: 2.3.2
dev: true
/chownr@2.0.0:
resolution:
{
integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==,
}
engines: { node: ">=10" }
dev: false
/clsx@2.0.0:
resolution:
{
@@ -2578,6 +2589,16 @@ packages:
universalify: 2.0.0
dev: true
/fs-minipass@2.1.0:
resolution:
{
integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==,
}
engines: { node: ">= 8" }
dependencies:
minipass: 3.3.6
dev: false
/fsevents@2.3.2:
resolution:
{
@@ -2992,6 +3013,44 @@ packages:
brace-expansion: 1.1.11
dev: true
/minipass@3.3.6:
resolution:
{
integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==,
}
engines: { node: ">=8" }
dependencies:
yallist: 4.0.0
dev: false
/minipass@5.0.0:
resolution:
{
integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==,
}
engines: { node: ">=8" }
dev: false
/minizlib@2.1.2:
resolution:
{
integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==,
}
engines: { node: ">= 8" }
dependencies:
minipass: 3.3.6
yallist: 4.0.0
dev: false
/mkdirp@1.0.4:
resolution:
{
integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==,
}
engines: { node: ">=10" }
hasBin: true
dev: false
/monaco-editor@0.34.1:
resolution:
{
@@ -3694,6 +3753,21 @@ packages:
react: 18.2.0
dev: false
/tar@6.2.0:
resolution:
{
integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==,
}
engines: { node: ">=10" }
dependencies:
chownr: 2.0.0
fs-minipass: 2.1.0
minipass: 5.0.0
minizlib: 2.1.2
mkdirp: 1.0.4
yallist: 4.0.0
dev: false
/to-fast-properties@2.0.0:
resolution:
{
@@ -3897,6 +3971,13 @@ packages:
}
dev: true
/yallist@4.0.0:
resolution:
{
integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==,
}
dev: false
/yaml@1.10.2:
resolution:
{

View File

@@ -45,8 +45,8 @@ async function resolve() {
const join = (p) => path.join(bundlePath, p);
const appPathList = [
join("macos/Clash Nyanpasu.aarch64.app.tar.gz"),
join("macos/Clash Nyanpasu.aarch64.app.tar.gz.sig"),
join("macos/Clash Verge.aarch64.app.tar.gz"),
join("macos/Clash Verge.aarch64.app.tar.gz.sig"),
];
for (const appPath of appPathList) {
@@ -55,8 +55,8 @@ async function resolve() {
}
}
fs.copyFileSync(join("macos/Clash Nyanpasu.app.tar.gz"), appPathList[0]);
fs.copyFileSync(join("macos/Clash Nyanpasu.app.tar.gz.sig"), appPathList[1]);
fs.copyFileSync(join("macos/Clash Verge.app.tar.gz"), appPathList[0]);
fs.copyFileSync(join("macos/Clash Verge.app.tar.gz.sig"), appPathList[1]);
const options = { owner: context.repo.owner, repo: context.repo.repo };
const github = getOctokit(process.env.GITHUB_TOKEN);
@@ -69,7 +69,7 @@ async function resolve() {
if (!release.id) throw new Error("failed to find the release");
await uploadAssets(release.id, [
join(`dmg/Clash Nyanpasu_${version}_aarch64.dmg`),
join(`dmg/Clash Verge_${version}_aarch64.dmg`),
...appPathList,
]);
}

View File

@@ -1,5 +1,6 @@
import fs from "fs-extra";
import zlib from "zlib";
import tar from "tar";
import path from "path";
import AdmZip from "adm-zip";
import fetch from "node-fetch";
@@ -14,11 +15,11 @@ const SIDECAR_HOST = execSync("rustc -vV")
.toString()
.match(/(?<=host: ).+(?=\s*)/g)[0];
/* ======= clash ======= */
/* ======= clash =======
const CLASH_STORAGE_PREFIX = "https://release.dreamacro.workers.dev/";
const CLASH_URL_PREFIX =
"https://github.com/Dreamacro/clash/releases/download/premium/";
const CLASH_LATEST_DATE = "2023.08.17";
const CLASH_LATEST_DATE = "latest";
const CLASH_BACKUP_URL_PREFIX =
"https://github.com/zhongfly/Clash-premium-backup/releases/download/";
@@ -34,31 +35,33 @@ const CLASH_MAP = {
"linux-x64": "clash-linux-amd64",
"linux-arm64": "clash-linux-arm64",
};
*/
/* ======= clash meta ======= */
const META_URL_PREFIX = `https://github.com/MetaCubeX/Clash.Meta/releases/download/`;
const META_VERSION = "v1.16.0";
const META_URL_PREFIX = `https://github.com/wonfen/Clash.Meta/releases/download/latest`;
// const META_VERSION = "2023.11.23";
const META_MAP = {
"win32-x64": "clash.meta-windows-amd64-compatible",
"win32-x64": "clash.meta-win-amd64",
"darwin-x64": "clash.meta-darwin-amd64",
"darwin-arm64": "clash.meta-darwin-arm64",
"linux-x64": "clash.meta-linux-amd64-compatible",
"linux-x64": "clash.meta-linux-amd64",
"linux-arm64": "clash.meta-linux-arm64",
};
/**
/*
* check available
*/
const { platform, arch } = process;
/*
if (!CLASH_MAP[`${platform}-${arch}`]) {
throw new Error(`clash unsupported platform "${platform}-${arch}"`);
}
*/
if (!META_MAP[`${platform}-${arch}`]) {
throw new Error(`clash meta unsupported platform "${platform}-${arch}"`);
}
/*
function clash() {
const name = CLASH_MAP[`${platform}-${arch}`];
@@ -112,14 +115,18 @@ function clashS3() {
downloadURL,
};
}
*/
function clashMeta() {
const name = META_MAP[`${platform}-${arch}`];
const isWin = platform === "win32";
const urlExt = isWin ? "zip" : "gz";
/* const urlExt = isWin ? "zip" : "gz";
const downloadURL = `${META_URL_PREFIX}${META_VERSION}/${name}-${META_VERSION}.${urlExt}`;
const exeFile = `${name}${isWin ? ".exe" : ""}`;
const zipFile = `${name}-${META_VERSION}.${urlExt}`;
const zipFile = `${name}-${META_VERSION}.${urlExt}`; */
const urlExt = isWin ? "zip" : "tgz";
const downloadURL = `${META_URL_PREFIX}/${name}.${urlExt}`;
const exeFile = isWin ? "虚空终端-win-amd64.exe" : name;
const zipFile = `${name}.${urlExt}`;
return {
name: "clash-meta",
@@ -160,6 +167,26 @@ async function resolveSidecar(binInfo) {
zip.extractAllTo(tempDir, true);
await fs.rename(tempExe, sidecarPath);
console.log(`[INFO]: "${name}" unzip finished`);
} else if (zipFile.endsWith(".tgz")) {
// tgz
await fs.mkdirp(tempDir);
await tar.extract({
cwd: tempDir,
file: tempZip,
//strip: 1, // 可能需要根据实际的 .tgz 文件结构调整
});
const files = await fs.readdir(tempDir);
console.log(`[DEBUG]: "${name}" files in tempDir:`, files);
const extractedFile = files.find((file) => file.startsWith("虚空终端-"));
if (extractedFile) {
const extractedFilePath = path.join(tempDir, extractedFile);
await fs.rename(extractedFilePath, sidecarPath);
console.log(`[INFO]: "${name}" file renamed to "${sidecarPath}"`);
execSync(`chmod 755 ${sidecarPath}`);
console.log(`[INFO]: "${name}" chmod binary finished`);
} else {
throw new Error(`Expected file not found in ${tempDir}`);
}
} else {
// gz
const readStream = fs.createReadStream(tempZip);
@@ -207,7 +234,7 @@ async function resolveClash() {
/**
* only Windows
* get the wintun.dll (not required)
*/
async function resolveWintun() {
const { platform } = process;
@@ -242,7 +269,7 @@ async function resolveWintun() {
console.log(`[INFO]: resolve wintun.dll finished`);
}
*/
/**
* download the file to the resources dir
*/
@@ -323,17 +350,28 @@ const resolveGeoIP = () =>
file: "geoip.dat",
downloadURL: `https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat`,
});
const resolveEnableLoopback = () =>
resolveResource({
file: "enableLoopback.exe",
downloadURL: `https://github.com/Kuingsmile/uwp-tool/releases/download/latest/enableLoopback.exe`,
});
const tasks = [
{ name: "clash", func: () => resolveSidecar(clashBackup()), retry: 5 },
// { name: "clash", func: resolveClash, retry: 5 },
{ name: "clash-meta", func: () => resolveSidecar(clashMeta()), retry: 5 },
{ name: "wintun", func: resolveWintun, retry: 5, winOnly: true },
// { name: "wintun", func: resolveWintun, retry: 5, winOnly: true },
{ name: "service", func: resolveService, retry: 5, winOnly: true },
{ name: "install", func: resolveInstall, retry: 5, winOnly: true },
{ name: "uninstall", func: resolveUninstall, retry: 5, winOnly: true },
{ name: "mmdb", func: resolveMmdb, retry: 5 },
{ name: "geosite", func: resolveGeosite, retry: 5 },
{ name: "geoip", func: resolveGeoIP, retry: 5 },
{
name: "enableLoopback",
func: resolveEnableLoopback,
retry: 5,
winOnly: true,
},
];
async function runTask() {

View File

@@ -17,8 +17,8 @@ async function resolvePortable() {
const zip = new AdmZip();
zip.addLocalFile(path.join(releaseDir, "Clash Nyanpasu.exe"));
zip.addLocalFile(path.join(releaseDir, "clash.exe"));
zip.addLocalFile(path.join(releaseDir, "Clash Verge.exe"));
// zip.addLocalFile(path.join(releaseDir, "clash.exe"));
zip.addLocalFile(path.join(releaseDir, "clash-meta.exe"));
zip.addLocalFolder(path.join(releaseDir, "resources"), "resources");
@@ -26,7 +26,7 @@ async function resolvePortable() {
const packageJson = require("../package.json");
const { version } = packageJson;
const zipFile = `Clash.Nyanpasu_${version}_x64_portable.zip`;
const zipFile = `Clash.Verge_${version}_x64_portable.zip`;
zip.writeZip(zipFile);
console.log("[INFO]: create portable zip successfully");

View File

@@ -46,7 +46,6 @@ async function resolveUpdater() {
"darwin-x86_64": { signature: "", url: "" },
"linux-x86_64": { signature: "", url: "" },
"windows-x86_64": { signature: "", url: "" },
"windows-i686": { signature: "", url: "" }, // no supported
},
};
@@ -120,7 +119,8 @@ async function resolveUpdater() {
Object.entries(updateDataNew.platforms).forEach(([key, value]) => {
if (value.url) {
updateDataNew.platforms[key].url = "https://ghproxy.com/" + value.url;
updateDataNew.platforms[key].url =
"https://mirror.ghproxy.com/" + value.url;
} else {
console.log(`[Error]: updateDataNew.platforms.${key} is null`);
}

2071
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
[package]
name = "clash-verge"
version = "0.1.0"
version = "1.4.1"
description = "clash verge"
authors = ["zzzgydi"]
license = "GPL-3.0"
repository = "https://github.com/keiko233/clash-nyanpasu.git"
repository = "https://github.com/wonfen/clash-verge-rev.git"
default-run = "clash-verge"
edition = "2021"
build = "build.rs"
@@ -44,7 +44,7 @@ wry = { version = "0.24.3" }
[target.'cfg(windows)'.dependencies]
runas = "1.1.0"
runas = "=1.0.0"
deelevate = "0.2.0"
winreg = { version = "0.50", features = ["transactions"] }
windows-sys = { version = "0.48", features = ["Win32_System_LibraryLoader", "Win32_System_SystemInformation"] }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -229,6 +229,29 @@ pub fn open_web_url(url: String) -> CmdResult<()> {
wrap_err!(open::that(url))
}
#[cfg(windows)]
pub mod uwp {
use super::*;
use crate::core::win_uwp;
#[tauri::command]
pub async fn invoke_uwp_tool() -> CmdResult {
wrap_err!(win_uwp::invoke_uwptools().await)
}
}
#[tauri::command]
pub async fn clash_api_get_proxy_delay(
name: String,
url: Option<String>,
) -> CmdResult<clash_api::DelayRes> {
match clash_api::get_proxy_delay(name, url).await {
Ok(res) => Ok(res),
Err(err) => Err(format!("{}", err.to_string())),
}
}
#[cfg(windows)]
pub mod service {
use super::*;
@@ -267,3 +290,13 @@ pub mod service {
Ok(())
}
}
#[cfg(not(windows))]
pub mod uwp {
use super::*;
#[tauri::command]
pub async fn invoke_uwp_tool() -> CmdResult {
Ok(())
}
}

View File

@@ -24,17 +24,29 @@ impl IClashTemp {
pub fn template() -> Self {
let mut map = Mapping::new();
map.insert("mixed-port".into(), 7890.into());
map.insert(
"mixed-port".into(),
match cfg!(feature = "default-meta") {
false => 7890.into(),
true => 7898.into(),
},
);
map.insert("log-level".into(), "info".into());
map.insert("allow-lan".into(), false.into());
map.insert("mode".into(), "rule".into());
map.insert("external-controller".into(), "127.0.0.1:9090".into());
map.insert(
"external-controller".into(),
match cfg!(feature = "default-meta") {
false => "127.0.0.1:9090".into(),
true => "127.0.0.1:9098".into(),
},
);
map.insert("secret".into(), "".into());
#[cfg(feature = "default-meta")]
map.insert("unified-delay".into(), true.into());
#[cfg(feature = "default-meta")]
map.insert("tcp-concurrent".into(), true.into());
map.insert("ipv6".into(), false.into());
// map.insert("ipv6".into(), false.into());
Self(map)
}
@@ -58,7 +70,7 @@ impl IClashTemp {
help::save_yaml(
&dirs::clash_path()?,
&self.0,
Some("# Generated by Clash Nyanpasu"),
Some("# Generated by Clash Verge"),
)
}

View File

@@ -45,7 +45,7 @@ impl Config {
Self::global().runtime_config.clone()
}
/// 初始化配置
/// 初始化订阅
pub fn init_config() -> Result<()> {
crate::log_err!(Self::generate());
if let Err(err) = Self::generate_file(ConfigType::Run) {
@@ -57,14 +57,14 @@ impl Config {
help::save_yaml(
&runtime_path,
&Config::clash().latest().0,
Some("# Clash Nyanpasu Runtime"),
Some("# Clash Verge Runtime"),
)?;
}
}
Ok(())
}
/// 将配置丢到对应的文件中
/// 将订阅丢到对应的文件中
pub fn generate_file(typ: ConfigType) -> Result<PathBuf> {
let path = match typ {
ConfigType::Run => dirs::app_home_dir()?.join(RUNTIME_CONFIG),
@@ -78,11 +78,11 @@ impl Config {
.as_ref()
.ok_or(anyhow!("failed to get runtime config"))?;
help::save_yaml(&path, &config, Some("# Generated by Clash Nyanpasu"))?;
help::save_yaml(&path, &config, Some("# Generated by Clash Verge"))?;
Ok(path)
}
/// 生成配置存好
/// 生成订阅存好
pub fn generate() -> Result<()> {
let (config, exists_keys, logs) = enhance::enhance();

View File

@@ -55,11 +55,7 @@ impl IProfiles {
pub fn template() -> Self {
Self {
valid: Some(vec![
"dns".into(),
"unified-delay".into(),
"tcp-concurrent".into(),
]),
valid: Some(vec!["dns".into(), "sub-rules".into(), "unified-delay".into(), "tcp-concurrent".into()]),
items: Some(vec![]),
..Self::default()
}
@@ -69,7 +65,7 @@ impl IProfiles {
help::save_yaml(
&dirs::profiles_path()?,
self,
Some("# Profiles Config for Clash Nyanpasu"),
Some("# Profiles Config for Clash Verge"),
)
}
@@ -265,7 +261,7 @@ impl IProfiles {
Ok(current == uid)
}
/// 获取current指向的配置内容
/// 获取current指向的订阅内容
pub fn current_mapping(&self) -> Result<Mapping> {
match (self.current.as_ref(), self.items.as_ref()) {
(Some(current), Some(items)) => {

View File

@@ -5,7 +5,7 @@ use std::collections::HashMap;
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct IRuntime {
pub config: Option<Mapping>,
// 记录在配置包括merge和script生成的出现过的keys
// 记录在订阅包括merge和script生成的出现过的keys
// 这些keys不一定都生效
pub exists_keys: Vec<String>,
pub chain_logs: HashMap<String, Vec<(String, String)>>,

View File

@@ -23,6 +23,9 @@ pub struct IVerge {
/// maybe be able to set the alpha
pub theme_blur: Option<bool>,
/// tray click event
pub tray_event: Option<String>,
/// enable traffic graph default is true
pub traffic_graph: Option<bool>,
@@ -83,6 +86,10 @@ pub struct IVerge {
/// proxy 页面布局 列数
pub proxy_layout_column: Option<i32>,
/// 日志清理
/// 0: 不清理; 1: 7天; 2: 30天; 3: 90天
pub auto_log_clean: Option<i32>,
/// window size and position
#[serde(skip_serializing_if = "Option::is_none")]
pub window_size_position: Option<Vec<f64>>,
@@ -137,13 +144,14 @@ impl IVerge {
auto_close_connection: Some(true),
enable_builtin_enhanced: Some(true),
enable_clash_fields: Some(true),
auto_log_clean: Some(3),
..Self::default()
}
}
/// Save IVerge App Config
pub fn save_file(&self) -> Result<()> {
help::save_yaml(&dirs::verge_path()?, &self, Some("# Clash Nyanpasu Config"))
help::save_yaml(&dirs::verge_path()?, &self, Some("# Clash Verge Config"))
}
/// patch verge config
@@ -161,6 +169,7 @@ impl IVerge {
patch!(language);
patch!(theme_mode);
patch!(theme_blur);
patch!(tray_event);
patch!(traffic_graph);
patch!(enable_memory_usage);
@@ -183,7 +192,7 @@ impl IVerge {
patch!(enable_builtin_enhanced);
patch!(proxy_layout_column);
patch!(enable_clash_fields);
patch!(auto_log_clean);
patch!(window_size_position);
}

View File

@@ -1,6 +1,7 @@
use crate::config::Config;
use anyhow::{bail, Result};
use reqwest::header::HeaderMap;
use serde::{Deserialize, Serialize};
use serde_yaml::Mapping;
use std::collections::HashMap;
@@ -36,6 +37,32 @@ pub async fn patch_configs(config: &Mapping) -> Result<()> {
Ok(())
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct DelayRes {
delay: u64,
}
/// GET /proxies/{name}/delay
/// 获取代理延迟
pub async fn get_proxy_delay(name: String, test_url: Option<String>) -> Result<DelayRes> {
let (url, headers) = clash_client_info()?;
let url = format!("{url}/proxies/{name}/delay");
let default_url = "http://1.1.1.1";
let test_url = test_url
.map(|s| if s.is_empty() { default_url.into() } else { s })
.unwrap_or(default_url.into());
let client = reqwest::ClientBuilder::new().no_proxy().build()?;
let builder = client
.get(&url)
.headers(headers)
.query(&[("timeout", "10000"), ("url", &test_url)]);
let response = builder.send().await?;
Ok(response.json::<DelayRes>().await?)
}
/// 根据clash info获取clash服务地址和请求头
fn clash_client_info() -> Result<(String, HeaderMap)> {
let client = { Config::clash().data().get_client_info() };

View File

@@ -51,7 +51,7 @@ impl CoreManager {
Ok(())
}
/// 检查配置是否正确
/// 检查订阅是否正确
pub fn check_config(&self) -> Result<()> {
let config_path = Config::generate_file(ConfigType::Check)?;
let config_path = dirs::path_to_str(&config_path)?;
@@ -267,7 +267,7 @@ impl CoreManager {
Config::verge().draft().clash_core = Some(clash_core);
// 更新配置
// 更新订阅
Config::generate()?;
self.check_config()?;
@@ -295,13 +295,13 @@ impl CoreManager {
pub async fn update_config(&self) -> Result<()> {
log::debug!(target: "app", "try to update clash config");
// 更新配置
// 更新订阅
Config::generate()?;
// 检查配置是否正常
// 检查订阅是否正常
self.check_config()?;
// 更新运行时配置
// 更新运行时订阅
let path = Config::generate_file(ConfigType::Run)?;
let path = dirs::path_to_str(&path)?;

View File

@@ -13,7 +13,7 @@ pub fn grant_permission(core: String) -> anyhow::Result<()> {
#[cfg(target_os = "macos")]
let output = {
// the path of clash /Applications/Clash Nyanpasu.app/Contents/MacOS/clash
// the path of clash /Applications/Clash Verge.app/Contents/MacOS/clash
// https://apple.stackexchange.com/questions/82967/problem-with-empty-spaces-when-executing-shell-commands-in-applescript
// let path = escape(&path);
let path = path.replace(' ', "\\\\ ");

View File

@@ -8,5 +8,6 @@ pub mod sysopt;
pub mod timer;
pub mod tray;
pub mod win_service;
pub mod win_uwp;
pub use self::core::*;

View File

@@ -158,7 +158,7 @@ impl Sysopt {
#[cfg(target_os = "windows")]
let app_path = format!("\"{app_path}\"");
// use the /Applications/Clash Nyanpasu.app path
// use the /Applications/Clash Verge.app path
#[cfg(target_os = "macos")]
let app_path = (|| -> Option<String> {
let path = std::path::PathBuf::from(&app_path);

View File

@@ -107,6 +107,20 @@ impl Tray {
}
pub fn update_part(app_handle: &AppHandle) -> Result<()> {
let zh = { Config::verge().latest().language == Some("zh".into()) };
let version = app_handle.package_info().version.to_string();
macro_rules! t {
($en: expr, $zh: expr) => {
if zh {
$zh
} else {
$en
}
};
}
let mode = {
Config::clash()
.latest()
@@ -143,11 +157,39 @@ impl Tray {
let _ = tray.get_item("system_proxy").set_selected(*system_proxy);
let _ = tray.get_item("tun_mode").set_selected(*tun_mode);
let switch_map = {
let mut map = std::collections::HashMap::new();
map.insert(true, "on");
map.insert(false, "off");
map
};
#[cfg(not(target_os = "linux"))]
let _ = tray.set_tooltip(&format!(
"Clash Verge {version}\n{}: {}\n{}: {}",
t!("System Proxy", "系统代理"),
switch_map[system_proxy],
t!("TUN Mode", "Tun 模式"),
switch_map[tun_mode]
));
Ok(())
}
pub fn on_left_click(app_handle: &AppHandle) {
let tray_event = { Config::verge().latest().tray_event.clone() };
let tray_event = tray_event.unwrap_or("main_window".into());
match tray_event.as_str() {
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(),
_ => resolve::create_window(app_handle),
}
}
pub fn on_system_tray_event(app_handle: &AppHandle, event: SystemTrayEvent) {
match event {
#[cfg(not(target_os = "linux"))]
SystemTrayEvent::LeftClick { .. } => Tray::on_left_click(app_handle),
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
mode @ ("rule_mode" | "global_mode" | "direct_mode" | "script_mode") => {
let mode = &mode[0..mode.len() - 5];
@@ -177,10 +219,6 @@ impl Tray {
}
_ => {}
},
#[cfg(target_os = "windows")]
SystemTrayEvent::LeftClick { .. } => {
resolve::create_window(app_handle);
}
_ => {}
}
}

View File

@@ -30,7 +30,7 @@ pub struct JsonResponse {
pub data: Option<ResponseBody>,
}
/// Install the Clash Nyanpasu Service
/// Install the Clash Verge Service
/// 该函数应该在协程或者线程中执行避免UAC弹窗阻塞主线程
pub async fn install_service() -> Result<()> {
let binary_path = dirs::service_path()?;
@@ -60,7 +60,7 @@ pub async fn install_service() -> Result<()> {
Ok(())
}
/// Uninstall the Clash Nyanpasu Service
/// Uninstall the Clash Verge Service
/// 该函数应该在协程或者线程中执行避免UAC弹窗阻塞主线程
pub async fn uninstall_service() -> Result<()> {
let binary_path = dirs::service_path()?;
@@ -99,10 +99,10 @@ pub async fn check_service() -> Result<JsonResponse> {
.get(url)
.send()
.await
.context("failed to connect to the Clash Nyanpasu Service")?
.context("failed to connect to the Clash Verge Service")?
.json::<JsonResponse>()
.await
.context("failed to parse the Clash Nyanpasu Service response")?;
.context("failed to parse the Clash Verge Service response")?;
Ok(response)
}
@@ -148,7 +148,7 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
.await?
.json::<JsonResponse>()
.await
.context("failed to connect to the Clash Nyanpasu Service")?;
.context("failed to connect to the Clash Verge Service")?;
if res.code != 0 {
bail!(res.msg);
@@ -168,7 +168,7 @@ pub(super) async fn stop_core_by_service() -> Result<()> {
.await?
.json::<JsonResponse>()
.await
.context("failed to connect to the Clash Nyanpasu Service")?;
.context("failed to connect to the Clash Verge Service")?;
if res.code != 0 {
bail!(res.msg);

View File

@@ -0,0 +1,27 @@
#![cfg(target_os = "windows")]
use crate::utils::dirs;
use anyhow::{bail, Result};
use deelevate::{PrivilegeLevel, Token};
use runas::Command as RunasCommand;
use std::process::Command as StdCommand;
pub async fn invoke_uwptools() -> Result<()> {
let binary_path = dirs::service_path()?;
let tool_path = binary_path.with_file_name("enableLoopback.exe");
if !tool_path.exists() {
bail!("enableLoopback exe not found");
}
let token = Token::with_current_process()?;
let level = token.privilege_level()?;
match level {
PrivilegeLevel::NotPrivileged => RunasCommand::new(tool_path).status()?,
_ => StdCommand::new(tool_path)
.status()?,
};
Ok(())
}

View File

@@ -18,9 +18,9 @@ use std::collections::HashSet;
type ResultLog = Vec<(String, String)>;
/// Enhance mode
/// 返回最终配置、该配置包含的键、和script执行的结果
/// 返回最终订阅、该订阅包含的键、和script执行的结果
pub fn enhance() -> (Mapping, Vec<String>, HashMap<String, ResultLog>) {
// config.yaml 的配置
// config.yaml 的订阅
let clash_config = { Config::clash().latest().0.clone() };
let (clash_core, enable_tun, enable_builtin, enable_filter) = {

View File

@@ -47,7 +47,7 @@ pub fn change_clash_mode(mode: String) {
match clash_api::patch_configs(&mapping).await {
Ok(_) => {
// 更新配置
// 更新订阅
Config::clash().data().patch_config(mapping);
if Config::clash().data().save_config().is_ok() {
@@ -156,7 +156,7 @@ pub fn disable_tun_mode() {
});
}
/// 修改clash的配置
/// 修改clash的订阅
pub async fn patch_clash(patch: Mapping) -> Result<()> {
Config::clash().draft().patch_config(patch.clone());
@@ -175,7 +175,7 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
}
};
// 激活配置
// 激活订阅
if mixed_port.is_some()
|| patch.get("secret").is_some()
|| patch.get("external-controller").is_some()
@@ -210,7 +210,7 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
}
}
/// 修改verge的配置
/// 修改verge的订阅
/// 一般都是一个个的修改
pub async fn patch_verge(patch: IVerge) -> Result<()> {
Config::verge().draft().patch_config(patch.clone());
@@ -278,7 +278,7 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
}
/// 更新某个profile
/// 如果更新当前配置就激活配置
/// 如果更新当前订阅就激活订阅
pub async fn update_profile(uid: String, option: Option<PrfOption>) -> Result<()> {
let url_opt = {
let profiles = Config::profiles();
@@ -316,7 +316,7 @@ pub async fn update_profile(uid: String, option: Option<PrfOption>) -> Result<()
Ok(())
}
/// 更新配置
/// 更新订阅
async fn update_core_config() -> Result<()> {
match CoreManager::global().update_config().await {
Ok(_) => {

View File

@@ -46,6 +46,7 @@ fn main() -> std::io::Result<()> {
cmds::get_runtime_yaml,
cmds::get_runtime_exists,
cmds::get_runtime_logs,
cmds::uwp::invoke_uwp_tool,
// verge
cmds::get_verge_config,
cmds::patch_verge_config,
@@ -66,6 +67,8 @@ fn main() -> std::io::Result<()> {
cmds::service::check_service,
cmds::service::install_service,
cmds::service::uninstall_service,
// clash api
cmds::clash_api_get_proxy_delay
]);
#[cfg(target_os = "macos")]

View File

@@ -1,13 +1,14 @@
use crate::config::*;
use crate::utils::{dirs, help};
use anyhow::Result;
use chrono::Local;
use chrono::{Local, TimeZone};
use log::LevelFilter;
use log4rs::append::console::ConsoleAppender;
use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Logger, Root};
use log4rs::encode::pattern::PatternEncoder;
use std::fs;
use std::fs::{self, DirEntry};
use std::str::FromStr;
use tauri::PackageInfo;
/// initialize this instance's log file
@@ -69,6 +70,72 @@ fn init_log() -> Result<()> {
Ok(())
}
/// 删除log文件
pub fn delete_log() -> Result<()> {
let log_dir = dirs::app_logs_dir()?;
if !log_dir.exists() {
return Ok(());
}
let auto_log_clean = {
let verge = Config::verge();
let verge = verge.data();
verge.auto_log_clean.clone().unwrap_or(0)
};
let day = match auto_log_clean {
1 => 7,
2 => 30,
3 => 90,
_ => return Ok(()),
};
log::debug!(target: "app", "try to delete log files, day: {day}");
// %Y-%m-%d to NaiveDateTime
let parse_time_str = |s: &str| {
let sa: Vec<&str> = s.split('-').collect();
if sa.len() != 4 {
return Err(anyhow::anyhow!("invalid time str"));
}
let year = i32::from_str(sa[0])?;
let month = u32::from_str(sa[1])?;
let day = u32::from_str(sa[2])?;
let time = chrono::NaiveDate::from_ymd_opt(year, month, day)
.ok_or(anyhow::anyhow!("invalid time str"))?
.and_hms_opt(0, 0, 0)
.ok_or(anyhow::anyhow!("invalid time str"))?;
Ok(time)
};
let process_file = |file: DirEntry| -> Result<()> {
let file_name = file.file_name();
let file_name = file_name.to_str().unwrap_or_default();
if file_name.ends_with(".log") {
let now = Local::now();
let created_time = parse_time_str(&file_name[0..file_name.len() - 4])?;
let file_time = Local.from_local_datetime(&created_time).single().ok_or(anyhow::anyhow!("invalid local datetime"))?;
let duration = now.signed_duration_since(file_time);
if duration.num_days() > day {
let file_path = file.path();
let _ = fs::remove_file(file_path);
log::info!(target: "app", "delete log file: {file_name}");
}
}
Ok(())
};
for file in fs::read_dir(&log_dir)? {
if let Ok(file) = file {
let _ = process_file(file);
}
}
Ok(())
}
/// Initialize all the config files
/// before tauri setup
pub fn init_config() -> Result<()> {
@@ -78,6 +145,7 @@ pub fn init_config() -> Result<()> {
}
let _ = init_log();
let _ = delete_log();
crate::log_err!(dirs::app_home_dir().map(|app_dir| {
if !app_dir.exists() {
@@ -93,21 +161,21 @@ pub fn init_config() -> Result<()> {
crate::log_err!(dirs::clash_path().map(|path| {
if !path.exists() {
help::save_yaml(&path, &IClashTemp::template().0, Some("# Clash Nyanpasuasu"))?;
help::save_yaml(&path, &IClashTemp::template().0, Some("# Clash Vergeasu"))?;
}
<Result<()>>::Ok(())
}));
crate::log_err!(dirs::verge_path().map(|path| {
if !path.exists() {
help::save_yaml(&path, &IVerge::template(), Some("# Clash Nyanpasu"))?;
help::save_yaml(&path, &IVerge::template(), Some("# Clash Verge"))?;
}
<Result<()>>::Ok(())
}));
crate::log_err!(dirs::profiles_path().map(|path| {
if !path.exists() {
help::save_yaml(&path, &IProfiles::template(), Some("# Clash Nyanpasu"))?;
help::save_yaml(&path, &IProfiles::template(), Some("# Clash Verge"))?;
}
<Result<()>>::Ok(())
}));
@@ -129,7 +197,7 @@ pub fn init_resources(package_info: &PackageInfo) -> Result<()> {
}
#[cfg(target_os = "windows")]
let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat", "wintun.dll"];
let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];
#[cfg(not(target_os = "windows"))]
let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];

View File

@@ -59,7 +59,7 @@ pub fn create_window(app_handle: &AppHandle) {
"main".to_string(),
tauri::WindowUrl::App("index.html".into()),
)
.title("Clash Nyanpasu")
.title("Clash Verge")
.fullscreen(false)
.min_inner_size(600.0, 520.0);

View File

@@ -1,7 +1,7 @@
{
"package": {
"productName": "Clash Nyanpasu",
"version": "1.4.0"
"productName": "Clash Verge",
"version": "1.4.1"
},
"build": {
"distDir": "../dist",
@@ -17,7 +17,7 @@
"bundle": {
"active": true,
"targets": "all",
"identifier": "moe.elaina.clash.nyanpasu",
"identifier": "moe.elaina.clash.verge",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
@@ -26,7 +26,7 @@
"icons/icon.ico"
],
"resources": ["resources"],
"externalBin": ["sidecar/clash", "sidecar/clash-meta"],
"externalBin": ["sidecar/clash-meta"],
"copyright": "© 2022 zzzgydi All Rights Reserved",
"category": "DeveloperTool",
"shortDescription": "A Clash GUI based on tauri.",
@@ -53,11 +53,11 @@
"updater": {
"active": true,
"endpoints": [
"https://ghproxy.com/https://github.com/keiko233/clash-nyanpasu/releases/download/updater/update-proxy.json",
"https://github.com/keiko233/clash-nyanpasu/releases/download/updater/update.json"
"https://mirror.ghproxy.com/https://github.com/wonfen/clash-verge-rev/releases/download/updater/update-proxy.json",
"https://github.com/wonfen/clash-verge-rev/releases/download/updater/update.json"
],
"dialog": false,
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDlBMUM0NjMxREZCNDRGMjYKUldRbVQ3VGZNVVljbW43N0FlWjA4UkNrbTgxSWxSSXJQcExXNkZjUTlTQkIyYkJzL0tsSWF2d0cK"
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
},
"allowlist": {
"shell": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -1,36 +1,18 @@
<!--
Copyright (C) 2022 The Project Nyanpasu
SPDX-License-Identifier: Apache-2.0
thanks: @ReallySnow
-->
<svg width="420px" height="490px" viewBox="0 0 420 490" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400"
height="400" viewBox="0, 0, 400,400">
<defs>
<style><![CDATA[
#element {
fill: #000000;
}
]]></style>
<linearGradient id="Gradient2" x1="0" x2="-0.1" y1="0" y2="1">
<stop offset="0%" stop-color="#5b5c9d" />
<stop offset="80%" stop-color="rgb(63, 64, 109)" />
<stop offset="100%" stop-color="rgb(63, 64, 109)" />
</linearGradient>
</defs>
<g id="nyanpasu_logo" fill-rule="nonzero">
<path
d="M349.980734,470.820835 C362.906597,470.820835 375.380055,471.040616 387.808272,470.736801 C394.678368,470.562269 398.898662,465.526692 400.333433,457.394784 C402.20122,446.832354 400.417451,436.780592 395.809381,427.284747 C390.832924,417.03906 385.255414,407.090725 380.233716,396.903216 C360.528238,356.825451 356.463054,315.532425 371.896535,273.134028 C376.646789,260.076434 384.111475,248.479739 394.781775,239.255389 C400.869857,233.993566 405.684741,233.870747 409.911498,238.718864 C414.138255,243.56698 413.285148,248.415097 407.500824,253.663991 C390.535629,269.081003 384.285974,289.34613 382.230762,311.27901 C379.516331,340.367711 385.669042,367.633519 399.499715,393.373787 C407.100123,407.523823 416.070671,421.169656 418.88851,437.433471 C420.614112,447.317165 420.484854,457.129754 417.402035,466.787202 C412.613003,481.764651 401.244707,490.012913 385.513931,490 C273.567341,489.896558 161.622905,489.814679 49.6806226,489.754347 C42.5713979,489.754347 35.4621733,489.993521 28.605003,487.73753 C11.4136053,482.081394 -0.0322464095,467.259085 0,448.855634 C0.103475152,390.930336 0.374918274,333.011502 3.10227536,275.124988 C4.89250738,237.057576 7.30964376,199.054805 11.2067914,161.148996 C16.3771366,110.612228 23.6608604,60.405131 34.5315112,10.7604159 C35.0024707,8.67513302 35.7547542,6.66358964 36.7676855,4.78107191 C38.5191399,1.50374502 41.1689418,-0.513071536 45.1694964,0.113951558 C49.170051,0.740974653 49.3768648,4.11526388 49.9326769,6.9530282 C53.9913979,27.6706469 60.3056819,47.7612426 66.8590945,67.7742684 C68.9853989,74.238424 70.1875042,82.4543658 74.7891114,86.326395 C79.26146,90.0949977 87.6051045,87.3541957 94.2425352,87.3735882 C154.302557,87.5028713 214.369043,86.8176708 274.422602,88.3755323 C279.256875,88.4983513 281.615845,87.0827012 283.509484,82.6353621 C293.203881,59.8750702 301.967616,36.8044988 308.495177,12.925908 C309.309506,9.94593225 309.942874,6.778496 313.710763,6.46175237 C317.129653,6.17732953 319.346439,8.49796139 320.858765,11.1547293 C321.981523,13.2263513 322.777248,15.4591645 323.217735,17.7740247 C332.832735,64.3247661 340.022746,111.343788 344.758685,158.640904 C354.220417,251.724745 355.745669,345.112401 356.152834,438.538842 C356.152834,444.123872 356.217463,449.695975 355.370819,455.274541 C354.569415,460.646254 352.048872,465.38448 349.980734,470.820835 Z"
id="element" fill-rule="evenodd"></path>
<path
d="M314.373914,51.8580359 C319.16418,79.1645649 322.474053,106.509891 325.189183,133.926344 C335.474355,237.585109 337,341.580114 337,445.633314 C337,462.193111 328.052999,470.974135 311.283837,470.980602 C222.356854,471.006466 133.429871,471.006466 44.5028879,470.980602 C27.8242301,470.980602 18.9741981,462.050856 19,445.491059 C19.0776317,397.460537 19.1422776,349.423548 20.816608,301.425356 C22.7559868,246.3726 25.665055,191.384506 31.4637977,136.538667 C34.2500385,110.221458 37.8831415,84.0335719 41.044329,57.7745583 C41.348165,55.2398296 42.0398768,52.7503639 42.8026991,49 C47.5541772,66.3034032 53.702008,81.848015 58.6926762,97.7676631 C60.6902363,104.123883 64.0001095,106.632747 70.7620769,106.632747 C141.816607,106.58964 212.868982,106.72974 283.919202,107.053047 C290.11875,107.053047 293.415694,104.679972 295.555475,99.1643504 C301.63866,83.3804912 308.652746,67.9328716 314.373914,51.8580359 Z"
id="bg" fill="#ffffff" fill-rule="evenodd"></path>
<path
d="M119.999315,204.118735 C120.083729,213.985193 112.350174,222.057169 102.850433,222 C94.0584657,221.961379 86.9547636,214.451375 87,205.249067 C87.0456702,196.148935 94.5909186,188.268541 103.493273,188.006712 C112.395627,187.744884 119.921396,195.178255 119.999315,204.118735 Z"
id="element" fill-rule="evenodd"></path>
<path
d="M236,204.861743 C236,195.671258 243.035135,188.142475 251.816026,188.001869 C261.124552,187.861264 268.993481,195.671258 269,205.104607 C269.006509,214.537955 262.179823,221.772746 253.255623,221.996436 C244.16206,222.194562 236.026056,214.103357 236,204.861743 Z"
id="element" fill-rule="evenodd"></path>
<path
d="M190.493614,267.920884 C185.555364,268.142338 181.468093,262.430145 177.097162,262.137045 C172.945422,261.850458 168.716321,267.914371 162.875519,267.999044 C153.295574,268.096744 144.921179,260.691085 144.089542,251.064378 C143.851011,248.296212 143.844564,245.541072 147.312943,245.059085 C150.362279,244.622692 151.0263,246.902358 151.638746,249.481638 C153.327808,256.646305 157.286143,260.411011 162.701456,259.935538 C168.890385,259.394931 172.371657,255.649765 173.087252,249.468612 C173.383805,247.045652 174.234782,245.104678 176.819949,245.026518 C179.869286,244.935332 180.481732,247.208485 180.855647,249.813818 C181.751752,255.988458 185.426428,259.870405 191.570229,259.889945 C197.71403,259.909485 201.433834,255.981945 202.342833,249.872438 C202.774769,246.954465 203.516151,244.433805 206.907168,245.111192 C210.130569,245.762525 210.195037,248.634905 209.872697,251.383532 C208.750953,260.769245 200.621538,268.044638 190.493614,267.920884 Z"
id="element" fill-rule="evenodd"></path>
<g id="svgg">
<path id="path0"
d="M118.124 39.858 C 116.645 40.182,114.562 42.930,113.283 46.247 C 111.908 49.812,110.887 54.542,107.205 74.400 C 106.736 76.930,105.926 81.160,105.404 83.800 C 104.527 88.237,103.654 92.889,102.177 101.000 C 101.856 102.760,101.413 105.100,101.192 106.200 C 100.754 108.375,100.784 108.199,98.436 122.200 C 96.675 132.702,95.947 137.215,94.984 143.600 C 94.636 145.910,94.098 149.420,93.789 151.400 C 92.649 158.697,91.961 164.413,92.180 164.768 C 92.304 164.968,92.223 165.192,92.000 165.266 C 91.777 165.340,96.852 165.347,103.277 165.282 C 116.520 165.149,115.721 165.379,116.358 161.519 C 122.839 122.279,179.334 121.580,186.617 160.650 C 186.981 162.602,187.463 164.425,187.689 164.700 C 188.328 165.481,229.717 165.423,230.367 164.640 C 230.622 164.332,231.013 162.937,231.235 161.540 C 237.531 121.949,295.239 121.807,301.620 161.367 C 302.274 165.421,301.855 165.252,310.962 165.117 C 315.273 165.052,318.861 165.090,318.935 165.200 C 319.009 165.310,319.005 165.152,318.927 164.848 C 318.849 164.545,318.519 162.610,318.193 160.548 C 317.867 158.487,317.330 155.135,317.000 153.100 C 316.162 147.934,315.312 142.663,314.823 139.600 C 314.595 138.170,314.226 136.010,314.004 134.800 C 313.781 133.590,312.423 125.400,310.985 116.600 C 304.278 75.545,304.008 74.156,298.145 50.400 C 295.961 41.553,294.621 39.584,290.800 39.611 C 287.927 39.631,283.053 43.395,279.420 48.400 C 277.509 51.032,261.566 79.109,256.960 87.953 C 253.991 93.654,253.647 93.789,245.600 92.402 C 218.757 87.774,194.454 87.780,170.478 92.420 C 162.868 93.893,163.987 94.596,157.579 84.306 C 133.879 46.247,126.566 38.009,118.124 39.858 M147.277 134.807 C 123.365 138.118,111.083 165.918,124.948 185.349 C 140.543 207.202,173.704 202.274,182.466 176.800 C 190.000 154.900,170.471 131.596,147.277 134.807 M262.051 134.810 C 235.780 138.440,224.730 170.720,243.356 189.422 C 264.398 210.548,299.874 195.275,298.689 165.600 C 297.927 146.523,280.892 132.207,262.051 134.810 M157.600 153.840 C 163.092 156.341,166.343 161.914,165.902 168.074 C 164.875 182.425,145.082 186.221,138.715 173.287 C 132.759 161.189,145.324 148.250,157.600 153.840 M273.193 153.597 C 279.788 156.926,283.287 165.159,280.844 171.600 C 275.229 186.406,253.594 183.910,252.135 168.287 C 251.125 157.467,263.609 148.758,273.193 153.597 M91.200 168.809 C 91.200 169.522,90.939 171.836,90.621 173.952 C 89.933 178.523,87.567 196.170,85.788 210.000 C 85.462 212.530,85.012 215.860,84.786 217.400 C 84.561 218.940,84.191 221.820,83.964 223.800 C 83.737 225.780,83.288 229.560,82.965 232.200 C 81.886 241.026,80.172 255.664,79.404 262.600 C 78.867 267.450,78.532 270.381,76.987 283.800 C 76.251 290.187,75.405 297.881,74.568 305.800 C 74.220 309.100,73.789 313.150,73.613 314.800 C 73.436 316.450,73.063 320.230,72.784 323.200 C 72.504 326.170,72.169 328.723,72.038 328.874 C 71.701 329.262,59.638 327.033,54.028 325.546 C 34.668 320.412,26.096 301.951,35.625 285.911 C 38.026 281.869,41.515 278.587,49.795 272.581 C 58.081 266.570,59.262 265.247,59.510 261.702 C 59.969 255.136,50.677 252.070,40.551 255.447 C -6.127 271.014,-3.894 337.227,43.806 351.951 C 50.541 354.030,58.050 355.239,67.760 355.807 C 72.410 356.079,75.202 356.542,82.181 358.199 C 88.822 359.777,100.215 360.425,156.000 362.398 C 170.725 362.918,255.192 362.921,267.760 362.401 C 273.062 362.182,281.900 361.820,287.400 361.597 C 302.851 360.972,326.558 359.339,333.200 358.444 C 343.055 357.116,343.889 354.966,341.839 336.200 C 341.502 333.120,340.948 327.900,340.607 324.600 C 340.266 321.300,339.709 315.990,339.370 312.800 C 339.030 309.610,338.499 304.570,338.189 301.600 C 337.022 290.393,335.650 278.160,334.622 269.800 C 333.105 257.460,332.638 254.027,330.408 238.800 C 329.716 234.070,328.983 229.030,328.781 227.600 C 328.579 226.170,328.231 223.920,328.008 222.600 C 327.785 221.280,326.695 214.260,325.587 207.000 C 324.478 199.740,323.124 191.010,322.578 187.600 C 322.032 184.190,321.325 179.780,321.007 177.800 C 320.689 175.820,320.203 172.711,319.925 170.892 C 319.508 168.155,319.315 167.635,318.810 167.885 C 318.475 168.051,314.780 168.279,310.600 168.393 C 301.870 168.631,302.159 168.535,301.810 171.300 C 299.468 189.825,283.036 203.371,264.230 202.279 C 247.552 201.310,233.532 188.465,231.203 172.020 C 230.651 168.125,232.337 168.400,209.000 168.400 C 185.703 168.400,187.432 168.114,186.814 172.064 C 180.639 211.474,123.556 212.329,116.559 173.117 C 115.684 168.218,116.787 168.629,103.881 168.400 C 97.676 168.290,92.285 168.046,91.900 167.857 C 91.307 167.567,91.200 167.712,91.200 168.809 M211.015 197.632 C 214.247 200.942,215.394 201.357,220.447 201.050 C 225.236 200.759,225.846 201.071,224.310 203.023 C 221.899 206.089,216.333 205.843,210.779 202.425 C 208.312 200.907,207.846 200.906,205.600 202.405 C 200.180 206.022,193.561 206.136,191.600 202.647 C 190.824 201.267,191.555 200.665,193.600 201.001 C 199.643 201.993,201.561 201.450,204.900 197.805 C 207.534 194.929,208.352 194.906,211.015 197.632 "
stroke="none" fill="url(#Gradient2)" fill-rule="evenodd"></path>
<path id="path1"
d="M148.000 131.622 C 132.020 133.140,119.114 145.293,116.377 161.400 C 115.675 165.535,116.697 165.239,103.579 165.112 C 97.252 165.050,92.159 165.135,92.261 165.300 C 92.364 165.465,92.279 165.600,92.074 165.600 C 91.391 165.600,91.684 167.617,92.424 168.013 C 92.839 168.235,97.730 168.400,103.897 168.400 C 116.551 168.400,115.666 168.070,116.562 173.117 C 123.522 212.326,180.639 211.470,186.814 172.064 C 187.432 168.114,185.703 168.400,209.000 168.400 C 232.337 168.400,230.651 168.125,231.203 172.020 C 233.532 188.465,247.552 201.310,264.230 202.279 C 283.039 203.371,299.468 189.826,301.811 171.294 C 302.169 168.458,302.345 168.400,310.600 168.400 C 318.988 168.400,319.609 168.159,318.852 165.200 C 318.824 165.090,315.273 165.052,310.961 165.117 C 301.855 165.252,302.274 165.421,301.620 161.367 C 295.239 121.807,237.531 121.949,231.235 161.540 C 231.013 162.937,230.622 164.332,230.367 164.640 C 229.717 165.423,188.328 165.481,187.689 164.700 C 187.463 164.425,186.981 162.602,186.617 160.650 C 183.194 142.288,166.648 129.850,148.000 131.622 M159.886 135.622 C 183.880 141.759,192.035 172.033,174.435 189.636 C 156.404 207.671,125.892 198.962,119.944 174.084 C 114.368 150.761,136.343 129.601,159.886 135.622 M274.658 135.615 C 299.082 141.861,307.061 172.817,288.734 190.222 C 267.975 209.936,234.188 195.420,234.219 166.800 C 234.241 145.502,253.935 130.315,274.658 135.615 M148.542 152.793 C 139.499 154.706,134.598 164.925,138.715 173.287 C 145.082 186.221,164.875 182.425,165.902 168.074 C 166.591 158.446,157.916 150.811,148.542 152.793 M262.091 153.188 C 253.922 156.127,249.883 165.408,253.408 173.139 C 257.835 182.850,271.593 184.491,278.201 176.097 C 287.389 164.426,275.974 148.192,262.091 153.188 M204.900 197.805 C 201.561 201.450,199.643 201.993,193.600 201.001 C 191.555 200.665,190.824 201.267,191.600 202.647 C 193.561 206.136,200.180 206.022,205.600 202.405 C 207.846 200.906,208.312 200.907,210.779 202.425 C 216.333 205.843,221.899 206.089,224.310 203.023 C 225.846 201.071,225.236 200.759,220.447 201.050 C 215.394 201.357,214.247 200.942,211.015 197.632 C 208.352 194.906,207.534 194.929,204.900 197.805 "
stroke="none" fill="#ffffff" fill-rule="evenodd"></path>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -5,12 +5,12 @@
overflow: hidden;
&__left {
flex: 1 0 25%;
flex: 1 0 15%;
display: flex;
height: 100%;
max-width: 225px;
min-width: 125px;
padding: 36px 0 28px;
padding: 16px 0 8px;
position: relative;
flex-direction: column;
box-sizing: border-box;
@@ -90,8 +90,8 @@
position: absolute;
top: 0;
left: 0;
right: 28px;
bottom: 28px;
right: 2px;
bottom: 0px;
}
}
}

View File

@@ -9,7 +9,7 @@
width: 100%;
// max-width: 850px;
margin: 0 auto;
padding-right: 4px;
padding-right: 8px;
box-sizing: border-box;
display: flex;
align-items: center;
@@ -27,28 +27,15 @@
width: 100%;
height: 100%;
overflow: auto;
padding: 28px 0;
padding: 5px 5px;
box-sizing: border-box;
scrollbar-gutter: stable;
background-color: var(--background-color);
.base-content {
width: 90%;
width: 100%;
// max-width: 850px;
margin: 0 auto;
animation: baseContentIn 0.3s normal 1 forwards;
@keyframes baseContentIn {
0% {
opacity: 0;
transform: translateY(50%) scale(0.9);
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
}
}
}
}
}

View File

@@ -58,7 +58,7 @@ export const ConnectionItem = (props: Props) => {
{!!metadata.process && <Tag>{metadata.process}</Tag>}
{chains.length > 0 && <Tag>{chains[value.chains.length - 1]}</Tag>}
{chains?.length > 0 && <Tag>{chains[value.chains.length - 1]}</Tag>}
<Tag>{dayjs(start).fromNow()}</Tag>

View File

@@ -10,20 +10,24 @@ export const LayoutItem = (props: LinkProps) => {
const navigate = useNavigate();
return (
<ListItem sx={{ py: 0.5, maxWidth: 250, mx: "auto" }}>
<ListItem
sx={{ py: 0.5, maxWidth: 250, mx: "auto", padding: "4px 0px 4px 2px" }}
>
<ListItemButton
selected={!!match}
sx={[
{
borderRadius: 8,
borderTopLeftRadius: 18,
borderBottomLeftRadius: 18,
textAlign: "center",
"& .MuiListItemText-primary": { color: "text.secondary" },
},
({ palette: { mode, primary } }) => {
const bgcolor =
/* const bgcolor =
mode === "light"
? alpha(primary.main, 0.15)
: alpha(primary.main, 0.35);
: alpha(primary.main, 0.35); */
const bgcolor = mode === "light" ? "#ffffff" : "#0E1621";
const color = mode === "light" ? primary.main : primary.light;
return {

View File

@@ -84,7 +84,7 @@ export const useCustomTheme = () => {
}
// css
const backgroundColor = mode === "light" ? "#ffffff" : "#121212";
const backgroundColor = mode === "light" ? "#ffffff" : "#0E1621";
const selectColor = mode === "light" ? "#f5f5f5" : "#d5d5d5";
const scrollColor = mode === "light" ? "#90939980" : "#54545480";

View File

@@ -74,11 +74,11 @@ export const EditorViewer = (props: Props) => {
});
return (
<Dialog open={open} onClose={onClose}>
<Dialog open={open} onClose={onClose} maxWidth="xl" fullWidth>
<DialogTitle>{t("Edit File")}</DialogTitle>
<DialogContent sx={{ width: 520, pb: 1, userSelect: "text" }}>
<div style={{ width: "100%", height: "420px" }} ref={editorRef} />
<DialogContent sx={{ width: "95%", pb: 1, userSelect: "text" }}>
<div style={{ width: "100%", height: "500px" }} ref={editorRef} />
</DialogContent>
<DialogActions>

View File

@@ -112,8 +112,8 @@ export const ProfileItem = (props: Props) => {
});
/// 0 不使用任何代理
/// 1 使用配置好的代理
/// 2 至少使用一个代理,根据配置,如果没配置,默认使用系统代理
/// 1 使用订阅好的代理
/// 2 至少使用一个代理,根据订阅,如果没订阅,默认使用系统代理
const onUpdate = useLockFn(async (type: 0 | 1 | 2) => {
setAnchorEl(null);
setLoadingCache((cache) => ({ ...cache, [itemData.uid]: true }));

View File

@@ -137,20 +137,14 @@ export const ProxyItemMini = (props: Props) => {
e.stopPropagation();
onDelay();
}}
color={
delay > 500
? "error.main"
: delay < 100
? "success.main"
: "text.secondary"
}
color={delayManager.formatDelayColor(delay)}
sx={({ palette }) =>
!proxy.provider
? { ":hover": { bgcolor: alpha(palette.primary.main, 0.15) } }
: {}
}
>
{delay > 1e5 ? "Error" : delay > 3000 ? "Timeout" : `${delay}`}
{delayManager.formatDelay(delay)}
</Widget>
)}

View File

@@ -145,20 +145,14 @@ export const ProxyItem = (props: Props) => {
e.stopPropagation();
onDelay();
}}
color={
delay > 500
? "error.main"
: delay < 100
? "success.main"
: "text.secondary"
}
color={delayManager.formatDelayColor(delay)}
sx={({ palette }) =>
!proxy.provider
? { ":hover": { bgcolor: alpha(palette.primary.main, 0.15) } }
: {}
}
>
{delay > 1e5 ? "Error" : delay > 3000 ? "Timeout" : `${delay}ms`}
{delayManager.formatDelay(delay)}
</Widget>
)}

View File

@@ -35,9 +35,9 @@ export const useRenderList = (mode: string) => {
// 自适应
if (col >= 6 || col <= 0) {
if (width > 1450) col = 5;
else if (width > 1024) col = 4;
else if (width > 900) col = 3;
if (width > 1450) col = 4;
else if (width > 1024) col = 3;
else if (width > 900) col = 2;
else if (width >= 600) col = 2;
else col = 1;
}

View File

@@ -18,10 +18,11 @@ import { closeAllConnections } from "@/services/api";
import { grantPermission } from "@/services/cmds";
import getSystem from "@/utils/get-system";
const VALID_CORE = [
/* const VALID_CORE = [
{ name: "Clash", core: "clash" },
{ name: "Clash Meta", core: "clash-meta" },
];
]; */
const VALID_CORE = [{ name: "Clash Meta", core: "clash-meta" }];
const OS = getSystem();
@@ -91,7 +92,7 @@ export const ClashCoreViewer = forwardRef<DialogRef>((props, ref) => {
contentSx={{
pb: 0,
width: 320,
height: 200,
height: 90,
overflowY: "auto",
userSelect: "text",
marginTop: "-8px",
@@ -111,7 +112,7 @@ export const ClashCoreViewer = forwardRef<DialogRef>((props, ref) => {
<ListItemText primary={each.name} secondary={`/${each.core}`} />
{(OS === "macos" || OS === "linux") && (
<IconButton
/* <IconButton
color="inherit"
size="small"
edge="end"
@@ -122,7 +123,19 @@ export const ClashCoreViewer = forwardRef<DialogRef>((props, ref) => {
}}
>
<Lock fontSize="inherit" />
</IconButton>
</IconButton> */
<Button
variant="outlined"
size="small"
title={t("Tun mode requires")}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
onGrant(each.core);
}}
>
{t("Grant")}
</Button>
)}
</ListItemButton>
))}

View File

@@ -100,7 +100,7 @@ export const ClashFieldViewer = forwardRef<DialogRef>((props, ref) => {
<Divider sx={{ my: 1 }}>
<Typography color="text.secondary" fontSize={14}>
Clash Nyanpasu Control Fields
Clash Verge Control Fields
</Typography>
</Divider>

View File

@@ -21,10 +21,11 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
const [values, setValues] = useState({
appLogLevel: "info",
autoCloseConnection: false,
enableClashFields: true,
enableClashFields: false,
enableBuiltinEnhanced: true,
proxyLayoutColumn: 6,
defaultLatencyTest: "",
autoLogClean: 0,
});
useImperativeHandle(ref, () => ({
@@ -32,11 +33,12 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
setOpen(true);
setValues({
appLogLevel: verge?.app_log_level ?? "info",
autoCloseConnection: verge?.auto_close_connection ?? false,
enableClashFields: verge?.enable_clash_fields ?? true,
autoCloseConnection: verge?.auto_close_connection ?? true,
enableClashFields: verge?.enable_clash_fields ?? false,
enableBuiltinEnhanced: verge?.enable_builtin_enhanced ?? true,
proxyLayoutColumn: verge?.proxy_layout_column || 6,
defaultLatencyTest: verge?.default_latency_test || "",
autoLogClean: verge?.auto_log_clean || 0,
});
},
close: () => setOpen(false),
@@ -51,6 +53,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
enable_builtin_enhanced: values.enableBuiltinEnhanced,
proxy_layout_column: values.proxyLayoutColumn,
default_latency_test: values.defaultLatencyTest,
auto_log_clean: values.autoLogClean as any,
});
setOpen(false);
} catch (err: any) {
@@ -128,7 +131,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItemText primary={t("Proxy Layout Column")} />
<Select
size="small"
sx={{ width: 100, "> div": { py: "7.5px" } }}
sx={{ width: 135, "> div": { py: "7.5px" } }}
value={values.proxyLayoutColumn}
onChange={(e) => {
setValues((v) => ({
@@ -148,6 +151,32 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
</Select>
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary={t("Auto Log Clean")} />
<Select
size="small"
sx={{ width: 135, "> div": { py: "7.5px" } }}
value={values.autoLogClean}
onChange={(e) => {
setValues((v) => ({
...v,
autoLogClean: e.target.value as number,
}));
}}
>
{[
{ key: "Never Clean", value: 0 },
{ key: "Retain 7 Days", value: 1 },
{ key: "Retain 30 Days", value: 2 },
{ key: "Retain 90 Days", value: 3 },
].map((i) => (
<MenuItem key={i.value} value={i.value}>
{t(i.key)}
</MenuItem>
))}
</Select>
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary={t("Default Latency Test")} />
<TextField
@@ -158,7 +187,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
spellCheck="false"
sx={{ width: 250 }}
value={values.defaultLatencyTest}
placeholder="http://www.gstatic.com/generate_204"
placeholder="http://1.1.1.1"
onChange={(e) =>
setValues((v) => ({ ...v, defaultLatencyTest: e.target.value }))
}

View File

@@ -90,7 +90,7 @@ export const ServiceViewer = forwardRef<DialogRef, Props>((props, ref) => {
{(state === "unknown" || state === "uninstall") && (
<Typography>
Information: Please make sure that the Clash Nyanpasu Service is
Information: Please make sure that the Clash Verge Service is
installed and enabled
</Typography>
)}

View File

@@ -142,19 +142,19 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
</Typography>
<FlexBox>
<Typography className="label">Enable:</Typography>
<Typography className="label">{t("Enable status")}</Typography>
<Typography className="value">
{(!!sysproxy?.enable).toString()}
</Typography>
</FlexBox>
<FlexBox>
<Typography className="label">Server:</Typography>
<Typography className="label">{t("Server Addr")}</Typography>
<Typography className="value">{sysproxy?.server || "-"}</Typography>
</FlexBox>
<FlexBox>
<Typography className="label">Bypass:</Typography>
<Typography className="label">{t("Bypass")}</Typography>
<Typography className="value">{sysproxy?.bypass || "-"}</Typography>
</FlexBox>
</Box>

View File

@@ -18,6 +18,10 @@ import { ClashPortViewer } from "./mods/clash-port-viewer";
import { ControllerViewer } from "./mods/controller-viewer";
import { SettingList, SettingItem } from "./mods/setting-comp";
import { ClashCoreViewer } from "./mods/clash-core-viewer";
import { invoke_uwp_tool } from "@/services/cmds";
import getSystem from "@/utils/get-system";
const isWIN = getSystem() === "windows";
interface Props {
onError: (err: Error) => void;
@@ -162,6 +166,19 @@ const SettingClash = ({ onError }: Props) => {
>
<Typography sx={{ py: "7px", pr: 1 }}>{version}</Typography>
</SettingItem>
{isWIN && (
<SettingItem label={t("Open UWP tool")}>
<IconButton
color="inherit"
size="small"
sx={{ my: "2px" }}
onClick={invoke_uwp_tool}
>
<ArrowForward />
</IconButton>
</SettingItem>
)}
</SettingList>
);
};

View File

@@ -29,8 +29,7 @@ const SettingVerge = ({ onError }: Props) => {
const { t } = useTranslation();
const { verge, patchVerge, mutateVerge } = useVerge();
const { theme_mode, language } = verge ?? {};
const { theme_mode, language, tray_event } = verge ?? {};
const configRef = useRef<DialogRef>(null);
const hotkeyRef = useRef<DialogRef>(null);
const miscRef = useRef<DialogRef>(null);
@@ -56,7 +55,7 @@ const SettingVerge = ({ onError }: Props) => {
});
return (
<SettingList title={t("Nyanpasu Setting")}>
<SettingList title={t("Verge Setting")}>
<ThemeViewer ref={themeRef} />
<ConfigViewer ref={configRef} />
<HotkeyViewer ref={hotkeyRef} />
@@ -91,6 +90,24 @@ const SettingVerge = ({ onError }: Props) => {
</GuardState>
</SettingItem>
{OS !== "linux" && (
<SettingItem label={t("Tray Click Event")}>
<GuardState
value={tray_event ?? "main_window"}
onCatch={onError}
onFormat={(e: any) => e.target.value}
onChange={(e) => onChangeData({ tray_event: e })}
onGuard={(e) => patchVerge({ tray_event: e })}
>
<Select size="small" sx={{ width: 140, "> div": { py: "7.5px" } }}>
<MenuItem value="main_window">{t("Show Main Window")}</MenuItem>
<MenuItem value="system_proxy">{t("System Proxy")}</MenuItem>
<MenuItem value="tun_mode">{t("Tun Mode")}</MenuItem>
</Select>
</GuardState>
</SettingItem>
)}
<SettingItem label={t("Theme Setting")}>
<IconButton
color="inherit"
@@ -192,7 +209,7 @@ const SettingVerge = ({ onError }: Props) => {
</SettingItem>
)}
<SettingItem label={t("Nyanpasu Version")}>
<SettingItem label={t("Verge Version")}>
<Typography sx={{ py: "7px", pr: 1 }}>v{version}</Typography>
</SettingItem>
</SettingList>

View File

@@ -8,7 +8,7 @@
type="image/x-icon"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Clash Nyanpasu</title>
<title>Clash Verge</title>
<script>
(function () {
var _matchMedia = window.matchMedia;

View File

@@ -7,9 +7,6 @@
"Label-Settings": "Settings",
"Connections": "Connections",
"Upload Total": "Upload Total",
"Download Total": "Download Total",
"Active Connections": "Active Connections",
"Logs": "Logs",
"Clear": "Clear",
"Proxies": "Proxies",
@@ -52,6 +49,7 @@
"Filter": "Filter",
"Filter conditions": "Filter conditions",
"Refresh profiles": "Refresh profiles",
"Rules": "Rules",
"Type": "Type",
"Name": "Name",
@@ -64,25 +62,33 @@
"Settings": "Settings",
"Clash Setting": "Clash Setting",
"System Setting": "System Setting",
"Nyanpasu Setting": "Nyanpasu Setting",
"Verge Setting": "Verge Setting",
"Allow Lan": "Allow Lan",
"IPv6": "IPv6",
"Log Level": "Log Level",
"Mixed Port": "Mixed Port",
"External": "External",
"Clash Core": "Clash Core",
"Grant": "Grant",
"Tun mode requires": "Tun mode requires",
"Tun Mode": "Tun Mode",
"Service Mode": "Service Mode",
"Auto Launch": "Auto Launch",
"Silent Start": "Silent Start",
"System Proxy": "System Proxy",
"System Proxy Setting": "System Proxy Setting",
"Open UWP tool": "Open UWP tool",
"Proxy Guard": "Proxy Guard",
"Guard Duration": "Guard Duration",
"Proxy Bypass": "Proxy Bypass",
"Enable status": "Enable status",
"Server Addr": "Server Addr",
"Bypass": "Bypass",
"Current System Proxy": "Current System Proxy",
"Theme Mode": "Theme Mode",
"Theme Blur": "Theme Blur",
"Tray Click Event": "Tray Click Event",
"Show Main Window": "Show Main Window",
"Theme Setting": "Theme Setting",
"Layout Setting": "Layout Setting",
"Miscellaneous": "Miscellaneous",
@@ -94,7 +100,7 @@
"Open Core Dir": "Open Core Dir",
"Open Logs Dir": "Open Logs Dir",
"Check for Updates": "Check for Updates",
"Nyanpasu Version": "Nyanpasu Version",
"Verge Version": "Verge Version",
"theme.light": "Light",
"theme.dark": "Dark",
"theme.system": "System",
@@ -128,5 +134,11 @@
"Enable Clash Fields Filter": "Enable Clash Fields Filter",
"Enable Builtin Enhanced": "Enable Builtin Enhanced",
"Proxy Layout Column": "Proxy Layout Column",
"Default Latency Test": "Default Latency Test"
"Default Latency Test": "Default Latency Test",
"Auto Log Clean": "Auto Log Clean",
"Never Clean": "Never Clean",
"Retain 7 Days": "Retain 7 Days",
"Retain 30 Days": "Retain 30 Days",
"Retain 90 Days": "Retain 90 Days"
}

View File

@@ -59,7 +59,7 @@
"Settings": "Настройки",
"Clash Setting": "Настройки Clash",
"System Setting": "Настройки системы",
"Nyanpasu Setting": "Настройки Nyanpasu",
"Verge Setting": "Настройки Verge",
"Allow Lan": "Разрешить локальную сеть",
"IPv6": "IPv6",
"Log Level": "Уровень логов",
@@ -71,12 +71,15 @@
"Silent Start": "Тихий запуск",
"System Proxy": "Системный прокси",
"System Proxy Setting": "Настройка системного прокси",
"Open UWP tool": "Открыть UWP инструмент",
"Proxy Guard": "Защита прокси",
"Guard Duration": "Период защиты",
"Proxy Bypass": "Игнорирование прокси",
"Current System Proxy": "Текущий системный прокси",
"Theme Mode": "Режим темы",
"Theme Blur": "Размытие темы",
"Tray Click Event": "Событие щелчка в лотке",
"Show Main Window": "Показать главное окно",
"Theme Setting": "Настройка темы",
"Hotkey Setting": "Настройка клавиатурных сокращений",
"Traffic Graph": "График трафика",
@@ -84,7 +87,7 @@
"Open App Dir": "Открыть папку приложения",
"Open Core Dir": "Открыть папку ядра",
"Open Logs Dir": "Открыть папку логов",
"Nyanpasu Version": "Версия Nyanpasu",
"Verge Version": "Версия Verge",
"theme.light": "Светлая",
"theme.dark": "Тёмная",
"theme.system": "Системная",

View File

@@ -1,15 +1,12 @@
{
"Label-Proxies": "代 理",
"Label-Profiles": "配 置",
"Label-Profiles": "订 阅",
"Label-Connections": "连 接",
"Label-Logs": "日 志",
"Label-Rules": "规 则",
"Label-Settings": "设 置",
"Connections": "连接",
"Upload Total": "上传总量",
"Download Total": "下载总量",
"Active Connections": "活动连接",
"Logs": "日志",
"Clear": "清除",
"Proxies": "代理",
@@ -19,11 +16,11 @@
"direct": "直连",
"script": "脚本",
"Profiles": "配置",
"Profile URL": "配置文件链接",
"Profiles": "订阅",
"Profile URL": "订阅文件链接",
"Import": "导入",
"New": "新建",
"Create Profile": "新建配置",
"Create Profile": "新建订阅",
"Choose File": "选择文件",
"Close All": "关闭全部",
"Select": "使用",
@@ -38,9 +35,9 @@
"Refresh": "刷新",
"To Top": "移到最前",
"To End": "移到末尾",
"Update All Profiles": "更新所有配置",
"View Runtime Config": "查看运行时配置",
"Reactivate Profiles": "重新激活配置",
"Update All Profiles": "更新所有订阅",
"View Runtime Config": "查看运行时订阅",
"Reactivate Profiles": "重新激活订阅",
"Location": "当前节点",
"Delay check": "延迟测试",
@@ -51,7 +48,8 @@
"Proxy detail": "展示节点细节",
"Filter": "过滤节点",
"Filter conditions": "过滤条件",
"Refresh profiles": "刷新配置",
"Refresh profiles": "刷新订阅",
"Rules": "规则",
"Type": "类型",
"Name": "名称",
@@ -64,25 +62,33 @@
"Settings": "设置",
"Clash Setting": "Clash 设置",
"System Setting": "系统设置",
"Nyanpasu Setting": "Nyanpasu 设置",
"Verge Setting": "Verge 设置",
"Allow Lan": "局域网连接",
"IPv6": "IPv6",
"Log Level": "日志等级",
"Mixed Port": "端口设置",
"External": "外部控制",
"Clash Core": "Clash 内核",
"Grant": "授权",
"Tun mode requires": "如需启用TUN模式需要授权",
"Tun Mode": "Tun 模式",
"Service Mode": "服务模式",
"Auto Launch": "开机自启",
"Silent Start": "静默启动",
"System Proxy": "系统代理",
"System Proxy Setting": "系统代理设置",
"Open UWP tool": "UWP工具",
"Proxy Guard": "系统代理守卫",
"Guard Duration": "代理守卫间隔",
"Proxy Bypass": "Proxy Bypass",
"Proxy Bypass": "代理绕过",
"Current System Proxy": "当前系统代理",
"Enable status": "开启状态:",
"Server Addr": "服务地址:",
"Bypass": "当前绕过:",
"Theme Mode": "主题模式",
"Theme Blur": "背景模糊",
"Tray Click Event": "托盘点击事件",
"Show Main Window": "显示主窗口",
"Theme Setting": "主题设置",
"Layout Setting": "界面设置",
"Miscellaneous": "杂项设置",
@@ -94,12 +100,12 @@
"Open Core Dir": "内核目录",
"Open Logs Dir": "日志目录",
"Check for Updates": "检查更新",
"Nyanpasu Version": "Nyanpasu 版本",
"Verge Version": "Verge 版本",
"theme.light": "浅色",
"theme.dark": "深色",
"theme.system": "系统",
"Clash Field": "Clash 字段",
"Runtime Config": "运行配置",
"Runtime Config": "当前配置",
"ReadOnly": "只读",
"Restart": "重启内核",
@@ -128,5 +134,11 @@
"Enable Clash Fields Filter": "开启Clash字段过滤",
"Enable Builtin Enhanced": "开启内建增强功能",
"Proxy Layout Column": "代理页布局列数",
"Default Latency Test": "默认测试链接"
"Default Latency Test": "默认测试链接",
"Auto Log Clean": "自动清理日志",
"Never Clean": "不清理",
"Retain 7 Days": "保留7天",
"Retain 30 Days": "保留30天",
"Retain 90 Days": "保留90天"
}

Some files were not shown because too many files have changed in this diff Show More