mirror of
https://github.com/bolucat/Archive.git
synced 2025-09-26 20:21:35 +08:00
Update On Mon Oct 7 20:33:43 CEST 2024
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -786,3 +786,4 @@ Update On Thu Oct 3 20:36:48 CEST 2024
|
||||
Update On Fri Oct 4 20:35:09 CEST 2024
|
||||
Update On Sat Oct 5 20:31:49 CEST 2024
|
||||
Update On Sun Oct 6 20:31:42 CEST 2024
|
||||
Update On Mon Oct 7 20:33:33 CEST 2024
|
||||
|
@@ -53,7 +53,7 @@
|
||||
"@csstools/normalize.css": "12.1.1",
|
||||
"@emotion/babel-plugin": "11.12.0",
|
||||
"@emotion/react": "11.13.3",
|
||||
"@iconify/json": "2.2.256",
|
||||
"@iconify/json": "2.2.257",
|
||||
"@monaco-editor/react": "4.6.0",
|
||||
"@tanstack/react-router": "1.62.1",
|
||||
"@tanstack/router-devtools": "1.62.1",
|
||||
@@ -76,7 +76,7 @@
|
||||
"monaco-yaml": "5.2.2",
|
||||
"nanoid": "5.0.7",
|
||||
"sass": "1.79.4",
|
||||
"shiki": "1.21.1",
|
||||
"shiki": "1.22.0",
|
||||
"tailwindcss-textshadow": "2.1.3",
|
||||
"unplugin-auto-import": "0.18.3",
|
||||
"unplugin-icons": "0.19.3",
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.18.9",
|
||||
"mihomo_alpha": "alpha-8e6eb70",
|
||||
"mihomo_alpha": "alpha-9fd63fe",
|
||||
"clash_rs": "v0.5.0",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.5.0-alpha+sha.801972b"
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2024-10-05T22:20:52.009Z"
|
||||
"updated_at": "2024-10-06T22:20:32.722Z"
|
||||
}
|
||||
|
@@ -82,7 +82,7 @@
|
||||
"eslint-plugin-react": "7.37.0",
|
||||
"eslint-plugin-react-compiler": "0.0.0-experimental-f444e11-20240926",
|
||||
"eslint-plugin-react-hooks": "4.6.2",
|
||||
"knip": "5.31.0",
|
||||
"knip": "5.32.0",
|
||||
"lint-staged": "15.2.10",
|
||||
"npm-run-all2": "6.2.3",
|
||||
"postcss": "8.4.47",
|
||||
|
80
clash-nyanpasu/pnpm-lock.yaml
generated
80
clash-nyanpasu/pnpm-lock.yaml
generated
@@ -96,8 +96,8 @@ importers:
|
||||
specifier: 4.6.2
|
||||
version: 4.6.2(eslint@8.57.1)
|
||||
knip:
|
||||
specifier: 5.31.0
|
||||
version: 5.31.0(@types/node@22.7.4)(typescript@5.6.2)
|
||||
specifier: 5.32.0
|
||||
version: 5.32.0(@types/node@22.7.4)(typescript@5.6.2)
|
||||
lint-staged:
|
||||
specifier: 15.2.10
|
||||
version: 15.2.10
|
||||
@@ -308,8 +308,8 @@ importers:
|
||||
specifier: 11.13.3
|
||||
version: 11.13.3(react@19.0.0-rc-1460d67c-20241003)(types-react@19.0.0-rc.1)
|
||||
'@iconify/json':
|
||||
specifier: 2.2.256
|
||||
version: 2.2.256
|
||||
specifier: 2.2.257
|
||||
version: 2.2.257
|
||||
'@monaco-editor/react':
|
||||
specifier: 4.6.0
|
||||
version: 4.6.0(monaco-editor@0.52.0)(react-dom@19.0.0-rc-1460d67c-20241003(react@19.0.0-rc-1460d67c-20241003))(react@19.0.0-rc-1460d67c-20241003)
|
||||
@@ -377,8 +377,8 @@ importers:
|
||||
specifier: 1.79.4
|
||||
version: 1.79.4
|
||||
shiki:
|
||||
specifier: 1.21.1
|
||||
version: 1.21.1
|
||||
specifier: 1.22.0
|
||||
version: 1.22.0
|
||||
tailwindcss-textshadow:
|
||||
specifier: 2.1.3
|
||||
version: 2.1.3
|
||||
@@ -1372,8 +1372,8 @@ packages:
|
||||
'@vue/compiler-sfc':
|
||||
optional: true
|
||||
|
||||
'@iconify/json@2.2.256':
|
||||
resolution: {integrity: sha512-u2RwfBUuDE3A8qx3vnXdcJMtirHc9QrRRULfGY6Il6/K76Odfrm4yVqS/fYIh+wXwWl/fZdAZEozqxpZftfnIQ==}
|
||||
'@iconify/json@2.2.257':
|
||||
resolution: {integrity: sha512-IqjXD7BrtORxEK1eRq77550zMztRnwTn8Qyid+WuGspYP+wn5PUEoNPvF3bOJkWiq14QqPphi339nEKuomgR2A==}
|
||||
|
||||
'@iconify/types@2.0.0':
|
||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||
@@ -2107,17 +2107,17 @@ packages:
|
||||
'@rushstack/ts-command-line@4.22.6':
|
||||
resolution: {integrity: sha512-QSRqHT/IfoC5nk9zn6+fgyqOPXHME0BfchII9EUPR19pocsNp/xSbeBCbD3PIR2Lg+Q5qk7OFqk1VhWPMdKHJg==}
|
||||
|
||||
'@shikijs/core@1.21.1':
|
||||
resolution: {integrity: sha512-scBQo4V4O4WZLEDg11e75UPmXoCMq4Ya2A16U6efi/aTiR4o7T/GMNWZs2rq1U8dEvFKGxJZxiUy+tXgmr/4vw==}
|
||||
'@shikijs/core@1.22.0':
|
||||
resolution: {integrity: sha512-S8sMe4q71TJAW+qG93s5VaiihujRK6rqDFqBnxqvga/3LvqHEnxqBIOPkt//IdXVtHkQWKu4nOQNk0uBGicU7Q==}
|
||||
|
||||
'@shikijs/engine-javascript@1.21.1':
|
||||
resolution: {integrity: sha512-29EG4KYKlAona8yikEx8uoKbK7N2YoXUO26LS1GOIxpMMIAlQS9UFONg95lkGmIfp1rRcvCvSpYYIJ/blsQxvg==}
|
||||
'@shikijs/engine-javascript@1.22.0':
|
||||
resolution: {integrity: sha512-AeEtF4Gcck2dwBqCFUKYfsCq0s+eEbCEbkUuFou53NZ0sTGnJnJ/05KHQFZxpii5HMXbocV9URYVowOP2wH5kw==}
|
||||
|
||||
'@shikijs/engine-oniguruma@1.21.1':
|
||||
resolution: {integrity: sha512-PvfEtXCDbQZc9ud0SC0bPiuMbul44Cv0Ky2go4SsvVkYAAKYJsMe/Hx7nxThW8yS0r+w8USa0WfOtQKsD9DU9A==}
|
||||
'@shikijs/engine-oniguruma@1.22.0':
|
||||
resolution: {integrity: sha512-5iBVjhu/DYs1HB0BKsRRFipRrD7rqjxlWTj4F2Pf+nQSPqc3kcyqFFeZXnBMzDf0HdqaFVvhDRAGiYNvyLP+Mw==}
|
||||
|
||||
'@shikijs/types@1.21.1':
|
||||
resolution: {integrity: sha512-yLuTJTCHmYznerJ0nxF+f2rBKHQf2FMAd08QL/3du2xNBy/7yQ8CjuKN4Zc+Pk0vfIFzdBoxdzvEXE4JtXoR4Q==}
|
||||
'@shikijs/types@1.22.0':
|
||||
resolution: {integrity: sha512-Fw/Nr7FGFhlQqHfxzZY8Cwtwk5E9nKDUgeLjZgt3UuhcM3yJR9xj3ZGNravZZok8XmEZMiYkSMTPlPkULB8nww==}
|
||||
|
||||
'@shikijs/vscode-textmate@9.3.0':
|
||||
resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==}
|
||||
@@ -4746,8 +4746,8 @@ packages:
|
||||
resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
|
||||
hasBin: true
|
||||
|
||||
jiti@2.1.2:
|
||||
resolution: {integrity: sha512-cYNjJus5X9J4jLzTaI8rYoIq1k6YySiA1lK4wxSnOrBRXkbVyreZfhoboJhsUmwgU82lpPjj1IoU7Ggrau8r3g==}
|
||||
jiti@2.3.1:
|
||||
resolution: {integrity: sha512-xPZ6pPzUifI8XDBBxIL4OB1w1ZKmBpmNEeKwNt2d0Spn8XisAIZhWrlOHq5seBrFGTxVx9PbrWvEMyrk4IO5bA==}
|
||||
hasBin: true
|
||||
|
||||
jju@1.4.0:
|
||||
@@ -4853,8 +4853,8 @@ packages:
|
||||
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
knip@5.31.0:
|
||||
resolution: {integrity: sha512-4hR+qHx/id7mniCWWUqA4MXwGjYFN75xv3qLmEkl9Hm6eCKAhv0wGP0CyrXKUYxVyDplJQsqQaAlsjuRKYsdPA==}
|
||||
knip@5.32.0:
|
||||
resolution: {integrity: sha512-2M4qnAu1rjg17DEC1oXNmdb3gPqsEclTQasnAYPYr9wuGSRQLkb2X3VrqMpBHAcvboyB/gF8iE3FFdFhIjFwww==}
|
||||
engines: {node: '>=18.6.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -6337,8 +6337,8 @@ packages:
|
||||
shell-quote@1.8.1:
|
||||
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
|
||||
|
||||
shiki@1.21.1:
|
||||
resolution: {integrity: sha512-jSOKRHyQJxGOW3kJflmwzHJbp/kjg6hP8LYuVbCPw5oyX+fSNNoCywvcCD3w9eHbj2rvNljt7YMa5BP5Xi+nHg==}
|
||||
shiki@1.22.0:
|
||||
resolution: {integrity: sha512-/t5LlhNs+UOKQCYBtl5ZsH/Vclz73GIqT2yQsCBygr8L/ppTdmpL4w3kPLoZJbMKVWtoG77Ue1feOjZfDxvMkw==}
|
||||
|
||||
side-channel@1.0.6:
|
||||
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
|
||||
@@ -8156,7 +8156,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@iconify/json@2.2.256':
|
||||
'@iconify/json@2.2.257':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
pathe: 1.1.2
|
||||
@@ -8895,27 +8895,27 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
|
||||
'@shikijs/core@1.21.1':
|
||||
'@shikijs/core@1.22.0':
|
||||
dependencies:
|
||||
'@shikijs/engine-javascript': 1.21.1
|
||||
'@shikijs/engine-oniguruma': 1.21.1
|
||||
'@shikijs/types': 1.21.1
|
||||
'@shikijs/engine-javascript': 1.22.0
|
||||
'@shikijs/engine-oniguruma': 1.22.0
|
||||
'@shikijs/types': 1.22.0
|
||||
'@shikijs/vscode-textmate': 9.3.0
|
||||
'@types/hast': 3.0.4
|
||||
hast-util-to-html: 9.0.3
|
||||
|
||||
'@shikijs/engine-javascript@1.21.1':
|
||||
'@shikijs/engine-javascript@1.22.0':
|
||||
dependencies:
|
||||
'@shikijs/types': 1.21.1
|
||||
'@shikijs/types': 1.22.0
|
||||
'@shikijs/vscode-textmate': 9.3.0
|
||||
oniguruma-to-js: 0.4.3
|
||||
|
||||
'@shikijs/engine-oniguruma@1.21.1':
|
||||
'@shikijs/engine-oniguruma@1.22.0':
|
||||
dependencies:
|
||||
'@shikijs/types': 1.21.1
|
||||
'@shikijs/types': 1.22.0
|
||||
'@shikijs/vscode-textmate': 9.3.0
|
||||
|
||||
'@shikijs/types@1.21.1':
|
||||
'@shikijs/types@1.22.0':
|
||||
dependencies:
|
||||
'@shikijs/vscode-textmate': 9.3.0
|
||||
'@types/hast': 3.0.4
|
||||
@@ -11831,7 +11831,7 @@ snapshots:
|
||||
|
||||
jiti@1.21.6: {}
|
||||
|
||||
jiti@2.1.2: {}
|
||||
jiti@2.3.1: {}
|
||||
|
||||
jju@1.4.0: {}
|
||||
|
||||
@@ -11908,7 +11908,7 @@ snapshots:
|
||||
|
||||
kind-of@6.0.3: {}
|
||||
|
||||
knip@5.31.0(@types/node@22.7.4)(typescript@5.6.2):
|
||||
knip@5.32.0(@types/node@22.7.4)(typescript@5.6.2):
|
||||
dependencies:
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
'@snyk/github-codeowners': 1.1.0
|
||||
@@ -11916,7 +11916,7 @@ snapshots:
|
||||
easy-table: 1.2.0
|
||||
enhanced-resolve: 5.17.1
|
||||
fast-glob: 3.3.2
|
||||
jiti: 2.1.2
|
||||
jiti: 2.3.1
|
||||
js-yaml: 4.1.0
|
||||
minimist: 1.2.8
|
||||
picocolors: 1.1.0
|
||||
@@ -13469,12 +13469,12 @@ snapshots:
|
||||
|
||||
shell-quote@1.8.1: {}
|
||||
|
||||
shiki@1.21.1:
|
||||
shiki@1.22.0:
|
||||
dependencies:
|
||||
'@shikijs/core': 1.21.1
|
||||
'@shikijs/engine-javascript': 1.21.1
|
||||
'@shikijs/engine-oniguruma': 1.21.1
|
||||
'@shikijs/types': 1.21.1
|
||||
'@shikijs/core': 1.22.0
|
||||
'@shikijs/engine-javascript': 1.22.0
|
||||
'@shikijs/engine-oniguruma': 1.22.0
|
||||
'@shikijs/types': 1.22.0
|
||||
'@shikijs/vscode-textmate': 9.3.0
|
||||
'@types/hast': 3.0.4
|
||||
|
||||
|
@@ -32,7 +32,7 @@ PROJECT_NAME=$(shell basename "${ROOT}")
|
||||
# - pkg/version/current.go
|
||||
#
|
||||
# Use `tools/bump_version.sh` script to change all those files at one shot.
|
||||
VERSION="3.5.1"
|
||||
VERSION="3.6.0"
|
||||
|
||||
# Build binaries and installation packages.
|
||||
.PHONY: build
|
||||
@@ -353,6 +353,7 @@ test-binary:
|
||||
CGO_ENABLED=0 go build -ldflags="-X 'github.com/enfein/mieru/pkg/log.LogPrefix=S'" -o mita cmd/mita/mita.go
|
||||
CGO_ENABLED=1 go build -race -ldflags="-X 'github.com/enfein/mieru/pkg/log.LogPrefix=C2'" -o mieru2 cmd/mieru/mieru.go
|
||||
CGO_ENABLED=1 go build -race -ldflags="-X 'github.com/enfein/mieru/pkg/log.LogPrefix=S2'" -o mita2 cmd/mita/mita.go
|
||||
CGO_ENABLED=0 go build test/cmd/exampleapiclient/exampleapiclient.go
|
||||
CGO_ENABLED=0 go build test/cmd/httpserver/httpserver.go
|
||||
CGO_ENABLED=0 go build test/cmd/sockshttpclient/sockshttpclient.go
|
||||
CGO_ENABLED=0 go build test/cmd/socksudpclient/socksudpclient.go
|
||||
@@ -365,14 +366,14 @@ test-container: test-binary
|
||||
docker build -t mieru_httptest:${SHORT_SHA} -f test/deploy/httptest/Dockerfile .;\
|
||||
docker build -t mieru_proxychain:${SHORT_SHA} -f test/deploy/proxychain/Dockerfile .;\
|
||||
fi
|
||||
rm -f mieru mieru2 mita mita2 httpserver sockshttpclient socksudpclient udpserver
|
||||
rm -f exampleapiclient mieru mieru2 mita mita2 httpserver sockshttpclient socksudpclient udpserver
|
||||
|
||||
# Run docker integration tests.
|
||||
.PHONY: run-container-test
|
||||
run-container-test: test-container
|
||||
if [ ! -z $$(command -v docker) ]; then\
|
||||
docker run mieru_proxychain:${SHORT_SHA};\
|
||||
docker run mieru_httptest:${SHORT_SHA};\
|
||||
docker run mieru_proxychain:${SHORT_SHA};\
|
||||
fi
|
||||
|
||||
# Format source code.
|
||||
|
@@ -19,14 +19,12 @@ For an explanation of the mieru protocol, see [mieru Proxy Protocol](./docs/prot
|
||||
|
||||
## Features
|
||||
|
||||
1. mieru uses a high-strength XChaCha20-Poly1305 encryption algorithm that generates encryption keys based on username, password and system time.
|
||||
1. mieru implements complete encryption of all transmitted content between the client and the proxy server, without transmitting any plaintext information.
|
||||
1. When mieru sends a packet, it is padded with random bytes at the end. Even when the same content is transmitted, the packet size varies.
|
||||
1. When using the UDP transport protocol, mieru does not require a handshake between client and server.
|
||||
1. When the server can not decrypt the data sent by the client, no content is returned. it is difficult for GFW to discover the mieru service through active probing.
|
||||
1. mieru supports multiple users sharing a single proxy server.
|
||||
1. mieru supports IPv4 and IPv6.
|
||||
1. mieru provides socks5, HTTP and HTTPS proxy.
|
||||
1. Provides socks5, HTTP, and HTTPS proxy interfaces.
|
||||
1. Does not use TLS protocol. No need to register a domain name or set up a fake website.
|
||||
1. Uses the high-strength XChaCha20-Poly1305 encryption algorithm that generates encryption keys based on username, password and system time.
|
||||
1. Utilizes random padding and replay attack detection to prevent GFW from detecting the mieru service.
|
||||
1. Supports multiple users sharing a single proxy server.
|
||||
1. Supports both IPv4 and IPv6.
|
||||
1. The server software supports socks5 outbound (proxy chain).
|
||||
1. The client software supports Windows, Mac OS, Linux and Android. Android clients include
|
||||
- [NekoBox](https://github.com/MatsuriDayo/NekoBoxForAndroid) version 1.3.1 or above, with [mieru plugin](https://github.com/enfein/NekoBoxPlugins).
|
||||
|
@@ -17,14 +17,12 @@ mieru 的翻墙原理与 shadowsocks / v2ray 等软件类似,在客户端和
|
||||
|
||||
## 特性
|
||||
|
||||
1. 提供 socks5, HTTP 和 HTTPS 代理接口。
|
||||
1. 不使用 TLS 协议,无需注册域名和架设伪装站点。
|
||||
1. 使用高强度的 XChaCha20-Poly1305 加密算法,基于用户名、密码和系统时间生成密钥。
|
||||
1. mieru 实现了客户端和代理服务器之间所有传输内容的完整加密,不传输任何明文信息。
|
||||
1. 当 mieru 发送数据包时,会在尾部填充随机信息。即便是传输相同的内容,数据包大小也不相同。
|
||||
1. 在使用 UDP 传输协议时,mieru 不需要客户端和服务器进行握手,即可直接发送数据。
|
||||
1. 当服务器无法解密客户端发送的数据时,不会返回任何内容。GFW 很难通过主动探测发现 mieru 服务。
|
||||
1. mieru 支持多个用户共享代理服务器。
|
||||
1. mieru 支持 IPv4 和 IPv6。
|
||||
1. mieru 提供 socks5, HTTP 和 HTTPS 代理。
|
||||
1. 使用随机填充与重放攻击检测阻止 GFW 探测 mieru 服务。
|
||||
1. 支持多个用户共享代理服务器。
|
||||
1. 支持 IPv4 和 IPv6。
|
||||
1. 服务器软件支持 socks5 出站(链式代理)。
|
||||
1. 客户端软件支持 Windows, Mac OS, Linux 和 Android 系统。Android 客户端包括
|
||||
- [NekoBox](https://github.com/MatsuriDayo/NekoBoxForAndroid) 1.3.1 及以上版本,并安装 [mieru 插件](https://github.com/enfein/NekoBoxPlugins)。
|
||||
|
@@ -25,9 +25,10 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoClientConfig = errors.New("no client config")
|
||||
ErrInvalidConfigConfig = errors.New("invalid client config")
|
||||
ErrClientIsNotRunning = errors.New("client is not running")
|
||||
ErrNoClientConfig = errors.New("no client config")
|
||||
ErrInvalidConfigConfig = errors.New("invalid client config")
|
||||
ErrClientIsNotRunning = errors.New("client is not running")
|
||||
ErrStoreClientConfigAfterStart = errors.New("can't store client config after start")
|
||||
)
|
||||
|
||||
// Client contains methods supported by a mieru client.
|
||||
@@ -44,7 +45,7 @@ type ClientConfigurationService interface {
|
||||
Load() (*ClientConfig, error)
|
||||
|
||||
// Store saves the client config.
|
||||
// It returns wrapped ErrInvalidConfigConfig if client config is invalid.
|
||||
// It returns wrapped ErrInvalidConfigConfig if the provided client config is invalid.
|
||||
Store(*ClientConfig) error
|
||||
}
|
||||
|
||||
@@ -64,16 +65,19 @@ type ClientLifecycleService interface {
|
||||
IsRunning() bool
|
||||
}
|
||||
|
||||
// ClientNetworkService contains methods to establish proxy connections.
|
||||
// ClientNetworkService contains methods to establish connections to proxy server.
|
||||
type ClientNetworkService interface {
|
||||
// DialContext returns a new mieru connection to reach proxy server.
|
||||
// DialContext returns a new proxy connection to reach proxy server.
|
||||
// It returns an error if the client has not been started,
|
||||
// or has been stopped.
|
||||
DialContext(context.Context) (net.Conn, error)
|
||||
|
||||
// HandshakeWithConnect completes the socks5 CONNECT request with proxy server.
|
||||
// After this, the mieru connection is able to send and receive user payload.
|
||||
// The mieru connection is NOT terminated when an error is returned.
|
||||
// HandshakeWithConnect completes the socks5 CONNECT request with proxy server
|
||||
// in the given proxy connection.
|
||||
// You may need to send a response back to the application that initiated
|
||||
// the proxy connection.
|
||||
// After that, the proxy connection is able to send and receive user payload.
|
||||
// The proxy connection is NOT terminated when an error is returned.
|
||||
HandshakeWithConnect(context.Context, net.Conn, model.AddrSpec) error
|
||||
}
|
||||
|
||||
@@ -82,7 +86,7 @@ type ClientConfig struct {
|
||||
Profile *appctlpb.ClientProfile
|
||||
}
|
||||
|
||||
// NewClient returns a blank mieru client.
|
||||
// NewClient creates a blank mieru client with no client config.
|
||||
func NewClient() Client {
|
||||
mc := &mieruClient{}
|
||||
mc.initOnce()
|
||||
|
@@ -75,6 +75,9 @@ func (mc *mieruClient) Store(config *ClientConfig) error {
|
||||
if config.Profile == nil {
|
||||
return fmt.Errorf("%w: client config profile is nil", ErrInvalidConfigConfig)
|
||||
}
|
||||
if mc.running {
|
||||
return ErrStoreClientConfigAfterStart
|
||||
}
|
||||
if err := appctl.ValidateClientConfigSingleProfile(config.Profile); err != nil {
|
||||
return fmt.Errorf("%w: %s", ErrInvalidConfigConfig, err.Error())
|
||||
}
|
||||
@@ -120,7 +123,7 @@ func (mc *mieruClient) Start() error {
|
||||
}
|
||||
mc.mux = mc.mux.SetClientMultiplexFactor(multiplexFactor)
|
||||
|
||||
// Set endpoints.
|
||||
// Set server endpoints.
|
||||
mtu := util.DefaultMTU
|
||||
if activeProfile.GetMtu() != 0 {
|
||||
mtu = int(activeProfile.GetMtu())
|
||||
|
@@ -33,3 +33,15 @@ const (
|
||||
Socks5FQDNAddress byte = 3
|
||||
Socks5IPv6Address byte = 4
|
||||
)
|
||||
|
||||
// socks5 authentication options.
|
||||
const (
|
||||
Socks5NoAuth byte = 0
|
||||
Socks5UserPassAuth byte = 2
|
||||
Socks5NoAcceptableAuth byte = 255
|
||||
|
||||
Socks5UserPassAuthVersion byte = 1
|
||||
|
||||
Socks5AuthSuccess byte = 0
|
||||
Socks5AuthFailure byte = 1
|
||||
)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Package: mieru
|
||||
Version: 3.5.1
|
||||
Version: 3.6.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Name: mieru
|
||||
Version: 3.5.1
|
||||
Version: 3.6.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy client
|
||||
License: GPLv3+
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Package: mieru
|
||||
Version: 3.5.1
|
||||
Version: 3.6.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: arm64
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Name: mieru
|
||||
Version: 3.5.1
|
||||
Version: 3.6.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy client
|
||||
License: GPLv3+
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Package: mita
|
||||
Version: 3.5.1
|
||||
Version: 3.6.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Name: mita
|
||||
Version: 3.5.1
|
||||
Version: 3.6.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy server
|
||||
License: GPLv3+
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Package: mita
|
||||
Version: 3.5.1
|
||||
Version: 3.6.0
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: arm64
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Name: mita
|
||||
Version: 3.5.1
|
||||
Version: 3.6.0
|
||||
Release: 1%{?dist}
|
||||
Summary: Mieru proxy server
|
||||
License: GPLv3+
|
||||
|
@@ -8,32 +8,32 @@ Before installation and configuration, connect to the server via SSH and then ex
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.5.1/mita_3.5.1_amd64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.6.0/mita_3.6.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.5.1/mita_3.5.1_arm64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.6.0/mita_3.6.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.5.1/mita-3.5.1-1.x86_64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.6.0/mita-3.6.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.5.1/mita-3.5.1-1.aarch64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.6.0/mita-3.6.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
## Install mita package
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
sudo dpkg -i mita_3.5.1_amd64.deb
|
||||
sudo dpkg -i mita_3.6.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
sudo dpkg -i mita_3.5.1_arm64.deb
|
||||
sudo dpkg -i mita_3.6.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
sudo rpm -Uvh --force mita-3.5.1-1.x86_64.rpm
|
||||
sudo rpm -Uvh --force mita-3.6.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
sudo rpm -Uvh --force mita-3.5.1-1.aarch64.rpm
|
||||
sudo rpm -Uvh --force mita-3.6.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
Those instructions can also be used to upgrade the version of mita software package.
|
||||
|
@@ -8,32 +8,32 @@
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.5.1/mita_3.5.1_amd64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.6.0/mita_3.6.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.5.1/mita_3.5.1_arm64.deb
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.6.0/mita_3.6.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.5.1/mita-3.5.1-1.x86_64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.6.0/mita-3.6.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.5.1/mita-3.5.1-1.aarch64.rpm
|
||||
curl -LSO https://github.com/enfein/mieru/releases/download/v3.6.0/mita-3.6.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
## 安装 mita 软件包
|
||||
|
||||
```sh
|
||||
# Debian / Ubuntu - X86_64
|
||||
sudo dpkg -i mita_3.5.1_amd64.deb
|
||||
sudo dpkg -i mita_3.6.0_amd64.deb
|
||||
|
||||
# Debian / Ubuntu - ARM 64
|
||||
sudo dpkg -i mita_3.5.1_arm64.deb
|
||||
sudo dpkg -i mita_3.6.0_arm64.deb
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - X86_64
|
||||
sudo rpm -Uvh --force mita-3.5.1-1.x86_64.rpm
|
||||
sudo rpm -Uvh --force mita-3.6.0-1.x86_64.rpm
|
||||
|
||||
# RedHat / CentOS / Rocky Linux - ARM 64
|
||||
sudo rpm -Uvh --force mita-3.5.1-1.aarch64.rpm
|
||||
sudo rpm -Uvh --force mita-3.6.0-1.aarch64.rpm
|
||||
```
|
||||
|
||||
上述指令也可以用来升级 mita 软件包的版本。
|
||||
|
@@ -25,17 +25,6 @@ import (
|
||||
"github.com/enfein/mieru/v3/pkg/util"
|
||||
)
|
||||
|
||||
const (
|
||||
noAuth byte = 0
|
||||
userPassAuth byte = 2
|
||||
noAcceptableAuth byte = 255
|
||||
|
||||
userPassAuthVersion byte = 1
|
||||
|
||||
authSuccess byte = 0
|
||||
authFailure byte = 1
|
||||
)
|
||||
|
||||
// Auth provide authentication settings to socks5 server.
|
||||
type Auth struct {
|
||||
// Do socks5 authentication at proxy client side.
|
||||
@@ -93,17 +82,17 @@ func (s *Server) handleAuthentication(conn net.Conn) error {
|
||||
return fmt.Errorf("get authentication method failed: %w", err)
|
||||
}
|
||||
for _, method := range authMethods {
|
||||
if method == noAuth {
|
||||
if method == constant.Socks5NoAuth {
|
||||
requestNoAuth = true
|
||||
}
|
||||
if method == userPassAuth {
|
||||
if method == constant.Socks5UserPassAuth {
|
||||
requestUserPassAuth = true
|
||||
}
|
||||
}
|
||||
|
||||
if !requestNoAuth && !requestUserPassAuth {
|
||||
HandshakeErrors.Add(1)
|
||||
if _, err := conn.Write([]byte{constant.Socks5Version, noAcceptableAuth}); err != nil {
|
||||
if _, err := conn.Write([]byte{constant.Socks5Version, constant.Socks5NoAcceptableAuth}); err != nil {
|
||||
return fmt.Errorf("write authentication response (no acceptable methods) failed: %w", err)
|
||||
}
|
||||
return fmt.Errorf("socks5 client provided authentication is not supported by socks5 server")
|
||||
@@ -114,7 +103,7 @@ func (s *Server) handleAuthentication(conn net.Conn) error {
|
||||
HandshakeErrors.Add(1)
|
||||
return fmt.Errorf("socks5 client requested no authentication, but user and password are required by socks5 server")
|
||||
}
|
||||
if _, err := conn.Write([]byte{constant.Socks5Version, noAuth}); err != nil {
|
||||
if _, err := conn.Write([]byte{constant.Socks5Version, constant.Socks5NoAuth}); err != nil {
|
||||
HandshakeErrors.Add(1)
|
||||
return fmt.Errorf("write authentication response (no authentication required) failed: %w", err)
|
||||
}
|
||||
@@ -126,7 +115,7 @@ func (s *Server) handleAuthentication(conn net.Conn) error {
|
||||
}
|
||||
|
||||
// Tell the client to use user password authentication.
|
||||
if _, err := conn.Write([]byte{constant.Socks5Version, userPassAuth}); err != nil {
|
||||
if _, err := conn.Write([]byte{constant.Socks5Version, constant.Socks5UserPassAuth}); err != nil {
|
||||
HandshakeErrors.Add(1)
|
||||
return fmt.Errorf("write user password authentication request failed: %w", err)
|
||||
}
|
||||
@@ -136,7 +125,7 @@ func (s *Server) handleAuthentication(conn net.Conn) error {
|
||||
if _, err := io.ReadFull(conn, header); err != nil {
|
||||
return fmt.Errorf("get user password authentication version failed: %w", err)
|
||||
}
|
||||
if header[0] != userPassAuthVersion {
|
||||
if header[0] != constant.Socks5UserPassAuthVersion {
|
||||
return fmt.Errorf("user password authentication version %d is not supported by socks5 server", header[0])
|
||||
}
|
||||
|
||||
@@ -163,7 +152,7 @@ func (s *Server) handleAuthentication(conn net.Conn) error {
|
||||
passwordStr := string(password)
|
||||
for _, c := range s.config.AuthOpts.IngressCredentials {
|
||||
if c.User == userStr && c.Password == passwordStr {
|
||||
if _, err := conn.Write([]byte{userPassAuthVersion, authSuccess}); err != nil {
|
||||
if _, err := conn.Write([]byte{constant.Socks5UserPassAuthVersion, constant.Socks5AuthSuccess}); err != nil {
|
||||
HandshakeErrors.Add(1)
|
||||
return fmt.Errorf("write user password authentication success response failed: %w", err)
|
||||
}
|
||||
@@ -171,7 +160,7 @@ func (s *Server) handleAuthentication(conn net.Conn) error {
|
||||
}
|
||||
}
|
||||
HandshakeErrors.Add(1)
|
||||
if _, err := conn.Write([]byte{userPassAuthVersion, authFailure}); err != nil {
|
||||
if _, err := conn.Write([]byte{constant.Socks5UserPassAuthVersion, constant.Socks5AuthFailure}); err != nil {
|
||||
return fmt.Errorf("write user password authentication failure response failed: %w", err)
|
||||
}
|
||||
return fmt.Errorf("user password authentication failed: invalid user or password")
|
||||
@@ -187,7 +176,7 @@ func (s *Server) dialWithAuthentication(proxyConn net.Conn, auth *appctlpb.Auth)
|
||||
|
||||
if auth == nil || auth.GetUser() == "" || auth.GetPassword() == "" {
|
||||
// No authentication required.
|
||||
if _, err := proxyConn.Write([]byte{constant.Socks5Version, 1, noAuth}); err != nil {
|
||||
if _, err := proxyConn.Write([]byte{constant.Socks5Version, 1, constant.Socks5NoAuth}); err != nil {
|
||||
HandshakeErrors.Add(1)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("failed to write socks5 authentication header to egress proxy: %w", err)
|
||||
@@ -199,14 +188,14 @@ func (s *Server) dialWithAuthentication(proxyConn net.Conn, auth *appctlpb.Auth)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("failed to read socks5 authentication response from egress proxy: %w", err)
|
||||
}
|
||||
if resp[0] != constant.Socks5Version || resp[1] != noAuth {
|
||||
if resp[0] != constant.Socks5Version || resp[1] != constant.Socks5NoAuth {
|
||||
HandshakeErrors.Add(1)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("got unexpected socks5 authentication response from egress proxy: %v", resp)
|
||||
}
|
||||
} else {
|
||||
// User password authentication.
|
||||
if _, err := proxyConn.Write([]byte{constant.Socks5Version, 1, userPassAuth}); err != nil {
|
||||
if _, err := proxyConn.Write([]byte{constant.Socks5Version, 1, constant.Socks5UserPassAuth}); err != nil {
|
||||
HandshakeErrors.Add(1)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("failed to write socks5 authentication header to egress proxy: %w", err)
|
||||
@@ -218,14 +207,14 @@ func (s *Server) dialWithAuthentication(proxyConn net.Conn, auth *appctlpb.Auth)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("failed to read socks5 authentication response from egress proxy: %w", err)
|
||||
}
|
||||
if resp[0] != constant.Socks5Version || resp[1] != userPassAuth {
|
||||
if resp[0] != constant.Socks5Version || resp[1] != constant.Socks5UserPassAuth {
|
||||
HandshakeErrors.Add(1)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("got unexpected socks5 authentication response from egress proxy: %v", resp)
|
||||
}
|
||||
|
||||
// Send socks5 credential.
|
||||
credential := []byte{userPassAuthVersion}
|
||||
credential := []byte{constant.Socks5UserPassAuthVersion}
|
||||
credential = append(credential, byte(len(auth.GetUser())))
|
||||
credential = append(credential, []byte(auth.GetUser())...)
|
||||
credential = append(credential, byte(len(auth.GetPassword())))
|
||||
@@ -241,12 +230,12 @@ func (s *Server) dialWithAuthentication(proxyConn net.Conn, auth *appctlpb.Auth)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("failed to read socks5 authentication response from egress proxy: %w", err)
|
||||
}
|
||||
if resp[0] != userPassAuthVersion {
|
||||
if resp[0] != constant.Socks5UserPassAuthVersion {
|
||||
HandshakeErrors.Add(1)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("got unexpected socks5 user password authentication version from egress proxy: %v", resp[0])
|
||||
}
|
||||
if resp[1] != authSuccess {
|
||||
if resp[1] != constant.Socks5AuthSuccess {
|
||||
HandshakeErrors.Add(1)
|
||||
proxyConn.Close()
|
||||
return fmt.Errorf("socks5 authentication with user password failed from egress proxy")
|
||||
|
@@ -135,9 +135,9 @@ func (c *Client) dialSocks5Long(targetAddr string) (conn net.Conn, udpConn *net.
|
||||
// Prepare the first request.
|
||||
var req bytes.Buffer
|
||||
version := byte(constant.Socks5Version)
|
||||
method := byte(noAuth)
|
||||
method := byte(constant.Socks5NoAuth)
|
||||
if c.Credential != nil {
|
||||
method = userPassAuth
|
||||
method = constant.Socks5UserPassAuth
|
||||
}
|
||||
req.Write([]byte{
|
||||
version,
|
||||
@@ -158,7 +158,7 @@ func (c *Client) dialSocks5Long(targetAddr string) (conn net.Conn, udpConn *net.
|
||||
return nil, nil, nil, fmt.Errorf("socks method negotiation failed")
|
||||
}
|
||||
if c.Credential != nil {
|
||||
version := byte(userPassAuthVersion)
|
||||
version := byte(constant.Socks5UserPassAuthVersion)
|
||||
req.Reset()
|
||||
req.Write([]byte{version})
|
||||
req.Write([]byte{byte(len(c.Credential.User))})
|
||||
@@ -173,7 +173,7 @@ func (c *Client) dialSocks5Long(targetAddr string) (conn net.Conn, udpConn *net.
|
||||
return nil, nil, nil, fmt.Errorf("server does not respond properly")
|
||||
} else if resp[0] != version {
|
||||
return nil, nil, nil, fmt.Errorf("server does not support user/password version 1")
|
||||
} else if resp[1] != authSuccess {
|
||||
} else if resp[1] != constant.Socks5AuthSuccess {
|
||||
return nil, nil, nil, fmt.Errorf("user/password login failed")
|
||||
}
|
||||
}
|
||||
|
@@ -73,9 +73,8 @@ func TestSocks5Connect(t *testing.T) {
|
||||
}
|
||||
|
||||
req := bytes.NewBuffer(nil)
|
||||
req.Write([]byte{5})
|
||||
req.Write([]byte{1, noAuth})
|
||||
req.Write([]byte{5, 1, 0, 1, 127, 0, 0, 1})
|
||||
req.Write([]byte{constant.Socks5Version, 1, constant.Socks5NoAuth})
|
||||
req.Write([]byte{constant.Socks5Version, constant.Socks5ConnectCmd, 0, constant.Socks5IPv4Address, 127, 0, 0, 1})
|
||||
port := []byte{0, 0}
|
||||
binary.BigEndian.PutUint16(port, uint16(lAddr.Port))
|
||||
req.Write(port)
|
||||
@@ -88,8 +87,8 @@ func TestSocks5Connect(t *testing.T) {
|
||||
|
||||
// Verify response from socks server.
|
||||
want := []byte{
|
||||
constant.Socks5Version, noAuth,
|
||||
constant.Socks5Version, 0, 0, 1,
|
||||
constant.Socks5Version, constant.Socks5NoAuth,
|
||||
constant.Socks5Version, 0, 0, constant.Socks5IPv4Address,
|
||||
127, 0, 0, 1,
|
||||
0, 0,
|
||||
'p', 'o', 'n', 'g',
|
||||
@@ -182,9 +181,8 @@ func TestSocks5UDPAssociation(t *testing.T) {
|
||||
}
|
||||
|
||||
req := bytes.NewBuffer(nil)
|
||||
req.Write([]byte{5})
|
||||
req.Write([]byte{1, noAuth})
|
||||
req.Write([]byte{5, 3, 0, 1, 127, 0, 0, 1, 0, 0})
|
||||
req.Write([]byte{constant.Socks5Version, 1, constant.Socks5NoAuth})
|
||||
req.Write([]byte{constant.Socks5Version, constant.Socks5UDPAssociateCmd, 0, constant.Socks5IPv4Address, 127, 0, 0, 1, 0, 0})
|
||||
|
||||
// Send initial UDP association request.
|
||||
if _, err := conn.Write(req.Bytes()); err != nil {
|
||||
@@ -193,8 +191,8 @@ func TestSocks5UDPAssociation(t *testing.T) {
|
||||
|
||||
// Verify response from socks server.
|
||||
want := []byte{
|
||||
constant.Socks5Version, noAuth,
|
||||
constant.Socks5Version, 0, 0, 1,
|
||||
constant.Socks5Version, constant.Socks5NoAuth,
|
||||
constant.Socks5Version, 0, 0, constant.Socks5IPv4Address,
|
||||
0, 0, 0, 0,
|
||||
0, 0,
|
||||
}
|
||||
|
@@ -16,5 +16,5 @@
|
||||
package version
|
||||
|
||||
const (
|
||||
AppVersion = "3.5.1"
|
||||
AppVersion = "3.6.0"
|
||||
)
|
||||
|
178
mieru/test/cmd/exampleapiclient/exampleapiclient.go
Normal file
178
mieru/test/cmd/exampleapiclient/exampleapiclient.go
Normal file
@@ -0,0 +1,178 @@
|
||||
// Copyright (C) 2024 mieru authors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/enfein/mieru/v3/apis/client"
|
||||
"github.com/enfein/mieru/v3/apis/constant"
|
||||
"github.com/enfein/mieru/v3/apis/model"
|
||||
"github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
|
||||
"github.com/enfein/mieru/v3/pkg/util"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
port = flag.Int("port", 0, "mieru API client socks5 port")
|
||||
username = flag.String("username", "", "mieru username")
|
||||
password = flag.String("password", "", "mieru password")
|
||||
serverIP = flag.String("server_ip", "", "IP address of mieru proxy server")
|
||||
serverPort = flag.Int("server_port", 0, "Port number of mieru proxy server")
|
||||
serverProtocol = flag.String("server_protocol", "", "Transport protocol: TCP or UDP")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if *port < 1 || *port > 65535 {
|
||||
panic(fmt.Sprintf("port %d is invalid", *port))
|
||||
}
|
||||
if *username == "" {
|
||||
panic("username is not set")
|
||||
}
|
||||
if *password == "" {
|
||||
panic("password is not set")
|
||||
}
|
||||
if *serverIP == "" {
|
||||
panic("server_ip is not set")
|
||||
}
|
||||
if net.ParseIP(*serverIP) == nil {
|
||||
panic(fmt.Sprintf("Failed to parse server_ip %q", *serverIP))
|
||||
}
|
||||
if *serverPort < 1 || *serverPort > 65535 {
|
||||
panic(fmt.Sprintf("server_port %d is invalid", *serverPort))
|
||||
}
|
||||
var transportProtocol *appctlpb.TransportProtocol
|
||||
switch *serverProtocol {
|
||||
case "TCP":
|
||||
transportProtocol = appctlpb.TransportProtocol_TCP.Enum()
|
||||
case "UDP":
|
||||
transportProtocol = appctlpb.TransportProtocol_UDP.Enum()
|
||||
default:
|
||||
panic(fmt.Sprintf("Transport protocol %q is invalid", *serverProtocol))
|
||||
}
|
||||
|
||||
c := client.NewClient()
|
||||
if err := c.Store(&client.ClientConfig{
|
||||
Profile: &appctlpb.ClientProfile{
|
||||
ProfileName: proto.String("api"),
|
||||
User: &appctlpb.User{
|
||||
Name: username,
|
||||
Password: password,
|
||||
},
|
||||
Servers: []*appctlpb.ServerEndpoint{
|
||||
{
|
||||
IpAddress: serverIP,
|
||||
PortBindings: []*appctlpb.PortBinding{
|
||||
{
|
||||
Port: proto.Int32(int32(*serverPort)),
|
||||
Protocol: transportProtocol,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Mtu: proto.Int32(1400),
|
||||
},
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if _, err := c.Load(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := c.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !c.IsRunning() {
|
||||
panic("client is not running after start")
|
||||
}
|
||||
|
||||
l, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: *port})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go handleOneSocks5Conn(c, conn)
|
||||
}
|
||||
}
|
||||
|
||||
func handleOneSocks5Conn(c client.Client, conn net.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
// Handle socks5 authentication.
|
||||
if err := socks5ClientHandshake(conn); err != nil {
|
||||
panic(fmt.Sprintf("socks5ClientHandshake() failed: %v", err))
|
||||
}
|
||||
|
||||
// Find destination.
|
||||
socks5Header := make([]byte, 3)
|
||||
if _, err := io.ReadFull(conn, socks5Header); err != nil {
|
||||
panic(fmt.Sprintf("Read socks5 header failed: %v", err))
|
||||
}
|
||||
addr := model.AddrSpec{}
|
||||
if err := addr.ReadFromSocks5(conn); err != nil {
|
||||
panic(fmt.Sprintf("ReadFromSocks5() failed: %v", err))
|
||||
}
|
||||
|
||||
// Dial to proxy server and do handshake.
|
||||
ctx := context.Background()
|
||||
proxyConn, err := c.DialContext(ctx)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("DialContext() failed: %v", err))
|
||||
}
|
||||
defer proxyConn.Close()
|
||||
if err := c.HandshakeWithConnect(ctx, proxyConn, addr); err != nil {
|
||||
panic(fmt.Sprintf("HandshakeWithConnect() failed: %v", err))
|
||||
}
|
||||
|
||||
// Send the connect response back to the application.
|
||||
var resp bytes.Buffer
|
||||
resp.Write([]byte{constant.Socks5Version, 0, 0})
|
||||
if err := addr.WriteToSocks5(&resp); err != nil {
|
||||
panic(fmt.Sprintf("WriteToSocks5() failed: %v", err))
|
||||
}
|
||||
if _, err := conn.Write(resp.Bytes()); err != nil {
|
||||
panic(fmt.Sprintf("Write socks5 response failed: %v", err))
|
||||
}
|
||||
|
||||
// Exchange payload.
|
||||
util.BidiCopy(conn, proxyConn)
|
||||
}
|
||||
|
||||
func socks5ClientHandshake(conn net.Conn) error {
|
||||
// Only accept socks5 with no authentication.
|
||||
socks5Header := make([]byte, 3)
|
||||
if _, err := io.ReadFull(conn, socks5Header); err != nil {
|
||||
return err
|
||||
}
|
||||
wantHeader := []byte{constant.Socks5Version, 1, constant.Socks5NoAuth}
|
||||
if !bytes.Equal(socks5Header, wantHeader) {
|
||||
return fmt.Errorf("got socks5 header %v, want %v", socks5Header, wantHeader)
|
||||
}
|
||||
if _, err := conn.Write([]byte{constant.Socks5Version, constant.Socks5AuthSuccess}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@@ -44,4 +44,5 @@ echo "========== BEGIN OF TCP TEST =========="
|
||||
echo "========== END OF TCP TEST =========="
|
||||
|
||||
echo "Test is successful."
|
||||
sleep 1
|
||||
exit 0
|
||||
|
@@ -20,7 +20,7 @@ FROM ubuntu:24.04
|
||||
WORKDIR /test
|
||||
|
||||
# Copy binaries, data and test script into the container.
|
||||
COPY mieru mita httpserver sockshttpclient socksudpclient udpserver \
|
||||
COPY exampleapiclient mieru mita httpserver sockshttpclient socksudpclient udpserver \
|
||||
test/deploy/httptest/client_mix.json test/deploy/httptest/server_mix.json \
|
||||
test/deploy/httptest/client_tcp.json test/deploy/httptest/server_tcp.json \
|
||||
test/deploy/httptest/client_udp.json test/deploy/httptest/server_udp.json \
|
||||
|
@@ -35,11 +35,6 @@ sleep 1
|
||||
./mita run &
|
||||
sleep 1
|
||||
|
||||
# Run UDP associate test.
|
||||
echo "========== BEGIN OF UDP ASSOCIATE TEST =========="
|
||||
./test_mix_udp_associate.sh
|
||||
echo "========== END OF UDP ASSOCIATE TEST =========="
|
||||
|
||||
# Run TCP test.
|
||||
echo "========== BEGIN OF TCP TEST =========="
|
||||
./test_tcp.sh
|
||||
@@ -50,5 +45,11 @@ echo "========== BEGIN OF UDP TEST =========="
|
||||
./test_udp.sh
|
||||
echo "========== END OF UDP TEST =========="
|
||||
|
||||
# Run UDP associate test.
|
||||
echo "========== BEGIN OF UDP ASSOCIATE TEST =========="
|
||||
./test_mix_udp_associate.sh
|
||||
echo "========== END OF UDP ASSOCIATE TEST =========="
|
||||
|
||||
echo "Test is successful."
|
||||
sleep 1
|
||||
exit 0
|
||||
|
@@ -55,6 +55,10 @@ if [[ "$?" -ne 0 ]]; then
|
||||
fi
|
||||
./mieru profile cpu start /test/mieru.tcp.cpu.gz
|
||||
|
||||
# Start mieru API client.
|
||||
./exampleapiclient -port=1081 -username=baozi -password=manlianpenfen \
|
||||
-server_ip=127.0.0.1 -server_port=8964 -server_protocol=TCP &
|
||||
|
||||
# Start testing.
|
||||
sleep 2
|
||||
echo ">>> socks5 - new connections - TCP <<<"
|
||||
@@ -69,6 +73,16 @@ if [ "$?" -ne "0" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - new connections with API client - TCP <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1081 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
echo "TCP - test socks5 new_conn with API client failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> http - new connections - TCP <<<"
|
||||
./sockshttpclient -proxy_mode=http -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
|
@@ -55,6 +55,10 @@ if [[ "$?" -ne 0 ]]; then
|
||||
fi
|
||||
./mieru profile cpu start /test/mieru.udp.cpu.gz
|
||||
|
||||
# Start mieru API client.
|
||||
./exampleapiclient -port=1082 -username=baozi -password=manlianpenfen \
|
||||
-server_ip=127.0.0.1 -server_port=8964 -server_protocol=UDP &
|
||||
|
||||
# Start testing.
|
||||
sleep 2
|
||||
echo ">>> socks5 - new connections - UDP <<<"
|
||||
@@ -69,6 +73,16 @@ if [ "$?" -ne "0" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - new connections with API client - UDP <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1082 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
echo "UDP - test socks5 new_conn with API client failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> http - new connections - UDP <<<"
|
||||
./sockshttpclient -proxy_mode=http -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
|
@@ -90,4 +90,5 @@ iptables -D INPUT -p tcp --sport 8964 -m statistic --mode random --probability 0
|
||||
iptables -D INPUT -p udp --sport 8964 -m statistic --mode random --probability 0.001 -j DROP
|
||||
|
||||
echo "Test is successful."
|
||||
sleep 1
|
||||
exit 0
|
||||
|
@@ -78,4 +78,5 @@ if [ "$?" -ne "0" ]; then
|
||||
fi
|
||||
|
||||
echo "Test is successful."
|
||||
sleep 1
|
||||
exit 0
|
||||
|
34
naiveproxy/.github/workflows/build.yml
vendored
34
naiveproxy/.github/workflows/build.yml
vendored
@@ -375,40 +375,6 @@ jobs:
|
||||
run: gh release upload "${GITHUB_REF##*/}" ${{ env.BUNDLE }}.tar.xz --clobber
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ios:
|
||||
needs: cache-toolchains-mac
|
||||
runs-on: macos-13
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch: [arm64]
|
||||
env:
|
||||
EXTRA_FLAGS: 'target_cpu="${{ matrix.arch }}" target_os="ios" ios_enable_code_signing=false'
|
||||
BUNDLE: naiveproxy-${{ github.event.release.tag_name }}-${{ github.job }}-${{ matrix.arch }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Cache toolchains and PGO
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
src/third_party/llvm-build/Release+Asserts/
|
||||
src/chrome/build/pgo_profiles/chrome-mac-*
|
||||
src/gn/
|
||||
key: toolchains-pgo-mac-${{ hashFiles('CHROMIUM_VERSION') }}-v${{ env.CACHE_EPOCH }}
|
||||
- id: ccache-timestamp
|
||||
run: echo "CCACHE_TIMESTAMP=$(date +%s)" >>$GITHUB_OUTPUT
|
||||
- name: Cache ccache files
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/Library/Caches/ccache
|
||||
key: ccache-ios-${{ matrix.arch }}-${{ hashFiles('CHROMIUM_VERSION') }}-${{ steps.ccache-timestamp.outputs.CCACHE_TIMESTAMP }}
|
||||
restore-keys: ccache-ios-${{ matrix.arch }}-${{ hashFiles('CHROMIUM_VERSION') }}-
|
||||
- run: brew install ninja ccache
|
||||
- run: pip install setuptools
|
||||
- run: ./get-clang.sh
|
||||
- run: ccache -z
|
||||
- run: ./build.sh
|
||||
- run: ccache -s
|
||||
openwrt:
|
||||
needs: cache-toolchains-posix
|
||||
runs-on: ubuntu-22.04
|
||||
|
@@ -82,7 +82,7 @@ Or `quic://user:pass@example.com`, if it works better. See also [parameter usage
|
||||
* [v2rayN](https://github.com/2dust/v2rayN), GUI client, Windows
|
||||
* [NekoBox for Android](https://github.com/MatsuriDayo/NekoBoxForAndroid), Proxy toolchain, Android
|
||||
* [NekoRay / NekoBox For PC](https://github.com/MatsuriDayo/nekoray), Qt based GUI, Windows, Linux
|
||||
* [Yet Another Shadow Socket](https://github.com/Chilledheart/yass), NaïveProxy-compatible forward proxy, Android, iOS, Windows, macOS, Linux, FreeBSD
|
||||
* [Yet Another Shadow Socket](https://github.com/Chilledheart/yass), NaïveProxy-compatible forward proxy, Android, iOS, Windows, macOS, Linux, FreeBSD
|
||||
|
||||
## Notes for downstream
|
||||
|
||||
@@ -114,7 +114,7 @@ Further reads and writes after `kFirstPaddings` are unpadded to avoid performanc
|
||||
|
||||
### H2 RST_STREAM frame padding
|
||||
|
||||
In experiments, NaïveProxy tends to send too many RST_STREAM frames per session, an uncommon behavior from regular browsers. To solve this, an END_STREAM DATA frame padded with total length distributed in [48, 72] is prepended to the RST_STREAM frame so it looks like a HEADERS frame. The server often replies to this with a WINDOW_UPDATE because padding is accounted in flow control. Whether this results in a new uncommon behavior is still unclear.
|
||||
In experiments, NaïveProxy tends to send too many RST_STREAM frames per session, an uncommon behavior from regular browsers. To solve this, an END_STREAM DATA frame padded with total length distributed in [48, 72] is prepended to the RST_STREAM frame so it looks like a HEADERS frame. The server often replies to this with a WINDOW_UPDATE because padding is accounted in flow control. Whether this results in a new uncommon behavior is still unclear.
|
||||
|
||||
### H2 HEADERS frame padding
|
||||
|
||||
|
@@ -1153,15 +1153,12 @@ component("base") {
|
||||
"android/build_info_stub.cc",
|
||||
"android/content_uri_utils.h",
|
||||
"android/content_uri_utils_stub.cc",
|
||||
"android/jni_android.h",
|
||||
"android/library_loader/anchor_functions.h",
|
||||
"android/library_loader/library_loader_hooks.h",
|
||||
"android/path_utils.h",
|
||||
"android/scoped_hardware_buffer_fence_sync.cc",
|
||||
"android/scoped_hardware_buffer_fence_sync.h",
|
||||
"android/scoped_hardware_buffer_handle.cc",
|
||||
"android/scoped_hardware_buffer_handle.h",
|
||||
"android/scoped_java_ref.h",
|
||||
"android/sys_utils.h",
|
||||
"debug/stack_trace_android.cc",
|
||||
"files/file_util_android.cc",
|
||||
@@ -1196,7 +1193,6 @@ component("base") {
|
||||
deps += [
|
||||
"//third_party/ashmem",
|
||||
"//third_party/cpu_features:ndk_compat",
|
||||
"//third_party/jni_zero:jni_zero",
|
||||
]
|
||||
|
||||
# Needs to be a public config so that dependent targets link against it as
|
||||
@@ -1276,6 +1272,8 @@ component("base") {
|
||||
"android/unguessable_token_android.h",
|
||||
]
|
||||
deps += [ "//build:robolectric_buildflags" ]
|
||||
}
|
||||
if (is_android || is_robolectric) {
|
||||
public_deps += [ "//third_party/jni_zero:jni_zero" ]
|
||||
} # is_android || is_robolectric
|
||||
|
||||
|
@@ -125,10 +125,6 @@ class BASE_EXPORT StackTrace {
|
||||
// prefix string prepended to each line.
|
||||
void OutputToStreamWithPrefix(std::ostream* os,
|
||||
cstring_view prefix_string) const;
|
||||
#else
|
||||
void OutputToStream(std::ostream* os) const;
|
||||
void OutputToStreamWithPrefix(std::ostream* os,
|
||||
cstring_view prefix_string) const;
|
||||
#endif
|
||||
|
||||
// Resolves backtrace to symbols and returns as string.
|
||||
@@ -152,9 +148,6 @@ class BASE_EXPORT StackTrace {
|
||||
#if !defined(__UCLIBC__) && !defined(_AIX)
|
||||
void OutputToStreamWithPrefixImpl(std::ostream* os,
|
||||
cstring_view prefix_string) const;
|
||||
#else
|
||||
void OutputToStreamWithPrefixImpl(std::ostream* os,
|
||||
cstring_view prefix_string) const {}
|
||||
#endif
|
||||
|
||||
// Returns true if generation of symbolized stack traces is to be suppressed.
|
||||
|
@@ -1075,6 +1075,10 @@ void StackTrace::OutputToStreamWithPrefixImpl(
|
||||
StreamBacktraceOutputHandler handler(os);
|
||||
ProcessBacktrace(addresses(), prefix_string, &handler);
|
||||
}
|
||||
#else
|
||||
void StackTrace::OutputToStreamWithPrefixImpl(
|
||||
std::ostream*, cstring_view) const {
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace internal {
|
||||
|
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
#include "base/tracing_buildflags.h"
|
||||
|
||||
#if 1
|
||||
#if BUILDFLAG(ENABLE_BASE_TRACING)
|
||||
#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h" // nogncheck
|
||||
#else
|
||||
|
||||
|
@@ -5,8 +5,6 @@
|
||||
#ifndef BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_H_
|
||||
#define BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_H_
|
||||
|
||||
#include "base/trace_event/trace_event_stub.h"
|
||||
#if 0
|
||||
#include <stdint.h>
|
||||
|
||||
#include <iosfwd>
|
||||
@@ -161,5 +159,4 @@ void BASE_EXPORT PrintTo(const MemoryAllocatorDump::Entry&, std::ostream*);
|
||||
} // namespace trace_event
|
||||
} // namespace base
|
||||
|
||||
#endif
|
||||
#endif // BASE_TRACE_EVENT_MEMORY_ALLOCATOR_DUMP_H_
|
||||
|
@@ -5,8 +5,6 @@
|
||||
#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
|
||||
#define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
|
||||
|
||||
#include "base/trace_event/trace_event_stub.h"
|
||||
#if 0
|
||||
#include <stdint.h>
|
||||
|
||||
#include <map>
|
||||
@@ -279,5 +277,4 @@ class BASE_EXPORT MemoryDumpManager {
|
||||
} // namespace trace_event
|
||||
} // namespace base
|
||||
|
||||
#endif
|
||||
#endif // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
|
||||
|
@@ -5,8 +5,6 @@
|
||||
#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_H_
|
||||
#define BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_H_
|
||||
|
||||
#include "base/trace_event/trace_event_stub.h"
|
||||
#if 0
|
||||
#include "base/base_export.h"
|
||||
#include "base/process/process_handle.h"
|
||||
#include "base/trace_event/memory_dump_request_args.h"
|
||||
@@ -50,5 +48,4 @@ class BASE_EXPORT MemoryDumpProvider {
|
||||
} // namespace trace_event
|
||||
} // namespace base
|
||||
|
||||
#endif
|
||||
#endif // BASE_TRACE_EVENT_MEMORY_DUMP_PROVIDER_H_
|
||||
|
@@ -5,8 +5,6 @@
|
||||
#ifndef BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
|
||||
#define BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
|
||||
|
||||
#include "base/trace_event/trace_event_stub.h"
|
||||
#if 0
|
||||
#include <stddef.h>
|
||||
|
||||
#include <map>
|
||||
@@ -297,5 +295,4 @@ class BASE_EXPORT ProcessMemoryDump {
|
||||
} // namespace trace_event
|
||||
} // namespace base
|
||||
|
||||
#endif
|
||||
#endif // BASE_TRACE_EVENT_PROCESS_MEMORY_DUMP_H_
|
||||
|
@@ -5,8 +5,6 @@
|
||||
#ifndef BASE_TRACE_EVENT_TRACE_EVENT_H_
|
||||
#define BASE_TRACE_EVENT_TRACE_EVENT_H_
|
||||
|
||||
#include "base/trace_event/trace_event_stub.h"
|
||||
#if 0
|
||||
// This header file defines implementation details of how the trace macros in
|
||||
// trace_event_common.h collect and store trace events. Anything not
|
||||
// implementation-specific should go in trace_event_common.h instead of here.
|
||||
@@ -467,5 +465,4 @@ class TraceScopedTrackableObject {
|
||||
} // namespace trace_event
|
||||
} // namespace base
|
||||
|
||||
#endif
|
||||
#endif // BASE_TRACE_EVENT_TRACE_EVENT_H_
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <string_view>
|
||||
|
||||
#include "base/base_export.h"
|
||||
#include "base/check.h"
|
||||
#include "base/trace_event/common/trace_event_common.h"
|
||||
#include "base/trace_event/memory_allocator_dump_guid.h"
|
||||
#include "base/values.h"
|
||||
@@ -373,41 +372,6 @@ class BASE_EXPORT MemoryDumpProvider {
|
||||
MemoryDumpProvider() = default;
|
||||
};
|
||||
|
||||
class BASE_EXPORT MemoryAllocatorDump {
|
||||
public:
|
||||
static constexpr char* kNameSize = nullptr;
|
||||
static constexpr char* kNameObjectCount = nullptr;
|
||||
static constexpr char* kUnitsBytes = nullptr;
|
||||
static constexpr char* kUnitsObjects = nullptr;
|
||||
static constexpr char* kTypeScalar = nullptr;
|
||||
static constexpr char* kTypeString = nullptr;
|
||||
void AddScalar(const char* name, const char* units, uint64_t value) {}
|
||||
void AddString(const char* name,
|
||||
const char* units,
|
||||
const std::string& value) {}
|
||||
const std::string& absolute_name() const { return absolute_name_; }
|
||||
const MemoryAllocatorDumpGuid& guid() const { return guid_; }
|
||||
|
||||
private:
|
||||
const std::string absolute_name_;
|
||||
MemoryAllocatorDumpGuid guid_;
|
||||
};
|
||||
|
||||
class BASE_EXPORT ProcessMemoryDump {
|
||||
public:
|
||||
MemoryAllocatorDump* CreateAllocatorDump(const std::string& absolute_name) {
|
||||
CHECK(false);
|
||||
return nullptr;
|
||||
}
|
||||
MemoryAllocatorDump* GetAllocatorDump(
|
||||
const std::string& absolute_name) const {
|
||||
CHECK(false);
|
||||
return nullptr;
|
||||
}
|
||||
void AddOwnershipEdge(const MemoryAllocatorDumpGuid& source,
|
||||
const MemoryAllocatorDumpGuid& target) {}
|
||||
};
|
||||
|
||||
class BASE_EXPORT MemoryDumpManager {
|
||||
public:
|
||||
static constexpr const char* const kTraceCategory =
|
||||
@@ -430,19 +394,19 @@ class TracedArray;
|
||||
class TracedDictionary;
|
||||
class EventContext;
|
||||
|
||||
class BASE_EXPORT StaticString {
|
||||
class StaticString {
|
||||
public:
|
||||
template <typename T>
|
||||
StaticString(T) {}
|
||||
};
|
||||
|
||||
class BASE_EXPORT DynamicString {
|
||||
class DynamicString {
|
||||
public:
|
||||
template <typename T>
|
||||
explicit DynamicString(T) {}
|
||||
};
|
||||
|
||||
class BASE_EXPORT TracedValue {
|
||||
class TracedValue {
|
||||
public:
|
||||
void WriteInt64(int64_t) && {}
|
||||
void WriteUInt64(uint64_t) && {}
|
||||
@@ -457,7 +421,7 @@ class BASE_EXPORT TracedValue {
|
||||
TracedArray WriteArray() &&;
|
||||
};
|
||||
|
||||
class BASE_EXPORT TracedDictionary {
|
||||
class TracedDictionary {
|
||||
public:
|
||||
TracedValue AddItem(StaticString) { return TracedValue(); }
|
||||
TracedValue AddItem(DynamicString) { return TracedValue(); }
|
||||
@@ -473,7 +437,7 @@ class BASE_EXPORT TracedDictionary {
|
||||
TracedArray AddArray(DynamicString);
|
||||
};
|
||||
|
||||
class BASE_EXPORT TracedArray {
|
||||
class TracedArray {
|
||||
public:
|
||||
TracedValue AppendItem() { return TracedValue(); }
|
||||
|
||||
@@ -485,7 +449,7 @@ class BASE_EXPORT TracedArray {
|
||||
};
|
||||
|
||||
template <class T>
|
||||
BASE_EXPORT void WriteIntoTracedValue(TracedValue, T&&) {}
|
||||
void WriteIntoTracedValue(TracedValue, T&&) {}
|
||||
|
||||
struct Track {
|
||||
explicit Track(uint64_t id) {}
|
||||
|
@@ -11,10 +11,8 @@
|
||||
|
||||
// Needed not for this file, but for every user of the TRACE_EVENT macros for
|
||||
// the lambda definition. So included here for convenience.
|
||||
#if 0
|
||||
#include "base/tracing/protos/chrome_track_event.pbzero.h"
|
||||
#include "third_party/perfetto/include/perfetto/tracing/event_context.h"
|
||||
#include "third_party/perfetto/include/perfetto/tracing/string_helpers.h"
|
||||
#endif
|
||||
|
||||
#endif // BASE_TRACE_EVENT_TYPED_MACROS_H_
|
||||
|
@@ -50,6 +50,9 @@ flags="$flags"'
|
||||
fatal_linker_warnings=false
|
||||
treat_warnings_as_errors=false
|
||||
|
||||
is_cronet_build=true
|
||||
chrome_pgo_phase=2
|
||||
|
||||
enable_base_tracing=false
|
||||
use_udev=false
|
||||
use_aura=false
|
||||
@@ -58,16 +61,17 @@ flags="$flags"'
|
||||
use_gtk=false
|
||||
use_platform_icu_alternatives=true
|
||||
use_glib=false
|
||||
enable_js_protobuf=false
|
||||
|
||||
disable_file_support=true
|
||||
enable_websockets=false
|
||||
use_kerberos=false
|
||||
disable_file_support=true
|
||||
disable_zstd_filter=false
|
||||
enable_mdns=false
|
||||
enable_reporting=false
|
||||
include_transport_security_state_preload_list=false
|
||||
use_nss_certs=false
|
||||
enable_device_bound_sessions=false
|
||||
use_nss_certs=false
|
||||
|
||||
enable_backup_ref_ptr_support=false
|
||||
enable_dangling_raw_ptr_checks=false
|
||||
|
@@ -27,7 +27,7 @@ config("compiler") {
|
||||
|
||||
defines = [
|
||||
"_LIBCPP_HAS_MUSL_LIBC",
|
||||
"__UCLIBC__",
|
||||
#"__UCLIBC__",
|
||||
"__MUSL__",
|
||||
]
|
||||
|
||||
|
@@ -461,6 +461,7 @@ def cleanup_jail_symlinks(install_root: str) -> None:
|
||||
os.remove(full_path)
|
||||
os.symlink(relative_path, full_path)
|
||||
|
||||
|
||||
def verify_library_deps(install_root: str) -> None:
|
||||
"""
|
||||
Verifies if all required libraries are present in the sysroot environment.
|
||||
@@ -487,7 +488,6 @@ def verify_library_deps(install_root: str) -> None:
|
||||
output = subprocess.check_output(cmd_readelf).decode()
|
||||
for line in output.split("\n"):
|
||||
if "NEEDED" in line:
|
||||
print(file, line)
|
||||
needed_libs.add(line.split("[")[1].split("]")[0])
|
||||
|
||||
missing_libs = needed_libs - shared_libs
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"listen": "socks://127.0.0.1:1080",
|
||||
"listen": ["socks://127.0.0.1:1080", "http://127.0.0.1:8080"],
|
||||
"proxy": "https://user:pass@domain.example",
|
||||
"log": ""
|
||||
}
|
||||
|
@@ -683,6 +683,8 @@ component("net") {
|
||||
"log/net_log_values.h",
|
||||
"log/net_log_with_source.cc",
|
||||
"log/net_log_with_source.h",
|
||||
"log/trace_net_log_observer.cc",
|
||||
"log/trace_net_log_observer.h",
|
||||
"nqe/cached_network_quality.cc",
|
||||
"nqe/cached_network_quality.h",
|
||||
"nqe/effective_connection_type.cc",
|
||||
@@ -1654,7 +1656,7 @@ component("net") {
|
||||
configs += [ "//build/config/compiler:optimize_max" ]
|
||||
}
|
||||
|
||||
if (false) {
|
||||
if (!is_cronet_build) {
|
||||
deps += [ "//mojo/public/cpp/bindings:default_construct_tag" ]
|
||||
}
|
||||
}
|
||||
|
@@ -12,9 +12,9 @@
|
||||
#ifndef NET_BASE_TRACE_EVENT_STUB_H_
|
||||
#define NET_BASE_TRACE_EVENT_STUB_H_
|
||||
|
||||
#import "base/base_export.h"
|
||||
#import "base/memory/weak_ptr.h"
|
||||
#import "base/trace_event/trace_event_stub.h"
|
||||
#include "base/base_export.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/trace_event/trace_event_stub.h"
|
||||
|
||||
namespace base::trace_event {
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#include "build/build_config.h"
|
||||
#include "net/base/cronet_buildflags.h"
|
||||
|
||||
#if BUILDFLAG(CRONET_BUILD) && !BUILDFLAG(IS_APPLE)
|
||||
#if BUILDFLAG(CRONET_BUILD)
|
||||
#include "net/base/trace_event_stub.h" // IWYU pragma: export
|
||||
#endif // BUILDFLAG(CRONET_BUILD) && !BUILDFLAG(IS_APPLE)
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#include "net/cookies/cookie_util.h"
|
||||
#include "net/cookies/site_for_cookies.h"
|
||||
|
||||
#if 0
|
||||
#if !BUILDFLAG(CRONET_BUILD)
|
||||
#include "mojo/public/cpp/bindings/default_construct_tag.h"
|
||||
#endif
|
||||
|
||||
@@ -60,7 +60,7 @@ std::string CookiePartitionKey::SerializedCookiePartitionKey::GetDebugString()
|
||||
return out;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if !BUILDFLAG(CRONET_BUILD)
|
||||
CookiePartitionKey::CookiePartitionKey(mojo::DefaultConstruct::Tag) {}
|
||||
#endif
|
||||
bool CookiePartitionKey::SerializedCookiePartitionKey::has_cross_site_ancestor()
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#include "net/base/schemeful_site.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
#if 0
|
||||
#if !BUILDFLAG(CRONET_BUILD)
|
||||
#include "mojo/public/cpp/bindings/default_construct_tag.h"
|
||||
#endif
|
||||
|
||||
@@ -60,7 +60,7 @@ class NET_EXPORT CookiePartitionKey {
|
||||
static AncestorChainBit BoolToAncestorChainBit(bool val);
|
||||
|
||||
CookiePartitionKey() = delete;
|
||||
#if 0
|
||||
#if !BUILDFLAG(CRONET_BUILD)
|
||||
explicit CookiePartitionKey(mojo::DefaultConstruct::Tag);
|
||||
#endif
|
||||
CookiePartitionKey(const CookiePartitionKey& other);
|
||||
|
@@ -257,12 +257,12 @@
|
||||
#if __has_cpp_attribute(clang::musttail) && !defined(__arm__) && \
|
||||
!defined(_ARCH_PPC) && !defined(__wasm__) && \
|
||||
!(defined(_MSC_VER) && defined(_M_IX86)) && \
|
||||
!(defined(__NDK_MAJOR__) && __NDK_MAJOR__ <= 24) && !defined(__mips__)
|
||||
!(defined(__NDK_MAJOR__) && __NDK_MAJOR__ <= 24)
|
||||
# ifndef PROTO2_OPENSOURCE
|
||||
// Compilation fails on ARM32: b/195943306
|
||||
// Compilation fails on powerpc64le: b/187985113
|
||||
// Compilation fails on X86 Windows:
|
||||
// 1
|
||||
// https://github.com/llvm/llvm-project/issues/53271
|
||||
# endif
|
||||
#define PROTOBUF_MUSTTAIL [[clang::musttail]]
|
||||
#define PROTOBUF_TAILCALL true
|
||||
|
@@ -69,6 +69,24 @@ component("url") {
|
||||
|
||||
configs += [ "//build/config/compiler:wexit_time_destructors" ]
|
||||
|
||||
if (is_android || is_robolectric) {
|
||||
#deps += [ ":url_jni_headers" ]
|
||||
if (!is_cronet_build) {
|
||||
sources += [
|
||||
"android/gurl_android.cc",
|
||||
"android/gurl_android.h",
|
||||
"android/origin_android.cc",
|
||||
"android/parsed_android.cc",
|
||||
"android/parsed_android.h",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_robolectric) {
|
||||
# Make jni.h available.
|
||||
public_configs = [ "//third_party/jdk" ]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
# Don't conflict with Windows' "url.dll".
|
||||
output_name = "url_lib"
|
||||
|
@@ -154,10 +154,7 @@ CanonHostInfo::Family DoIPv4AddressToNumber(const CHAR* spec,
|
||||
while (true) {
|
||||
// If this is not the first character of a component, go to the next
|
||||
// component.
|
||||
// XXX: On mips64el, using
|
||||
// `current_position != host.begin && spec[current_position - 1] != '.'`
|
||||
// would have current_position going to the negative.
|
||||
if (current_position > host.begin && spec[current_position - 1] != '.') {
|
||||
if (current_position != host.begin && spec[current_position - 1] != '.') {
|
||||
--current_position;
|
||||
continue;
|
||||
}
|
||||
|
@@ -49,10 +49,19 @@ nfpms:
|
||||
- src: release/config/config.json
|
||||
dst: /etc/sing-box/config.json
|
||||
type: config
|
||||
|
||||
- src: release/config/sing-box.service
|
||||
dst: /usr/lib/systemd/system/sing-box.service
|
||||
- src: release/config/sing-box@.service
|
||||
dst: /usr/lib/systemd/system/sing-box@.service
|
||||
|
||||
- src: release/completions/sing-box.bash
|
||||
dst: /usr/share/bash-completion/completions/sing-box.bash
|
||||
- src: release/completions/sing-box.fish
|
||||
dst: /usr/share/fish/vendor_completions.d/sing-box.fish
|
||||
- src: release/completions/sing-box.zsh
|
||||
dst: /usr/share/zsh/site-functions/_sing-box
|
||||
|
||||
- src: LICENSE
|
||||
dst: /usr/share/licenses/sing-box/LICENSE
|
||||
deb:
|
||||
|
@@ -122,7 +122,7 @@ nfpms:
|
||||
- deb
|
||||
- rpm
|
||||
- archlinux
|
||||
- apk
|
||||
# - apk
|
||||
# - ipk
|
||||
priority: extra
|
||||
contents:
|
||||
|
@@ -68,7 +68,6 @@ release:
|
||||
dist/*.zip \
|
||||
dist/*.deb \
|
||||
dist/*.rpm \
|
||||
dist/*.apk \
|
||||
dist/*_amd64.pkg.tar.zst \
|
||||
dist/*_arm64.pkg.tar.zst \
|
||||
dist/release
|
||||
|
@@ -188,7 +188,7 @@ func (d *DNS) newPacketConnection(ctx context.Context, conn N.PacketConn, readWa
|
||||
fastClose, cancel := common.ContextWithCancelCause(ctx)
|
||||
timeout := canceler.New(fastClose, cancel, C.DNSTimeout)
|
||||
var group task.Group
|
||||
group.Append0(func(ctx context.Context) error {
|
||||
group.Append0(func(_ context.Context) error {
|
||||
for {
|
||||
var (
|
||||
message mDNS.Msg
|
||||
|
@@ -1,6 +1,6 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_VERSION:=1.8.4
|
||||
PKG_VERSION:=1.8.5
|
||||
|
||||
LUCI_TITLE:=LuCI Support for mihomo
|
||||
LUCI_DEPENDS:=+luci-base +mihomo
|
||||
|
@@ -252,7 +252,7 @@ return view.extend({
|
||||
|
||||
s.tab('general', _('General Config'));
|
||||
|
||||
o = s.taboption('general', form.ListValue, 'log_level', _('Log Level'));
|
||||
o = s.taboption('general', form.ListValue, 'log_level', '*' + ' ' + _('Log Level'));
|
||||
o.value('silent');
|
||||
o.value('error');
|
||||
o.value('warning');
|
||||
@@ -269,11 +269,10 @@ return view.extend({
|
||||
o.value('always', _('Enable'));
|
||||
o.value('off', _('Disable'));
|
||||
|
||||
o = s.taboption('general', widgets.NetworkSelect, 'outbound_interface', _('Outbound Interface'));
|
||||
o = s.taboption('general', widgets.NetworkSelect, 'outbound_interface', '*' + ' ' + _('Outbound Interface'));
|
||||
o.optional = true;
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('general', form.Flag, 'ipv6', _('IPv6'));
|
||||
o = s.taboption('general', form.Flag, 'ipv6', '*' + ' ' + _('IPv6'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('general', form.Value, 'tcp_keep_alive_idle', _('TCP Keep Alive Idle'));
|
||||
@@ -286,20 +285,20 @@ return view.extend({
|
||||
|
||||
s.tab('external_control', _('External Control Config'));
|
||||
|
||||
o = s.taboption('external_control', form.Value, 'ui_name', _('UI Name'));
|
||||
o = s.taboption('external_control', form.Value, 'ui_name', '*' + ' ' + _('UI Name'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('external_control', form.Value, 'ui_url', _('UI Url'));
|
||||
o = s.taboption('external_control', form.Value, 'ui_url', '*' + ' ' + _('UI Url'));
|
||||
o.rmempty = false;
|
||||
o.value('https://mirror.ghproxy.com/https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip', 'MetaCubeXD')
|
||||
o.value('https://mirror.ghproxy.com/https://github.com/MetaCubeX/Yacd-meta/archive/refs/heads/gh-pages.zip', 'YACD')
|
||||
o.value('https://mirror.ghproxy.com/https://github.com/MetaCubeX/Razord-meta/archive/refs/heads/gh-pages.zip', 'Razord')
|
||||
|
||||
o = s.taboption('external_control', form.Value, 'api_port', _('API Port'));
|
||||
o = s.taboption('external_control', form.Value, 'api_port', '*' + ' ' + _('API Port'));
|
||||
o.datatype = 'port';
|
||||
o.placeholder = '9090';
|
||||
|
||||
o = s.taboption('external_control', form.Value, 'api_secret', _('API Secret'));
|
||||
o = s.taboption('external_control', form.Value, 'api_secret', '*' + ' ' + _('API Secret'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('external_control', form.Flag, 'selection_cache', _('Save Proxy Selection'));
|
||||
@@ -307,30 +306,30 @@ return view.extend({
|
||||
|
||||
s.tab('inbound', _('Inbound Config'));
|
||||
|
||||
o = s.taboption('inbound', form.Flag, 'allow_lan', _('Allow Lan'));
|
||||
o = s.taboption('inbound', form.Flag, 'allow_lan', '*' + ' ' + _('Allow Lan'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('inbound', form.Value, 'http_port', _('HTTP Port'));
|
||||
o = s.taboption('inbound', form.Value, 'http_port', '*' + ' ' + _('HTTP Port'));
|
||||
o.datatype = 'port';
|
||||
o.placeholder = '8080';
|
||||
|
||||
o = s.taboption('inbound', form.Value, 'socks_port', _('SOCKS Port'));
|
||||
o = s.taboption('inbound', form.Value, 'socks_port', '*' + ' ' + _('SOCKS Port'));
|
||||
o.datatype = 'port';
|
||||
o.placeholder = '1080';
|
||||
|
||||
o = s.taboption('inbound', form.Value, 'mixed_port', _('Mixed Port'));
|
||||
o = s.taboption('inbound', form.Value, 'mixed_port', '*' + ' ' + _('Mixed Port'));
|
||||
o.datatype = 'port';
|
||||
o.placeholder = '7890';
|
||||
|
||||
o = s.taboption('inbound', form.Value, 'redir_port', _('Redirect Port'));
|
||||
o = s.taboption('inbound', form.Value, 'redir_port', '*' + ' ' + _('Redirect Port'));
|
||||
o.datatype = 'port';
|
||||
o.placeholder = '7891';
|
||||
|
||||
o = s.taboption('inbound', form.Value, 'tproxy_port', _('TPROXY Port'));
|
||||
o = s.taboption('inbound', form.Value, 'tproxy_port', '*' + ' ' + _('TPROXY Port'));
|
||||
o.datatype = 'port';
|
||||
o.placeholder = '7892';
|
||||
|
||||
o = s.taboption('inbound', form.Flag, 'authentication', _('Authentication'));
|
||||
o = s.taboption('inbound', form.Flag, 'authentication', '*' + ' ' + _('Overwrite Authentication'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('inbound', form.SectionValue, '_authentications', form.TableSection, 'authentication', _('Edit Authentications'));
|
||||
@@ -351,27 +350,27 @@ return view.extend({
|
||||
|
||||
s.tab('tun', _('TUN Config'));
|
||||
|
||||
o = s.taboption('tun', form.ListValue, 'tun_stack', _('Stack'));
|
||||
o = s.taboption('tun', form.ListValue, 'tun_stack', '*' + ' ' + _('Stack'));
|
||||
o.value('system', 'System');
|
||||
o.value('gvisor', 'gVisor');
|
||||
o.value('mixed', 'Mixed');
|
||||
|
||||
o = s.taboption('tun', form.Value, 'tun_mtu', _('MTU'));
|
||||
o = s.taboption('tun', form.Value, 'tun_mtu', '*' + ' ' + _('MTU'));
|
||||
o.placeholder = '9000';
|
||||
|
||||
o = s.taboption('tun', form.Flag, 'tun_gso', _('GSO'));
|
||||
o = s.taboption('tun', form.Flag, 'tun_gso', '*' + ' ' + _('GSO'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('tun', form.Value, 'tun_gso_max_size', _('GSO Max Size'));
|
||||
o = s.taboption('tun', form.Value, 'tun_gso_max_size', '*' + ' ' + _('GSO Max Size'));
|
||||
o.placeholder = '65536';
|
||||
o.depends('tun_gso', '1');
|
||||
|
||||
o = s.taboption('tun', form.Flag, 'tun_endpoint_independent_nat', _('Endpoint Independent NAT'));
|
||||
o = s.taboption('tun', form.Flag, 'tun_endpoint_independent_nat', '*' + ' ' + _('Endpoint Independent NAT'));
|
||||
o.rmempty = false;
|
||||
|
||||
s.tab('dns', _('DNS Config'));
|
||||
|
||||
o = s.taboption('dns', form.Value, 'dns_port', _('DNS Port'));
|
||||
o = s.taboption('dns', form.Value, 'dns_port', '*' + ' ' + _('DNS Port'));
|
||||
o.datatype = 'port';
|
||||
o.placeholder = '1053';
|
||||
|
||||
|
@@ -244,8 +244,8 @@ msgstr "Redirect 端口"
|
||||
msgid "TPROXY Port"
|
||||
msgstr "TPROXY 端口"
|
||||
|
||||
msgid "Authentication"
|
||||
msgid "身份验证"
|
||||
msgid "Overwrite Authentication"
|
||||
msgstr "覆盖身份验证"
|
||||
|
||||
msgid "Edit Authentications"
|
||||
msgstr "编辑身份验证"
|
||||
|
@@ -146,13 +146,13 @@ start_service() {
|
||||
# do mixin
|
||||
log_level="$log_level" ipv6="$ipv6" \
|
||||
ui_path="ui" ui_name="$ui_name" ui_url="$ui_url" api_listen="0.0.0.0:$api_port" api_secret="$api_secret" \
|
||||
http_port="$http_port" socks_port="$socks_port" mixed_port="$mixed_port" redir_port="$redir_port" tproxy_port="$tproxy_port" \
|
||||
allow_lan="$allow_lan" http_port="$http_port" socks_port="$socks_port" mixed_port="$mixed_port" redir_port="$redir_port" tproxy_port="$tproxy_port" \
|
||||
tun_enable="$tun_enable" tun_stack="$tun_stack" tun_device="$TUN_DEVICE" tun_mtu="$tun_mtu" tun_gso="$tun_gso" tun_gso_max_size="$tun_gso_max_size" tun_endpoint_independent_nat="$tun_endpoint_independent_nat" \
|
||||
dns_enable="true" dns_listen="0.0.0.0:$dns_port" \
|
||||
yq -M -i '
|
||||
.log-level = env(log_level) | .ipv6 = env(ipv6) == 1 |
|
||||
.external-ui = env(ui_path) | .external-ui-name = env(ui_name) | .external-ui-url = env(ui_url) | .external-controller = env(api_listen) | .secret = env(api_secret) |
|
||||
.port = env(http_port) | .socks-port = env(socks_port) | .mixed-port = env(mixed_port) | .redir-port = env(redir_port) | .tproxy-port = env(tproxy_port) |
|
||||
.allow-lan = env(allow_lan) == 1 | .port = env(http_port) | .socks-port = env(socks_port) | .mixed-port = env(mixed_port) | .redir-port = env(redir_port) | .tproxy-port = env(tproxy_port) |
|
||||
.tun.enable = env(tun_enable) == 1 | .tun.stack = env(tun_stack) | .tun.device = env(tun_device) | .tun.mtu = env(tun_mtu) | .tun.gso = env(tun_gso) == 1 | .tun.gso-max-size = env(tun_gso_max_size) | .tun.endpoint-independent-nat = env(tun_endpoint_independent_nat) == 1 |
|
||||
.dns.enable = env(dns_enable) | .dns.listen = env(dns_listen)
|
||||
' "$RUN_PROFILE_PATH"
|
||||
@@ -178,10 +178,6 @@ start_service() {
|
||||
.geo-auto-update = env(geox_auto_update) == 1 | .geo-update-interval = env(geox_update_interval)
|
||||
' "$RUN_PROFILE_PATH"
|
||||
|
||||
if [ "$authentication" == 1 ]; then
|
||||
yq -M -i 'del(.authentication)' "$RUN_PROFILE_PATH"
|
||||
config_foreach mixin_authentications "authentication"
|
||||
fi
|
||||
if [ "$fake_ip_filter" == 1 ]; then
|
||||
fake_ip_filter_mode="$fake_ip_filter_mode" \
|
||||
yq -M -i 'del(.dns.fake-ip-filter) | .dns.fake-ip-filter-mode = env(fake_ip_filter_mode)' "$RUN_PROFILE_PATH"
|
||||
@@ -205,9 +201,6 @@ start_service() {
|
||||
fi
|
||||
fi
|
||||
yq -M -i 'del (.bind-address)' "$RUN_PROFILE_PATH"
|
||||
if [ "$tun_enable" == 1 ]; then
|
||||
yq -M -i '.tun.auto-route = false | .tun.auto-redirect = false | .tun.auto-detect-interface = false | .tun.dns-hijack = []' "$RUN_PROFILE_PATH"
|
||||
fi
|
||||
if [ -n "$outbound_interface" ]; then
|
||||
local outbound_device
|
||||
network_get_device outbound_device "$outbound_interface"
|
||||
@@ -215,6 +208,13 @@ start_service() {
|
||||
outbound_device="$outbound_device" yq -M -i '.interface-name = env(outbound_device)' "$RUN_PROFILE_PATH"
|
||||
fi
|
||||
fi
|
||||
if [ "$authentication" == 1 ]; then
|
||||
yq -M -i 'del(.authentication)' "$RUN_PROFILE_PATH"
|
||||
config_foreach mixin_authentications "authentication"
|
||||
fi
|
||||
if [ "$tun_enable" == 1 ]; then
|
||||
yq -M -i '.tun.auto-route = false | .tun.auto-redirect = false | .tun.auto-detect-interface = false | .tun.dns-hijack = []' "$RUN_PROFILE_PATH"
|
||||
fi
|
||||
# test profile
|
||||
if [ "$test_profile" == 1 ]; then
|
||||
log "Profile testing..."
|
||||
|
@@ -6,12 +6,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=sing-box
|
||||
PKG_VERSION:=1.9.6
|
||||
PKG_VERSION:=1.9.7
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/SagerNet/sing-box/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=09412fcc7b3a56c325886af090fb88b2cd8a61984856da43e2d16ff203f3a267
|
||||
PKG_HASH:=5b015352f3434bb780af01a6b1f6c0fe706166d6c44a69547e29892f0920b944
|
||||
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
@@ -30,13 +30,13 @@ define Download/geosite
|
||||
HASH:=aeefcd8b3e5b27c22e2e7dfb6ff5e8d0741fd540d96ab355fd00a0472f5884a7
|
||||
endef
|
||||
|
||||
GEOSITE_IRAN_VER:=202409300035
|
||||
GEOSITE_IRAN_VER:=202410070035
|
||||
GEOSITE_IRAN_FILE:=iran.dat.$(GEOSITE_IRAN_VER)
|
||||
define Download/geosite-ir
|
||||
URL:=https://github.com/bootmortis/iran-hosted-domains/releases/download/$(GEOSITE_IRAN_VER)/
|
||||
URL_FILE:=iran.dat
|
||||
FILE:=$(GEOSITE_IRAN_FILE)
|
||||
HASH:=b10725db0a82d919cc72cd161dec4b14b6870c760322f6e503c55de3c1828f3d
|
||||
HASH:=be31e14b61dc3e98c9ac518686bc932b45aa04dd2f9491d18456417ba28f3b70
|
||||
endef
|
||||
|
||||
define Package/v2ray-geodata/template
|
||||
|
@@ -6,6 +6,5 @@ namespace ServiceLib.Base
|
||||
{
|
||||
protected static Config? _config;
|
||||
protected Func<EViewAction, object?, Task<bool>>? _updateView;
|
||||
protected NoticeHandler? _noticeHandler;
|
||||
}
|
||||
}
|
@@ -36,7 +36,7 @@ namespace ServiceLib.Common
|
||||
}
|
||||
};
|
||||
|
||||
using var downloader = new DownloadService(downloadOpt);
|
||||
using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
downloader.DownloadFileCompleted += (sender, value) =>
|
||||
{
|
||||
if (value.Error != null)
|
||||
@@ -76,7 +76,7 @@ namespace ServiceLib.Common
|
||||
int totalSecond = 0;
|
||||
var hasValue = false;
|
||||
double maxSpeed = 0;
|
||||
using var downloader = new DownloadService(downloadOpt);
|
||||
using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
//downloader.DownloadStarted += (sender, value) =>
|
||||
//{
|
||||
// if (progress != null)
|
||||
@@ -145,7 +145,7 @@ namespace ServiceLib.Common
|
||||
|
||||
var progressPercentage = 0;
|
||||
var hasValue = false;
|
||||
using var downloader = new DownloadService(downloadOpt);
|
||||
using var downloader = new Downloader.DownloadService(downloadOpt);
|
||||
downloader.DownloadStarted += (sender, value) =>
|
||||
{
|
||||
progress?.Report(0);
|
||||
|
@@ -4,11 +4,14 @@
|
||||
{
|
||||
v2fly = 1,
|
||||
Xray = 2,
|
||||
|
||||
//SagerNet = 3,
|
||||
v2fly_v5 = 4,
|
||||
|
||||
//clash = 11,
|
||||
//clash_meta = 12,
|
||||
mihomo = 13,
|
||||
|
||||
hysteria = 21,
|
||||
naiveproxy = 22,
|
||||
tuic = 23,
|
||||
|
@@ -2,8 +2,9 @@
|
||||
global using ServiceLib.Common;
|
||||
global using ServiceLib.Enums;
|
||||
global using ServiceLib.Handler;
|
||||
global using ServiceLib.Handler.CoreConfig;
|
||||
global using ServiceLib.Handler.Fmt;
|
||||
global using ServiceLib.Handler.Statistics;
|
||||
global using ServiceLib.Services;
|
||||
global using ServiceLib.Services.Statistics;
|
||||
global using ServiceLib.Services.CoreConfig;
|
||||
global using ServiceLib.Models;
|
||||
global using ServiceLib.Resx;
|
@@ -1,13 +1,13 @@
|
||||
namespace ServiceLib.Handler
|
||||
{
|
||||
public sealed class LazyConfig
|
||||
public sealed class AppHandler
|
||||
{
|
||||
private static readonly Lazy<LazyConfig> _instance = new(() => new());
|
||||
private static readonly Lazy<AppHandler> _instance = new(() => new());
|
||||
private Config _config;
|
||||
private int? _statePort;
|
||||
private int? _statePort2;
|
||||
|
||||
public static LazyConfig Instance => _instance.Value;
|
||||
private Job? _processJob;
|
||||
public static AppHandler Instance => _instance.Value;
|
||||
public Config Config => _config;
|
||||
|
||||
public int StatePort
|
||||
@@ -28,21 +28,49 @@
|
||||
}
|
||||
}
|
||||
|
||||
private Job? _processJob;
|
||||
#region Init
|
||||
|
||||
public LazyConfig()
|
||||
public AppHandler()
|
||||
{
|
||||
}
|
||||
|
||||
public bool InitApp()
|
||||
{
|
||||
if (ConfigHandler.LoadConfig(ref _config) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Thread.CurrentThread.CurrentUICulture = new(_config.uiItem.currentLanguage);
|
||||
|
||||
//Under Win10
|
||||
if (Utils.IsWindows() && Environment.OSVersion.Version.Major < 10)
|
||||
{
|
||||
Environment.SetEnvironmentVariable("DOTNET_EnableWriteXorExecute", "0", EnvironmentVariableTarget.User);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool InitComponents()
|
||||
{
|
||||
Logging.Setup();
|
||||
Logging.LoggingEnabled(true);
|
||||
Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}");
|
||||
Logging.SaveLog($"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
||||
Logging.ClearLogs();
|
||||
|
||||
SQLiteHelper.Instance.CreateTable<SubItem>();
|
||||
SQLiteHelper.Instance.CreateTable<ProfileItem>();
|
||||
SQLiteHelper.Instance.CreateTable<ServerStatItem>();
|
||||
SQLiteHelper.Instance.CreateTable<RoutingItem>();
|
||||
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
|
||||
SQLiteHelper.Instance.CreateTable<DNSItem>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region Config
|
||||
#endregion Init
|
||||
|
||||
public void SetConfig(Config config) => _config = config;
|
||||
#region Config
|
||||
|
||||
public int GetLocalPort(EInboundProtocol protocol)
|
||||
{
|
@@ -76,7 +76,7 @@ namespace ServiceLib.Handler
|
||||
return;
|
||||
}
|
||||
var urlBase = $"{GetApiUrl()}/proxies";
|
||||
urlBase += @"/{0}/delay?timeout=10000&url=" + LazyConfig.Instance.Config.speedTestItem.speedPingTestUrl;
|
||||
urlBase += @"/{0}/delay?timeout=10000&url=" + AppHandler.Instance.Config.speedTestItem.speedPingTestUrl;
|
||||
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (var it in lstProxy)
|
||||
@@ -200,7 +200,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
private string GetApiUrl()
|
||||
{
|
||||
return $"{Global.HttpProtocol}{Global.Loopback}:{LazyConfig.Instance.StatePort2}";
|
||||
return $"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort2}";
|
||||
}
|
||||
}
|
||||
}
|
@@ -364,7 +364,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static int AddServer(Config config, ProfileItem profileItem)
|
||||
{
|
||||
var item = LazyConfig.Instance.GetProfileItem(profileItem.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(profileItem.indexId);
|
||||
if (item is null)
|
||||
{
|
||||
item = profileItem;
|
||||
@@ -476,7 +476,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
foreach (var it in indexes)
|
||||
{
|
||||
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(it.indexId);
|
||||
if (item is null)
|
||||
{
|
||||
continue;
|
||||
@@ -541,7 +541,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static ProfileItem? GetDefaultServer(Config config)
|
||||
{
|
||||
var item = LazyConfig.Instance.GetProfileItem(config.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(config.indexId);
|
||||
if (item is null)
|
||||
{
|
||||
var item2 = SQLiteHelper.Instance.Table<ProfileItem>().FirstOrDefault();
|
||||
@@ -677,7 +677,7 @@ namespace ServiceLib.Handler
|
||||
/// <returns></returns>
|
||||
public static int EditCustomServer(Config config, ProfileItem profileItem)
|
||||
{
|
||||
var item = LazyConfig.Instance.GetProfileItem(profileItem.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(profileItem.indexId);
|
||||
if (item is null)
|
||||
{
|
||||
item = profileItem;
|
||||
@@ -717,7 +717,7 @@ namespace ServiceLib.Handler
|
||||
profileItem.id = profileItem.id.TrimEx();
|
||||
profileItem.security = profileItem.security.TrimEx();
|
||||
|
||||
if (!LazyConfig.Instance.GetShadowsocksSecurities(profileItem).Contains(profileItem.security))
|
||||
if (!AppHandler.Instance.GetShadowsocksSecurities(profileItem).Contains(profileItem.security))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -894,7 +894,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static int SortServers(Config config, string subId, string colName, bool asc)
|
||||
{
|
||||
var lstModel = LazyConfig.Instance.ProfileItems(subId, "");
|
||||
var lstModel = AppHandler.Instance.ProfileItems(subId, "");
|
||||
if (lstModel.Count <= 0)
|
||||
{
|
||||
return -1;
|
||||
@@ -1026,7 +1026,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static Tuple<int, int> DedupServerList(Config config, string subId)
|
||||
{
|
||||
var lstProfile = LazyConfig.Instance.ProfileItems(subId);
|
||||
var lstProfile = AppHandler.Instance.ProfileItems(subId);
|
||||
|
||||
List<ProfileItem> lstKeep = new();
|
||||
List<ProfileItem> lstRemove = new();
|
||||
@@ -1126,7 +1126,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
try
|
||||
{
|
||||
var item = LazyConfig.Instance.GetProfileItem(indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(indexId);
|
||||
if (item == null)
|
||||
{
|
||||
return 0;
|
||||
@@ -1161,7 +1161,7 @@ namespace ServiceLib.Handler
|
||||
return -1;
|
||||
}
|
||||
|
||||
var profileItem = LazyConfig.Instance.GetProfileItem(indexId) ?? new();
|
||||
var profileItem = AppHandler.Instance.GetProfileItem(indexId) ?? new();
|
||||
profileItem.indexId = indexId;
|
||||
profileItem.remarks = coreType == ECoreType.sing_box ? ResUI.menuSetDefaultMultipleServer : ResUI.menuSetDefaultLoadBalanceServer;
|
||||
profileItem.address = Global.CoreMultipleLoadConfigFileName;
|
||||
@@ -1196,7 +1196,7 @@ namespace ServiceLib.Handler
|
||||
if (isSub && Utils.IsNotEmpty(subid))
|
||||
{
|
||||
RemoveServerViaSubid(config, subid, isSub);
|
||||
subFilter = LazyConfig.Instance.GetSubItem(subid)?.filter ?? "";
|
||||
subFilter = AppHandler.Instance.GetSubItem(subid)?.filter ?? "";
|
||||
}
|
||||
|
||||
int countServers = 0;
|
||||
@@ -1235,7 +1235,7 @@ namespace ServiceLib.Handler
|
||||
//Check for duplicate indexId
|
||||
if (lstDbIndexId is null)
|
||||
{
|
||||
lstDbIndexId = LazyConfig.Instance.ProfileItemIndexes("");
|
||||
lstDbIndexId = AppHandler.Instance.ProfileItemIndexes("");
|
||||
}
|
||||
if (lstAdd.Any(t => t.indexId == existItem.indexId)
|
||||
|| lstDbIndexId.Any(t => t == existItem.indexId))
|
||||
@@ -1295,7 +1295,7 @@ namespace ServiceLib.Handler
|
||||
return -1;
|
||||
}
|
||||
|
||||
var subItem = LazyConfig.Instance.GetSubItem(subid);
|
||||
var subItem = AppHandler.Instance.GetSubItem(subid);
|
||||
var subRemarks = subItem?.remarks;
|
||||
var preSocksPort = subItem?.preSocksPort;
|
||||
|
||||
@@ -1430,7 +1430,7 @@ namespace ServiceLib.Handler
|
||||
List<ProfileItem>? lstOriSub = null;
|
||||
if (isSub && Utils.IsNotEmpty(subid))
|
||||
{
|
||||
lstOriSub = LazyConfig.Instance.ProfileItems(subid);
|
||||
lstOriSub = AppHandler.Instance.ProfileItems(subid);
|
||||
}
|
||||
|
||||
var counter = 0;
|
||||
@@ -1500,7 +1500,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static int AddSubItem(Config config, SubItem subItem)
|
||||
{
|
||||
var item = LazyConfig.Instance.GetSubItem(subItem.id);
|
||||
var item = AppHandler.Instance.GetSubItem(subItem.id);
|
||||
if (item is null)
|
||||
{
|
||||
item = subItem;
|
||||
@@ -1577,7 +1577,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static int DeleteSubItem(Config config, string id)
|
||||
{
|
||||
var item = LazyConfig.Instance.GetSubItem(id);
|
||||
var item = AppHandler.Instance.GetSubItem(id);
|
||||
if (item is null)
|
||||
{
|
||||
return 0;
|
||||
@@ -1752,7 +1752,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static RoutingItem GetDefaultRouting(Config config)
|
||||
{
|
||||
var item = LazyConfig.Instance.GetRoutingItem(config.routingBasicItem.routingIndexId);
|
||||
var item = AppHandler.Instance.GetRoutingItem(config.routingBasicItem.routingIndexId);
|
||||
if (item is null)
|
||||
{
|
||||
var item2 = SQLiteHelper.Instance.Table<RoutingItem>().FirstOrDefault(t => t.locked == false);
|
||||
@@ -1766,7 +1766,7 @@ namespace ServiceLib.Handler
|
||||
public static int InitBuiltinRouting(Config config, bool blImportAdvancedRules = false)
|
||||
{
|
||||
var ver = "V3-";
|
||||
var items = LazyConfig.Instance.RoutingItems();
|
||||
var items = AppHandler.Instance.RoutingItems();
|
||||
if (blImportAdvancedRules || items.Where(t => t.remarks.StartsWith(ver)).ToList().Count <= 0)
|
||||
{
|
||||
var maxSort = items.Count;
|
||||
@@ -1832,7 +1832,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public static int InitBuiltinDNS(Config config)
|
||||
{
|
||||
var items = LazyConfig.Instance.DNSItems();
|
||||
var items = AppHandler.Instance.DNSItems();
|
||||
if (items.Count <= 0)
|
||||
{
|
||||
var item = new DNSItem()
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace ServiceLib.Handler.CoreConfig
|
||||
namespace ServiceLib.Handler
|
||||
{
|
||||
/// <summary>
|
||||
/// Core configuration file processing class
|
||||
@@ -15,19 +15,19 @@
|
||||
msg = ResUI.CheckServerSettings;
|
||||
return -1;
|
||||
}
|
||||
var config = LazyConfig.Instance.Config;
|
||||
var config = AppHandler.Instance.Config;
|
||||
|
||||
msg = ResUI.InitialConfiguration;
|
||||
if (node.configType == EConfigType.Custom)
|
||||
{
|
||||
if (node.coreType is ECoreType.mihomo)
|
||||
if (node.coreType is ECoreType.mihomo)
|
||||
{
|
||||
var configGenClash = new CoreConfigClash(config);
|
||||
var configGenClash = new CoreConfigClashService(config);
|
||||
return configGenClash.GenerateClientCustomConfig(node, fileName, out msg);
|
||||
}
|
||||
if (node.coreType is ECoreType.sing_box)
|
||||
{
|
||||
var configGenSingbox = new CoreConfigSingbox(config);
|
||||
var configGenSingbox = new CoreConfigSingboxService(config);
|
||||
return configGenSingbox.GenerateClientCustomConfig(node, fileName, out msg);
|
||||
}
|
||||
else
|
||||
@@ -35,9 +35,9 @@
|
||||
return GenerateClientCustomConfig(node, fileName, out msg);
|
||||
}
|
||||
}
|
||||
else if (LazyConfig.Instance.GetCoreType(node, node.configType) == ECoreType.sing_box)
|
||||
else if (AppHandler.Instance.GetCoreType(node, node.configType) == ECoreType.sing_box)
|
||||
{
|
||||
var configGenSingbox = new CoreConfigSingbox(config);
|
||||
var configGenSingbox = new CoreConfigSingboxService(config);
|
||||
if (configGenSingbox.GenerateClientConfigContent(node, out SingboxConfig? singboxConfig, out msg) != 0)
|
||||
{
|
||||
return -1;
|
||||
@@ -53,7 +53,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
var coreConfigV2ray = new CoreConfigV2ray(config);
|
||||
var coreConfigV2ray = new CoreConfigV2rayService(config);
|
||||
if (coreConfigV2ray.GenerateClientConfigContent(node, out V2rayConfig? v2rayConfig, out msg) != 0)
|
||||
{
|
||||
return -1;
|
||||
@@ -128,7 +128,7 @@
|
||||
{
|
||||
if (coreType == ECoreType.sing_box)
|
||||
{
|
||||
if (new CoreConfigSingbox(config).GenerateClientSpeedtestConfig(selecteds, out SingboxConfig? singboxConfig, out msg) != 0)
|
||||
if (new CoreConfigSingboxService(config).GenerateClientSpeedtestConfig(selecteds, out SingboxConfig? singboxConfig, out msg) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -136,7 +136,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
if (new CoreConfigV2ray(config).GenerateClientSpeedtestConfig(selecteds, out V2rayConfig? v2rayConfig, out msg) != 0)
|
||||
if (new CoreConfigV2rayService(config).GenerateClientSpeedtestConfig(selecteds, out V2rayConfig? v2rayConfig, out msg) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -150,7 +150,7 @@
|
||||
msg = ResUI.CheckServerSettings;
|
||||
if (coreType == ECoreType.sing_box)
|
||||
{
|
||||
if (new CoreConfigSingbox(config).GenerateClientMultipleLoadConfig(selecteds, out SingboxConfig? singboxConfig, out msg) != 0)
|
||||
if (new CoreConfigSingboxService(config).GenerateClientMultipleLoadConfig(selecteds, out SingboxConfig? singboxConfig, out msg) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -158,7 +158,7 @@
|
||||
}
|
||||
else if (coreType == ECoreType.Xray)
|
||||
{
|
||||
if (new CoreConfigV2ray(config).GenerateClientMultipleLoadConfig(selecteds, out V2rayConfig? v2rayConfig, out msg) != 0)
|
||||
if (new CoreConfigV2rayService(config).GenerateClientMultipleLoadConfig(selecteds, out V2rayConfig? v2rayConfig, out msg) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
@@ -8,12 +8,14 @@ namespace ServiceLib.Handler
|
||||
/// </summary>
|
||||
public class CoreHandler
|
||||
{
|
||||
private static readonly Lazy<CoreHandler> _instance = new(() => new());
|
||||
public static CoreHandler Instance => _instance.Value;
|
||||
private Config _config;
|
||||
private Process? _process;
|
||||
private Process? _processPre;
|
||||
private Action<bool, string> _updateFunc;
|
||||
|
||||
public CoreHandler(Config config, Action<bool, string> update)
|
||||
public void Init(Config config, Action<bool, string> update)
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = update;
|
||||
@@ -106,17 +108,17 @@ namespace ServiceLib.Handler
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
||||
foreach (var it in coreInfo)
|
||||
{
|
||||
if (it.coreType == ECoreType.v2rayN)
|
||||
if (it.CoreType == ECoreType.v2rayN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
foreach (string vName in it.coreExes)
|
||||
foreach (string vName in it.CoreExes)
|
||||
{
|
||||
var existing = Process.GetProcessesByName(vName);
|
||||
foreach (Process p in existing)
|
||||
{
|
||||
string? path = p.MainModule?.FileName;
|
||||
if (path == Utils.GetExeName(Utils.GetBinPath(vName, it.coreType.ToString())))
|
||||
if (path == Utils.GetExeName(Utils.GetBinPath(vName, it.CoreType.ToString())))
|
||||
{
|
||||
KillProcess(p);
|
||||
}
|
||||
@@ -149,10 +151,10 @@ namespace ServiceLib.Handler
|
||||
private string CoreFindExe(CoreInfo coreInfo)
|
||||
{
|
||||
string fileName = string.Empty;
|
||||
foreach (string name in coreInfo.coreExes)
|
||||
foreach (string name in coreInfo.CoreExes)
|
||||
{
|
||||
string vName = Utils.GetExeName(name);
|
||||
vName = Utils.GetBinPath(vName, coreInfo.coreType.ToString());
|
||||
vName = Utils.GetBinPath(vName, coreInfo.CoreType.ToString());
|
||||
if (File.Exists(vName))
|
||||
{
|
||||
fileName = vName;
|
||||
@@ -161,7 +163,7 @@ namespace ServiceLib.Handler
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(fileName))
|
||||
{
|
||||
string msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.coreType.ToString()), string.Join(", ", coreInfo.coreExes.ToArray()), coreInfo.coreUrl);
|
||||
string msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath("", coreInfo.CoreType.ToString()), string.Join(", ", coreInfo.CoreExes.ToArray()), coreInfo.Url);
|
||||
Logging.SaveLog(msg);
|
||||
ShowMsg(false, msg);
|
||||
}
|
||||
@@ -182,7 +184,7 @@ namespace ServiceLib.Handler
|
||||
//{
|
||||
// coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
|
||||
//}
|
||||
var coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
|
||||
var coreType = AppHandler.Instance.GetCoreType(node, node.configType);
|
||||
_config.runningCoreType = coreType;
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
|
||||
|
||||
@@ -207,7 +209,7 @@ namespace ServiceLib.Handler
|
||||
configType = EConfigType.SOCKS,
|
||||
address = Global.Loopback,
|
||||
sni = node.address, //Tun2SocksAddress
|
||||
port = LazyConfig.Instance.GetLocalPort(EInboundProtocol.socks)
|
||||
port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)
|
||||
};
|
||||
}
|
||||
else if ((node.configType == EConfigType.Custom && node.preSocksPort > 0))
|
||||
@@ -286,7 +288,7 @@ namespace ServiceLib.Handler
|
||||
StartInfo = new()
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = string.Format(coreInfo.arguments, configPath),
|
||||
Arguments = string.Format(coreInfo.Arguments, configPath),
|
||||
WorkingDirectory = Utils.GetConfigPath(),
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = displayLog,
|
||||
@@ -339,7 +341,7 @@ namespace ServiceLib.Handler
|
||||
startUpSuccessful = true;
|
||||
}
|
||||
|
||||
LazyConfig.Instance.AddProcess(proc.Handle);
|
||||
AppHandler.Instance.AddProcess(proc.Handle);
|
||||
return proc;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@@ -19,7 +19,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
InitCoreInfo();
|
||||
}
|
||||
return _coreInfo?.FirstOrDefault(t => t.coreType == coreType);
|
||||
return _coreInfo?.FirstOrDefault(t => t.CoreType == coreType);
|
||||
}
|
||||
|
||||
public List<CoreInfo> GetCoreInfo()
|
||||
@@ -37,139 +37,135 @@ namespace ServiceLib.Handler
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.v2rayN,
|
||||
coreUrl = Global.NUrl,
|
||||
coreReleaseApiUrl = Global.NUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
coreDownloadUrl32 = Global.NUrl + "/download/{0}/v2rayN-32.zip",
|
||||
coreDownloadUrl64 = Global.NUrl + "/download/{0}/v2rayN.zip",
|
||||
coreDownloadUrlArm64 = Global.NUrl + "/download/{0}/v2rayN-arm64.zip",
|
||||
coreDownloadUrlLinux32 = Global.NUrl + "/download/{0}/v2rayN-linux-32.zip",
|
||||
coreDownloadUrlLinux64 = Global.NUrl + "/download/{0}/v2rayN-linux-64.zip",
|
||||
coreDownloadUrlLinuxArm64 = Global.NUrl + "/download/{0}/v2rayN-linux-arm64.zip",
|
||||
CoreType = ECoreType.v2rayN,
|
||||
Url = Global.NUrl,
|
||||
ReleaseApiUrl = Global.NUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
DownloadUrlWin32 = Global.NUrl + "/download/{0}/v2rayN-windows-32.zip",
|
||||
DownloadUrlWin64 = Global.NUrl + "/download/{0}/v2rayN-windows-64.zip",
|
||||
DownloadUrlWinArm64 = Global.NUrl + "/download/{0}/v2rayN-windows-arm64.zip",
|
||||
DownloadUrlLinux64 = Global.NUrl + "/download/{0}/v2rayN-linux-64.zip",
|
||||
DownloadUrlLinuxArm64 = Global.NUrl + "/download/{0}/v2rayN-linux-arm64.zip",
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.v2fly,
|
||||
coreExes = new List<string> { "wv2ray", "v2ray" },
|
||||
arguments = "",
|
||||
coreUrl = Global.V2flyCoreUrl,
|
||||
coreReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
match = "V2Ray",
|
||||
versionArg = "-version",
|
||||
redirectInfo = true,
|
||||
CoreType = ECoreType.v2fly,
|
||||
CoreExes = new List<string> { "wv2ray", "v2ray" },
|
||||
Arguments = "",
|
||||
Url = Global.V2flyCoreUrl,
|
||||
ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
Match = "V2Ray",
|
||||
VersionArg = "-version",
|
||||
RedirectInfo = true,
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.v2fly_v5,
|
||||
coreExes = new List<string> { "v2ray" },
|
||||
arguments = "run -c config.json -format jsonv5",
|
||||
coreUrl = Global.V2flyCoreUrl,
|
||||
coreReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
match = "V2Ray",
|
||||
versionArg = "version",
|
||||
redirectInfo = true,
|
||||
CoreType = ECoreType.v2fly_v5,
|
||||
CoreExes = new List<string> { "v2ray" },
|
||||
Arguments = "run -c config.json -format jsonv5",
|
||||
Url = Global.V2flyCoreUrl,
|
||||
ReleaseApiUrl = Global.V2flyCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
Match = "V2Ray",
|
||||
VersionArg = "version",
|
||||
RedirectInfo = true,
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.Xray,
|
||||
coreExes = new List<string> { "xray", "wxray" },
|
||||
arguments = "run {0}",
|
||||
coreUrl = Global.XrayCoreUrl,
|
||||
coreReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
coreDownloadUrl32 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-32.zip",
|
||||
coreDownloadUrl64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-64.zip",
|
||||
coreDownloadUrlArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-arm64-v8a.zip",
|
||||
coreDownloadUrlLinux32 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-32.zip",
|
||||
coreDownloadUrlLinux64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-64.zip",
|
||||
coreDownloadUrlLinuxArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-arm64-v8a.zip",
|
||||
match = "Xray",
|
||||
versionArg = "-version",
|
||||
redirectInfo = true,
|
||||
CoreType = ECoreType.Xray,
|
||||
CoreExes = new List<string> { "xray", "wxray" },
|
||||
Arguments = "run {0}",
|
||||
Url = Global.XrayCoreUrl,
|
||||
ReleaseApiUrl = Global.XrayCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
DownloadUrlWin32 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-32.zip",
|
||||
DownloadUrlWin64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-64.zip",
|
||||
DownloadUrlWinArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-windows-arm64-v8a.zip",
|
||||
DownloadUrlLinux64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-64.zip",
|
||||
DownloadUrlLinuxArm64 = Global.XrayCoreUrl + "/download/{0}/Xray-linux-arm64-v8a.zip",
|
||||
Match = "Xray",
|
||||
VersionArg = "-version",
|
||||
RedirectInfo = true,
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.mihomo,
|
||||
coreExes = new List<string> { $"mihomo-windows-amd64{(Avx2.X64.IsSupported ? "" : "-compatible")}", "mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-windows-386", "mihomo", "clash" },
|
||||
arguments = "-f config.json" + PortableMode(),
|
||||
coreUrl = Global.MihomoCoreUrl,
|
||||
coreReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
coreDownloadUrl32 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-386-{0}.zip",
|
||||
coreDownloadUrl64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-amd64-compatible-{0}.zip",
|
||||
coreDownloadUrlArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-arm64-{0}.zip",
|
||||
coreDownloadUrlLinux32 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-386-{0}.gz",
|
||||
coreDownloadUrlLinux64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-amd64-compatible-{0}.gz",
|
||||
coreDownloadUrlLinuxArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-arm64-{0}.gz",
|
||||
match = "Mihomo",
|
||||
versionArg = "-v",
|
||||
redirectInfo = true,
|
||||
CoreType = ECoreType.mihomo,
|
||||
CoreExes = new List<string> { $"mihomo-windows-amd64{(Avx2.X64.IsSupported ? "" : "-compatible")}", "mihomo-windows-amd64-compatible", "mihomo-windows-amd64", "mihomo-windows-386", "mihomo", "clash" },
|
||||
Arguments = "-f config.json" + PortableMode(),
|
||||
Url = Global.MihomoCoreUrl,
|
||||
ReleaseApiUrl = Global.MihomoCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
DownloadUrlWin32 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-386-{0}.zip",
|
||||
DownloadUrlWin64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-amd64-compatible-{0}.zip",
|
||||
DownloadUrlWinArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-windows-arm64-{0}.zip",
|
||||
DownloadUrlLinux64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-amd64-compatible-{0}.gz",
|
||||
DownloadUrlLinuxArm64 = Global.MihomoCoreUrl + "/download/{0}/mihomo-linux-arm64-{0}.gz",
|
||||
Match = "Mihomo",
|
||||
VersionArg = "-v",
|
||||
RedirectInfo = true,
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.hysteria,
|
||||
coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
|
||||
arguments = "",
|
||||
coreUrl = Global.HysteriaCoreUrl,
|
||||
coreReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
redirectInfo = true,
|
||||
CoreType = ECoreType.hysteria,
|
||||
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
|
||||
Arguments = "",
|
||||
Url = Global.HysteriaCoreUrl,
|
||||
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
RedirectInfo = true,
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.naiveproxy,
|
||||
coreExes = new List<string> { "naiveproxy", "naive" },
|
||||
arguments = "config.json",
|
||||
coreUrl = Global.NaiveproxyCoreUrl,
|
||||
redirectInfo = false,
|
||||
CoreType = ECoreType.naiveproxy,
|
||||
CoreExes = new List<string> { "naiveproxy", "naive" },
|
||||
Arguments = "config.json",
|
||||
Url = Global.NaiveproxyCoreUrl,
|
||||
RedirectInfo = false,
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.tuic,
|
||||
coreExes = new List<string> { "tuic-client", "tuic" },
|
||||
arguments = "-c config.json",
|
||||
coreUrl = Global.TuicCoreUrl,
|
||||
redirectInfo = true,
|
||||
CoreType = ECoreType.tuic,
|
||||
CoreExes = new List<string> { "tuic-client", "tuic" },
|
||||
Arguments = "-c config.json",
|
||||
Url = Global.TuicCoreUrl,
|
||||
RedirectInfo = true,
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.sing_box,
|
||||
coreExes = new List<string> { "sing-box-client", "sing-box" },
|
||||
arguments = "run {0} --disable-color",
|
||||
coreUrl = Global.SingboxCoreUrl,
|
||||
redirectInfo = true,
|
||||
coreReleaseApiUrl = Global.SingboxCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
coreDownloadUrl32 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-386.zip",
|
||||
coreDownloadUrl64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-amd64.zip",
|
||||
coreDownloadUrlArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-arm64.zip",
|
||||
coreDownloadUrlLinux32 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-386.tar.gz",
|
||||
coreDownloadUrlLinux64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-amd64.tar.gz",
|
||||
coreDownloadUrlLinuxArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-arm64.tar.gz",
|
||||
match = "sing-box",
|
||||
versionArg = "version",
|
||||
CoreType = ECoreType.sing_box,
|
||||
CoreExes = new List<string> { "sing-box-client", "sing-box" },
|
||||
Arguments = "run {0} --disable-color",
|
||||
Url = Global.SingboxCoreUrl,
|
||||
RedirectInfo = true,
|
||||
ReleaseApiUrl = Global.SingboxCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
DownloadUrlWin32 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-386.zip",
|
||||
DownloadUrlWin64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-amd64.zip",
|
||||
DownloadUrlWinArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-windows-arm64.zip",
|
||||
DownloadUrlLinux64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-amd64.tar.gz",
|
||||
DownloadUrlLinuxArm64 = Global.SingboxCoreUrl + "/download/{0}/sing-box-{1}-linux-arm64.tar.gz",
|
||||
Match = "sing-box",
|
||||
VersionArg = "version",
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.juicity,
|
||||
coreExes = new List<string> { "juicity-client", "juicity" },
|
||||
arguments = "run -c config.json",
|
||||
coreUrl = Global.JuicityCoreUrl
|
||||
CoreType = ECoreType.juicity,
|
||||
CoreExes = new List<string> { "juicity-client", "juicity" },
|
||||
Arguments = "run -c config.json",
|
||||
Url = Global.JuicityCoreUrl
|
||||
});
|
||||
|
||||
_coreInfo.Add(new CoreInfo
|
||||
{
|
||||
coreType = ECoreType.hysteria2,
|
||||
coreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
|
||||
arguments = "",
|
||||
coreUrl = Global.HysteriaCoreUrl,
|
||||
coreReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
redirectInfo = true,
|
||||
CoreType = ECoreType.hysteria2,
|
||||
CoreExes = new List<string> { "hysteria-windows-amd64", "hysteria-windows-386", "hysteria" },
|
||||
Arguments = "",
|
||||
Url = Global.HysteriaCoreUrl,
|
||||
ReleaseApiUrl = Global.HysteriaCoreUrl.Replace(Global.GithubUrl, Global.GithubApiUrl),
|
||||
RedirectInfo = true,
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,9 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
public class NoticeHandler
|
||||
{
|
||||
private static readonly Lazy<NoticeHandler> _instance = new(() => new());
|
||||
public static NoticeHandler Instance => _instance.Value;
|
||||
|
||||
public void Enqueue(string? content)
|
||||
{
|
||||
if (content.IsNullOrEmpty())
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace ServiceLib.Handler.Statistics
|
||||
namespace ServiceLib.Handler
|
||||
{
|
||||
public class StatisticsHandler
|
||||
{
|
||||
@@ -9,8 +9,8 @@
|
||||
private ServerStatItem? _serverStatItem;
|
||||
private List<ServerStatItem> _lstServerStat;
|
||||
private Action<ServerSpeedItem> _updateFunc;
|
||||
private StatisticsV2ray? _statisticsV2Ray;
|
||||
private StatisticsSingbox? _statisticsSingbox;
|
||||
private StatisticsV2rayService? _statisticsV2Ray;
|
||||
private StatisticsSingboxService? _statisticsSingbox;
|
||||
|
||||
public List<ServerStatItem> ServerStat => _lstServerStat;
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
InitData();
|
||||
|
||||
_statisticsV2Ray = new StatisticsV2ray(config, UpdateServerStat);
|
||||
_statisticsSingbox = new StatisticsSingbox(config, UpdateServerStat);
|
||||
_statisticsV2Ray = new StatisticsV2rayService(config, UpdateServerStat);
|
||||
_statisticsSingbox = new StatisticsSingboxService(config, UpdateServerStat);
|
||||
}
|
||||
|
||||
public void Close()
|
@@ -20,11 +20,11 @@
|
||||
await Task.Delay(60000);
|
||||
Logging.SaveLog("UpdateTaskRunSubscription");
|
||||
|
||||
var updateHandle = new UpdateHandler();
|
||||
var updateHandle = new UpdateService();
|
||||
while (true)
|
||||
{
|
||||
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
||||
var lstSubs = LazyConfig.Instance.SubItems()
|
||||
var lstSubs = AppHandler.Instance.SubItems()
|
||||
.Where(t => t.autoUpdateInterval > 0)
|
||||
.Where(t => updateTime - t.updateTime >= t.autoUpdateInterval * 60)
|
||||
.ToList();
|
||||
@@ -53,7 +53,7 @@
|
||||
//await Task.Delay(1000 * 120);
|
||||
Logging.SaveLog("UpdateTaskRunGeo");
|
||||
|
||||
var updateHandle = new UpdateHandler();
|
||||
var updateHandle = new UpdateService();
|
||||
while (true)
|
||||
{
|
||||
await Task.Delay(1000 * 3600);
|
||||
|
@@ -17,7 +17,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public WebDavHandler()
|
||||
{
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_config = AppHandler.Instance.Config;
|
||||
}
|
||||
|
||||
private async Task<bool> GetClient()
|
||||
@@ -110,7 +110,7 @@ namespace ServiceLib.Handler
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveLog(result.Description);
|
||||
SaveLog(result.Description);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@@ -2,10 +2,10 @@
|
||||
{
|
||||
public class CheckUpdateItem
|
||||
{
|
||||
public bool? isSelected { get; set; }
|
||||
public string coreType { get; set; }
|
||||
public string? remarks { get; set; }
|
||||
public string? fileName { get; set; }
|
||||
public bool? isFinished { get; set; }
|
||||
public bool? IsSelected { get; set; }
|
||||
public string? CoreType { get; set; }
|
||||
public string? Remarks { get; set; }
|
||||
public string? FileName { get; set; }
|
||||
public bool? IsFinished { get; set; }
|
||||
}
|
||||
}
|
@@ -103,8 +103,6 @@
|
||||
public int trayMenuServersLimit { get; set; } = 20;
|
||||
|
||||
public bool enableHWA { get; set; } = false;
|
||||
|
||||
public bool enableLog { get; set; } = true;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
@@ -3,28 +3,18 @@
|
||||
[Serializable]
|
||||
public class CoreInfo
|
||||
{
|
||||
public ECoreType coreType { get; set; }
|
||||
|
||||
public List<string> coreExes { get; set; }
|
||||
|
||||
public string arguments { get; set; }
|
||||
|
||||
public string coreUrl { get; set; }
|
||||
|
||||
public string coreReleaseApiUrl { get; set; }
|
||||
|
||||
public string coreDownloadUrl32 { get; set; }
|
||||
|
||||
public string coreDownloadUrl64 { get; set; }
|
||||
|
||||
public string coreDownloadUrlArm64 { get; set; }
|
||||
public string? coreDownloadUrlLinux32 { get; set; }
|
||||
public string? coreDownloadUrlLinux64 { get; set; }
|
||||
public string? coreDownloadUrlLinuxArm64 { get; set; }
|
||||
|
||||
public string match { get; set; }
|
||||
public string versionArg { get; set; }
|
||||
|
||||
public bool redirectInfo { get; set; }
|
||||
public ECoreType CoreType { get; set; }
|
||||
public List<string>? CoreExes { get; set; }
|
||||
public string? Arguments { get; set; }
|
||||
public string? Url { get; set; }
|
||||
public string? ReleaseApiUrl { get; set; }
|
||||
public string? DownloadUrlWin32 { get; set; }
|
||||
public string? DownloadUrlWin64 { get; set; }
|
||||
public string? DownloadUrlWinArm64 { get; set; }
|
||||
public string? DownloadUrlLinux64 { get; set; }
|
||||
public string? DownloadUrlLinuxArm64 { get; set; }
|
||||
public string? Match { get; set; }
|
||||
public string? VersionArg { get; set; }
|
||||
public bool RedirectInfo { get; set; }
|
||||
}
|
||||
}
|
@@ -1,13 +1,13 @@
|
||||
namespace ServiceLib.Handler.CoreConfig
|
||||
namespace ServiceLib.Services.CoreConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Core configuration file processing class
|
||||
/// </summary>
|
||||
public class CoreConfigClash
|
||||
public class CoreConfigClashService
|
||||
{
|
||||
private Config _config;
|
||||
|
||||
public CoreConfigClash(Config config)
|
||||
public CoreConfigClashService(Config config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
@@ -78,14 +78,14 @@
|
||||
}
|
||||
|
||||
//port
|
||||
fileContent["port"] = LazyConfig.Instance.GetLocalPort(EInboundProtocol.http);
|
||||
fileContent["port"] = AppHandler.Instance.GetLocalPort(EInboundProtocol.http);
|
||||
//socks-port
|
||||
fileContent["socks-port"] = LazyConfig.Instance.GetLocalPort(EInboundProtocol.socks);
|
||||
fileContent["socks-port"] = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks);
|
||||
//log-level
|
||||
fileContent["log-level"] = GetLogLevel(_config.coreBasicItem.loglevel);
|
||||
|
||||
//external-controller
|
||||
fileContent["external-controller"] = $"{Global.Loopback}:{LazyConfig.Instance.StatePort2}";
|
||||
fileContent["external-controller"] = $"{Global.Loopback}:{AppHandler.Instance.StatePort2}";
|
||||
//allow-lan
|
||||
if (_config.inbound[0].allowLANConn)
|
||||
{
|
@@ -2,13 +2,13 @@
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace ServiceLib.Handler.CoreConfig
|
||||
namespace ServiceLib.Services.CoreConfig
|
||||
{
|
||||
public class CoreConfigSingbox
|
||||
public class CoreConfigSingboxService
|
||||
{
|
||||
private Config _config;
|
||||
|
||||
public CoreConfigSingbox(Config config)
|
||||
public CoreConfigSingboxService(Config config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
singboxConfig.inbounds.Clear(); // Remove "proxy" service for speedtest, avoiding port conflicts.
|
||||
singboxConfig.outbounds.RemoveAt(0);
|
||||
|
||||
int httpPort = LazyConfig.Instance.GetLocalPort(EInboundProtocol.speedtest);
|
||||
int httpPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.speedtest);
|
||||
|
||||
foreach (var it in selecteds)
|
||||
{
|
||||
@@ -132,7 +132,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(it.indexId);
|
||||
if (it.configType is EConfigType.VMess or EConfigType.VLESS)
|
||||
{
|
||||
if (item is null || Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id))
|
||||
@@ -192,7 +192,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((it.configType is EConfigType.VLESS or EConfigType.Trojan)
|
||||
if (it.configType is EConfigType.VLESS or EConfigType.Trojan
|
||||
&& item.streamSecurity == Global.StreamSecurityReality
|
||||
&& item.publicKey.IsNullOrEmpty())
|
||||
{
|
||||
@@ -282,7 +282,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(it.indexId);
|
||||
if (item is null)
|
||||
{
|
||||
continue;
|
||||
@@ -476,7 +476,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
singboxConfig.inbounds = [];
|
||||
|
||||
if (!_config.tunModeItem.enableTun
|
||||
|| (_config.tunModeItem.enableTun && _config.tunModeItem.enableExInbound && _config.runningCoreType == ECoreType.sing_box))
|
||||
|| _config.tunModeItem.enableTun && _config.tunModeItem.enableExInbound && _config.runningCoreType == ECoreType.sing_box)
|
||||
{
|
||||
var inbound = new Inbound4Sbox()
|
||||
{
|
||||
@@ -486,7 +486,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
};
|
||||
singboxConfig.inbounds.Add(inbound);
|
||||
|
||||
inbound.listen_port = LazyConfig.Instance.GetLocalPort(EInboundProtocol.socks);
|
||||
inbound.listen_port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks);
|
||||
inbound.sniff = _config.inbound[0].sniffingEnabled;
|
||||
inbound.sniff_override_destination = _config.inbound[0].routeOnly ? false : _config.inbound[0].sniffingEnabled;
|
||||
inbound.domain_strategy = Utils.IsNullOrEmpty(_config.routingBasicItem.domainStrategy4Singbox) ? null : _config.routingBasicItem.domainStrategy4Singbox;
|
||||
@@ -600,7 +600,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
}
|
||||
case EConfigType.Shadowsocks:
|
||||
{
|
||||
outbound.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None;
|
||||
outbound.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None;
|
||||
outbound.password = node.id;
|
||||
|
||||
GenOutboundMux(node, outbound);
|
||||
@@ -854,7 +854,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
}
|
||||
try
|
||||
{
|
||||
var subItem = LazyConfig.Instance.GetSubItem(node.subid);
|
||||
var subItem = AppHandler.Instance.GetSubItem(node.subid);
|
||||
if (subItem is null)
|
||||
{
|
||||
return 0;
|
||||
@@ -865,7 +865,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound);
|
||||
|
||||
//Previous proxy
|
||||
var prevNode = LazyConfig.Instance.GetProfileItemViaRemarks(subItem.prevProfile);
|
||||
var prevNode = AppHandler.Instance.GetProfileItemViaRemarks(subItem.prevProfile);
|
||||
if (prevNode is not null
|
||||
&& prevNode.configType != EConfigType.Custom)
|
||||
{
|
||||
@@ -878,7 +878,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
}
|
||||
|
||||
//Next proxy
|
||||
var nextNode = LazyConfig.Instance.GetProfileItemViaRemarks(subItem.nextProfile);
|
||||
var nextNode = AppHandler.Instance.GetProfileItemViaRemarks(subItem.nextProfile);
|
||||
if (nextNode is not null
|
||||
&& nextNode.configType != EConfigType.Custom)
|
||||
{
|
||||
@@ -992,13 +992,13 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo();
|
||||
foreach (var it in coreInfo)
|
||||
{
|
||||
if (it.coreType == ECoreType.v2rayN)
|
||||
if (it.CoreType == ECoreType.v2rayN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
foreach (var it2 in it.coreExes)
|
||||
foreach (var it2 in it.CoreExes)
|
||||
{
|
||||
if (!lstDnsExe.Contains(it2) && it.coreType != ECoreType.sing_box)
|
||||
if (!lstDnsExe.Contains(it2) && it.CoreType != ECoreType.sing_box)
|
||||
{
|
||||
lstDnsExe.Add($"{it2}.exe");
|
||||
}
|
||||
@@ -1173,7 +1173,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
{
|
||||
try
|
||||
{
|
||||
var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
var item = AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
var strDNS = string.Empty;
|
||||
if (_config.tunModeItem.enableTun)
|
||||
{
|
||||
@@ -1260,7 +1260,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
singboxConfig.experimental ??= new Experimental4Sbox();
|
||||
singboxConfig.experimental.clash_api = new Clash_Api4Sbox()
|
||||
{
|
||||
external_controller = $"{Global.Loopback}:{LazyConfig.Instance.StatePort2}",
|
||||
external_controller = $"{Global.Loopback}:{AppHandler.Instance.StatePort2}",
|
||||
};
|
||||
}
|
||||
|
@@ -2,13 +2,13 @@
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace ServiceLib.Handler.CoreConfig
|
||||
namespace ServiceLib.Services.CoreConfig
|
||||
{
|
||||
public class CoreConfigV2ray
|
||||
public class CoreConfigV2rayService
|
||||
{
|
||||
private Config _config;
|
||||
|
||||
public CoreConfigV2ray(Config config)
|
||||
public CoreConfigV2rayService(Config config)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(it.indexId);
|
||||
if (item is null)
|
||||
{
|
||||
continue;
|
||||
@@ -236,7 +236,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
v2rayConfig.inbounds.Clear(); // Remove "proxy" service for speedtest, avoiding port conflicts.
|
||||
v2rayConfig.outbounds.RemoveAt(0);
|
||||
|
||||
int httpPort = LazyConfig.Instance.GetLocalPort(EInboundProtocol.speedtest);
|
||||
int httpPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.speedtest);
|
||||
|
||||
foreach (var it in selecteds)
|
||||
{
|
||||
@@ -248,7 +248,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(it.indexId);
|
||||
if (it.configType is EConfigType.VMess or EConfigType.VLESS)
|
||||
{
|
||||
if (item is null || Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id))
|
||||
@@ -308,7 +308,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((it.configType is EConfigType.VLESS or EConfigType.Trojan)
|
||||
if (it.configType is EConfigType.VLESS or EConfigType.Trojan
|
||||
&& item.streamSecurity == Global.StreamSecurityReality
|
||||
&& item.publicKey.IsNullOrEmpty())
|
||||
{
|
||||
@@ -637,7 +637,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
serversItem.address = node.address;
|
||||
serversItem.port = node.port;
|
||||
serversItem.password = node.id;
|
||||
serversItem.method = LazyConfig.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : "none";
|
||||
serversItem.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : "none";
|
||||
|
||||
serversItem.ota = false;
|
||||
serversItem.level = 1;
|
||||
@@ -1029,7 +1029,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
{
|
||||
try
|
||||
{
|
||||
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
|
||||
var item = AppHandler.Instance.GetDNSItem(ECoreType.Xray);
|
||||
var normalDNS = item?.normalDNS;
|
||||
var domainStrategy4Freedom = item?.domainStrategy4Freedom;
|
||||
if (Utils.IsNullOrEmpty(normalDNS))
|
||||
@@ -1136,7 +1136,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
Inboundsettings4Ray apiInboundSettings = new();
|
||||
apiInbound.tag = tag;
|
||||
apiInbound.listen = Global.Loopback;
|
||||
apiInbound.port = LazyConfig.Instance.StatePort;
|
||||
apiInbound.port = AppHandler.Instance.StatePort;
|
||||
apiInbound.protocol = Global.InboundAPIProtocol;
|
||||
apiInboundSettings.address = Global.Loopback;
|
||||
apiInbound.settings = apiInboundSettings;
|
||||
@@ -1193,7 +1193,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
}
|
||||
try
|
||||
{
|
||||
var subItem = LazyConfig.Instance.GetSubItem(node.subid);
|
||||
var subItem = AppHandler.Instance.GetSubItem(node.subid);
|
||||
if (subItem is null)
|
||||
{
|
||||
return 0;
|
||||
@@ -1204,7 +1204,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
|
||||
|
||||
//Previous proxy
|
||||
var prevNode = LazyConfig.Instance.GetProfileItemViaRemarks(subItem.prevProfile);
|
||||
var prevNode = AppHandler.Instance.GetProfileItemViaRemarks(subItem.prevProfile);
|
||||
if (prevNode is not null
|
||||
&& prevNode.configType != EConfigType.Custom
|
||||
&& prevNode.configType != EConfigType.Hysteria2
|
||||
@@ -1223,7 +1223,7 @@ namespace ServiceLib.Handler.CoreConfig
|
||||
}
|
||||
|
||||
//Next proxy
|
||||
var nextNode = LazyConfig.Instance.GetProfileItemViaRemarks(subItem.nextProfile);
|
||||
var nextNode = AppHandler.Instance.GetProfileItemViaRemarks(subItem.nextProfile);
|
||||
if (nextNode is not null
|
||||
&& nextNode.configType != EConfigType.Custom
|
||||
&& nextNode.configType != EConfigType.Hysteria2
|
@@ -3,12 +3,12 @@ using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace ServiceLib.Handler
|
||||
namespace ServiceLib.Services
|
||||
{
|
||||
/// <summary>
|
||||
///Download
|
||||
/// </summary>
|
||||
public class DownloadHandler
|
||||
public class DownloadService
|
||||
{
|
||||
public event EventHandler<ResultEventArgs>? UpdateCompleted;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
|
||||
var progress = new Progress<string>();
|
||||
progress.ProgressChanged += (sender, value) =>
|
||||
@@ -62,7 +62,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, $"{ResUI.Downloading} {url}"));
|
||||
|
||||
var progress = new Progress<double>();
|
||||
@@ -92,7 +92,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
public async Task<string?> UrlRedirectAsync(string url, bool blProxy)
|
||||
{
|
||||
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
var webRequestHandler = new SocketsHttpHandler
|
||||
{
|
||||
AllowAutoRedirect = false,
|
||||
@@ -181,7 +181,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
var webProxy = GetWebProxy(blProxy);
|
||||
var client = new HttpClient(new SocketsHttpHandler()
|
||||
{
|
||||
@@ -226,7 +226,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
try
|
||||
{
|
||||
Utils.SetSecurityProtocol(LazyConfig.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
Utils.SetSecurityProtocol(AppHandler.Instance.Config.guiItem.enableSecurityProtocolTls13);
|
||||
|
||||
var webProxy = GetWebProxy(blProxy);
|
||||
|
||||
@@ -260,7 +260,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
try
|
||||
{
|
||||
var config = LazyConfig.Instance.Config;
|
||||
var config = AppHandler.Instance.Config;
|
||||
int responseTime = await GetRealPingTime(config.speedTestItem.speedPingTestUrl, webProxy, 10);
|
||||
return responseTime;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var httpPort = LazyConfig.Instance.GetLocalPort(EInboundProtocol.http);
|
||||
var httpPort = AppHandler.Instance.GetLocalPort(EInboundProtocol.http);
|
||||
if (!SocketCheck(Global.Loopback, httpPort))
|
||||
{
|
||||
return null;
|
@@ -2,21 +2,20 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace ServiceLib.Handler
|
||||
namespace ServiceLib.Services
|
||||
{
|
||||
public class SpeedtestHandler
|
||||
public class SpeedtestService
|
||||
{
|
||||
private Config? _config;
|
||||
private CoreHandler _coreHandler;
|
||||
private List<ServerTestItem> _selecteds;
|
||||
private ESpeedActionType _actionType;
|
||||
private Action<SpeedTestResult> _updateFunc;
|
||||
private bool _exitLoop = false;
|
||||
|
||||
public SpeedtestHandler(Config config, CoreHandler coreHandler, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<SpeedTestResult> update)
|
||||
public SpeedtestService(Config config, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<SpeedTestResult> update)
|
||||
{
|
||||
_config = config;
|
||||
_coreHandler = coreHandler;
|
||||
|
||||
_actionType = actionType;
|
||||
_updateFunc = update;
|
||||
|
||||
@@ -137,14 +136,14 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
string msg = string.Empty;
|
||||
|
||||
pid = _coreHandler.LoadCoreConfigSpeedtest(_selecteds);
|
||||
pid = CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds);
|
||||
if (pid < 0)
|
||||
{
|
||||
UpdateFunc("", ResUI.FailedToRunCore);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
DownloadHandler downloadHandle = new DownloadHandler();
|
||||
DownloadService downloadHandle = new DownloadService();
|
||||
|
||||
List<Task> tasks = new();
|
||||
foreach (var it in _selecteds)
|
||||
@@ -185,7 +184,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
if (pid > 0)
|
||||
{
|
||||
_coreHandler.CoreStopPid(pid);
|
||||
CoreHandler.Instance.CoreStopPid(pid);
|
||||
}
|
||||
ProfileExHandler.Instance.SaveTo();
|
||||
}
|
||||
@@ -201,7 +200,7 @@ namespace ServiceLib.Handler
|
||||
// _selecteds = _selecteds.OrderBy(t => t.delay).ToList();
|
||||
//}
|
||||
|
||||
pid = _coreHandler.LoadCoreConfigSpeedtest(_selecteds);
|
||||
pid = CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds);
|
||||
if (pid < 0)
|
||||
{
|
||||
UpdateFunc("", ResUI.FailedToRunCore);
|
||||
@@ -211,7 +210,7 @@ namespace ServiceLib.Handler
|
||||
string url = _config.speedTestItem.speedTestUrl;
|
||||
var timeout = _config.speedTestItem.speedTestTimeout;
|
||||
|
||||
DownloadHandler downloadHandle = new();
|
||||
DownloadService downloadHandle = new();
|
||||
|
||||
foreach (var it in _selecteds)
|
||||
{
|
||||
@@ -236,12 +235,12 @@ namespace ServiceLib.Handler
|
||||
ProfileExHandler.Instance.SetTestSpeed(it.indexId, "-1");
|
||||
UpdateFunc(it.indexId, "", ResUI.Speedtesting);
|
||||
|
||||
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(it.indexId);
|
||||
if (item is null) continue;
|
||||
|
||||
WebProxy webProxy = new(Global.Loopback, it.port);
|
||||
|
||||
await downloadHandle.DownloadDataAsync(url, webProxy, timeout, (bool success, string msg) =>
|
||||
await downloadHandle.DownloadDataAsync(url, webProxy, timeout, (success, msg) =>
|
||||
{
|
||||
decimal.TryParse(msg, out decimal dec);
|
||||
if (dec > 0)
|
||||
@@ -254,7 +253,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
_coreHandler.CoreStopPid(pid);
|
||||
CoreHandler.Instance.CoreStopPid(pid);
|
||||
}
|
||||
UpdateFunc("", ResUI.SpeedtestingCompleted);
|
||||
ProfileExHandler.Instance.SaveTo();
|
||||
@@ -263,7 +262,7 @@ namespace ServiceLib.Handler
|
||||
private async Task RunSpeedTestMulti()
|
||||
{
|
||||
int pid = -1;
|
||||
pid = _coreHandler.LoadCoreConfigSpeedtest(_selecteds);
|
||||
pid = CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds);
|
||||
if (pid < 0)
|
||||
{
|
||||
UpdateFunc("", ResUI.FailedToRunCore);
|
||||
@@ -273,7 +272,7 @@ namespace ServiceLib.Handler
|
||||
string url = _config.speedTestItem.speedTestUrl;
|
||||
var timeout = _config.speedTestItem.speedTestTimeout;
|
||||
|
||||
DownloadHandler downloadHandle = new();
|
||||
DownloadService downloadHandle = new();
|
||||
|
||||
foreach (var it in _selecteds)
|
||||
{
|
||||
@@ -299,11 +298,11 @@ namespace ServiceLib.Handler
|
||||
ProfileExHandler.Instance.SetTestSpeed(it.indexId, "-1");
|
||||
UpdateFunc(it.indexId, "", ResUI.Speedtesting);
|
||||
|
||||
var item = LazyConfig.Instance.GetProfileItem(it.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(it.indexId);
|
||||
if (item is null) continue;
|
||||
|
||||
WebProxy webProxy = new(Global.Loopback, it.port);
|
||||
_ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (bool success, string msg) =>
|
||||
_ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (success, msg) =>
|
||||
{
|
||||
decimal.TryParse(msg, out decimal dec);
|
||||
if (dec > 0)
|
||||
@@ -319,7 +318,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
_coreHandler.CoreStopPid(pid);
|
||||
CoreHandler.Instance.CoreStopPid(pid);
|
||||
}
|
||||
UpdateFunc("", ResUI.SpeedtestingCompleted);
|
||||
ProfileExHandler.Instance.SaveTo();
|
||||
@@ -334,7 +333,7 @@ namespace ServiceLib.Handler
|
||||
await RunSpeedTestMulti();
|
||||
}
|
||||
|
||||
private async Task<string> GetRealPingTime(DownloadHandler downloadHandle, IWebProxy webProxy)
|
||||
private async Task<string> GetRealPingTime(DownloadService downloadHandle, IWebProxy webProxy)
|
||||
{
|
||||
int responseTime = await downloadHandle.GetRealPingTime(_config.speedTestItem.speedPingTestUrl, webProxy, 10);
|
||||
//string output = Utile.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status;
|
||||
@@ -349,7 +348,7 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
if (!IPAddress.TryParse(url, out IPAddress? ipAddress))
|
||||
{
|
||||
IPHostEntry ipHostInfo = System.Net.Dns.GetHostEntry(url);
|
||||
IPHostEntry ipHostInfo = Dns.GetHostEntry(url);
|
||||
ipAddress = ipHostInfo.AddressList[0];
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
|
||||
namespace ServiceLib.Handler.Statistics
|
||||
namespace ServiceLib.Services.Statistics
|
||||
{
|
||||
public class StatisticsSingbox
|
||||
public class StatisticsSingboxService
|
||||
{
|
||||
private Config _config;
|
||||
private bool _exitFlag;
|
||||
@@ -11,7 +11,7 @@ namespace ServiceLib.Handler.Statistics
|
||||
private string url = string.Empty;
|
||||
private Action<ServerSpeedItem> _updateFunc;
|
||||
|
||||
public StatisticsSingbox(Config config, Action<ServerSpeedItem> update)
|
||||
public StatisticsSingboxService(Config config, Action<ServerSpeedItem> update)
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = update;
|
||||
@@ -26,7 +26,7 @@ namespace ServiceLib.Handler.Statistics
|
||||
|
||||
try
|
||||
{
|
||||
url = $"ws://{Global.Loopback}:{LazyConfig.Instance.StatePort2}/traffic";
|
||||
url = $"ws://{Global.Loopback}:{AppHandler.Instance.StatePort2}/traffic";
|
||||
|
||||
if (webSocket == null)
|
||||
{
|
||||
@@ -63,7 +63,7 @@ namespace ServiceLib.Handler.Statistics
|
||||
await Task.Delay(1000);
|
||||
try
|
||||
{
|
||||
if (!(_config.IsRunningCore(ECoreType.sing_box)))
|
||||
if (!_config.IsRunningCore(ECoreType.sing_box))
|
||||
{
|
||||
continue;
|
||||
}
|
@@ -2,9 +2,9 @@
|
||||
using Grpc.Net.Client;
|
||||
using ProtosLib.Statistics;
|
||||
|
||||
namespace ServiceLib.Handler.Statistics
|
||||
namespace ServiceLib.Services.Statistics
|
||||
{
|
||||
public class StatisticsV2ray
|
||||
public class StatisticsV2rayService
|
||||
{
|
||||
private Models.Config _config;
|
||||
private GrpcChannel? _channel;
|
||||
@@ -12,7 +12,7 @@ namespace ServiceLib.Handler.Statistics
|
||||
private bool _exitFlag;
|
||||
private Action<ServerSpeedItem> _updateFunc;
|
||||
|
||||
public StatisticsV2ray(Models.Config config, Action<ServerSpeedItem> update)
|
||||
public StatisticsV2rayService(Models.Config config, Action<ServerSpeedItem> update)
|
||||
{
|
||||
_config = config;
|
||||
_updateFunc = update;
|
||||
@@ -29,7 +29,7 @@ namespace ServiceLib.Handler.Statistics
|
||||
{
|
||||
try
|
||||
{
|
||||
_channel = GrpcChannel.ForAddress($"{Global.HttpProtocol}{Global.Loopback}:{LazyConfig.Instance.StatePort}");
|
||||
_channel = GrpcChannel.ForAddress($"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort}");
|
||||
_client = new StatsService.StatsServiceClient(_channel);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -51,7 +51,7 @@ namespace ServiceLib.Handler.Statistics
|
||||
await Task.Delay(1000);
|
||||
try
|
||||
{
|
||||
if (!(_config.IsRunningCore(ECoreType.Xray)))
|
||||
if (!_config.IsRunningCore(ECoreType.Xray))
|
||||
{
|
||||
continue;
|
||||
}
|
@@ -3,9 +3,9 @@ using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ServiceLib.Handler
|
||||
namespace ServiceLib.Services
|
||||
{
|
||||
public class UpdateHandler
|
||||
public class UpdateService
|
||||
{
|
||||
private Action<bool, string> _updateFunc;
|
||||
private Config _config;
|
||||
@@ -32,7 +32,7 @@ namespace ServiceLib.Handler
|
||||
var url = string.Empty;
|
||||
var fileName = string.Empty;
|
||||
|
||||
DownloadHandler downloadHandle = new();
|
||||
DownloadService downloadHandle = new();
|
||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||
{
|
||||
if (args.Success)
|
||||
@@ -74,7 +74,7 @@ namespace ServiceLib.Handler
|
||||
var url = string.Empty;
|
||||
var fileName = string.Empty;
|
||||
|
||||
DownloadHandler downloadHandle = new();
|
||||
DownloadService downloadHandle = new();
|
||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||
{
|
||||
if (args.Success)
|
||||
@@ -110,7 +110,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
url = args.Url;
|
||||
var ext = Path.GetExtension(url);
|
||||
fileName = Utils.GetTempPath(Utils.GetGUID()+ ext);
|
||||
fileName = Utils.GetTempPath(Utils.GetGUID() + ext);
|
||||
await downloadHandle.DownloadFileAsync(url, fileName, true, _timeout);
|
||||
}
|
||||
else
|
||||
@@ -128,7 +128,7 @@ namespace ServiceLib.Handler
|
||||
_updateFunc = update;
|
||||
|
||||
_updateFunc(false, ResUI.MsgUpdateSubscriptionStart);
|
||||
var subItem = LazyConfig.Instance.SubItems().OrderBy(t => t.sort).ToList();
|
||||
var subItem = AppHandler.Instance.SubItems().OrderBy(t => t.sort).ToList();
|
||||
|
||||
if (subItem == null || subItem.Count <= 0)
|
||||
{
|
||||
@@ -144,7 +144,7 @@ namespace ServiceLib.Handler
|
||||
string url = item.url.TrimEx();
|
||||
string userAgent = item.userAgent.TrimEx();
|
||||
string hashCode = $"{item.remarks}->";
|
||||
if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || (Utils.IsNotEmpty(subId) && item.id != subId))
|
||||
if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || Utils.IsNotEmpty(subId) && item.id != subId)
|
||||
{
|
||||
//_updateFunc(false, $"{hashCode}{ResUI.MsgNoValidSubscription}");
|
||||
continue;
|
||||
@@ -159,7 +159,7 @@ namespace ServiceLib.Handler
|
||||
continue;
|
||||
}
|
||||
|
||||
var downloadHandle = new DownloadHandler();
|
||||
var downloadHandle = new DownloadService();
|
||||
downloadHandle.Error += (sender2, args) =>
|
||||
{
|
||||
_updateFunc(false, $"{hashCode}{args.GetException().Message}");
|
||||
@@ -264,18 +264,18 @@ namespace ServiceLib.Handler
|
||||
|
||||
public async Task RunAvailabilityCheck(Action<bool, string> update)
|
||||
{
|
||||
var time = await (new DownloadHandler()).RunAvailabilityCheck(null);
|
||||
var time = await new DownloadService().RunAvailabilityCheck(null);
|
||||
update(false, string.Format(ResUI.TestMeOutput, time));
|
||||
}
|
||||
|
||||
#region private
|
||||
|
||||
private async Task<ResultEventArgs> CheckUpdateAsync(DownloadHandler downloadHandle, ECoreType type, bool preRelease)
|
||||
private async Task<ResultEventArgs> CheckUpdateAsync(DownloadService downloadHandle, ECoreType type, bool preRelease)
|
||||
{
|
||||
try
|
||||
{
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
|
||||
var url = coreInfo?.coreReleaseApiUrl;
|
||||
var url = coreInfo?.ReleaseApiUrl;
|
||||
|
||||
var result = await downloadHandle.TryDownloadString(url, true, Global.AppName);
|
||||
if (Utils.IsNotEmpty(result))
|
||||
@@ -304,10 +304,10 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
|
||||
string filePath = string.Empty;
|
||||
foreach (string name in coreInfo.coreExes)
|
||||
foreach (string name in coreInfo.CoreExes)
|
||||
{
|
||||
string vName = Utils.GetExeName(name);
|
||||
vName = Utils.GetBinPath(vName, coreInfo.coreType.ToString());
|
||||
vName = Utils.GetBinPath(vName, coreInfo.CoreType.ToString());
|
||||
if (File.Exists(vName))
|
||||
{
|
||||
filePath = vName;
|
||||
@@ -324,7 +324,7 @@ namespace ServiceLib.Handler
|
||||
|
||||
using Process p = new();
|
||||
p.StartInfo.FileName = filePath;
|
||||
p.StartInfo.Arguments = coreInfo.versionArg;
|
||||
p.StartInfo.Arguments = coreInfo.VersionArg;
|
||||
p.StartInfo.WorkingDirectory = Utils.GetConfigPath();
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
@@ -339,7 +339,7 @@ namespace ServiceLib.Handler
|
||||
case ECoreType.v2fly:
|
||||
case ECoreType.Xray:
|
||||
case ECoreType.v2fly_v5:
|
||||
version = Regex.Match(echo, $"{coreInfo.match} ([0-9.]+) \\(").Groups[1].Value;
|
||||
version = Regex.Match(echo, $"{coreInfo.Match} ([0-9.]+) \\(").Groups[1].Value;
|
||||
break;
|
||||
|
||||
case ECoreType.mihomo:
|
||||
@@ -429,19 +429,19 @@ namespace ServiceLib.Handler
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
//Check for standalone windows .Net version
|
||||
if (coreInfo?.coreType == ECoreType.v2rayN
|
||||
if (coreInfo?.CoreType == ECoreType.v2rayN
|
||||
&& File.Exists(Path.Combine(Utils.StartupPath(), "wpfgfx_cor3.dll"))
|
||||
&& File.Exists(Path.Combine(Utils.StartupPath(), "D3DCompiler_47_cor3.dll"))
|
||||
)
|
||||
{
|
||||
return coreInfo?.coreDownloadUrl64.Replace("v2rayN.zip", "zz_v2rayN-SelfContained.zip");
|
||||
return coreInfo?.DownloadUrlWin64?.Replace("v2rayN.zip", "zz_v2rayN-SelfContained.zip");
|
||||
}
|
||||
|
||||
return RuntimeInformation.ProcessArchitecture switch
|
||||
{
|
||||
Architecture.Arm64 => coreInfo?.coreDownloadUrlArm64,
|
||||
Architecture.X86 => coreInfo?.coreDownloadUrl32,
|
||||
Architecture.X64 => coreInfo?.coreDownloadUrl64,
|
||||
Architecture.Arm64 => coreInfo?.DownloadUrlWinArm64,
|
||||
Architecture.X86 => coreInfo?.DownloadUrlWin32,
|
||||
Architecture.X64 => coreInfo?.DownloadUrlWin64,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
@@ -449,9 +449,8 @@ namespace ServiceLib.Handler
|
||||
{
|
||||
return RuntimeInformation.ProcessArchitecture switch
|
||||
{
|
||||
Architecture.Arm64 => coreInfo?.coreDownloadUrlLinuxArm64,
|
||||
Architecture.X86 => coreInfo?.coreDownloadUrlLinux32,
|
||||
Architecture.X64 => coreInfo?.coreDownloadUrlLinux64,
|
||||
Architecture.Arm64 => coreInfo?.DownloadUrlLinuxArm64,
|
||||
Architecture.X64 => coreInfo?.DownloadUrlLinux64,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
@@ -465,7 +464,7 @@ namespace ServiceLib.Handler
|
||||
var url = string.Format(Global.GeoUrl, geoName);
|
||||
var fileName = Utils.GetTempPath(Utils.GetGUID());
|
||||
|
||||
DownloadHandler downloadHandle = new();
|
||||
DownloadService downloadHandle = new();
|
||||
downloadHandle.UpdateCompleted += (sender2, args) =>
|
||||
{
|
||||
if (args.Success)
|
@@ -1,6 +1,5 @@
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Splat;
|
||||
using System.Reactive;
|
||||
|
||||
namespace ServiceLib.ViewModels
|
||||
@@ -20,8 +19,7 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
public AddServer2ViewModel(ProfileItem profileItem, Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_config = AppHandler.Instance.Config;
|
||||
_updateView = updateView;
|
||||
|
||||
if (profileItem.indexId.IsNullOrEmpty())
|
||||
@@ -55,25 +53,25 @@ namespace ServiceLib.ViewModels
|
||||
string remarks = SelectedSource.remarks;
|
||||
if (Utils.IsNullOrEmpty(remarks))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.PleaseFillRemarks);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Utils.IsNullOrEmpty(SelectedSource.address))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.FillServerAddressCustom);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillServerAddressCustom);
|
||||
return;
|
||||
}
|
||||
SelectedSource.coreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType);
|
||||
|
||||
if (ConfigHandler.EditCustomServer(_config, SelectedSource) == 0)
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||
await _updateView?.Invoke(EViewAction.CloseWindow, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.OperationFailed);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,12 +82,12 @@ namespace ServiceLib.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
var item = LazyConfig.Instance.GetProfileItem(SelectedSource.indexId);
|
||||
var item = AppHandler.Instance.GetProfileItem(SelectedSource.indexId);
|
||||
item ??= SelectedSource;
|
||||
item.address = fileName;
|
||||
if (ConfigHandler.AddCustomServer(_config, item, false) == 0)
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.SuccessfullyImportedCustomServer);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedCustomServer);
|
||||
if (Utils.IsNotEmpty(item.indexId))
|
||||
{
|
||||
SelectedSource = JsonUtils.DeepCopy(item);
|
||||
@@ -98,7 +96,7 @@ namespace ServiceLib.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.FailedImportedCustomServer);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FailedImportedCustomServer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +105,7 @@ namespace ServiceLib.ViewModels
|
||||
var address = SelectedSource.address;
|
||||
if (Utils.IsNullOrEmpty(address))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.FillServerAddressCustom);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillServerAddressCustom);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -118,7 +116,7 @@ namespace ServiceLib.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.FailedReadConfiguration);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FailedReadConfiguration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Splat;
|
||||
using System.Reactive;
|
||||
|
||||
namespace ServiceLib.ViewModels
|
||||
@@ -17,8 +16,8 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
public AddServerViewModel(ProfileItem profileItem, Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
_config = AppHandler.Instance.Config;
|
||||
|
||||
_updateView = updateView;
|
||||
|
||||
if (profileItem.indexId.IsNullOrEmpty())
|
||||
@@ -45,32 +44,32 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(SelectedSource.remarks))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.PleaseFillRemarks);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Utils.IsNullOrEmpty(SelectedSource.address))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.FillServerAddress);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillServerAddress);
|
||||
return;
|
||||
}
|
||||
var port = SelectedSource.port.ToString();
|
||||
if (Utils.IsNullOrEmpty(port) || !Utils.IsNumeric(port)
|
||||
|| SelectedSource.port <= 0 || SelectedSource.port >= Global.MaxPort)
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.FillCorrectServerPort);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectServerPort);
|
||||
return;
|
||||
}
|
||||
if (SelectedSource.configType == EConfigType.Shadowsocks)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(SelectedSource.id))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.FillPassword);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillPassword);
|
||||
return;
|
||||
}
|
||||
if (Utils.IsNullOrEmpty(SelectedSource.security))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.PleaseSelectEncryption);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectEncryption);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -79,7 +78,7 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(SelectedSource.id))
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.FillUUID);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.FillUUID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -87,12 +86,12 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
if (ConfigHandler.AddServer(_config, SelectedSource) == 0)
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||
await _updateView?.Invoke(EViewAction.CloseWindow, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.OperationFailed);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,9 +22,8 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
public BackupAndRestoreViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_config = AppHandler.Instance.Config;
|
||||
_updateView = updateView;
|
||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
|
||||
WebDavCheckCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
|
@@ -22,9 +22,8 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
public CheckUpdateViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_config = AppHandler.Instance.Config;
|
||||
_updateView = updateView;
|
||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
|
||||
RefreshSubItems();
|
||||
|
||||
@@ -51,61 +50,61 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
||||
{
|
||||
isSelected = false,
|
||||
coreType = _v2rayN,
|
||||
remarks = ResUI.menuCheckUpdate,
|
||||
IsSelected = false,
|
||||
CoreType = _v2rayN,
|
||||
Remarks = ResUI.menuCheckUpdate,
|
||||
});
|
||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
||||
{
|
||||
isSelected = true,
|
||||
coreType = ECoreType.Xray.ToString(),
|
||||
remarks = ResUI.menuCheckUpdate,
|
||||
IsSelected = true,
|
||||
CoreType = ECoreType.Xray.ToString(),
|
||||
Remarks = ResUI.menuCheckUpdate,
|
||||
});
|
||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
||||
{
|
||||
isSelected = true,
|
||||
coreType = ECoreType.mihomo.ToString(),
|
||||
remarks = ResUI.menuCheckUpdate,
|
||||
IsSelected = true,
|
||||
CoreType = ECoreType.mihomo.ToString(),
|
||||
Remarks = ResUI.menuCheckUpdate,
|
||||
});
|
||||
if (Utils.IsWindows())
|
||||
{
|
||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
||||
{
|
||||
isSelected = true,
|
||||
coreType = ECoreType.sing_box.ToString(),
|
||||
remarks = ResUI.menuCheckUpdate,
|
||||
IsSelected = true,
|
||||
CoreType = ECoreType.sing_box.ToString(),
|
||||
Remarks = ResUI.menuCheckUpdate,
|
||||
});
|
||||
}
|
||||
_checkUpdateItem.Add(new CheckUpdateItem()
|
||||
{
|
||||
isSelected = true,
|
||||
coreType = _geo,
|
||||
remarks = ResUI.menuCheckUpdate,
|
||||
IsSelected = true,
|
||||
CoreType = _geo,
|
||||
Remarks = ResUI.menuCheckUpdate,
|
||||
});
|
||||
}
|
||||
|
||||
private async Task CheckUpdate()
|
||||
{
|
||||
_lstUpdated.Clear();
|
||||
_lstUpdated = _checkUpdateItem.Where(x => x.isSelected == true)
|
||||
.Select(x => new CheckUpdateItem() { coreType = x.coreType }).ToList();
|
||||
_lstUpdated = _checkUpdateItem.Where(x => x.IsSelected == true)
|
||||
.Select(x => new CheckUpdateItem() { CoreType = x.CoreType }).ToList();
|
||||
|
||||
for (int k = _checkUpdateItem.Count - 1; k >= 0; k--)
|
||||
{
|
||||
var item = _checkUpdateItem[k];
|
||||
if (item.isSelected == true)
|
||||
if (item.IsSelected == true)
|
||||
{
|
||||
IsCheckUpdate = false;
|
||||
UpdateView(item.coreType, "...");
|
||||
if (item.coreType == _geo)
|
||||
UpdateView(item.CoreType, "...");
|
||||
if (item.CoreType == _geo)
|
||||
{
|
||||
await CheckUpdateGeo();
|
||||
}
|
||||
else if (item.coreType == _v2rayN)
|
||||
else if (item.CoreType == _v2rayN)
|
||||
{
|
||||
await CheckUpdateN(EnableCheckPreReleaseUpdate);
|
||||
}
|
||||
else if (item.coreType == ECoreType.mihomo.ToString())
|
||||
else if (item.CoreType == ECoreType.mihomo.ToString())
|
||||
{
|
||||
await CheckUpdateCore(item, false);
|
||||
}
|
||||
@@ -119,15 +118,15 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
private void UpdatedPlusPlus(string coreType, string fileName)
|
||||
{
|
||||
var item = _lstUpdated.FirstOrDefault(x => x.coreType == coreType);
|
||||
var item = _lstUpdated.FirstOrDefault(x => x.CoreType == coreType);
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
item.isFinished = true;
|
||||
item.IsFinished = true;
|
||||
if (!fileName.IsNullOrEmpty())
|
||||
{
|
||||
item.fileName = fileName;
|
||||
item.FileName = fileName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +140,7 @@ namespace ServiceLib.ViewModels
|
||||
UpdatedPlusPlus(_geo, "");
|
||||
}
|
||||
}
|
||||
await (new UpdateHandler()).UpdateGeoFileAll(_config, _updateUI)
|
||||
await (new UpdateService()).UpdateGeoFileAll(_config, _updateUI)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
UpdatedPlusPlus(_geo, "");
|
||||
@@ -169,7 +168,7 @@ namespace ServiceLib.ViewModels
|
||||
UpdatedPlusPlus(_v2rayN, msg);
|
||||
}
|
||||
}
|
||||
await (new UpdateHandler()).CheckUpdateGuiN(_config, _updateUI, preRelease)
|
||||
await (new UpdateService()).CheckUpdateGuiN(_config, _updateUI, preRelease)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
UpdatedPlusPlus(_v2rayN, "");
|
||||
@@ -180,31 +179,31 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
void _updateUI(bool success, string msg)
|
||||
{
|
||||
UpdateView(item.coreType, msg);
|
||||
UpdateView(item.CoreType, msg);
|
||||
if (success)
|
||||
{
|
||||
UpdateView(item.coreType, ResUI.MsgUpdateV2rayCoreSuccessfullyMore);
|
||||
UpdateView(item.CoreType, ResUI.MsgUpdateV2rayCoreSuccessfullyMore);
|
||||
|
||||
UpdatedPlusPlus(item.coreType, msg);
|
||||
UpdatedPlusPlus(item.CoreType, msg);
|
||||
}
|
||||
}
|
||||
var type = (ECoreType)Enum.Parse(typeof(ECoreType), item.coreType);
|
||||
await (new UpdateHandler()).CheckUpdateCore(type, _config, _updateUI, preRelease)
|
||||
var type = (ECoreType)Enum.Parse(typeof(ECoreType), item.CoreType);
|
||||
await (new UpdateService()).CheckUpdateCore(type, _config, _updateUI, preRelease)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
UpdatedPlusPlus(item.coreType, "");
|
||||
UpdatedPlusPlus(item.CoreType, "");
|
||||
});
|
||||
}
|
||||
|
||||
private async Task UpdateFinished()
|
||||
{
|
||||
if (_lstUpdated.Count > 0 && _lstUpdated.Count(x => x.isFinished == true) == _lstUpdated.Count)
|
||||
if (_lstUpdated.Count > 0 && _lstUpdated.Count(x => x.IsFinished == true) == _lstUpdated.Count)
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.DispatcherCheckUpdateFinished, false);
|
||||
await Task.Delay(2000);
|
||||
UpgradeCore();
|
||||
|
||||
if (_lstUpdated.Any(x => x.coreType == _v2rayN && x.isFinished == true))
|
||||
if (_lstUpdated.Any(x => x.CoreType == _v2rayN && x.IsFinished == true))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
UpgradeN();
|
||||
@@ -231,7 +230,7 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileName = _lstUpdated.FirstOrDefault(x => x.coreType == _v2rayN)?.fileName;
|
||||
var fileName = _lstUpdated.FirstOrDefault(x => x.CoreType == _v2rayN)?.FileName;
|
||||
if (fileName.IsNullOrEmpty())
|
||||
{
|
||||
return;
|
||||
@@ -248,17 +247,17 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
foreach (var item in _lstUpdated)
|
||||
{
|
||||
if (item.fileName.IsNullOrEmpty())
|
||||
if (item.FileName.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var fileName = item.fileName;
|
||||
var fileName = item.FileName;
|
||||
if (!File.Exists(fileName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string toPath = Utils.GetBinPath("", item.coreType);
|
||||
string toPath = Utils.GetBinPath("", item.CoreType);
|
||||
|
||||
if (fileName.Contains(".tar.gz"))
|
||||
{
|
||||
@@ -266,14 +265,14 @@ namespace ServiceLib.ViewModels
|
||||
}
|
||||
else if (fileName.Contains(".gz"))
|
||||
{
|
||||
FileManager.UncompressedFile(fileName, toPath, item.coreType);
|
||||
FileManager.UncompressedFile(fileName, toPath, item.CoreType);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileManager.ZipExtractToFile(fileName, toPath, _config.guiItem.ignoreGeoUpdateCore ? "geo" : "");
|
||||
}
|
||||
|
||||
UpdateView(item.coreType, ResUI.MsgUpdateV2rayCoreSuccessfully);
|
||||
UpdateView(item.CoreType, ResUI.MsgUpdateV2rayCoreSuccessfully);
|
||||
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
@@ -286,19 +285,19 @@ namespace ServiceLib.ViewModels
|
||||
{
|
||||
var item = new CheckUpdateItem()
|
||||
{
|
||||
coreType = coreType,
|
||||
remarks = msg,
|
||||
CoreType = coreType,
|
||||
Remarks = msg,
|
||||
};
|
||||
_updateView?.Invoke(EViewAction.DispatcherCheckUpdate, item);
|
||||
}
|
||||
|
||||
public void UpdateViewResult(CheckUpdateItem item)
|
||||
{
|
||||
var found = _checkUpdateItem.FirstOrDefault(t => t.coreType == item.coreType);
|
||||
var found = _checkUpdateItem.FirstOrDefault(t => t.CoreType == item.CoreType);
|
||||
if (found != null)
|
||||
{
|
||||
var itemCopy = JsonUtils.DeepCopy(found);
|
||||
itemCopy.remarks = item.remarks;
|
||||
itemCopy.Remarks = item.Remarks;
|
||||
_checkUpdateItem.Replace(found, itemCopy);
|
||||
}
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
public ClashConnectionsViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_config = AppHandler.Instance.Config;
|
||||
_updateView = updateView;
|
||||
SortingSelected = _config.clashUIItem.connectionsSorting;
|
||||
AutoRefresh = _config.clashUIItem.connectionsAutoRefresh;
|
||||
|
@@ -2,7 +2,6 @@ using DynamicData;
|
||||
using DynamicData.Binding;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Splat;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using static ServiceLib.Models.ClashProviders;
|
||||
@@ -44,8 +43,7 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
public ClashProxiesViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||
{
|
||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||
_config = LazyConfig.Instance.Config;
|
||||
_config = AppHandler.Instance.Config;
|
||||
_updateView = updateView;
|
||||
|
||||
SelectedGroup = new();
|
||||
@@ -135,7 +133,7 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
private void UpdateHandler(bool notify, string msg)
|
||||
{
|
||||
_noticeHandler?.SendMessageEx(msg);
|
||||
NoticeHandler.Instance.SendMessageEx(msg);
|
||||
}
|
||||
|
||||
public void ProxiesReload()
|
||||
@@ -363,7 +361,7 @@ namespace ServiceLib.ViewModels
|
||||
var selectedProxy = TryGetProxy(name);
|
||||
if (selectedProxy == null || selectedProxy.type != "Selector")
|
||||
{
|
||||
_noticeHandler?.Enqueue(ResUI.OperationFailed);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -379,7 +377,7 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
SelectedGroup = group2;
|
||||
}
|
||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
|
||||
}
|
||||
|
||||
private void ProxiesDelayTest(bool blAll)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user