mirror of
https://github.com/bolucat/Archive.git
synced 2025-10-30 19:36:59 +08:00
Update On Sun Mar 2 19:33:11 CET 2025
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -929,3 +929,4 @@ Update On Wed Feb 26 19:35:34 CET 2025
|
||||
Update On Thu Feb 27 19:34:57 CET 2025
|
||||
Update On Fri Feb 28 19:34:20 CET 2025
|
||||
Update On Sat Mar 1 19:31:26 CET 2025
|
||||
Update On Sun Mar 2 19:33:02 CET 2025
|
||||
|
||||
@@ -21,10 +21,14 @@ type Client struct {
|
||||
|
||||
dialOut util.DialOutFunc
|
||||
|
||||
sessionCounter atomic.Uint64
|
||||
sessionCounter atomic.Uint64
|
||||
|
||||
idleSession *skiplist.SkipList[uint64, *Session]
|
||||
idleSessionLock sync.Mutex
|
||||
|
||||
sessions map[uint64]*Session
|
||||
sessionsLock sync.Mutex
|
||||
|
||||
padding *atomic.TypedValue[*padding.PaddingFactory]
|
||||
|
||||
idleSessionTimeout time.Duration
|
||||
@@ -33,6 +37,7 @@ type Client struct {
|
||||
|
||||
func NewClient(ctx context.Context, dialOut util.DialOutFunc, _padding *atomic.TypedValue[*padding.PaddingFactory], idleSessionCheckInterval, idleSessionTimeout time.Duration, minIdleSession int) *Client {
|
||||
c := &Client{
|
||||
sessions: make(map[uint64]*Session),
|
||||
dialOut: dialOut,
|
||||
padding: _padding,
|
||||
idleSessionTimeout: idleSessionTimeout,
|
||||
@@ -130,15 +135,35 @@ func (c *Client) createSession(ctx context.Context) (*Session, error) {
|
||||
c.idleSessionLock.Lock()
|
||||
c.idleSession.Remove(math.MaxUint64 - session.seq)
|
||||
c.idleSessionLock.Unlock()
|
||||
|
||||
c.sessionsLock.Lock()
|
||||
delete(c.sessions, session.seq)
|
||||
c.sessionsLock.Unlock()
|
||||
}
|
||||
|
||||
c.sessionsLock.Lock()
|
||||
c.sessions[session.seq] = session
|
||||
c.sessionsLock.Unlock()
|
||||
|
||||
session.Run()
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func (c *Client) Close() error {
|
||||
c.dieCancel()
|
||||
c.minIdleSession = 0
|
||||
go c.idleCleanupExpTime(time.Time{})
|
||||
|
||||
c.sessionsLock.Lock()
|
||||
sessionToClose := make([]*Session, 0, len(c.sessions))
|
||||
for seq, session := range c.sessions {
|
||||
sessionToClose = append(sessionToClose, session)
|
||||
delete(c.sessions, seq)
|
||||
}
|
||||
c.sessionsLock.Unlock()
|
||||
|
||||
for _, session := range sessionToClose {
|
||||
session.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
98
clash-nyanpasu/.github/workflows/ci.yml
vendored
98
clash-nyanpasu/.github/workflows/ci.yml
vendored
@@ -46,20 +46,27 @@ jobs:
|
||||
libxdo-dev
|
||||
webkit2gtk-driver
|
||||
xvfb
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './backend/'
|
||||
prefix-key: 'rust-stable'
|
||||
shared-key: 'ci'
|
||||
save-if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' }}
|
||||
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
if: startsWith(matrix.targets.os, 'macos-')
|
||||
with:
|
||||
xcode-version: '15.0'
|
||||
xcode-version: 'latest-stable'
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 22
|
||||
|
||||
- uses: actions/cache@v4
|
||||
name: Cache Rust dependencies
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
@@ -97,6 +104,81 @@ jobs:
|
||||
env:
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
|
||||
# TODO: support test cross-platform
|
||||
build:
|
||||
name: Build Tauri
|
||||
strategy:
|
||||
matrix:
|
||||
targets:
|
||||
- os: ubuntu-latest
|
||||
- os: macos-latest
|
||||
- os: windows-latest
|
||||
fail-fast: false
|
||||
runs-on: ${{ matrix.targets.os }}
|
||||
needs: lint
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Tauri dependencies
|
||||
if: startsWith(matrix.targets.os, 'ubuntu-')
|
||||
run: >-
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install -y
|
||||
libgtk-3-dev
|
||||
libayatana-appindicator3-dev
|
||||
libwebkit2gtk-4.1-dev
|
||||
librsvg2-dev
|
||||
libxdo-dev
|
||||
webkit2gtk-driver
|
||||
xvfb
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
if: startsWith(matrix.targets.os, 'macos-')
|
||||
with:
|
||||
xcode-version: 'latest-stable'
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- uses: actions/cache@v4
|
||||
name: Cache Rust dependencies
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
name: Install pnpm
|
||||
with:
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v4
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
|
||||
- name: Prepare sidecar and resources
|
||||
run: pnpm check
|
||||
|
||||
- name: Build Tauri
|
||||
run: pnpm tauri build
|
||||
env:
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
# 以后完善了新的测试套件后再添加
|
||||
# test_unit:
|
||||
# name: Unit Test
|
||||
|
||||
@@ -84,12 +84,6 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libwebkit2gtk-4.1-dev libxdo-dev libappindicator3-dev librsvg2-dev patchelf openssl
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './backend/'
|
||||
prefix-key: 'rust-stable'
|
||||
key: ubuntu-latest
|
||||
shared-key: 'release'
|
||||
|
||||
- name: Install Node latest
|
||||
uses: actions/setup-node@v4
|
||||
|
||||
@@ -56,13 +56,6 @@ jobs:
|
||||
rustup install stable --profile minimal --no-self-update
|
||||
rustup default stable
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './backend/'
|
||||
prefix-key: 'rust-stable'
|
||||
key: 'macos-latest'
|
||||
shared-key: 'release'
|
||||
|
||||
- name: Install Rust intel target
|
||||
if: ${{ inputs.aarch64 == false }}
|
||||
run: |
|
||||
@@ -127,6 +120,9 @@ jobs:
|
||||
echo "Uploading $file to release"
|
||||
gh release upload ${{ inputs.tag }} "$file" --clobber
|
||||
done
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload to Github Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
@@ -85,13 +85,6 @@ jobs:
|
||||
run: |
|
||||
rustup target add ${{ inputs.arch }}-pc-windows-msvc
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './backend/'
|
||||
prefix-key: 'rust-stable'
|
||||
key: windows-latest
|
||||
shared-key: 'release'
|
||||
|
||||
- name: Install Node latest
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
|
||||
91
clash-nyanpasu/backend/Cargo.lock
generated
91
clash-nyanpasu/backend/Cargo.lock
generated
@@ -1387,13 +1387,17 @@ dependencies = [
|
||||
"boa_engine",
|
||||
"boa_gc",
|
||||
"boa_parser",
|
||||
"futures-concurrency",
|
||||
"futures-util",
|
||||
"indoc",
|
||||
"isahc",
|
||||
"log",
|
||||
"rustc-hash 2.1.1",
|
||||
"smol",
|
||||
"test-log",
|
||||
"textwrap",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2143,6 +2147,16 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cordyceps"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec10f0a762d93c4498d2e97a333805cb6250d60bead623f71d8034f9a4152ba3"
|
||||
dependencies = [
|
||||
"loom",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
@@ -2608,6 +2622,12 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00"
|
||||
|
||||
[[package]]
|
||||
name = "diatomic-waker"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab03c107fafeb3ee9f5925686dbb7a73bc76e3932abb0d2b365cb64b169cf04c"
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
@@ -3366,6 +3386,12 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.0"
|
||||
@@ -3535,6 +3561,19 @@ dependencies = [
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-buffered"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe940397c8b744b9c2c974791c2c08bca2c3242ce0290393249e98f215a00472"
|
||||
dependencies = [
|
||||
"cordyceps",
|
||||
"diatomic-waker",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.31"
|
||||
@@ -3545,6 +3584,21 @@ dependencies = [
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-concurrency"
|
||||
version = "7.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eb68017df91f2e477ed4bea586c59eaecaa47ed885a770d0444e21e62572cd2"
|
||||
dependencies = [
|
||||
"fixedbitset 0.5.7",
|
||||
"futures-buffered",
|
||||
"futures-core",
|
||||
"futures-lite 2.6.0",
|
||||
"pin-project",
|
||||
"slab",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.31"
|
||||
@@ -3760,6 +3814,19 @@ dependencies = [
|
||||
"x11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generator"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
@@ -5504,6 +5571,19 @@ version = "0.4.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
|
||||
|
||||
[[package]]
|
||||
name = "loom"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"generator",
|
||||
"scoped-tls",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "loop9"
|
||||
version = "0.1.5"
|
||||
@@ -7390,7 +7470,7 @@ version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"fixedbitset 0.4.2",
|
||||
"indexmap 2.7.1",
|
||||
]
|
||||
|
||||
@@ -12410,6 +12490,15 @@ dependencies = [
|
||||
"windows-version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.52.0"
|
||||
|
||||
@@ -13,9 +13,13 @@ boa_gc = { version = "0.20" }
|
||||
boa_parser = { version = "0.20" }
|
||||
isahc = "1.7"
|
||||
futures-util = "0.3"
|
||||
futures-concurrency = "7"
|
||||
smol = "2"
|
||||
tracing = "0.1"
|
||||
url = "2"
|
||||
log = "0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
indoc = "2"
|
||||
textwrap = "0.16"
|
||||
test-log = "0.2"
|
||||
|
||||
73
clash-nyanpasu/backend/boa_utils/src/module/combine.rs
Normal file
73
clash-nyanpasu/backend/boa_utils/src/module/combine.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use boa_engine::module::ModuleLoader;
|
||||
use url::Url;
|
||||
|
||||
pub struct CombineModuleLoader {
|
||||
simple: Rc<boa_engine::module::SimpleModuleLoader>,
|
||||
http: Rc<super::http::HttpModuleLoader>,
|
||||
}
|
||||
|
||||
impl CombineModuleLoader {
|
||||
pub fn new(
|
||||
simple: boa_engine::module::SimpleModuleLoader,
|
||||
http: super::http::HttpModuleLoader,
|
||||
) -> Self {
|
||||
Self {
|
||||
simple: Rc::new(simple),
|
||||
http: Rc::new(http),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_simple(&self) -> Rc<boa_engine::module::SimpleModuleLoader> {
|
||||
self.simple.clone()
|
||||
}
|
||||
|
||||
pub fn clone_http(&self) -> Rc<super::http::HttpModuleLoader> {
|
||||
self.http.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleLoader for CombineModuleLoader {
|
||||
fn load_imported_module(
|
||||
&self,
|
||||
referrer: boa_engine::module::Referrer,
|
||||
specifier: boa_engine::JsString,
|
||||
finish_load: Box<
|
||||
dyn FnOnce(boa_engine::JsResult<boa_engine::Module>, &mut boa_engine::Context),
|
||||
>,
|
||||
context: &mut boa_engine::Context,
|
||||
) {
|
||||
let specifier_str = specifier.to_std_string_escaped();
|
||||
match Url::parse(&specifier_str) {
|
||||
Ok(url) if url.scheme() == "http" || url.scheme() == "https" => {
|
||||
self.http
|
||||
.load_imported_module(referrer, specifier, finish_load, context);
|
||||
}
|
||||
_ => {
|
||||
self.simple
|
||||
.load_imported_module(referrer, specifier, finish_load, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_module(&self, _specifier: boa_engine::JsString) -> Option<boa_engine::Module> {
|
||||
let specifier_str = _specifier.to_std_string_escaped();
|
||||
match Url::parse(&specifier_str) {
|
||||
Ok(url) if url.scheme() == "http" || url.scheme() == "https" => {
|
||||
self.http.get_module(_specifier)
|
||||
}
|
||||
_ => self.simple.get_module(_specifier),
|
||||
}
|
||||
}
|
||||
|
||||
fn register_module(&self, _specifier: boa_engine::JsString, _module: boa_engine::Module) {
|
||||
let specifier_str = _specifier.to_std_string_escaped();
|
||||
match Url::parse(&specifier_str) {
|
||||
Ok(url) if url.scheme() == "http" || url.scheme() == "https" => {
|
||||
self.http.register_module(_specifier, _module);
|
||||
}
|
||||
_ => self.simple.register_module(_specifier, _module),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// Most code is taken from https://github.com/boa-dev/boa/blob/main/examples/src/bin/module_fetch.rs
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
collections::VecDeque,
|
||||
@@ -40,7 +39,7 @@ impl ModuleLoader for HttpModuleLoader {
|
||||
// Adding some prints to show the non-deterministic nature of the async fetches.
|
||||
// Try to run the example several times to see how sometimes the fetches start in order
|
||||
// but finish in disorder.
|
||||
tracing::debug!("Fetching `{url}`...");
|
||||
log::debug!("fetching `{url}`...");
|
||||
// This could also retry fetching in case there's an error while requesting the module.
|
||||
let body: Result<_, isahc::Error> = async {
|
||||
let mut response = Request::get(&url)
|
||||
@@ -52,7 +51,7 @@ impl ModuleLoader for HttpModuleLoader {
|
||||
Ok(response.text().await?)
|
||||
}
|
||||
.await;
|
||||
tracing::debug!("Finished fetching `{url}`");
|
||||
log::debug!("finished fetching `{url}`");
|
||||
|
||||
// Since the async context cannot take the `context` by ref, we have to continue
|
||||
// parsing inside a new `NativeJob` that will be enqueued into the promise job queue.
|
||||
@@ -93,8 +92,8 @@ impl ModuleLoader for HttpModuleLoader {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn main() -> JsResult<()> {
|
||||
#[test]
|
||||
fn test_http_module_loader() -> JsResult<()> {
|
||||
// A simple snippet that imports modules from the web instead of the file system.
|
||||
const SRC: &str = r#"
|
||||
import YAML from 'https://esm.run/yaml@2.3.4';
|
||||
@@ -184,6 +183,12 @@ pub struct Queue<'a> {
|
||||
jobs: RefCell<VecDeque<NativeJob>>,
|
||||
}
|
||||
|
||||
impl Default for Queue<'_> {
|
||||
fn default() -> Self {
|
||||
Self::new(LocalExecutor::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Queue<'a> {
|
||||
fn new(executor: LocalExecutor<'a>) -> Self {
|
||||
Self {
|
||||
@@ -194,12 +199,6 @@ impl<'a> Queue<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Queue<'_> {
|
||||
fn default() -> Self {
|
||||
Self::new(LocalExecutor::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl JobQueue for Queue<'_> {
|
||||
fn enqueue_promise_job(&self, job: NativeJob, _context: &mut Context) {
|
||||
self.jobs.borrow_mut().push_back(job);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#![allow(dead_code)]
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
|
||||
use boa_engine::module::ModuleLoader as BoaModuleLoader;
|
||||
use std::sync::Mutex;
|
||||
pub mod combine;
|
||||
pub mod http;
|
||||
|
||||
pub struct ModuleLoader(Vec<Rc<dyn BoaModuleLoader>>, Mutex<HashMap<String, usize>>);
|
||||
|
||||
@@ -274,15 +274,3 @@ impl Drop for ClashConnectionsConnectorInner {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_connect_clash_server() {
|
||||
"ws://127.0.0.1:12649:10808/connections"
|
||||
.into_client_request()
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use boa_engine::{
|
||||
use boa_utils::{
|
||||
Console,
|
||||
module::{
|
||||
ModuleLoader,
|
||||
combine::CombineModuleLoader,
|
||||
http::{HttpModuleLoader, Queue},
|
||||
},
|
||||
};
|
||||
@@ -77,12 +77,11 @@ pub struct BoaRunner {
|
||||
|
||||
impl BoaRunner {
|
||||
pub fn try_new() -> Result<Self> {
|
||||
let simple_loader = Rc::new(SimpleModuleLoader::new(CUSTOM_SCRIPTS_DIR.as_path())?);
|
||||
let http_loader: Rc<dyn BoaModuleLoader> = Rc::new(HttpModuleLoader);
|
||||
let loader = Rc::new(ModuleLoader::from(vec![
|
||||
simple_loader.clone() as Rc<dyn BoaModuleLoader>,
|
||||
http_loader,
|
||||
]));
|
||||
let loader = Rc::new(CombineModuleLoader::new(
|
||||
SimpleModuleLoader::new(CUSTOM_SCRIPTS_DIR.as_path())?,
|
||||
HttpModuleLoader::default(),
|
||||
));
|
||||
let simple_loader = loader.clone_simple();
|
||||
let queue = Rc::new(Queue::default());
|
||||
let context = Context::builder()
|
||||
.job_queue(queue)
|
||||
@@ -333,6 +332,7 @@ mod utils {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_wrap_script_if_not_esm() {
|
||||
@@ -463,7 +463,7 @@ const foreignNameservers = [
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[test_log::test]
|
||||
fn test_process_honey_with_fetch() {
|
||||
use super::{super::runner::Runner, JSRunner};
|
||||
let runner = JSRunner::try_new().unwrap();
|
||||
|
||||
@@ -207,6 +207,7 @@ impl Indexer {
|
||||
.unwrap()
|
||||
.replace(".", "_")
|
||||
.replace(" ", "_")
|
||||
.replace("-", "__")
|
||||
))
|
||||
.await
|
||||
.context("failed to create index")?;
|
||||
|
||||
@@ -139,6 +139,5 @@ mod test {
|
||||
.await
|
||||
.unwrap();
|
||||
println!("{:?}", results);
|
||||
assert_eq!(results.len(), 5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/react-query": "5.66.9",
|
||||
"@tanstack/react-query": "5.66.11",
|
||||
"@tauri-apps/api": "2.2.0",
|
||||
"ahooks": "3.8.4",
|
||||
"dayjs": "1.11.13",
|
||||
|
||||
@@ -50,6 +50,13 @@ export const useClashConnections = () => {
|
||||
|
||||
const query = useQuery<ClashConnection[]>({
|
||||
queryKey: [CLASH_CONNECTIONS_QUERY_KEY],
|
||||
queryFn: () => {
|
||||
return (
|
||||
queryClient.getQueryData<ClashConnection[]>([
|
||||
CLASH_CONNECTIONS_QUERY_KEY,
|
||||
]) || []
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
const deleteConnections = useMutation({
|
||||
|
||||
@@ -16,6 +16,9 @@ export const useClashLogs = () => {
|
||||
|
||||
const query = useQuery<ClashLog[]>({
|
||||
queryKey: [CLASH_LOGS_QUERY_KEY],
|
||||
queryFn: () => {
|
||||
return queryClient.getQueryData<ClashLog[]>([CLASH_LOGS_QUERY_KEY]) || []
|
||||
},
|
||||
})
|
||||
|
||||
const clean = useMutation({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { CLASH_MEMORY_QUERY_KEY } from './consts'
|
||||
|
||||
export type ClashMemory = {
|
||||
@@ -7,8 +7,15 @@ export type ClashMemory = {
|
||||
}
|
||||
|
||||
export const useClashMemory = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const query = useQuery<ClashMemory[]>({
|
||||
queryKey: [CLASH_MEMORY_QUERY_KEY],
|
||||
queryFn: () => {
|
||||
return (
|
||||
queryClient.getQueryData<ClashMemory[]>([CLASH_MEMORY_QUERY_KEY]) || []
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
return query
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { CLASH_TRAAFFIC_QUERY_KEY } from './consts'
|
||||
|
||||
export type ClashTraffic = {
|
||||
@@ -7,8 +7,16 @@ export type ClashTraffic = {
|
||||
}
|
||||
|
||||
export const useClashTraffic = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const query = useQuery<ClashTraffic[]>({
|
||||
queryKey: [CLASH_TRAAFFIC_QUERY_KEY],
|
||||
queryFn: () => {
|
||||
return (
|
||||
queryClient.getQueryData<ClashTraffic[]>([CLASH_TRAAFFIC_QUERY_KEY]) ||
|
||||
[]
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
return query
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"i18next": "24.2.2",
|
||||
"jotai": "2.12.1",
|
||||
"json-schema": "0.4.0",
|
||||
"material-react-table": "3.2.0",
|
||||
"material-react-table": "3.2.1",
|
||||
"monaco-editor": "0.52.2",
|
||||
"mui-color-input": "5.0.1",
|
||||
"react": "19.0.0",
|
||||
@@ -55,7 +55,7 @@
|
||||
"@emotion/react": "11.14.0",
|
||||
"@iconify/json": "2.2.311",
|
||||
"@monaco-editor/react": "4.7.0",
|
||||
"@tanstack/react-query": "5.66.9",
|
||||
"@tanstack/react-query": "5.66.11",
|
||||
"@tanstack/react-router": "1.112.0",
|
||||
"@tanstack/router-devtools": "1.112.0",
|
||||
"@tanstack/router-plugin": "1.112.0",
|
||||
|
||||
@@ -3,6 +3,7 @@ import dayjs from 'dayjs'
|
||||
import { useSetAtom } from 'jotai'
|
||||
import { lazy, Suspense, useCallback, useState, useTransition } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { IS_NIGHTLY } from '@/consts'
|
||||
import { UpdaterIgnoredAtom } from '@/store/updater'
|
||||
import { formatError } from '@/utils'
|
||||
import { message } from '@/utils/notification'
|
||||
@@ -71,6 +72,10 @@ export default function UpdaterDialog({
|
||||
})
|
||||
})
|
||||
|
||||
const releasesPageUrl = IS_NIGHTLY
|
||||
? `https://github.com/libnyanpasu/clash-nyanpasu/releases/tag/pre-releases`
|
||||
: `https://github.com/libnyanpasu/clash-nyanpasu/releases/tag/v${update.version}`
|
||||
|
||||
return (
|
||||
<BaseDialog
|
||||
{...others}
|
||||
@@ -105,9 +110,7 @@ export default function UpdaterDialog({
|
||||
variant="contained"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
openThat(
|
||||
`https://github.com/libnyanpasu/clash-nyanpasu/releases/tag/v${update.version}`,
|
||||
)
|
||||
openThat(releasesPageUrl)
|
||||
}}
|
||||
>
|
||||
{t('updater.go')}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { getSystem } from '@nyanpasu/ui'
|
||||
|
||||
export const OS = getSystem()
|
||||
|
||||
export const IS_NIGHTLY = window.__IS_NIGHTLY__ === true
|
||||
|
||||
@@ -14,6 +14,8 @@ import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
|
||||
import legacy from '@vitejs/plugin-legacy'
|
||||
import react from '@vitejs/plugin-react-swc'
|
||||
|
||||
const IS_NIGHTLY = process.env.NIGHTLY?.toLowerCase() === 'true'
|
||||
|
||||
const devtools = () => {
|
||||
return {
|
||||
name: 'react-devtools',
|
||||
@@ -26,7 +28,17 @@ const devtools = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const IS_NIGHTLY = process.env.NIGHTLY?.toLowerCase() === 'true'
|
||||
const builtinVars = () => {
|
||||
return {
|
||||
name: 'built-in-vars',
|
||||
transformIndexHtml(html: string) {
|
||||
return html.replace(
|
||||
/<\/head>/,
|
||||
`<script>window.__IS_NIGHTLY__ = true</script></head>`,
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
@@ -80,6 +92,7 @@ export default defineConfig(({ command, mode }) => {
|
||||
},
|
||||
},
|
||||
}),
|
||||
builtinVars(),
|
||||
TanStackRouterVite(),
|
||||
svgr(),
|
||||
react({
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
"@tauri-apps/cli": "2.2.7",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/node": "22.13.5",
|
||||
"@types/node": "22.13.8",
|
||||
"@typescript-eslint/eslint-plugin": "8.25.0",
|
||||
"@typescript-eslint/parser": "8.25.0",
|
||||
"autoprefixer": "10.4.20",
|
||||
@@ -106,7 +106,7 @@
|
||||
"stylelint-scss": "6.11.1",
|
||||
"tailwindcss": "4.0.9",
|
||||
"tsx": "4.19.3",
|
||||
"typescript": "5.7.3",
|
||||
"typescript": "5.8.2",
|
||||
"typescript-eslint": "8.25.0"
|
||||
},
|
||||
"packageManager": "pnpm@10.5.2",
|
||||
|
||||
423
clash-nyanpasu/pnpm-lock.yaml
generated
423
clash-nyanpasu/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly"
|
||||
channel = "nightly-2025-02-25"
|
||||
|
||||
8
clash-verge-rev/.github/workflows/alpha.yml
vendored
8
clash-verge-rev/.github/workflows/alpha.yml
vendored
@@ -92,12 +92,6 @@ jobs:
|
||||
tauriScript: pnpm
|
||||
args: --target ${{ matrix.target }}
|
||||
|
||||
- name: Portable Bundle
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: pnpm portable ${{ matrix.target }} --alpha
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
alpha-for-linux-arm:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -347,7 +341,7 @@ jobs:
|
||||
- Linux arm64 architecture: arm64.deb/aarch64.rpm
|
||||
- Linux armv7架构: armhf.deb/armhfp.rpm
|
||||
|
||||
### Windows (Win7 用户请查看下面FAQ中的解决方案)
|
||||
### Windows (不再支持Win7)
|
||||
#### 正常版本(推荐)
|
||||
- 64位: x64-setup.exe
|
||||
- arm64架构: arm64-setup.exe
|
||||
|
||||
60
clash-verge-rev/.github/workflows/label_issue.yml
vendored
Normal file
60
clash-verge-rev/.github/workflows/label_issue.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
name: Label Issue
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
label-issue:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Label issue if it contains "windows"
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const { data: issue } = await github.rest.issues.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
});
|
||||
|
||||
const labelsToAdd = [];
|
||||
const existingLabels = issue.labels.map(label => label.name);
|
||||
const bodyContent = issue.body.toLowerCase();
|
||||
|
||||
// Check for keywords and add corresponding labels
|
||||
if (bodyContent.includes('windows')) {
|
||||
labelsToAdd.push('windows');
|
||||
}
|
||||
if (bodyContent.includes('linux')) {
|
||||
labelsToAdd.push('linux');
|
||||
}
|
||||
if (bodyContent.includes('macos')) {
|
||||
labelsToAdd.push('macos');
|
||||
}
|
||||
|
||||
if (bodyContent.includes("托盘") || bodyContent.includes("tray")) {
|
||||
labelsToAdd.push('tray');
|
||||
}
|
||||
|
||||
if (bodyContent.includes("菜单") || bodyContent.includes("menu")) {
|
||||
labelsToAdd.push('menu');
|
||||
}
|
||||
|
||||
// Add labels if any match
|
||||
// Filter out labels that already exist to avoid duplication
|
||||
const newLabelsToAdd = labelsToAdd.filter(label => !existingLabels.includes(label));
|
||||
|
||||
// Add labels if there are new ones to add
|
||||
if (newLabelsToAdd.length > 0) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
labels: newLabelsToAdd,
|
||||
});
|
||||
}
|
||||
@@ -87,12 +87,6 @@ jobs:
|
||||
tauriScript: pnpm
|
||||
args: --target ${{ matrix.target }}
|
||||
|
||||
- name: Portable Bundle
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: pnpm portable ${{ matrix.target }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
release-for-linux-arm:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -221,9 +215,6 @@ jobs:
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
arch: x64
|
||||
- os: windows-latest
|
||||
target: i686-pc-windows-msvc
|
||||
arch: x86
|
||||
- os: windows-latest
|
||||
target: aarch64-pc-windows-msvc
|
||||
arch: arm64
|
||||
|
||||
@@ -38,7 +38,7 @@ npm install pnpm -g
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Download the Clash Mihomo Core Binary
|
||||
### Download the Mihomo Core Binary
|
||||
|
||||
You have two options for downloading the clash binary:
|
||||
|
||||
@@ -48,7 +48,7 @@ You have two options for downloading the clash binary:
|
||||
# Use '--force' to force update to the latest version
|
||||
# pnpm run check --force
|
||||
```
|
||||
- Manually download it from the [Clash Meta release](https://github.com/MetaCubeX/Clash.Meta/releases). After downloading, rename the binary according to the [Tauri configuration](https://tauri.app/v1/api/config#bundleconfig.externalbin).
|
||||
- Manually download it from the [Mihomo release](https://github.com/MetaCubeX/mihomo/releases). After downloading, rename the binary according to the [Tauri configuration](https://tauri.app/v1/api/config#bundleconfig.externalbin).
|
||||
|
||||
### Run the Development Server
|
||||
|
||||
@@ -65,11 +65,35 @@ pnpm dev:diff
|
||||
To build this project:
|
||||
|
||||
```shell
|
||||
pnpm run build
|
||||
pnpm build
|
||||
```
|
||||
|
||||
For a faster build, use the following command
|
||||
|
||||
```shell
|
||||
pnpm build:fast
|
||||
```
|
||||
|
||||
This uses Rust's fast-release profile which significantly reduces compilation time by disabling optimization and LTO. The resulting binary will be larger and less performant than the standard build, but it's useful for testing changes quickly.
|
||||
|
||||
The `Artifacts` will display in the `log` in the Terminal.
|
||||
|
||||
### Build clean
|
||||
|
||||
To clean rust build:
|
||||
|
||||
```shell
|
||||
pnpm clean
|
||||
```
|
||||
|
||||
### Portable Version (Windows Only)
|
||||
|
||||
To package portable version after the build:
|
||||
|
||||
```shell
|
||||
pnpm portable
|
||||
```
|
||||
|
||||
## Contributing Your Changes
|
||||
|
||||
Once you have made your changes:
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
{
|
||||
"name": "clash-verge",
|
||||
"version": "2.1.2",
|
||||
"version": "2.1.3-alpha",
|
||||
"license": "GPL-3.0-only",
|
||||
"scripts": {
|
||||
"dev": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev",
|
||||
"dev:fast": "cross-env RUST_BACKTRACE=1 tauri dev",
|
||||
"dev:diff": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev",
|
||||
"dev": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev -- --profile fast-dev",
|
||||
"dev:diff": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev -- --profile fast-dev",
|
||||
"build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build",
|
||||
"build:fast": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build",
|
||||
"build:fast": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build -- --profile fast-release",
|
||||
"tauri": "tauri",
|
||||
"web:dev": "vite",
|
||||
"web:build": "tsc --noEmit && vite build",
|
||||
@@ -18,7 +17,8 @@
|
||||
"portable": "node scripts/portable.mjs",
|
||||
"portable-fixed-webview2": "node scripts/portable-fixed-webview2.mjs",
|
||||
"fix-alpha-version": "node scripts/alpha_version.mjs",
|
||||
"prepare": "husky"
|
||||
"prepare": "husky",
|
||||
"clean": "cd ./src-tauri && cargo clean && cd -"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
|
||||
@@ -26,29 +26,41 @@ async function getLatestCommitHash() {
|
||||
|
||||
/**
|
||||
* @param string 传入格式化后的hash
|
||||
* 将新的版本号写入文件 package.json
|
||||
* 将新的版本号写入文件 package.json / tauri.conf.json
|
||||
*/
|
||||
async function updatePackageVersion(newVersion) {
|
||||
// 获取内容根目录
|
||||
const _dirname = process.cwd();
|
||||
const packageJsonPath = path.join(_dirname, "package.json");
|
||||
const tauriDir = path.join(_dirname, "src-tauri");
|
||||
const internalfile = path.join(tauriDir, "tauri.conf.json");
|
||||
try {
|
||||
const data = await fs.readFile(packageJsonPath, "utf8");
|
||||
const tauriData = await fs.readFile(internalfile, "utf8");
|
||||
|
||||
const packageJson = JSON.parse(data);
|
||||
const initversion = packageJson.version;
|
||||
// 将匹配到的第一个 "alpha" => 具体的hash
|
||||
const fixversion = initversion.replace("alpha", newVersion);
|
||||
packageJson.version = fixversion;
|
||||
const tauriJson = JSON.parse(tauriData);
|
||||
|
||||
let result = packageJson.version.replace("alpha", newVersion);
|
||||
console.log("[INFO]: Current version is: ", result);
|
||||
packageJson.version = result;
|
||||
tauriJson.version = result;
|
||||
// 写入版本号
|
||||
await fs.writeFile(
|
||||
packageJsonPath,
|
||||
JSON.stringify(packageJson, null, 2),
|
||||
"utf8",
|
||||
);
|
||||
console.log(`Alpha version update to: ${fixversion}`);
|
||||
await fs.writeFile(
|
||||
internalfile,
|
||||
JSON.stringify(tauriJson, null, 2),
|
||||
"utf8",
|
||||
);
|
||||
console.log(`[INFO]: Alpha version update to: ${newVersion}`);
|
||||
} catch (error) {
|
||||
console.error("pnpm run fix-alpha-version ERROR", error);
|
||||
}
|
||||
}
|
||||
|
||||
const newVersion = await getLatestCommitHash();
|
||||
updatePackageVersion(newVersion);
|
||||
updatePackageVersion(newVersion).catch(console.error);
|
||||
|
||||
@@ -2,20 +2,16 @@ import fs from "fs";
|
||||
import path from "path";
|
||||
import AdmZip from "adm-zip";
|
||||
import { createRequire } from "module";
|
||||
import { getOctokit, context } from "@actions/github";
|
||||
import fsp from "fs/promises";
|
||||
|
||||
const target = process.argv.slice(2)[0];
|
||||
const alpha = process.argv.slice(2)[1];
|
||||
|
||||
const ARCH_MAP = {
|
||||
"x86_64-pc-windows-msvc": "x64",
|
||||
"i686-pc-windows-msvc": "x86",
|
||||
"aarch64-pc-windows-msvc": "arm64",
|
||||
};
|
||||
|
||||
const PROCESS_MAP = {
|
||||
x64: "x64",
|
||||
ia32: "x86",
|
||||
arm64: "arm64",
|
||||
};
|
||||
const arch = target ? ARCH_MAP[target] : PROCESS_MAP[process.arch];
|
||||
@@ -37,10 +33,9 @@ async function resolvePortable() {
|
||||
if (!fs.existsSync(path.join(configDir, "PORTABLE"))) {
|
||||
await fsp.writeFile(path.join(configDir, "PORTABLE"), "");
|
||||
}
|
||||
|
||||
const zip = new AdmZip();
|
||||
|
||||
zip.addLocalFile(path.join(releaseDir, "Clash Verge.exe"));
|
||||
zip.addLocalFile(path.join(releaseDir, "clash-verge.exe"));
|
||||
zip.addLocalFile(path.join(releaseDir, "verge-mihomo.exe"));
|
||||
zip.addLocalFile(path.join(releaseDir, "verge-mihomo-alpha.exe"));
|
||||
zip.addLocalFolder(path.join(releaseDir, "resources"), "resources");
|
||||
@@ -49,46 +44,9 @@ async function resolvePortable() {
|
||||
const require = createRequire(import.meta.url);
|
||||
const packageJson = require("../package.json");
|
||||
const { version } = packageJson;
|
||||
|
||||
const zipFile = `Clash.Verge_${version}_${arch}_portable.zip`;
|
||||
zip.writeZip(zipFile);
|
||||
|
||||
console.log("[INFO]: create portable zip successfully");
|
||||
|
||||
// push release assets
|
||||
if (process.env.GITHUB_TOKEN === undefined) {
|
||||
throw new Error("GITHUB_TOKEN is required");
|
||||
}
|
||||
|
||||
const options = { owner: context.repo.owner, repo: context.repo.repo };
|
||||
const github = getOctokit(process.env.GITHUB_TOKEN);
|
||||
const tag = alpha ? "alpha" : process.env.TAG_NAME || `v${version}`;
|
||||
console.log("[INFO]: upload to ", tag);
|
||||
|
||||
const { data: release } = await github.rest.repos.getReleaseByTag({
|
||||
...options,
|
||||
tag,
|
||||
});
|
||||
|
||||
let assets = release.assets.filter((x) => {
|
||||
return x.name === zipFile;
|
||||
});
|
||||
if (assets.length > 0) {
|
||||
let id = assets[0].id;
|
||||
await github.rest.repos.deleteReleaseAsset({
|
||||
...options,
|
||||
asset_id: id,
|
||||
});
|
||||
}
|
||||
|
||||
console.log(release.name);
|
||||
|
||||
await github.rest.repos.uploadReleaseAsset({
|
||||
...options,
|
||||
release_id: release.id,
|
||||
name: zipFile,
|
||||
data: zip.toBuffer(),
|
||||
});
|
||||
}
|
||||
|
||||
resolvePortable().catch(console.error);
|
||||
|
||||
@@ -57,13 +57,6 @@ pub fn copy_clash_env() {
|
||||
let http_proxy = format!("http://{clash_verge_rev_ip}:{}", port);
|
||||
let socks5_proxy = format!("socks5://{clash_verge_rev_ip}:{}", port);
|
||||
|
||||
let sh =
|
||||
format!("export https_proxy={http_proxy} http_proxy={http_proxy} all_proxy={socks5_proxy}");
|
||||
let cmd: String = format!("set http_proxy={http_proxy}\r\nset https_proxy={http_proxy}");
|
||||
let ps: String = format!("$env:HTTP_PROXY=\"{http_proxy}\"; $env:HTTPS_PROXY=\"{http_proxy}\"");
|
||||
let nu: String =
|
||||
format!("load-env {{ http_proxy: \"{http_proxy}\", https_proxy: \"{http_proxy}\" }}");
|
||||
|
||||
let cliboard = app_handle.clipboard();
|
||||
let env_type = { Config::verge().latest().env_type.clone() };
|
||||
let env_type = match env_type {
|
||||
@@ -77,11 +70,20 @@ pub fn copy_clash_env() {
|
||||
default.to_string()
|
||||
}
|
||||
};
|
||||
match env_type.as_str() {
|
||||
"bash" => cliboard.write_text(sh).unwrap_or_default(),
|
||||
"cmd" => cliboard.write_text(cmd).unwrap_or_default(),
|
||||
"powershell" => cliboard.write_text(ps).unwrap_or_default(),
|
||||
"nushell" => cliboard.write_text(nu).unwrap_or_default(),
|
||||
_ => log::error!(target: "app", "copy_clash_env: Invalid env type! {env_type}"),
|
||||
|
||||
let export_text = match env_type.as_str() {
|
||||
"bash" => format!("export https_proxy={http_proxy} http_proxy={http_proxy} all_proxy={socks5_proxy}"),
|
||||
"cmd" => format!("set http_proxy={http_proxy}\r\nset https_proxy={http_proxy}"),
|
||||
"powershell" => format!("$env:HTTP_PROXY=\"{http_proxy}\"; $env:HTTPS_PROXY=\"{http_proxy}\""),
|
||||
"nushell" => format!("load-env {{ http_proxy: \"{http_proxy}\", https_proxy: \"{http_proxy}\" }}"),
|
||||
"fish" => format!("set -x http_proxy {http_proxy}; set -x https_proxy {http_proxy}"),
|
||||
_ => {
|
||||
log::error!(target: "app", "copy_clash_env: Invalid env type! {env_type}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(_) = cliboard.write_text(export_text) {
|
||||
log::error!(target: "app", "Failed to write to clipboard");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ use tauri_plugin_autostart::MacosLauncher;
|
||||
use tauri_plugin_deep_link::DeepLinkExt;
|
||||
use std::sync::{Mutex, Once};
|
||||
use tauri::AppHandle;
|
||||
#[cfg(target_os = "macos")]
|
||||
use tauri::Manager;
|
||||
|
||||
/// A global singleton handle to the application.
|
||||
pub struct AppHandleManager {
|
||||
@@ -203,6 +205,11 @@ pub fn run() {
|
||||
app.run(|app_handle, e| match e {
|
||||
tauri::RunEvent::Ready | tauri::RunEvent::Resumed => {
|
||||
AppHandleManager::global().init(app_handle.clone());
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let main_window = AppHandleManager::global().get_handle().get_webview_window("main").unwrap();
|
||||
let _ = main_window.set_title("Clash Verge");
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
tauri::RunEvent::Reopen { has_visible_windows, .. } => {
|
||||
@@ -220,6 +227,7 @@ pub fn run() {
|
||||
if label == "main" {
|
||||
match event {
|
||||
tauri::WindowEvent::CloseRequested { api, .. } => {
|
||||
#[cfg(target_os = "macos")]
|
||||
AppHandleManager::global().set_activation_policy_accessory();
|
||||
if core::handle::Handle::global().is_exiting() {
|
||||
return;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use crate::config::IVerge;
|
||||
use crate::utils::error;
|
||||
use crate::{config::Config, config::PrfItem, core::*, utils::init, utils::server};
|
||||
use crate::{log_err, wrap_err, AppHandleManager};
|
||||
use crate::{log_err, wrap_err};
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::AppHandleManager;
|
||||
use anyhow::{bail, Result};
|
||||
use once_cell::sync::OnceCell;
|
||||
use percent_encoding::percent_decode_str;
|
||||
@@ -133,6 +135,7 @@ pub fn create_window() {
|
||||
log::info!(target: "app", "Starting to create window");
|
||||
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
#[cfg(target_os = "macos")]
|
||||
AppHandleManager::global().set_activation_policy_regular();
|
||||
|
||||
if let Some(window) = handle::Handle::global().get_window() {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"version": "2.1.3-alpha",
|
||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||
"bundle": {
|
||||
"active": true,
|
||||
@@ -25,7 +26,6 @@
|
||||
"devUrl": "http://localhost:3000/"
|
||||
},
|
||||
"productName": "Clash Verge",
|
||||
"version": "2.1.2",
|
||||
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
|
||||
"plugins": {
|
||||
"updater": {
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "Clash Verge"
|
||||
}
|
||||
],
|
||||
"trayIcon": {
|
||||
"iconPath": "icons/tray-icon-mono.ico",
|
||||
"iconAsTemplate": true
|
||||
|
||||
@@ -490,7 +490,7 @@ export const ProxyGroups = (props: Props) => {
|
||||
scrollerRef.current = ref as Element;
|
||||
}}
|
||||
components={{
|
||||
Footer: () => <div style={{ height: "2px" }} />,
|
||||
Footer: () => <div style={{ height: "8px" }} />,
|
||||
}}
|
||||
// 添加平滑滚动设置
|
||||
initialScrollTop={scrollPositionRef.current[mode]}
|
||||
@@ -508,8 +508,13 @@ export const ProxyGroups = (props: Props) => {
|
||||
)}
|
||||
/>
|
||||
<ScrollTopButton show={showScrollTop} onClick={scrollToTop} />
|
||||
|
||||
<AlphabetSelector ref={alphabetSelectorRef} style={{ maxHeight }}>
|
||||
<AlphabetSelector
|
||||
ref={alphabetSelectorRef}
|
||||
style={{
|
||||
maxHeight,
|
||||
right: 10,
|
||||
}}
|
||||
>
|
||||
<div className="scroll-container">
|
||||
<div ref={letterContainerRef} className="letter-container">
|
||||
{groupFirstLetters.map((name) => (
|
||||
|
||||
@@ -66,8 +66,8 @@ export const ProxyRender = (props: RenderProps) => {
|
||||
style={{
|
||||
background: itembackgroundcolor,
|
||||
height: "100%",
|
||||
margin: "8px 8px",
|
||||
borderRadius: "8px",
|
||||
margin: "10px 16px",
|
||||
borderRadius: "10px",
|
||||
}}
|
||||
onClick={() => onHeadState(group.name, { open: !headState?.open })}
|
||||
>
|
||||
@@ -131,7 +131,7 @@ export const ProxyRender = (props: RenderProps) => {
|
||||
if (type === 1) {
|
||||
return (
|
||||
<ProxyHead
|
||||
sx={{ pl: 2, pr: 3, mt: indent ? 1 : 0.5, mb: 1 }}
|
||||
sx={{ pl: 3, pr: 3.5, mt: indent ? 1 : 0.5, mb: 1 }}
|
||||
url={group.testUrl}
|
||||
groupName={group.name}
|
||||
headState={headState!}
|
||||
@@ -191,10 +191,10 @@ export const ProxyRender = (props: RenderProps) => {
|
||||
sx={{
|
||||
height: 56,
|
||||
display: "grid",
|
||||
gap: 1,
|
||||
pl: 2,
|
||||
pr: 2,
|
||||
pb: 1,
|
||||
gap: 1.5,
|
||||
pl: 3,
|
||||
pr: 3.5,
|
||||
pb: 1.25,
|
||||
gridTemplateColumns: `repeat(${item.col! || 2}, 1fr)`,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -142,8 +142,9 @@ const SettingVergeBasic = ({ onError }: Props) => {
|
||||
>
|
||||
<Select size="small" sx={{ width: 140, "> div": { py: "7.5px" } }}>
|
||||
<MenuItem value="bash">Bash</MenuItem>
|
||||
<MenuItem value="cmd">CMD</MenuItem>
|
||||
<MenuItem value="fish">Fish</MenuItem>
|
||||
<MenuItem value="nushell">Nushell</MenuItem>
|
||||
<MenuItem value="cmd">CMD</MenuItem>
|
||||
<MenuItem value="powershell">PowerShell</MenuItem>
|
||||
</Select>
|
||||
</GuardState>
|
||||
|
||||
@@ -5,18 +5,19 @@ import { useClashInfo } from "./use-clash";
|
||||
import dayjs from "dayjs";
|
||||
import { create } from "zustand";
|
||||
import { useVisibility } from "./use-visibility";
|
||||
import {
|
||||
useGlobalLogData,
|
||||
clearGlobalLogs,
|
||||
LogLevel,
|
||||
ILogItem,
|
||||
} from "@/services/global-log-service";
|
||||
|
||||
// 为了向后兼容,导出相同的类型
|
||||
export type { LogLevel };
|
||||
export type { ILogItem };
|
||||
|
||||
const MAX_LOG_NUM = 1000;
|
||||
|
||||
export type LogLevel = "warning" | "info" | "debug" | "error" | "all";
|
||||
|
||||
interface ILogItem {
|
||||
time?: string;
|
||||
type: string;
|
||||
payload: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const buildWSUrl = (server: string, secret: string, logLevel: LogLevel) => {
|
||||
const baseUrl = `ws://${server}/logs`;
|
||||
const params = new URLSearchParams();
|
||||
@@ -57,45 +58,6 @@ const useLogStore = create<LogStore>(
|
||||
}),
|
||||
);
|
||||
|
||||
export const useLogData = (logLevel: LogLevel) => {
|
||||
const { clashInfo } = useClashInfo();
|
||||
const [enableLog] = useEnableLog();
|
||||
const { logs, appendLog } = useLogStore();
|
||||
const pageVisible = useVisibility();
|
||||
export const useLogData = useGlobalLogData;
|
||||
|
||||
useEffect(() => {
|
||||
if (!enableLog || !clashInfo || !pageVisible) return;
|
||||
|
||||
const { server = "", secret = "" } = clashInfo;
|
||||
const wsUrl = buildWSUrl(server, secret, logLevel);
|
||||
|
||||
let isActive = true;
|
||||
const socket = createSockette(wsUrl, {
|
||||
onmessage(event) {
|
||||
if (!isActive) return;
|
||||
const data = JSON.parse(event.data) as ILogItem;
|
||||
const time = dayjs().format("MM-DD HH:mm:ss");
|
||||
appendLog({ ...data, time });
|
||||
},
|
||||
onerror() {
|
||||
if (!isActive) return;
|
||||
socket.close();
|
||||
},
|
||||
});
|
||||
|
||||
return () => {
|
||||
isActive = false;
|
||||
socket.close();
|
||||
};
|
||||
}, [clashInfo, enableLog, logLevel]);
|
||||
|
||||
// 根据当前选择的日志等级过滤日志
|
||||
return logLevel === "all"
|
||||
? logs
|
||||
: logs.filter((log) => log.type.toLowerCase() === logLevel);
|
||||
};
|
||||
|
||||
// 导出清空日志的方法
|
||||
export const clearLogs = () => {
|
||||
useLogStore.getState().clearLogs();
|
||||
};
|
||||
export const clearLogs = clearGlobalLogs;
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useVerge } from "@/hooks/use-verge";
|
||||
import LogoSvg from "@/assets/image/logo.svg?react";
|
||||
import iconLight from "@/assets/image/icon_light.svg?react";
|
||||
import iconDark from "@/assets/image/icon_dark.svg?react";
|
||||
import { useThemeMode } from "@/services/states";
|
||||
import { useThemeMode, useEnableLog } from "@/services/states";
|
||||
import { Notice } from "@/components/base";
|
||||
import { LayoutItem } from "@/components/layout/layout-item";
|
||||
import { LayoutControl } from "@/components/layout/layout-control";
|
||||
@@ -28,6 +28,8 @@ import React from "react";
|
||||
import { TransitionGroup, CSSTransition } from "react-transition-group";
|
||||
import { useListen } from "@/hooks/use-listen";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { useClashInfo } from "@/hooks/use-clash";
|
||||
import { initGlobalLogService } from "@/services/global-log-service";
|
||||
|
||||
const appWindow = getCurrentWebviewWindow();
|
||||
export let portableFlag = false;
|
||||
@@ -126,6 +128,8 @@ const Layout = () => {
|
||||
const { t } = useTranslation();
|
||||
const { theme } = useCustomTheme();
|
||||
const { verge } = useVerge();
|
||||
const { clashInfo } = useClashInfo();
|
||||
const [enableLog] = useEnableLog();
|
||||
const { language, start_page } = verge ?? {};
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
@@ -140,6 +144,15 @@ const Layout = () => {
|
||||
[t, navigate],
|
||||
);
|
||||
|
||||
// 初始化全局日志服务
|
||||
useEffect(() => {
|
||||
if (clashInfo) {
|
||||
const { server = "", secret = "" } = clashInfo;
|
||||
// 使用本地存储中的enableLog值初始化全局日志服务
|
||||
initGlobalLogService(server, secret, enableLog, "info");
|
||||
}
|
||||
}, [clashInfo, enableLog]);
|
||||
|
||||
// 设置监听器
|
||||
useEffect(() => {
|
||||
const listeners = [
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
PlayCircleOutlineRounded,
|
||||
PauseCircleOutlineRounded,
|
||||
} from "@mui/icons-material";
|
||||
import { useLogData, LogLevel, clearLogs } from "@/hooks/use-log-data";
|
||||
import { LogLevel, clearLogs } from "@/hooks/use-log-data";
|
||||
import { useClashInfo } from "@/hooks/use-clash";
|
||||
import { useEnableLog } from "@/services/states";
|
||||
import { BaseEmpty, BasePage } from "@/components/base";
|
||||
import LogItem from "@/components/log/log-item";
|
||||
@@ -16,10 +17,17 @@ import { useTheme } from "@mui/material/styles";
|
||||
import { BaseSearchBox } from "@/components/base/base-search-box";
|
||||
import { BaseStyledSelect } from "@/components/base/base-styled-select";
|
||||
import { SearchState } from "@/components/base/base-search-box";
|
||||
import {
|
||||
useGlobalLogData,
|
||||
clearGlobalLogs,
|
||||
changeLogLevel,
|
||||
toggleLogEnabled,
|
||||
} from "@/services/global-log-service";
|
||||
|
||||
const LogPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const [enableLog, setEnableLog] = useEnableLog();
|
||||
const { clashInfo } = useClashInfo();
|
||||
const theme = useTheme();
|
||||
const isDark = theme.palette.mode === "dark";
|
||||
const [logLevel, setLogLevel] = useLocalStorage<LogLevel>(
|
||||
@@ -27,7 +35,7 @@ const LogPage = () => {
|
||||
"info",
|
||||
);
|
||||
const [match, setMatch] = useState(() => (_: string) => true);
|
||||
const logData = useLogData(logLevel);
|
||||
const logData = useGlobalLogData(logLevel);
|
||||
const [searchState, setSearchState] = useState<SearchState>();
|
||||
|
||||
const filterLogs = useMemo(() => {
|
||||
@@ -44,6 +52,22 @@ const LogPage = () => {
|
||||
: [];
|
||||
}, [logData, logLevel, match]);
|
||||
|
||||
const handleLogLevelChange = (newLevel: LogLevel) => {
|
||||
setLogLevel(newLevel);
|
||||
if (clashInfo) {
|
||||
const { server = "", secret = "" } = clashInfo;
|
||||
changeLogLevel(newLevel, server, secret);
|
||||
}
|
||||
};
|
||||
|
||||
const handleToggleLog = () => {
|
||||
if (clashInfo) {
|
||||
const { server = "", secret = "" } = clashInfo;
|
||||
toggleLogEnabled(server, secret);
|
||||
setEnableLog(!enableLog);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<BasePage
|
||||
full
|
||||
@@ -60,7 +84,7 @@ const LogPage = () => {
|
||||
title={t("Pause")}
|
||||
size="small"
|
||||
color="inherit"
|
||||
onClick={() => setEnableLog((e) => !e)}
|
||||
onClick={handleToggleLog}
|
||||
>
|
||||
{enableLog ? (
|
||||
<PauseCircleOutlineRounded />
|
||||
@@ -74,7 +98,7 @@ const LogPage = () => {
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
clearLogs();
|
||||
clearGlobalLogs();
|
||||
}}
|
||||
>
|
||||
{t("Clear")}
|
||||
@@ -95,7 +119,7 @@ const LogPage = () => {
|
||||
>
|
||||
<BaseStyledSelect
|
||||
value={logLevel}
|
||||
onChange={(e) => setLogLevel(e.target.value as LogLevel)}
|
||||
onChange={(e) => handleLogLevelChange(e.target.value as LogLevel)}
|
||||
>
|
||||
<MenuItem value="all">ALL</MenuItem>
|
||||
<MenuItem value="info">INFO</MenuItem>
|
||||
|
||||
168
clash-verge-rev/src/services/global-log-service.ts
Normal file
168
clash-verge-rev/src/services/global-log-service.ts
Normal file
@@ -0,0 +1,168 @@
|
||||
// 全局日志服务,使应用在任何页面都能收集日志
|
||||
import { create } from "zustand";
|
||||
import { createSockette } from "../utils/websocket";
|
||||
import dayjs from "dayjs";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
// 最大日志数量
|
||||
const MAX_LOG_NUM = 1000;
|
||||
|
||||
export type LogLevel = "warning" | "info" | "debug" | "error" | "all";
|
||||
|
||||
export interface ILogItem {
|
||||
time?: string;
|
||||
type: string;
|
||||
payload: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface GlobalLogStore {
|
||||
logs: ILogItem[];
|
||||
enabled: boolean;
|
||||
isConnected: boolean;
|
||||
currentLevel: LogLevel;
|
||||
setEnabled: (enabled: boolean) => void;
|
||||
setCurrentLevel: (level: LogLevel) => void;
|
||||
clearLogs: () => void;
|
||||
appendLog: (log: ILogItem) => void;
|
||||
}
|
||||
|
||||
// 创建全局状态存储
|
||||
export const useGlobalLogStore = create<GlobalLogStore>((set) => ({
|
||||
logs: [],
|
||||
enabled: false,
|
||||
isConnected: false,
|
||||
currentLevel: "info",
|
||||
setEnabled: (enabled) => set({ enabled }),
|
||||
setCurrentLevel: (currentLevel) => set({ currentLevel }),
|
||||
clearLogs: () => set({ logs: [] }),
|
||||
appendLog: (log: ILogItem) =>
|
||||
set((state) => {
|
||||
const newLogs =
|
||||
state.logs.length >= MAX_LOG_NUM
|
||||
? [...state.logs.slice(1), log]
|
||||
: [...state.logs, log];
|
||||
return { logs: newLogs };
|
||||
}),
|
||||
}));
|
||||
|
||||
// 构建WebSocket URL
|
||||
const buildWSUrl = (server: string, secret: string, logLevel: LogLevel) => {
|
||||
const baseUrl = `ws://${server}/logs`;
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (secret) {
|
||||
params.append("token", secret);
|
||||
}
|
||||
if (logLevel === "all") {
|
||||
params.append("level", "debug");
|
||||
} else {
|
||||
params.append("level", logLevel);
|
||||
}
|
||||
const queryString = params.toString();
|
||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl;
|
||||
};
|
||||
|
||||
// 初始化全局日志服务
|
||||
let globalLogSocket: any = null;
|
||||
|
||||
export const initGlobalLogService = (
|
||||
server: string,
|
||||
secret: string,
|
||||
enabled: boolean = false,
|
||||
logLevel: LogLevel = "info",
|
||||
) => {
|
||||
const { appendLog, setEnabled } = useGlobalLogStore.getState();
|
||||
|
||||
// 更新启用状态
|
||||
setEnabled(enabled);
|
||||
|
||||
// 如果不启用或没有服务器信息,则不初始化
|
||||
if (!enabled || !server) {
|
||||
closeGlobalLogConnection();
|
||||
return;
|
||||
}
|
||||
|
||||
// 关闭现有连接
|
||||
closeGlobalLogConnection();
|
||||
|
||||
// 创建新的WebSocket连接
|
||||
const wsUrl = buildWSUrl(server, secret, logLevel);
|
||||
globalLogSocket = createSockette(wsUrl, {
|
||||
onmessage(event) {
|
||||
try {
|
||||
const data = JSON.parse(event.data) as ILogItem;
|
||||
const time = dayjs().format("MM-DD HH:mm:ss");
|
||||
appendLog({ ...data, time });
|
||||
} catch (error) {
|
||||
console.error("Failed to parse log data:", error);
|
||||
}
|
||||
},
|
||||
onerror() {
|
||||
console.error("Log WebSocket connection error");
|
||||
closeGlobalLogConnection();
|
||||
},
|
||||
onclose() {
|
||||
console.log("Log WebSocket connection closed");
|
||||
useGlobalLogStore.setState({ isConnected: false });
|
||||
},
|
||||
onopen() {
|
||||
console.log("Log WebSocket connection opened");
|
||||
useGlobalLogStore.setState({ isConnected: true });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 关闭全局日志连接
|
||||
export const closeGlobalLogConnection = () => {
|
||||
if (globalLogSocket) {
|
||||
globalLogSocket.close();
|
||||
globalLogSocket = null;
|
||||
useGlobalLogStore.setState({ isConnected: false });
|
||||
}
|
||||
};
|
||||
|
||||
// 切换日志级别
|
||||
export const changeLogLevel = (
|
||||
level: LogLevel,
|
||||
server: string,
|
||||
secret: string,
|
||||
) => {
|
||||
const { enabled } = useGlobalLogStore.getState();
|
||||
useGlobalLogStore.setState({ currentLevel: level });
|
||||
|
||||
if (enabled && server) {
|
||||
initGlobalLogService(server, secret, enabled, level);
|
||||
}
|
||||
};
|
||||
|
||||
// 切换启用状态
|
||||
export const toggleLogEnabled = (server: string, secret: string) => {
|
||||
const { enabled, currentLevel } = useGlobalLogStore.getState();
|
||||
const newEnabled = !enabled;
|
||||
|
||||
useGlobalLogStore.setState({ enabled: newEnabled });
|
||||
|
||||
if (newEnabled && server) {
|
||||
initGlobalLogService(server, secret, newEnabled, currentLevel);
|
||||
} else {
|
||||
closeGlobalLogConnection();
|
||||
}
|
||||
};
|
||||
|
||||
// 获取日志清理函数
|
||||
export const clearGlobalLogs = () => {
|
||||
useGlobalLogStore.getState().clearLogs();
|
||||
};
|
||||
|
||||
// 自定义钩子,用于获取过滤后的日志数据
|
||||
export const useGlobalLogData = (logLevel: LogLevel = "all") => {
|
||||
const logs = useGlobalLogStore((state) => state.logs);
|
||||
|
||||
// 根据当前选择的日志等级过滤日志
|
||||
if (logLevel === "all") {
|
||||
return logs;
|
||||
} else {
|
||||
return logs.filter((log) => log.type.toLowerCase() === logLevel);
|
||||
}
|
||||
};
|
||||
2
clash-verge-rev/src/services/types.d.ts
vendored
2
clash-verge-rev/src/services/types.d.ts
vendored
@@ -694,7 +694,7 @@ interface IVergeConfig {
|
||||
app_log_level?: "trace" | "debug" | "info" | "warn" | "error" | string;
|
||||
language?: string;
|
||||
tray_event?: "main_window" | "system_proxy" | "tun_mode" | string;
|
||||
env_type?: "bash" | "cmd" | "powershell" | string;
|
||||
env_type?: "bash" | "cmd" | "powershell" | "fish" | string;
|
||||
startup_script?: string;
|
||||
start_page?: string;
|
||||
clash_core?: string;
|
||||
|
||||
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=pcie_mhi
|
||||
PKG_VERSION:=1.3.6
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@@ -68,15 +68,13 @@ struct rmnet_nss_cb {
|
||||
int (*nss_tx)(struct sk_buff *skb);
|
||||
};
|
||||
static struct rmnet_nss_cb __read_mostly *nss_cb = NULL;
|
||||
#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018) || defined(CONFIG_PINCTRL_IPQ8074)
|
||||
//#ifdef CONFIG_RMNET_DATA //spf12.x have no macro defined, just for spf11.x
|
||||
#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018)
|
||||
#ifdef CONFIG_RMNET_DATA
|
||||
#define CONFIG_QCA_NSS_DRV
|
||||
/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */ //for spf11.x
|
||||
/* define at qsdk/qca/src/datarmnet/core/rmnet_config.c */ //for spf12.x
|
||||
/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */
|
||||
/* set at qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c */
|
||||
/* need add DEPENDS:= kmod-rmnet-core in feeds/makefile */
|
||||
extern struct rmnet_nss_cb *rmnet_nss_callbacks __rcu __read_mostly;
|
||||
//#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static const unsigned char node_id[ETH_ALEN] = {0x02, 0x50, 0xf4, 0x00, 0x00, 0x00};
|
||||
|
||||
@@ -561,6 +561,7 @@ CONFIG_SCSI_SAS_LIBSAS=y
|
||||
# CONFIG_SECURITY_DMESG_RESTRICT is not set
|
||||
# CONFIG_SENSORS_ARM_SCMI is not set
|
||||
CONFIG_SENSORS_ARM_SCPI=y
|
||||
CONFIG_SENSORS_PWM_FAN=y
|
||||
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_8250_DWLIB=y
|
||||
|
||||
@@ -625,6 +625,7 @@ CONFIG_SCSI_SAS_LIBSAS=y
|
||||
# CONFIG_SECURITY_DMESG_RESTRICT is not set
|
||||
# CONFIG_SENSORS_ARM_SCMI is not set
|
||||
CONFIG_SENSORS_ARM_SCPI=y
|
||||
CONFIG_SENSORS_PWM_FAN=y
|
||||
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_8250_DWLIB=y
|
||||
|
||||
@@ -605,6 +605,7 @@ CONFIG_SCSI_SAS_LIBSAS=y
|
||||
# CONFIG_SECURITY_DMESG_RESTRICT is not set
|
||||
# CONFIG_SENSORS_ARM_SCMI is not set
|
||||
CONFIG_SENSORS_ARM_SCPI=y
|
||||
CONFIG_SENSORS_PWM_FAN=y
|
||||
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_8250_DWLIB=y
|
||||
|
||||
@@ -21,10 +21,14 @@ type Client struct {
|
||||
|
||||
dialOut util.DialOutFunc
|
||||
|
||||
sessionCounter atomic.Uint64
|
||||
sessionCounter atomic.Uint64
|
||||
|
||||
idleSession *skiplist.SkipList[uint64, *Session]
|
||||
idleSessionLock sync.Mutex
|
||||
|
||||
sessions map[uint64]*Session
|
||||
sessionsLock sync.Mutex
|
||||
|
||||
padding *atomic.TypedValue[*padding.PaddingFactory]
|
||||
|
||||
idleSessionTimeout time.Duration
|
||||
@@ -33,6 +37,7 @@ type Client struct {
|
||||
|
||||
func NewClient(ctx context.Context, dialOut util.DialOutFunc, _padding *atomic.TypedValue[*padding.PaddingFactory], idleSessionCheckInterval, idleSessionTimeout time.Duration, minIdleSession int) *Client {
|
||||
c := &Client{
|
||||
sessions: make(map[uint64]*Session),
|
||||
dialOut: dialOut,
|
||||
padding: _padding,
|
||||
idleSessionTimeout: idleSessionTimeout,
|
||||
@@ -130,15 +135,35 @@ func (c *Client) createSession(ctx context.Context) (*Session, error) {
|
||||
c.idleSessionLock.Lock()
|
||||
c.idleSession.Remove(math.MaxUint64 - session.seq)
|
||||
c.idleSessionLock.Unlock()
|
||||
|
||||
c.sessionsLock.Lock()
|
||||
delete(c.sessions, session.seq)
|
||||
c.sessionsLock.Unlock()
|
||||
}
|
||||
|
||||
c.sessionsLock.Lock()
|
||||
c.sessions[session.seq] = session
|
||||
c.sessionsLock.Unlock()
|
||||
|
||||
session.Run()
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func (c *Client) Close() error {
|
||||
c.dieCancel()
|
||||
c.minIdleSession = 0
|
||||
go c.idleCleanupExpTime(time.Time{})
|
||||
|
||||
c.sessionsLock.Lock()
|
||||
sessionToClose := make([]*Session, 0, len(c.sessions))
|
||||
for seq, session := range c.sessions {
|
||||
sessionToClose = append(sessionToClose, session)
|
||||
delete(c.sessions, seq)
|
||||
}
|
||||
c.sessionsLock.Unlock()
|
||||
|
||||
for _, session := range sessionToClose {
|
||||
session.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -78,13 +78,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- sdk_ver: 21.02
|
||||
luci_ver: 19.07
|
||||
- sdk_ver: "21.02"
|
||||
luci_ver: "19.07"
|
||||
sdk_url: https://downloads.openwrt.org/releases/21.02.7/targets/x86/64/openwrt-sdk-21.02.7-x86-64_gcc-8.4.0_musl.Linux-x86_64.tar.xz
|
||||
|
||||
- sdk_ver: 23.05
|
||||
luci_ver: 23.05
|
||||
sdk_url: https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
- sdk_ver: "24.10"
|
||||
luci_ver: "24.10"
|
||||
sdk_url: https://downloads.openwrt.org/releases/24.10.0/targets/x86/64/openwrt-sdk-24.10.0-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
steps:
|
||||
- name: Install packages
|
||||
run: |
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
run: |
|
||||
wget ${{ matrix.sdk_url }}
|
||||
file_name=$(echo ${{ matrix.sdk_url }} | awk -F/ '{print $NF}')
|
||||
mkdir sdk && tar -xJf $file_name -C ./sdk --strip-components=1
|
||||
mkdir sdk && tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
cd sdk
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
@@ -115,6 +115,10 @@ jobs:
|
||||
echo "src-git routing https://git.openwrt.org/feed/routing.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git passwall_packages https://github.com/${{ env.packages }}.git;main" >> feeds.conf
|
||||
echo "src-git passwall https://github.com/${{ env.passwall }}.git;${{ github.ref_name }}" >> feeds.conf
|
||||
|
||||
rm -rf feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 24.x feeds/packages/lang/golang
|
||||
|
||||
./scripts/feeds update -a
|
||||
echo "CONFIG_PACKAGE_luci-app-passwall=m" > .config
|
||||
./scripts/feeds install -d n luci-app-passwall
|
||||
@@ -172,58 +176,76 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- platform: x86_64
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/x86/64/openwrt-sdk-24.10.0-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: aarch64_generic
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/rockchip/armv8/openwrt-sdk-23.05.5-rockchip-armv8_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/rockchip/armv8/openwrt-sdk-24.10.0-rockchip-armv8_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: aarch64_cortex-a53
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/mvebu/cortexa53/openwrt-sdk-23.05.5-mvebu-cortexa53_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/mvebu/cortexa53/openwrt-sdk-24.10.0-mvebu-cortexa53_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: aarch64_cortex-a72
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/mvebu/cortexa72/openwrt-sdk-23.05.5-mvebu-cortexa72_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/mvebu/cortexa72/openwrt-sdk-24.10.0-mvebu-cortexa72_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a5_vfpv4
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/at91/sama5/openwrt-sdk-23.05.5-at91-sama5_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/at91/sama5/openwrt-sdk-24.10.0-at91-sama5_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a7
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/mediatek/mt7629/openwrt-sdk-23.05.5-mediatek-mt7629_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/mediatek/mt7629/openwrt-sdk-24.10.0-mediatek-mt7629_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a7_neon-vfpv4
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/sunxi/cortexa7/openwrt-sdk-23.05.5-sunxi-cortexa7_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/sunxi/cortexa7/openwrt-sdk-24.10.0-sunxi-cortexa7_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a8_vfpv3
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/sunxi/cortexa8/openwrt-sdk-23.05.5-sunxi-cortexa8_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/sunxi/cortexa8/openwrt-sdk-24.10.0-sunxi-cortexa8_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a9
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/bcm53xx/generic/openwrt-sdk-23.05.5-bcm53xx-generic_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/bcm53xx/generic/openwrt-sdk-24.10.0-bcm53xx-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a9_neon
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/zynq/generic/openwrt-sdk-23.05.5-zynq-generic_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/zynq/generic/openwrt-sdk-24.10.0-zynq-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a9_vfpv3-d16
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/mvebu/cortexa9/openwrt-sdk-23.05.5-mvebu-cortexa9_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/mvebu/cortexa9/openwrt-sdk-24.10.0-mvebu-cortexa9_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a15_neon-vfpv4
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/ipq806x/generic/openwrt-sdk-23.05.5-ipq806x-generic_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/ipq806x/generic/openwrt-sdk-24.10.0-ipq806x-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mips_24kc
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/ath79/generic/openwrt-sdk-23.05.5-ath79-generic_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/ath79/generic/openwrt-sdk-24.10.0-ath79-generic_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mips_4kec
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/realtek/rtl838x/openwrt-sdk-23.05.5-realtek-rtl838x_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/realtek/rtl838x/openwrt-sdk-24.10.0-realtek-rtl838x_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mips_mips32
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/bcm63xx/generic/openwrt-sdk-23.05.5-bcm63xx-generic_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/bcm53xx/generic/openwrt-sdk-24.10.0-bcm53xx-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mipsel_24kc
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/ramips/rt288x/openwrt-sdk-23.05.5-ramips-rt288x_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/ramips/rt288x/openwrt-sdk-24.10.0-ramips-rt288x_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mipsel_74kc
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/ramips/rt3883/openwrt-sdk-23.05.5-ramips-rt3883_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/ramips/rt3883/openwrt-sdk-24.10.0-ramips-rt3883_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mipsel_mips32
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/bcm47xx/generic/openwrt-sdk-23.05.5-bcm47xx-generic_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/bcm47xx/generic/openwrt-sdk-24.10.0-bcm47xx-generic_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
steps:
|
||||
- name: Initialization ${{ matrix.platform }} compile environment
|
||||
@@ -239,7 +261,7 @@ jobs:
|
||||
run: |
|
||||
wget ${{ matrix.url_sdk }}
|
||||
file_name=$(echo ${{matrix.url_sdk}} | awk -F/ '{print $NF}')
|
||||
mkdir sdk && tar -xJf $file_name -C ./sdk --strip-components=1
|
||||
mkdir sdk && tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
cd sdk
|
||||
|
||||
- name: SSH connection to Actions
|
||||
@@ -249,10 +271,10 @@ jobs:
|
||||
- name: ${{ matrix.platform }} feeds configuration packages
|
||||
run: |
|
||||
cd sdk
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-23.05" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-23.05" >> feeds.conf
|
||||
echo "src-git luci https://github.com/openwrt/luci.git;openwrt-23.05" >> feeds.conf
|
||||
echo "src-git routing https://git.openwrt.org/feed/routing.git;openwrt-23.05" >> feeds.conf
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git routing https://git.openwrt.org/feed/routing.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git passwall_packages https://github.com/${{ env.packages }}.git;main" >> feeds.conf
|
||||
echo "src-git passwall https://github.com/${{ env.passwall }}.git;main" >> feeds.conf
|
||||
|
||||
@@ -305,7 +327,11 @@ jobs:
|
||||
cd sdk
|
||||
for package in $(ls feeds/passwall_packages); do
|
||||
if [ -d "feeds/passwall_packages/$package" ]; then
|
||||
make package/feeds/passwall_packages/$package/compile -j$(nproc) V=s 2>/dev/null
|
||||
echo "-----------begin compile $package ---------------"
|
||||
sleep 10s
|
||||
make package/feeds/passwall_packages/$package/compile -j$(nproc) V=s
|
||||
echo "-----------compiled $package ---------------"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=25.2.12
|
||||
PKG_VERSION:=25.3.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -78,13 +78,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- sdk_ver: 21.02
|
||||
luci_ver: 19.07
|
||||
- sdk_ver: "21.02"
|
||||
luci_ver: "19.07"
|
||||
sdk_url: https://downloads.openwrt.org/releases/21.02.7/targets/x86/64/openwrt-sdk-21.02.7-x86-64_gcc-8.4.0_musl.Linux-x86_64.tar.xz
|
||||
|
||||
- sdk_ver: 23.05
|
||||
luci_ver: 23.05
|
||||
sdk_url: https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
- sdk_ver: "24.10"
|
||||
luci_ver: "24.10"
|
||||
sdk_url: https://downloads.openwrt.org/releases/24.10.0/targets/x86/64/openwrt-sdk-24.10.0-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
steps:
|
||||
- name: Install packages
|
||||
run: |
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
run: |
|
||||
wget ${{ matrix.sdk_url }}
|
||||
file_name=$(echo ${{ matrix.sdk_url }} | awk -F/ '{print $NF}')
|
||||
mkdir sdk && tar -xJf $file_name -C ./sdk --strip-components=1
|
||||
mkdir sdk && tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
cd sdk
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
@@ -115,10 +115,14 @@ jobs:
|
||||
echo "src-git routing https://git.openwrt.org/feed/routing.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git passwall_packages https://github.com/${{ env.packages }}.git;main" >> feeds.conf
|
||||
echo "src-git passwall2 https://github.com/${{ env.passwall2 }}.git;${{ github.ref_name }}" >> feeds.conf
|
||||
|
||||
rm -rf feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 24.x feeds/packages/lang/golang
|
||||
|
||||
./scripts/feeds update -a
|
||||
echo "CONFIG_PACKAGE_luci-app-passwall2=m" > .config
|
||||
./scripts/feeds install -d n luci-app-passwall2
|
||||
make package/luci-app-passwall2/download -j1
|
||||
make package/luci-app-passwall2/download -j$(nproc)
|
||||
|
||||
- name: Update passwall2 feeds
|
||||
if: steps.cache-sdk.outputs.cache-hit == 'true'
|
||||
@@ -140,8 +144,8 @@ jobs:
|
||||
echo "CONFIG_LUCI_LANG_zh_Hans=y" >> .config
|
||||
echo "CONFIG_PACKAGE_luci-app-passwall2=m" >> .config
|
||||
make defconfig
|
||||
echo "make package/luci-app-passwall2/{clean,compile} -j1"
|
||||
make package/luci-app-passwall2/{clean,compile} -j1 V=s
|
||||
echo "make package/luci-app-passwall2/{clean,compile} -j$(nproc)"
|
||||
make package/luci-app-passwall2/{clean,compile} -j$(nproc) V=s
|
||||
mv bin/packages/x86_64/passwall2/ ../
|
||||
make clean
|
||||
rm .config .config.old
|
||||
@@ -172,58 +176,76 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- platform: x86_64
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/x86/64/openwrt-sdk-24.10.0-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: aarch64_generic
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/rockchip/armv8/openwrt-sdk-23.05.5-rockchip-armv8_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/rockchip/armv8/openwrt-sdk-24.10.0-rockchip-armv8_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: aarch64_cortex-a53
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/mvebu/cortexa53/openwrt-sdk-23.05.5-mvebu-cortexa53_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/mvebu/cortexa53/openwrt-sdk-24.10.0-mvebu-cortexa53_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: aarch64_cortex-a72
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/mvebu/cortexa72/openwrt-sdk-23.05.5-mvebu-cortexa72_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/mvebu/cortexa72/openwrt-sdk-24.10.0-mvebu-cortexa72_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a5_vfpv4
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/at91/sama5/openwrt-sdk-23.05.5-at91-sama5_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/at91/sama5/openwrt-sdk-24.10.0-at91-sama5_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a7
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/mediatek/mt7629/openwrt-sdk-23.05.5-mediatek-mt7629_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/mediatek/mt7629/openwrt-sdk-24.10.0-mediatek-mt7629_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a7_neon-vfpv4
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/sunxi/cortexa7/openwrt-sdk-23.05.5-sunxi-cortexa7_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/sunxi/cortexa7/openwrt-sdk-24.10.0-sunxi-cortexa7_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a8_vfpv3
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/sunxi/cortexa8/openwrt-sdk-23.05.5-sunxi-cortexa8_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/sunxi/cortexa8/openwrt-sdk-24.10.0-sunxi-cortexa8_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a9
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/bcm53xx/generic/openwrt-sdk-23.05.5-bcm53xx-generic_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/bcm53xx/generic/openwrt-sdk-24.10.0-bcm53xx-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a9_neon
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/zynq/generic/openwrt-sdk-23.05.5-zynq-generic_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/zynq/generic/openwrt-sdk-24.10.0-zynq-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a9_vfpv3-d16
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/mvebu/cortexa9/openwrt-sdk-23.05.5-mvebu-cortexa9_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/mvebu/cortexa9/openwrt-sdk-24.10.0-mvebu-cortexa9_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: arm_cortex-a15_neon-vfpv4
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/ipq806x/generic/openwrt-sdk-23.05.5-ipq806x-generic_gcc-12.3.0_musl_eabi.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/ipq806x/generic/openwrt-sdk-24.10.0-ipq806x-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mips_24kc
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/ath79/generic/openwrt-sdk-23.05.5-ath79-generic_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/ath79/generic/openwrt-sdk-24.10.0-ath79-generic_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mips_4kec
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/realtek/rtl838x/openwrt-sdk-23.05.5-realtek-rtl838x_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/realtek/rtl838x/openwrt-sdk-24.10.0-realtek-rtl838x_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mips_mips32
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/bcm63xx/generic/openwrt-sdk-23.05.5-bcm63xx-generic_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/bcm53xx/generic/openwrt-sdk-24.10.0-bcm53xx-generic_gcc-13.3.0_musl_eabi.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mipsel_24kc
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/ramips/rt288x/openwrt-sdk-23.05.5-ramips-rt288x_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/ramips/rt288x/openwrt-sdk-24.10.0-ramips-rt288x_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mipsel_74kc
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/ramips/rt3883/openwrt-sdk-23.05.5-ramips-rt3883_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/ramips/rt3883/openwrt-sdk-24.10.0-ramips-rt3883_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
- platform: mipsel_mips32
|
||||
url_sdk: https://downloads.openwrt.org/releases/23.05.5/targets/bcm47xx/generic/openwrt-sdk-23.05.5-bcm47xx-generic_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
||||
url_sdk: https://downloads.openwrt.org/releases/24.10.0/targets/bcm47xx/generic/openwrt-sdk-24.10.0-bcm47xx-generic_gcc-13.3.0_musl.Linux-x86_64.tar.zst
|
||||
sdk_ver: "24.10"
|
||||
|
||||
steps:
|
||||
- name: Initialization ${{ matrix.platform }} compile environment
|
||||
@@ -239,7 +261,7 @@ jobs:
|
||||
run: |
|
||||
wget ${{ matrix.url_sdk }}
|
||||
file_name=$(echo ${{matrix.url_sdk}} | awk -F/ '{print $NF}')
|
||||
mkdir sdk && tar -xJf $file_name -C ./sdk --strip-components=1
|
||||
mkdir sdk && tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
cd sdk
|
||||
|
||||
- name: SSH connection to Actions
|
||||
@@ -249,10 +271,10 @@ jobs:
|
||||
- name: ${{ matrix.platform }} feeds configuration packages
|
||||
run: |
|
||||
cd sdk
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-23.05" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-23.05" >> feeds.conf
|
||||
echo "src-git luci https://github.com/openwrt/luci.git;openwrt-23.05" >> feeds.conf
|
||||
echo "src-git routing https://git.openwrt.org/feed/routing.git;openwrt-23.05" >> feeds.conf
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git routing https://git.openwrt.org/feed/routing.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git passwall_packages https://github.com/${{ env.packages }}.git;main" >> feeds.conf
|
||||
echo "src-git passwall2 https://github.com/${{ env.passwall2 }}.git;main" >> feeds.conf
|
||||
|
||||
@@ -261,7 +283,7 @@ jobs:
|
||||
./scripts/feeds install luci-app-passwall2
|
||||
|
||||
rm -rf feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 23.x feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 24.x feeds/packages/lang/golang
|
||||
|
||||
echo "CONFIG_ALL_NONSHARED=n" > .config
|
||||
echo "CONFIG_ALL_KMODS=n" >> .config
|
||||
@@ -292,27 +314,26 @@ jobs:
|
||||
- name: ${{ matrix.platform }} download
|
||||
run: |
|
||||
cd sdk
|
||||
make download -j1
|
||||
make download -j$(nproc)
|
||||
find dl -size -1024c -exec ls -l {} \;
|
||||
|
||||
- name: ${{ matrix.platform }} compile
|
||||
id: compile
|
||||
run: |
|
||||
cd sdk
|
||||
make package/feeds/passwall_packages/chinadns-ng/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/geoview/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/tcping/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/xray-core/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/v2ray-geodata/compile -j1 V=s 2>/dev/null
|
||||
|
||||
make package/feeds/passwall_packages/hysteria/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/naiveproxy/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/shadowsocks-rust/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/shadowsocksr-libev/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/simple-obfs/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/sing-box/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/tuic-client/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/v2ray-plugin/compile -j1 V=s 2>/dev/null
|
||||
make package/feeds/passwall_packages/chinadns-ng/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/geoview/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/tcping/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/xray-core/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/v2ray-geodata/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/hysteria/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/naiveproxy/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/shadowsocks-rust/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/shadowsocksr-libev/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/simple-obfs/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/sing-box/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/tuic-client/compile -j$(nproc) V=s
|
||||
make package/feeds/passwall_packages/v2ray-plugin/compile -j$(nproc) V=s
|
||||
|
||||
echo "status=success" >> $GITHUB_OUTPUT
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall2
|
||||
PKG_VERSION:=25.1.27
|
||||
PKG_VERSION:=25.3.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -14,6 +14,7 @@ end
|
||||
|
||||
local normal_list = {}
|
||||
local balancing_list = {}
|
||||
local urltest_list = {}
|
||||
local shunt_list = {}
|
||||
local iface_list = {}
|
||||
for k, v in pairs(nodes_table) do
|
||||
@@ -23,6 +24,9 @@ for k, v in pairs(nodes_table) do
|
||||
if v.protocol and v.protocol == "_balancing" then
|
||||
balancing_list[#balancing_list + 1] = v
|
||||
end
|
||||
if v.protocol and v.protocol == "_urltest" then
|
||||
urltest_list[#urltest_list + 1] = v
|
||||
end
|
||||
if v.protocol and v.protocol == "_shunt" then
|
||||
shunt_list[#shunt_list + 1] = v
|
||||
end
|
||||
@@ -130,6 +134,9 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
for k1, v1 in pairs(balancing_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(urltest_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(iface_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
@@ -174,6 +181,9 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
for k1, v1 in pairs(balancing_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(urltest_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(iface_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
@@ -199,6 +209,9 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
for k1, v1 in pairs(balancing_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(urltest_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(iface_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
@@ -214,7 +227,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
o:value("", translate("Close"))
|
||||
o:value("main", translate("Preproxy Node"))
|
||||
for k1, v1 in pairs(normal_list) do
|
||||
if v1.protocol ~= "_balancing" then
|
||||
if v1.protocol ~= "_balancing" and v1.protocol ~= "_urltest" then
|
||||
o:depends({ [vid .. "-default_node"] = v1.id, [vid .. "-preproxy_enabled"] = "1" })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -96,6 +96,8 @@ o.cfgvalue = function(t, n)
|
||||
local protocol = m:get(n, "protocol")
|
||||
if protocol == "_balancing" then
|
||||
protocol = translate("Balancing")
|
||||
elseif protocol == "_urltest" then
|
||||
protocol = "URLTest"
|
||||
elseif protocol == "_shunt" then
|
||||
protocol = translate("Shunt")
|
||||
elseif protocol == "vmess" then
|
||||
|
||||
@@ -56,6 +56,7 @@ end
|
||||
if singbox_tags:find("with_quic") then
|
||||
o:value("hysteria2", "Hysteria2")
|
||||
end
|
||||
o:value("_urltest", translate("URLTest"))
|
||||
o:value("_shunt", translate("Shunt"))
|
||||
o:value("_iface", translate("Custom Interface"))
|
||||
|
||||
@@ -65,6 +66,7 @@ o:depends({ [_n("protocol")] = "_iface" })
|
||||
|
||||
local nodes_table = {}
|
||||
local iface_table = {}
|
||||
local urltest_table = {}
|
||||
for k, e in ipairs(api.get_valid_nodes()) do
|
||||
if e.node_type == "normal" then
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
@@ -79,6 +81,12 @@ for k, e in ipairs(api.get_valid_nodes()) do
|
||||
remark = e["remark"]
|
||||
}
|
||||
end
|
||||
if e.protocol == "_urltest" then
|
||||
urltest_table[#urltest_table + 1] = {
|
||||
id = e[".name"],
|
||||
remark = e["remark"]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local socks_list = {}
|
||||
@@ -91,6 +99,44 @@ m.uci:foreach(appname, "socks", function(s)
|
||||
end
|
||||
end)
|
||||
|
||||
--[[ URLTest ]]
|
||||
o = s:option(DynamicList, _n("urltest_node"), translate("URLTest node list"), translate("List of nodes to test, <a target='_blank' href='https://sing-box.sagernet.org/configuration/outbound/urltest'>document</a>"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remark) end
|
||||
|
||||
o = s:option(Value, _n("urltest_url"), translate("Probe URL"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o:value("https://cp.cloudflare.com/", "Cloudflare")
|
||||
o:value("https://www.gstatic.com/generate_204", "Gstatic")
|
||||
o:value("https://www.google.com/generate_204", "Google")
|
||||
o:value("https://www.youtube.com/generate_204", "YouTube")
|
||||
o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)")
|
||||
o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)")
|
||||
o.default = "https://www.gstatic.com/generate_204"
|
||||
o.description = translate("The URL used to detect the connection status.")
|
||||
|
||||
o = s:option(Value, _n("urltest_interval"), translate("Test interval"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o.datatype = "uinteger"
|
||||
o.default = "180"
|
||||
o.description = translate("The test interval in seconds.") .. "<br />" ..
|
||||
translate("Test interval must be less or equal than idle timeout.")
|
||||
|
||||
o = s:option(Value, _n("urltest_tolerance"), translate("Test tolerance"), translate("The test tolerance in milliseconds."))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o.datatype = "uinteger"
|
||||
o.default = "50"
|
||||
|
||||
o = s:option(Value, _n("urltest_idle_timeout"), translate("Idle timeout"), translate("The idle timeout in seconds."))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o.datatype = "uinteger"
|
||||
o.default = "1800"
|
||||
|
||||
o = s:option(Flag, _n("urltest_interrupt_exist_connections"), translate("Interrupt existing connections"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o.default = "0"
|
||||
o.description = translate("Interrupt existing connections when the selected outbound has changed.")
|
||||
|
||||
-- [[ 分流模块 ]]
|
||||
if #nodes_table > 0 then
|
||||
o = s:option(Flag, _n("preproxy_enabled"), translate("Preproxy"))
|
||||
@@ -101,6 +147,9 @@ if #nodes_table > 0 then
|
||||
for k, v in pairs(socks_list) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(urltest_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(iface_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
@@ -124,6 +173,9 @@ m.uci:foreach(appname, "shunt_rules", function(e)
|
||||
for k, v in pairs(socks_list) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(urltest_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(iface_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
@@ -155,6 +207,9 @@ if #nodes_table > 0 then
|
||||
for k, v in pairs(socks_list) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(urltest_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(iface_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
|
||||
@@ -314,7 +314,7 @@ function strToTable(str)
|
||||
end
|
||||
|
||||
function is_normal_node(e)
|
||||
if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then
|
||||
if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
@@ -444,7 +444,7 @@ function get_valid_nodes()
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
e.id = e[".name"]
|
||||
if e.type and e.remarks then
|
||||
if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then
|
||||
if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then
|
||||
local type = e.type
|
||||
if type == "sing-box" then type = "Sing-Box" end
|
||||
e["remark"] = "%s:[%s] " % {type .. " " .. i18n.translatef(e.protocol), e.remarks}
|
||||
@@ -494,7 +494,7 @@ end
|
||||
function get_node_remarks(n)
|
||||
local remarks = ""
|
||||
if n then
|
||||
if n.protocol and (n.protocol == "_balancing" or n.protocol == "_shunt" or n.protocol == "_iface") then
|
||||
if n.protocol and (n.protocol == "_balancing" or n.protocol == "_shunt" or n.protocol == "_iface" or n.protocol == "_urltest") then
|
||||
remarks = "%s:[%s] " % {n.type .. " " .. i18n.translatef(n.protocol), n.remarks}
|
||||
else
|
||||
local type2 = n.type
|
||||
@@ -1114,7 +1114,7 @@ end
|
||||
function get_version()
|
||||
local version = sys.exec("opkg list-installed luci-app-passwall2 2>/dev/null | awk '{print $3}'")
|
||||
if not version or #version == 0 then
|
||||
version = sys.exec("apk info -L luci-app-passwall2 2>/dev/null | awk 'NR == 1 {print $1}' | cut -d'-' -f4-")
|
||||
version = sys.exec("apk list luci-app-passwall2 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-")
|
||||
end
|
||||
return version or ""
|
||||
end
|
||||
|
||||
@@ -892,6 +892,54 @@ function gen_config(var)
|
||||
node.port = server_port
|
||||
end
|
||||
|
||||
local function gen_urltest(_node)
|
||||
local urltest_id = _node[".name"]
|
||||
local urltest_tag = "urltest-" .. urltest_id
|
||||
-- existing urltest
|
||||
for _, v in ipairs(outbounds) do
|
||||
if v.tag == urltest_tag then
|
||||
return urltest_tag
|
||||
end
|
||||
end
|
||||
-- new urltest
|
||||
local ut_nodes = _node.urltest_node
|
||||
local valid_nodes = {}
|
||||
for i = 1, #ut_nodes do
|
||||
local ut_node_id = ut_nodes[i]
|
||||
local ut_node_tag = "ut-" .. ut_node_id
|
||||
local is_new_ut_node = true
|
||||
for _, outbound in ipairs(outbounds) do
|
||||
if string.sub(outbound.tag, 1, #ut_node_tag) == ut_node_tag then
|
||||
is_new_ut_node = false
|
||||
valid_nodes[#valid_nodes + 1] = outbound.tag
|
||||
break
|
||||
end
|
||||
end
|
||||
if is_new_ut_node then
|
||||
local ut_node = uci:get_all(appname, ut_node_id)
|
||||
local outbound = gen_outbound(flag, ut_node, ut_node_tag)
|
||||
if outbound then
|
||||
outbound.tag = outbound.tag .. ":" .. ut_node.remarks
|
||||
table.insert(outbounds, outbound)
|
||||
valid_nodes[#valid_nodes + 1] = outbound.tag
|
||||
end
|
||||
end
|
||||
end
|
||||
if #valid_nodes == 0 then return nil end
|
||||
local outbound = {
|
||||
type = "urltest",
|
||||
tag = urltest_tag,
|
||||
outbounds = valid_nodes,
|
||||
url = _node.urltest_url or "https://www.gstatic.com/generate_204",
|
||||
interval = _node.urltest_interval and tonumber(_node.urltest_interval) and string.format("%dm", tonumber(_node.urltest_interval) / 60) or "3m",
|
||||
tolerance = _node.urltest_tolerance and tonumber(_node.urltest_tolerance) and tonumber(_node.urltest_tolerance) or 50,
|
||||
idle_timeout = _node.urltest_idle_timeout and tonumber(_node.urltest_idle_timeout) and string.format("%dm", tonumber(_node.urltest_idle_timeout) / 60) or "30m",
|
||||
interrupt_exist_connections = (_node.urltest_interrupt_exist_connections == "true" or _node.urltest_interrupt_exist_connections == "1") and true or false
|
||||
}
|
||||
table.insert(outbounds, outbound)
|
||||
return urltest_tag
|
||||
end
|
||||
|
||||
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
|
||||
if not node or not outbound or not outbounds_table then return nil end
|
||||
local default_outTag = outbound.tag
|
||||
@@ -1046,6 +1094,8 @@ function gen_config(var)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif _node.protocol == "_urltest" then
|
||||
rule_outboundTag = gen_urltest(_node)
|
||||
elseif _node.protocol == "_iface" then
|
||||
if _node.iface then
|
||||
local _outbound = {
|
||||
@@ -1220,6 +1270,10 @@ function gen_config(var)
|
||||
for index, value in ipairs(rules) do
|
||||
table.insert(route.rules, rules[index])
|
||||
end
|
||||
elseif node.protocol == "_urltest" then
|
||||
if node.urltest_node then
|
||||
COMMON.default_outbound_tag = gen_urltest(node)
|
||||
end
|
||||
elseif node.protocol == "_iface" then
|
||||
if node.iface then
|
||||
local outbound = {
|
||||
|
||||
@@ -1423,9 +1423,6 @@ msgstr "最大并发连接数"
|
||||
msgid "XUDP Mux concurrency"
|
||||
msgstr "XUDP 最大并发连接数"
|
||||
|
||||
msgid "Mux idle timeout"
|
||||
msgstr "最大闲置时间"
|
||||
|
||||
msgid "Padding"
|
||||
msgstr "填充"
|
||||
|
||||
@@ -1444,9 +1441,6 @@ msgstr "推荐值:Sec-WebSocket-Protocol"
|
||||
msgid "Health check"
|
||||
msgstr "健康检查"
|
||||
|
||||
msgid "Idle timeout"
|
||||
msgstr "闲置时间"
|
||||
|
||||
msgid "Health check timeout"
|
||||
msgstr "检查超时时间"
|
||||
|
||||
@@ -1647,3 +1641,39 @@ msgstr "是否要恢复客户端默认配置?"
|
||||
|
||||
msgid "Are you sure you want to restore the client to default settings?"
|
||||
msgstr "是否真的要恢复客户端默认配置?"
|
||||
|
||||
msgid "_urltest"
|
||||
msgstr "URLTest"
|
||||
|
||||
msgid "URLTest node list"
|
||||
msgstr "URLTest 节点列表"
|
||||
|
||||
msgid "List of nodes to test, <a target='_blank' href='https://sing-box.sagernet.org/configuration/outbound/urltest'>document</a>"
|
||||
msgstr "要测试的节点列表,<a target='_blank' href='https://sing-box.sagernet.org/zh/configuration/outbound/urltest'>文档原理</a>"
|
||||
|
||||
msgid "Test interval"
|
||||
msgstr "测试间隔"
|
||||
|
||||
msgid "The test interval in seconds."
|
||||
msgstr "测试间隔时间(单位:秒)。"
|
||||
|
||||
msgid "Test interval must be less or equal than idle timeout."
|
||||
msgstr "测试间隔时间必须小于或等于空闲超时时间。"
|
||||
|
||||
msgid "Test tolerance"
|
||||
msgstr "测试容差"
|
||||
|
||||
msgid "The test tolerance in milliseconds."
|
||||
msgstr "测试容差时间(单位:毫秒)。"
|
||||
|
||||
msgid "Idle timeout"
|
||||
msgstr "空闲超时"
|
||||
|
||||
msgid "The idle timeout in seconds."
|
||||
msgstr "空闲超时时间(单位:秒)。"
|
||||
|
||||
msgid "Interrupt existing connections"
|
||||
msgstr "中断现有连接"
|
||||
|
||||
msgid "Interrupt existing connections when the selected outbound has changed."
|
||||
msgstr "当选择的出站发生变化时中断现有连接。"
|
||||
|
||||
@@ -589,7 +589,7 @@ run_socks() {
|
||||
|
||||
if [ "$type" == "sing-box" ] || [ "$type" == "xray" ]; then
|
||||
local protocol=$(config_n_get $node protocol)
|
||||
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ]; then
|
||||
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ] || [ "$protocol" == "_urltest" ]; then
|
||||
unset error_msg
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -303,6 +303,36 @@ do
|
||||
end
|
||||
}
|
||||
end
|
||||
elseif node.protocol and node.protocol == '_urltest' then
|
||||
local flag = "Sing-Box URLTest节点[" .. node_id .. "]列表"
|
||||
local currentNodes = {}
|
||||
local newNodes = {}
|
||||
if node.urltest_node then
|
||||
for k, node in pairs(node.urltest_node) do
|
||||
currentNodes[#currentNodes + 1] = {
|
||||
log = false,
|
||||
node = node,
|
||||
currentNode = node and uci:get_all(appname, node) or nil,
|
||||
remarks = node,
|
||||
set = function(o, server)
|
||||
if o and server and server ~= "nil" then
|
||||
table.insert(o.newNodes, server)
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
remarks = flag,
|
||||
currentNodes = currentNodes,
|
||||
newNodes = newNodes,
|
||||
set = function(o, newNodes)
|
||||
if o then
|
||||
if not newNodes then newNodes = o.newNodes end
|
||||
uci:set_list(appname, node_id, "urltest_node", newNodes or {})
|
||||
end
|
||||
end
|
||||
}
|
||||
else
|
||||
--前置代理节点
|
||||
local currentNode = uci:get_all(appname, node_id) or nil
|
||||
@@ -1682,7 +1712,7 @@ local execute = function()
|
||||
f:close()
|
||||
raw = trim(stdout)
|
||||
local old_md5 = value.md5 or ""
|
||||
local new_md5 = luci.sys.exec("[ -f " .. tmp_file .. " ] && md5sum " .. tmp_file .. " | awk '{print $1}' || echo 0")
|
||||
local new_md5 = luci.sys.exec("[ -f " .. tmp_file .. " ] && md5sum " .. tmp_file .. " | awk '{print $1}' || echo 0"):gsub("\n", "")
|
||||
os.remove(tmp_file)
|
||||
if old_md5 == new_md5 then
|
||||
log('订阅:【' .. remark .. '】没有变化,无需更新。')
|
||||
|
||||
@@ -71,7 +71,7 @@ url_test_node() {
|
||||
sleep 1s
|
||||
result=$(curl --connect-timeout 3 -o /dev/null -I -skL -w "%{http_code}:%{time_starttransfer}" -x $curlx "https://www.google.com/generate_204")
|
||||
pgrep -af "url_test_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||
rm -rf "/tmp/etc/${CONFIG}/url_test_${node_id}.json"
|
||||
rm -rf "/tmp/etc/${CONFIG}/url_test_${node_id}"*.json
|
||||
}
|
||||
echo $result
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ env:
|
||||
RUST_LOG: "trace"
|
||||
|
||||
jobs:
|
||||
build-test-check:
|
||||
build-and-test:
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
|
||||
@@ -5,7 +5,7 @@ on:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
build-docker-image:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
|
||||
@@ -11,7 +11,7 @@ env:
|
||||
RUST_LOG: "trace"
|
||||
|
||||
jobs:
|
||||
shadowsocks-rust:
|
||||
build-msrv-shadowsocks-rust:
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
@@ -28,9 +28,9 @@ jobs:
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup toolchain install 1.80
|
||||
rustup default 1.80
|
||||
rustup override set 1.80
|
||||
rustup toolchain install 1.83
|
||||
rustup default 1.83
|
||||
rustup override set 1.83
|
||||
- name: Build with All Features Enabled (Unix)
|
||||
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
|
||||
run: cargo build --verbose --features "full-extra local-flow-stat utility-url-outline"
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
run: cargo build --verbose --features "full-extra local-flow-stat utility-url-outline winservice"
|
||||
|
||||
shadowsocks-service:
|
||||
build-msrv-shadowsocks-service:
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
@@ -55,13 +55,13 @@ jobs:
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup toolchain install 1.80
|
||||
rustup default 1.80
|
||||
rustup override set 1.80
|
||||
rustup toolchain install 1.83
|
||||
rustup default 1.83
|
||||
rustup override set 1.83
|
||||
- name: Build with All Features Enabled
|
||||
run: cargo build --manifest-path crates/shadowsocks-service/Cargo.toml --verbose --features "full dns-over-tls dns-over-https dns-over-h3 local-dns local-flow-stat local-http-rustls local-tun local-fake-dns local-online-config stream-cipher aead-cipher-extra aead-cipher-2022 aead-cipher-2022-extra security-replay-attack-detect"
|
||||
|
||||
shadowsocks:
|
||||
build-msrv-shadowsocks:
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
|
||||
@@ -8,7 +8,7 @@ env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build-cross:
|
||||
build-nightly-cross:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUST_BACKTRACE: full
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
name: ${{ matrix.platform.target }}
|
||||
path: build/release/*
|
||||
|
||||
build-unix:
|
||||
build-nightly-unix:
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
BUILD_EXTRA_FEATURES: "full"
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
name: ${{ matrix.target }}
|
||||
path: build/release/*
|
||||
|
||||
build-windows:
|
||||
build-nightly-windows:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
RUSTFLAGS: "-C target-feature=+crt-static"
|
||||
|
||||
@@ -14,7 +14,7 @@ env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build-cross:
|
||||
build-release-cross:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUST_BACKTRACE: full
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
prerelease: ${{ contains(github.ref_name, '-') }}
|
||||
tag_name: ${{ inputs.tag || github.ref_name }}
|
||||
|
||||
build-unix:
|
||||
build-release-unix:
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
BUILD_EXTRA_FEATURES: "full"
|
||||
@@ -162,7 +162,7 @@ jobs:
|
||||
prerelease: ${{ contains(github.ref_name, '-') }}
|
||||
tag_name: ${{ inputs.tag || github.ref_name }}
|
||||
|
||||
build-windows:
|
||||
build-release-windows:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
RUSTFLAGS: "-C target-feature=+crt-static"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Cargo Deny Check
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
cargo-deny:
|
||||
deny-check:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
|
||||
10
shadowsocks-rust/Cargo.lock
generated
10
shadowsocks-rust/Cargo.lock
generated
@@ -956,9 +956,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "etherparse"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8d8a704b617484e9d867a0423cd45f7577f008c4068e2e33378f8d3860a6d73"
|
||||
checksum = "b14e4ac78394e3ea04edbbc412099cf54f2f52ded51efb79c466a282729399d2"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
@@ -3232,7 +3232,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.0",
|
||||
"sendfd",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3299,7 +3299,7 @@ dependencies = [
|
||||
"mimalloc",
|
||||
"mime",
|
||||
"qrcode",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.0",
|
||||
"reqwest",
|
||||
"rpassword",
|
||||
"rpmalloc",
|
||||
@@ -3349,7 +3349,7 @@ dependencies = [
|
||||
"nix",
|
||||
"once_cell",
|
||||
"pin-project",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.0",
|
||||
"regex",
|
||||
"rustls-native-certs",
|
||||
"serde",
|
||||
|
||||
@@ -9,7 +9,7 @@ documentation = "https://docs.rs/shadowsocks-rust"
|
||||
keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"]
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
rust-version = "1.80"
|
||||
rust-version = "1.83"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "passively-maintained" }
|
||||
@@ -229,7 +229,7 @@ directories = "6.0"
|
||||
xdg = "2.5"
|
||||
rpassword = "7.3"
|
||||
libc = { version = "0.2", features = ["extra_traits"] }
|
||||
rand = "0.8"
|
||||
rand = "0.9"
|
||||
|
||||
futures = "0.3"
|
||||
tokio = { version = "1", features = ["rt", "signal"] }
|
||||
|
||||
@@ -1 +1 @@
|
||||
msrv = "1.77"
|
||||
msrv = "1.83"
|
||||
|
||||
@@ -9,7 +9,7 @@ documentation = "https://docs.rs/shadowsocks-service"
|
||||
keywords = ["shadowsocks", "proxy", "socks", "socks5", "firewall"]
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
rust-version = "1.80"
|
||||
rust-version = "1.83"
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "passively-maintained" }
|
||||
@@ -134,7 +134,7 @@ lru_time_cache = "0.11"
|
||||
bytes = "1.7"
|
||||
byte_string = "1.0"
|
||||
byteorder = "1.5"
|
||||
rand = { version = "0.8", features = ["small_rng"] }
|
||||
rand = { version = "0.9", features = ["small_rng"] }
|
||||
sled = { version = "0.34.7", optional = true }
|
||||
|
||||
futures = "0.3"
|
||||
@@ -181,7 +181,7 @@ brotli = { version = "7.0", optional = true }
|
||||
zstd = { version = "0.13", optional = true }
|
||||
|
||||
tun = { version = "0.7", optional = true, features = ["async"] }
|
||||
etherparse = { version = "0.16", optional = true }
|
||||
etherparse = { version = "0.17", optional = true }
|
||||
smoltcp = { version = "0.12", optional = true, default-features = false, features = [
|
||||
"std",
|
||||
"log",
|
||||
|
||||
@@ -23,7 +23,6 @@ use hickory_resolver::proto::{
|
||||
rr::{DNSClass, Name, RData, RecordType},
|
||||
};
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use rand::{thread_rng, Rng};
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
net::{TcpStream, UdpSocket},
|
||||
@@ -854,7 +853,7 @@ impl DnsClient {
|
||||
|
||||
async fn lookup_remote_inner(&self, query: &Query, remote_addr: &Address) -> io::Result<Message> {
|
||||
let mut message = Message::new();
|
||||
message.set_id(thread_rng().gen());
|
||||
message.set_id(rand::random());
|
||||
message.set_recursion_desired(true);
|
||||
message.add_query(query.clone());
|
||||
|
||||
@@ -884,7 +883,7 @@ impl DnsClient {
|
||||
// Then this future will be disabled and have no effect
|
||||
//
|
||||
// Randomly choose from 500ms ~ 1.5s for preventing obvious request pattern
|
||||
let sleep_time = thread_rng().gen_range(500..=1500);
|
||||
let sleep_time = rand::random_range(500..=1500);
|
||||
time::sleep(Duration::from_millis(sleep_time)).await;
|
||||
|
||||
let server = self.balancer.best_tcp_server();
|
||||
@@ -933,7 +932,7 @@ impl DnsClient {
|
||||
|
||||
async fn lookup_local_inner(&self, query: &Query, local_addr: &NameServerAddr) -> io::Result<Message> {
|
||||
let mut message = Message::new();
|
||||
message.set_id(thread_rng().gen());
|
||||
message.set_id(rand::random());
|
||||
message.set_recursion_desired(true);
|
||||
message.add_query(query.clone());
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ use bytes::{BufMut, BytesMut};
|
||||
use hickory_resolver::proto::{op::Message, ProtoError, ProtoErrorKind};
|
||||
use log::{error, trace};
|
||||
use lru_time_cache::{Entry, LruCache};
|
||||
use rand::{thread_rng, Rng};
|
||||
use shadowsocks::{
|
||||
config::ServerConfig,
|
||||
context::SharedContext,
|
||||
@@ -139,7 +138,7 @@ impl DnsClient {
|
||||
|
||||
async fn inner_lookup(&mut self, msg: &mut Message) -> Result<Message, ProtoError> {
|
||||
// Make a random ID
|
||||
msg.set_id(thread_rng().gen());
|
||||
msg.set_id(rand::random());
|
||||
|
||||
trace!("DNS lookup {:?}", msg);
|
||||
|
||||
|
||||
@@ -234,13 +234,18 @@ where
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static CLIENT_SESSION_RNG: RefCell<SmallRng> = RefCell::new(SmallRng::from_entropy());
|
||||
static CLIENT_SESSION_RNG: RefCell<SmallRng> = RefCell::new(SmallRng::from_os_rng());
|
||||
}
|
||||
|
||||
/// Generate an AEAD-2022 Client SessionID
|
||||
#[inline]
|
||||
pub fn generate_client_session_id() -> u64 {
|
||||
CLIENT_SESSION_RNG.with(|rng| rng.borrow_mut().gen())
|
||||
loop {
|
||||
let id = CLIENT_SESSION_RNG.with(|rng| rng.borrow_mut().random());
|
||||
if id != 0 {
|
||||
break id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<W> UdpAssociationContext<W>
|
||||
|
||||
@@ -462,12 +462,17 @@ impl Drop for UdpAssociationContext {
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static CLIENT_SESSION_RNG: RefCell<SmallRng> = RefCell::new(SmallRng::from_entropy());
|
||||
static CLIENT_SESSION_RNG: RefCell<SmallRng> = RefCell::new(SmallRng::from_os_rng());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn generate_server_session_id() -> u64 {
|
||||
CLIENT_SESSION_RNG.with(|rng| rng.borrow_mut().gen())
|
||||
loop {
|
||||
let id = CLIENT_SESSION_RNG.with(|rng| rng.borrow_mut().random());
|
||||
if id != 0 {
|
||||
break id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UdpAssociationContext {
|
||||
|
||||
@@ -62,7 +62,7 @@ spin = { version = "0.9", features = ["std"] }
|
||||
pin-project = "1.1"
|
||||
bloomfilter = { version = "3.0.0", optional = true }
|
||||
thiserror = "2.0"
|
||||
rand = { version = "0.8", optional = true }
|
||||
rand = { version = "0.9", optional = true }
|
||||
lru_time_cache = { version = "0.11", optional = true }
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
@@ -18,11 +18,11 @@ fn get_aead_2022_padding_size(payload: &[u8]) -> usize {
|
||||
use rand::{rngs::SmallRng, Rng, SeedableRng};
|
||||
|
||||
thread_local! {
|
||||
static PADDING_RNG: RefCell<SmallRng> = RefCell::new(SmallRng::from_entropy());
|
||||
static PADDING_RNG: RefCell<SmallRng> = RefCell::new(SmallRng::from_os_rng());
|
||||
}
|
||||
|
||||
if payload.is_empty() {
|
||||
PADDING_RNG.with(|rng| rng.borrow_mut().gen::<usize>() % AEAD2022_MAX_PADDING_SIZE)
|
||||
PADDING_RNG.with(|rng| rng.borrow_mut().random_range::<usize, _>(0..=AEAD2022_MAX_PADDING_SIZE))
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
@@ -92,9 +92,7 @@ impl ProxySocket<ShadowUdpSocket> {
|
||||
context: SharedContext,
|
||||
svr_cfg: &ServerConfig,
|
||||
) -> ProxySocketResult<ProxySocket<ShadowUdpSocket>> {
|
||||
ProxySocket::connect_with_opts(context, svr_cfg, &DEFAULT_CONNECT_OPTS)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
ProxySocket::connect_with_opts(context, svr_cfg, &DEFAULT_CONNECT_OPTS).await
|
||||
}
|
||||
|
||||
/// Create a client to communicate with Shadowsocks' UDP server (outbound)
|
||||
@@ -127,9 +125,7 @@ impl ProxySocket<ShadowUdpSocket> {
|
||||
context: SharedContext,
|
||||
svr_cfg: &ServerConfig,
|
||||
) -> ProxySocketResult<ProxySocket<ShadowUdpSocket>> {
|
||||
ProxySocket::bind_with_opts(context, svr_cfg, AcceptOpts::default())
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
ProxySocket::bind_with_opts(context, svr_cfg, AcceptOpts::default()).await
|
||||
}
|
||||
|
||||
/// Create a `ProxySocket` binding to a specific address (inbound)
|
||||
@@ -240,9 +236,7 @@ where
|
||||
/// Send a UDP packet to addr through proxy
|
||||
#[inline]
|
||||
pub async fn send(&self, addr: &Address, payload: &[u8]) -> ProxySocketResult<usize> {
|
||||
self.send_with_ctrl(addr, &DEFAULT_SOCKET_CONTROL, payload)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
self.send_with_ctrl(addr, &DEFAULT_SOCKET_CONTROL, payload).await
|
||||
}
|
||||
|
||||
/// Send a UDP packet to addr through proxy with `ControlData`
|
||||
@@ -391,9 +385,7 @@ where
|
||||
|
||||
/// Send a UDP packet to target through proxy `target`
|
||||
pub async fn send_to(&self, target: SocketAddr, addr: &Address, payload: &[u8]) -> ProxySocketResult<usize> {
|
||||
self.send_to_with_ctrl(target, addr, &DEFAULT_SOCKET_CONTROL, payload)
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
self.send_to_with_ctrl(target, addr, &DEFAULT_SOCKET_CONTROL, payload).await
|
||||
}
|
||||
|
||||
/// Send a UDP packet to target through proxy `target`
|
||||
|
||||
@@ -4,7 +4,6 @@ use std::process::ExitCode;
|
||||
|
||||
use base64::Engine as _;
|
||||
use clap::{builder::PossibleValuesParser, Arg, ArgAction, ArgMatches, Command};
|
||||
use rand::RngCore;
|
||||
|
||||
use shadowsocks_service::shadowsocks::crypto::{available_ciphers, CipherKind};
|
||||
|
||||
@@ -34,8 +33,7 @@ pub fn main(matches: &ArgMatches) -> ExitCode {
|
||||
let key_len = method.key_len();
|
||||
if key_len > 0 {
|
||||
let mut key = vec![0u8; key_len];
|
||||
let mut rng = rand::thread_rng();
|
||||
rng.fill_bytes(&mut key);
|
||||
rand::fill(key.as_mut_slice());
|
||||
|
||||
let encoded_key = base64::engine::general_purpose::STANDARD.encode(&key);
|
||||
println!("{encoded_key}");
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=25.2.12
|
||||
PKG_VERSION:=25.3.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall2
|
||||
PKG_VERSION:=25.1.27
|
||||
PKG_VERSION:=25.3.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -14,6 +14,7 @@ end
|
||||
|
||||
local normal_list = {}
|
||||
local balancing_list = {}
|
||||
local urltest_list = {}
|
||||
local shunt_list = {}
|
||||
local iface_list = {}
|
||||
for k, v in pairs(nodes_table) do
|
||||
@@ -23,6 +24,9 @@ for k, v in pairs(nodes_table) do
|
||||
if v.protocol and v.protocol == "_balancing" then
|
||||
balancing_list[#balancing_list + 1] = v
|
||||
end
|
||||
if v.protocol and v.protocol == "_urltest" then
|
||||
urltest_list[#urltest_list + 1] = v
|
||||
end
|
||||
if v.protocol and v.protocol == "_shunt" then
|
||||
shunt_list[#shunt_list + 1] = v
|
||||
end
|
||||
@@ -130,6 +134,9 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
for k1, v1 in pairs(balancing_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(urltest_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(iface_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
@@ -174,6 +181,9 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
for k1, v1 in pairs(balancing_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(urltest_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(iface_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
@@ -199,6 +209,9 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
for k1, v1 in pairs(balancing_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(urltest_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
for k1, v1 in pairs(iface_list) do
|
||||
o:value(v1.id, v1.remark)
|
||||
end
|
||||
@@ -214,7 +227,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||
o:value("", translate("Close"))
|
||||
o:value("main", translate("Preproxy Node"))
|
||||
for k1, v1 in pairs(normal_list) do
|
||||
if v1.protocol ~= "_balancing" then
|
||||
if v1.protocol ~= "_balancing" and v1.protocol ~= "_urltest" then
|
||||
o:depends({ [vid .. "-default_node"] = v1.id, [vid .. "-preproxy_enabled"] = "1" })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -96,6 +96,8 @@ o.cfgvalue = function(t, n)
|
||||
local protocol = m:get(n, "protocol")
|
||||
if protocol == "_balancing" then
|
||||
protocol = translate("Balancing")
|
||||
elseif protocol == "_urltest" then
|
||||
protocol = "URLTest"
|
||||
elseif protocol == "_shunt" then
|
||||
protocol = translate("Shunt")
|
||||
elseif protocol == "vmess" then
|
||||
|
||||
@@ -56,6 +56,7 @@ end
|
||||
if singbox_tags:find("with_quic") then
|
||||
o:value("hysteria2", "Hysteria2")
|
||||
end
|
||||
o:value("_urltest", translate("URLTest"))
|
||||
o:value("_shunt", translate("Shunt"))
|
||||
o:value("_iface", translate("Custom Interface"))
|
||||
|
||||
@@ -65,6 +66,7 @@ o:depends({ [_n("protocol")] = "_iface" })
|
||||
|
||||
local nodes_table = {}
|
||||
local iface_table = {}
|
||||
local urltest_table = {}
|
||||
for k, e in ipairs(api.get_valid_nodes()) do
|
||||
if e.node_type == "normal" then
|
||||
nodes_table[#nodes_table + 1] = {
|
||||
@@ -79,6 +81,12 @@ for k, e in ipairs(api.get_valid_nodes()) do
|
||||
remark = e["remark"]
|
||||
}
|
||||
end
|
||||
if e.protocol == "_urltest" then
|
||||
urltest_table[#urltest_table + 1] = {
|
||||
id = e[".name"],
|
||||
remark = e["remark"]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local socks_list = {}
|
||||
@@ -91,6 +99,44 @@ m.uci:foreach(appname, "socks", function(s)
|
||||
end
|
||||
end)
|
||||
|
||||
--[[ URLTest ]]
|
||||
o = s:option(DynamicList, _n("urltest_node"), translate("URLTest node list"), translate("List of nodes to test, <a target='_blank' href='https://sing-box.sagernet.org/configuration/outbound/urltest'>document</a>"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remark) end
|
||||
|
||||
o = s:option(Value, _n("urltest_url"), translate("Probe URL"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o:value("https://cp.cloudflare.com/", "Cloudflare")
|
||||
o:value("https://www.gstatic.com/generate_204", "Gstatic")
|
||||
o:value("https://www.google.com/generate_204", "Google")
|
||||
o:value("https://www.youtube.com/generate_204", "YouTube")
|
||||
o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)")
|
||||
o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)")
|
||||
o.default = "https://www.gstatic.com/generate_204"
|
||||
o.description = translate("The URL used to detect the connection status.")
|
||||
|
||||
o = s:option(Value, _n("urltest_interval"), translate("Test interval"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o.datatype = "uinteger"
|
||||
o.default = "180"
|
||||
o.description = translate("The test interval in seconds.") .. "<br />" ..
|
||||
translate("Test interval must be less or equal than idle timeout.")
|
||||
|
||||
o = s:option(Value, _n("urltest_tolerance"), translate("Test tolerance"), translate("The test tolerance in milliseconds."))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o.datatype = "uinteger"
|
||||
o.default = "50"
|
||||
|
||||
o = s:option(Value, _n("urltest_idle_timeout"), translate("Idle timeout"), translate("The idle timeout in seconds."))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o.datatype = "uinteger"
|
||||
o.default = "1800"
|
||||
|
||||
o = s:option(Flag, _n("urltest_interrupt_exist_connections"), translate("Interrupt existing connections"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
o.default = "0"
|
||||
o.description = translate("Interrupt existing connections when the selected outbound has changed.")
|
||||
|
||||
-- [[ 分流模块 ]]
|
||||
if #nodes_table > 0 then
|
||||
o = s:option(Flag, _n("preproxy_enabled"), translate("Preproxy"))
|
||||
@@ -101,6 +147,9 @@ if #nodes_table > 0 then
|
||||
for k, v in pairs(socks_list) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(urltest_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(iface_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
@@ -124,6 +173,9 @@ m.uci:foreach(appname, "shunt_rules", function(e)
|
||||
for k, v in pairs(socks_list) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(urltest_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(iface_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
@@ -155,6 +207,9 @@ if #nodes_table > 0 then
|
||||
for k, v in pairs(socks_list) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(urltest_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
for k, v in pairs(iface_table) do
|
||||
o:value(v.id, v.remark)
|
||||
end
|
||||
|
||||
@@ -314,7 +314,7 @@ function strToTable(str)
|
||||
end
|
||||
|
||||
function is_normal_node(e)
|
||||
if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then
|
||||
if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
@@ -444,7 +444,7 @@ function get_valid_nodes()
|
||||
uci:foreach(appname, "nodes", function(e)
|
||||
e.id = e[".name"]
|
||||
if e.type and e.remarks then
|
||||
if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then
|
||||
if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then
|
||||
local type = e.type
|
||||
if type == "sing-box" then type = "Sing-Box" end
|
||||
e["remark"] = "%s:[%s] " % {type .. " " .. i18n.translatef(e.protocol), e.remarks}
|
||||
@@ -494,7 +494,7 @@ end
|
||||
function get_node_remarks(n)
|
||||
local remarks = ""
|
||||
if n then
|
||||
if n.protocol and (n.protocol == "_balancing" or n.protocol == "_shunt" or n.protocol == "_iface") then
|
||||
if n.protocol and (n.protocol == "_balancing" or n.protocol == "_shunt" or n.protocol == "_iface" or n.protocol == "_urltest") then
|
||||
remarks = "%s:[%s] " % {n.type .. " " .. i18n.translatef(n.protocol), n.remarks}
|
||||
else
|
||||
local type2 = n.type
|
||||
@@ -1114,7 +1114,7 @@ end
|
||||
function get_version()
|
||||
local version = sys.exec("opkg list-installed luci-app-passwall2 2>/dev/null | awk '{print $3}'")
|
||||
if not version or #version == 0 then
|
||||
version = sys.exec("apk info -L luci-app-passwall2 2>/dev/null | awk 'NR == 1 {print $1}' | cut -d'-' -f4-")
|
||||
version = sys.exec("apk list luci-app-passwall2 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-")
|
||||
end
|
||||
return version or ""
|
||||
end
|
||||
|
||||
@@ -892,6 +892,54 @@ function gen_config(var)
|
||||
node.port = server_port
|
||||
end
|
||||
|
||||
local function gen_urltest(_node)
|
||||
local urltest_id = _node[".name"]
|
||||
local urltest_tag = "urltest-" .. urltest_id
|
||||
-- existing urltest
|
||||
for _, v in ipairs(outbounds) do
|
||||
if v.tag == urltest_tag then
|
||||
return urltest_tag
|
||||
end
|
||||
end
|
||||
-- new urltest
|
||||
local ut_nodes = _node.urltest_node
|
||||
local valid_nodes = {}
|
||||
for i = 1, #ut_nodes do
|
||||
local ut_node_id = ut_nodes[i]
|
||||
local ut_node_tag = "ut-" .. ut_node_id
|
||||
local is_new_ut_node = true
|
||||
for _, outbound in ipairs(outbounds) do
|
||||
if string.sub(outbound.tag, 1, #ut_node_tag) == ut_node_tag then
|
||||
is_new_ut_node = false
|
||||
valid_nodes[#valid_nodes + 1] = outbound.tag
|
||||
break
|
||||
end
|
||||
end
|
||||
if is_new_ut_node then
|
||||
local ut_node = uci:get_all(appname, ut_node_id)
|
||||
local outbound = gen_outbound(flag, ut_node, ut_node_tag)
|
||||
if outbound then
|
||||
outbound.tag = outbound.tag .. ":" .. ut_node.remarks
|
||||
table.insert(outbounds, outbound)
|
||||
valid_nodes[#valid_nodes + 1] = outbound.tag
|
||||
end
|
||||
end
|
||||
end
|
||||
if #valid_nodes == 0 then return nil end
|
||||
local outbound = {
|
||||
type = "urltest",
|
||||
tag = urltest_tag,
|
||||
outbounds = valid_nodes,
|
||||
url = _node.urltest_url or "https://www.gstatic.com/generate_204",
|
||||
interval = _node.urltest_interval and tonumber(_node.urltest_interval) and string.format("%dm", tonumber(_node.urltest_interval) / 60) or "3m",
|
||||
tolerance = _node.urltest_tolerance and tonumber(_node.urltest_tolerance) and tonumber(_node.urltest_tolerance) or 50,
|
||||
idle_timeout = _node.urltest_idle_timeout and tonumber(_node.urltest_idle_timeout) and string.format("%dm", tonumber(_node.urltest_idle_timeout) / 60) or "30m",
|
||||
interrupt_exist_connections = (_node.urltest_interrupt_exist_connections == "true" or _node.urltest_interrupt_exist_connections == "1") and true or false
|
||||
}
|
||||
table.insert(outbounds, outbound)
|
||||
return urltest_tag
|
||||
end
|
||||
|
||||
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
|
||||
if not node or not outbound or not outbounds_table then return nil end
|
||||
local default_outTag = outbound.tag
|
||||
@@ -1046,6 +1094,8 @@ function gen_config(var)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif _node.protocol == "_urltest" then
|
||||
rule_outboundTag = gen_urltest(_node)
|
||||
elseif _node.protocol == "_iface" then
|
||||
if _node.iface then
|
||||
local _outbound = {
|
||||
@@ -1220,6 +1270,10 @@ function gen_config(var)
|
||||
for index, value in ipairs(rules) do
|
||||
table.insert(route.rules, rules[index])
|
||||
end
|
||||
elseif node.protocol == "_urltest" then
|
||||
if node.urltest_node then
|
||||
COMMON.default_outbound_tag = gen_urltest(node)
|
||||
end
|
||||
elseif node.protocol == "_iface" then
|
||||
if node.iface then
|
||||
local outbound = {
|
||||
|
||||
@@ -1423,9 +1423,6 @@ msgstr "最大并发连接数"
|
||||
msgid "XUDP Mux concurrency"
|
||||
msgstr "XUDP 最大并发连接数"
|
||||
|
||||
msgid "Mux idle timeout"
|
||||
msgstr "最大闲置时间"
|
||||
|
||||
msgid "Padding"
|
||||
msgstr "填充"
|
||||
|
||||
@@ -1444,9 +1441,6 @@ msgstr "推荐值:Sec-WebSocket-Protocol"
|
||||
msgid "Health check"
|
||||
msgstr "健康检查"
|
||||
|
||||
msgid "Idle timeout"
|
||||
msgstr "闲置时间"
|
||||
|
||||
msgid "Health check timeout"
|
||||
msgstr "检查超时时间"
|
||||
|
||||
@@ -1647,3 +1641,39 @@ msgstr "是否要恢复客户端默认配置?"
|
||||
|
||||
msgid "Are you sure you want to restore the client to default settings?"
|
||||
msgstr "是否真的要恢复客户端默认配置?"
|
||||
|
||||
msgid "_urltest"
|
||||
msgstr "URLTest"
|
||||
|
||||
msgid "URLTest node list"
|
||||
msgstr "URLTest 节点列表"
|
||||
|
||||
msgid "List of nodes to test, <a target='_blank' href='https://sing-box.sagernet.org/configuration/outbound/urltest'>document</a>"
|
||||
msgstr "要测试的节点列表,<a target='_blank' href='https://sing-box.sagernet.org/zh/configuration/outbound/urltest'>文档原理</a>"
|
||||
|
||||
msgid "Test interval"
|
||||
msgstr "测试间隔"
|
||||
|
||||
msgid "The test interval in seconds."
|
||||
msgstr "测试间隔时间(单位:秒)。"
|
||||
|
||||
msgid "Test interval must be less or equal than idle timeout."
|
||||
msgstr "测试间隔时间必须小于或等于空闲超时时间。"
|
||||
|
||||
msgid "Test tolerance"
|
||||
msgstr "测试容差"
|
||||
|
||||
msgid "The test tolerance in milliseconds."
|
||||
msgstr "测试容差时间(单位:毫秒)。"
|
||||
|
||||
msgid "Idle timeout"
|
||||
msgstr "空闲超时"
|
||||
|
||||
msgid "The idle timeout in seconds."
|
||||
msgstr "空闲超时时间(单位:秒)。"
|
||||
|
||||
msgid "Interrupt existing connections"
|
||||
msgstr "中断现有连接"
|
||||
|
||||
msgid "Interrupt existing connections when the selected outbound has changed."
|
||||
msgstr "当选择的出站发生变化时中断现有连接。"
|
||||
|
||||
@@ -589,7 +589,7 @@ run_socks() {
|
||||
|
||||
if [ "$type" == "sing-box" ] || [ "$type" == "xray" ]; then
|
||||
local protocol=$(config_n_get $node protocol)
|
||||
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ]; then
|
||||
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ] || [ "$protocol" == "_urltest" ]; then
|
||||
unset error_msg
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -303,6 +303,36 @@ do
|
||||
end
|
||||
}
|
||||
end
|
||||
elseif node.protocol and node.protocol == '_urltest' then
|
||||
local flag = "Sing-Box URLTest节点[" .. node_id .. "]列表"
|
||||
local currentNodes = {}
|
||||
local newNodes = {}
|
||||
if node.urltest_node then
|
||||
for k, node in pairs(node.urltest_node) do
|
||||
currentNodes[#currentNodes + 1] = {
|
||||
log = false,
|
||||
node = node,
|
||||
currentNode = node and uci:get_all(appname, node) or nil,
|
||||
remarks = node,
|
||||
set = function(o, server)
|
||||
if o and server and server ~= "nil" then
|
||||
table.insert(o.newNodes, server)
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
CONFIG[#CONFIG + 1] = {
|
||||
remarks = flag,
|
||||
currentNodes = currentNodes,
|
||||
newNodes = newNodes,
|
||||
set = function(o, newNodes)
|
||||
if o then
|
||||
if not newNodes then newNodes = o.newNodes end
|
||||
uci:set_list(appname, node_id, "urltest_node", newNodes or {})
|
||||
end
|
||||
end
|
||||
}
|
||||
else
|
||||
--前置代理节点
|
||||
local currentNode = uci:get_all(appname, node_id) or nil
|
||||
@@ -1682,7 +1712,7 @@ local execute = function()
|
||||
f:close()
|
||||
raw = trim(stdout)
|
||||
local old_md5 = value.md5 or ""
|
||||
local new_md5 = luci.sys.exec("[ -f " .. tmp_file .. " ] && md5sum " .. tmp_file .. " | awk '{print $1}' || echo 0")
|
||||
local new_md5 = luci.sys.exec("[ -f " .. tmp_file .. " ] && md5sum " .. tmp_file .. " | awk '{print $1}' || echo 0"):gsub("\n", "")
|
||||
os.remove(tmp_file)
|
||||
if old_md5 == new_md5 then
|
||||
log('订阅:【' .. remark .. '】没有变化,无需更新。')
|
||||
|
||||
@@ -71,7 +71,7 @@ url_test_node() {
|
||||
sleep 1s
|
||||
result=$(curl --connect-timeout 3 -o /dev/null -I -skL -w "%{http_code}:%{time_starttransfer}" -x $curlx "https://www.google.com/generate_204")
|
||||
pgrep -af "url_test_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||
rm -rf "/tmp/etc/${CONFIG}/url_test_${node_id}.json"
|
||||
rm -rf "/tmp/etc/${CONFIG}/url_test_${node_id}"*.json
|
||||
}
|
||||
echo $result
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ define Download/geoip
|
||||
HASH:=f2f5f03da44d007fa91fb6a37c077c9efae8ad0269ef0e4130cf90b0822873e3
|
||||
endef
|
||||
|
||||
GEOSITE_VER:=20250227085631
|
||||
GEOSITE_VER:=20250302153845
|
||||
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
|
||||
define Download/geosite
|
||||
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
|
||||
URL_FILE:=dlc.dat
|
||||
FILE:=$(GEOSITE_FILE)
|
||||
HASH:=463eb36a757705c7ffefe7977752d7b610e62271e8b63a1ffcf55b27d50b0f73
|
||||
HASH:=525dcdd8ac80d473ad128b568d7f3e16d0392872945a9468d18ac2afddd5b253
|
||||
endef
|
||||
|
||||
GEOSITE_IRAN_VER:=202502240036
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>7.10.0</Version>
|
||||
<Version>7.10.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -5,21 +5,21 @@
|
||||
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.2.4" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="11.2.4" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.2.4" />
|
||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.2.4" />
|
||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.2.5" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="11.2.5" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.2.5" />
|
||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.2.5" />
|
||||
<PackageVersion Include="CliWrap" Version="3.8.1" />
|
||||
<PackageVersion Include="Downloader" Version="3.3.3" />
|
||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.2.0" />
|
||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.0" />
|
||||
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" />
|
||||
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
|
||||
<PackageVersion Include="QRCoder" Version="1.6.0" />
|
||||
<PackageVersion Include="ReactiveUI" Version="20.1.63" />
|
||||
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||
<PackageVersion Include="ReactiveUI.WPF" Version="20.1.63" />
|
||||
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.4" />
|
||||
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.4" />
|
||||
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.5" />
|
||||
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.5" />
|
||||
<PackageVersion Include="Splat.NLog" Version="15.3.1" />
|
||||
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
||||
<PackageVersion Include="TaskScheduler" Version="2.12.0" />
|
||||
@@ -27,4 +27,4 @@
|
||||
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
||||
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -711,6 +711,7 @@ type SocketConfig struct {
|
||||
Interface string `json:"interface"`
|
||||
TcpMptcp bool `json:"tcpMptcp"`
|
||||
CustomSockopt []*CustomSockoptConfig `json:"customSockopt"`
|
||||
AddressPortStrategy string `json:"addressPortStrategy"`
|
||||
}
|
||||
|
||||
// Build implements Buildable.
|
||||
@@ -780,6 +781,26 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
|
||||
customSockopts = append(customSockopts, customSockopt)
|
||||
}
|
||||
|
||||
addressPortStrategy := internet.AddressPortStrategy_None
|
||||
switch strings.ToLower(c.AddressPortStrategy) {
|
||||
case "none", "":
|
||||
addressPortStrategy = internet.AddressPortStrategy_None
|
||||
case "srvportonly":
|
||||
addressPortStrategy = internet.AddressPortStrategy_SrvPortOnly
|
||||
case "srvaddressonly":
|
||||
addressPortStrategy = internet.AddressPortStrategy_SrvAddressOnly
|
||||
case "srvportandaddress":
|
||||
addressPortStrategy = internet.AddressPortStrategy_SrvPortAndAddress
|
||||
case "txtportonly":
|
||||
addressPortStrategy = internet.AddressPortStrategy_TxtPortOnly
|
||||
case "txtaddressonly":
|
||||
addressPortStrategy = internet.AddressPortStrategy_TxtAddressOnly
|
||||
case "txtportandaddress":
|
||||
addressPortStrategy = internet.AddressPortStrategy_TxtPortAndAddress
|
||||
default:
|
||||
return nil, errors.New("unsupported address and port strategy: ", c.AddressPortStrategy)
|
||||
}
|
||||
|
||||
return &internet.SocketConfig{
|
||||
Mark: c.Mark,
|
||||
Tfo: tfo,
|
||||
@@ -798,6 +819,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) {
|
||||
Interface: c.Interface,
|
||||
TcpMptcp: c.TcpMptcp,
|
||||
CustomSockopt: customSockopts,
|
||||
AddressPortStrategy: addressPortStrategy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,67 @@ func (DomainStrategy) EnumDescriptor() ([]byte, []int) {
|
||||
return file_transport_internet_config_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type AddressPortStrategy int32
|
||||
|
||||
const (
|
||||
AddressPortStrategy_None AddressPortStrategy = 0
|
||||
AddressPortStrategy_SrvPortOnly AddressPortStrategy = 1
|
||||
AddressPortStrategy_SrvAddressOnly AddressPortStrategy = 2
|
||||
AddressPortStrategy_SrvPortAndAddress AddressPortStrategy = 3
|
||||
AddressPortStrategy_TxtPortOnly AddressPortStrategy = 4
|
||||
AddressPortStrategy_TxtAddressOnly AddressPortStrategy = 5
|
||||
AddressPortStrategy_TxtPortAndAddress AddressPortStrategy = 6
|
||||
)
|
||||
|
||||
// Enum value maps for AddressPortStrategy.
|
||||
var (
|
||||
AddressPortStrategy_name = map[int32]string{
|
||||
0: "None",
|
||||
1: "SrvPortOnly",
|
||||
2: "SrvAddressOnly",
|
||||
3: "SrvPortAndAddress",
|
||||
4: "TxtPortOnly",
|
||||
5: "TxtAddressOnly",
|
||||
6: "TxtPortAndAddress",
|
||||
}
|
||||
AddressPortStrategy_value = map[string]int32{
|
||||
"None": 0,
|
||||
"SrvPortOnly": 1,
|
||||
"SrvAddressOnly": 2,
|
||||
"SrvPortAndAddress": 3,
|
||||
"TxtPortOnly": 4,
|
||||
"TxtAddressOnly": 5,
|
||||
"TxtPortAndAddress": 6,
|
||||
}
|
||||
)
|
||||
|
||||
func (x AddressPortStrategy) Enum() *AddressPortStrategy {
|
||||
p := new(AddressPortStrategy)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x AddressPortStrategy) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (AddressPortStrategy) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_transport_internet_config_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (AddressPortStrategy) Type() protoreflect.EnumType {
|
||||
return &file_transport_internet_config_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x AddressPortStrategy) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AddressPortStrategy.Descriptor instead.
|
||||
func (AddressPortStrategy) EnumDescriptor() ([]byte, []int) {
|
||||
return file_transport_internet_config_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type SocketConfig_TProxyMode int32
|
||||
|
||||
const (
|
||||
@@ -131,11 +192,11 @@ func (x SocketConfig_TProxyMode) String() string {
|
||||
}
|
||||
|
||||
func (SocketConfig_TProxyMode) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_transport_internet_config_proto_enumTypes[1].Descriptor()
|
||||
return file_transport_internet_config_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (SocketConfig_TProxyMode) Type() protoreflect.EnumType {
|
||||
return &file_transport_internet_config_proto_enumTypes[1]
|
||||
return &file_transport_internet_config_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x SocketConfig_TProxyMode) Number() protoreflect.EnumNumber {
|
||||
@@ -434,23 +495,24 @@ type SocketConfig struct {
|
||||
Tproxy SocketConfig_TProxyMode `protobuf:"varint,3,opt,name=tproxy,proto3,enum=xray.transport.internet.SocketConfig_TProxyMode" json:"tproxy,omitempty"`
|
||||
// ReceiveOriginalDestAddress is for enabling IP_RECVORIGDSTADDR socket
|
||||
// option. This option is for UDP only.
|
||||
ReceiveOriginalDestAddress bool `protobuf:"varint,4,opt,name=receive_original_dest_address,json=receiveOriginalDestAddress,proto3" json:"receive_original_dest_address,omitempty"`
|
||||
BindAddress []byte `protobuf:"bytes,5,opt,name=bind_address,json=bindAddress,proto3" json:"bind_address,omitempty"`
|
||||
BindPort uint32 `protobuf:"varint,6,opt,name=bind_port,json=bindPort,proto3" json:"bind_port,omitempty"`
|
||||
AcceptProxyProtocol bool `protobuf:"varint,7,opt,name=accept_proxy_protocol,json=acceptProxyProtocol,proto3" json:"accept_proxy_protocol,omitempty"`
|
||||
DomainStrategy DomainStrategy `protobuf:"varint,8,opt,name=domain_strategy,json=domainStrategy,proto3,enum=xray.transport.internet.DomainStrategy" json:"domain_strategy,omitempty"`
|
||||
DialerProxy string `protobuf:"bytes,9,opt,name=dialer_proxy,json=dialerProxy,proto3" json:"dialer_proxy,omitempty"`
|
||||
TcpKeepAliveInterval int32 `protobuf:"varint,10,opt,name=tcp_keep_alive_interval,json=tcpKeepAliveInterval,proto3" json:"tcp_keep_alive_interval,omitempty"`
|
||||
TcpKeepAliveIdle int32 `protobuf:"varint,11,opt,name=tcp_keep_alive_idle,json=tcpKeepAliveIdle,proto3" json:"tcp_keep_alive_idle,omitempty"`
|
||||
TcpCongestion string `protobuf:"bytes,12,opt,name=tcp_congestion,json=tcpCongestion,proto3" json:"tcp_congestion,omitempty"`
|
||||
Interface string `protobuf:"bytes,13,opt,name=interface,proto3" json:"interface,omitempty"`
|
||||
V6Only bool `protobuf:"varint,14,opt,name=v6only,proto3" json:"v6only,omitempty"`
|
||||
TcpWindowClamp int32 `protobuf:"varint,15,opt,name=tcp_window_clamp,json=tcpWindowClamp,proto3" json:"tcp_window_clamp,omitempty"`
|
||||
TcpUserTimeout int32 `protobuf:"varint,16,opt,name=tcp_user_timeout,json=tcpUserTimeout,proto3" json:"tcp_user_timeout,omitempty"`
|
||||
TcpMaxSeg int32 `protobuf:"varint,17,opt,name=tcp_max_seg,json=tcpMaxSeg,proto3" json:"tcp_max_seg,omitempty"`
|
||||
Penetrate bool `protobuf:"varint,18,opt,name=penetrate,proto3" json:"penetrate,omitempty"`
|
||||
TcpMptcp bool `protobuf:"varint,19,opt,name=tcp_mptcp,json=tcpMptcp,proto3" json:"tcp_mptcp,omitempty"`
|
||||
CustomSockopt []*CustomSockopt `protobuf:"bytes,20,rep,name=customSockopt,proto3" json:"customSockopt,omitempty"`
|
||||
ReceiveOriginalDestAddress bool `protobuf:"varint,4,opt,name=receive_original_dest_address,json=receiveOriginalDestAddress,proto3" json:"receive_original_dest_address,omitempty"`
|
||||
BindAddress []byte `protobuf:"bytes,5,opt,name=bind_address,json=bindAddress,proto3" json:"bind_address,omitempty"`
|
||||
BindPort uint32 `protobuf:"varint,6,opt,name=bind_port,json=bindPort,proto3" json:"bind_port,omitempty"`
|
||||
AcceptProxyProtocol bool `protobuf:"varint,7,opt,name=accept_proxy_protocol,json=acceptProxyProtocol,proto3" json:"accept_proxy_protocol,omitempty"`
|
||||
DomainStrategy DomainStrategy `protobuf:"varint,8,opt,name=domain_strategy,json=domainStrategy,proto3,enum=xray.transport.internet.DomainStrategy" json:"domain_strategy,omitempty"`
|
||||
DialerProxy string `protobuf:"bytes,9,opt,name=dialer_proxy,json=dialerProxy,proto3" json:"dialer_proxy,omitempty"`
|
||||
TcpKeepAliveInterval int32 `protobuf:"varint,10,opt,name=tcp_keep_alive_interval,json=tcpKeepAliveInterval,proto3" json:"tcp_keep_alive_interval,omitempty"`
|
||||
TcpKeepAliveIdle int32 `protobuf:"varint,11,opt,name=tcp_keep_alive_idle,json=tcpKeepAliveIdle,proto3" json:"tcp_keep_alive_idle,omitempty"`
|
||||
TcpCongestion string `protobuf:"bytes,12,opt,name=tcp_congestion,json=tcpCongestion,proto3" json:"tcp_congestion,omitempty"`
|
||||
Interface string `protobuf:"bytes,13,opt,name=interface,proto3" json:"interface,omitempty"`
|
||||
V6Only bool `protobuf:"varint,14,opt,name=v6only,proto3" json:"v6only,omitempty"`
|
||||
TcpWindowClamp int32 `protobuf:"varint,15,opt,name=tcp_window_clamp,json=tcpWindowClamp,proto3" json:"tcp_window_clamp,omitempty"`
|
||||
TcpUserTimeout int32 `protobuf:"varint,16,opt,name=tcp_user_timeout,json=tcpUserTimeout,proto3" json:"tcp_user_timeout,omitempty"`
|
||||
TcpMaxSeg int32 `protobuf:"varint,17,opt,name=tcp_max_seg,json=tcpMaxSeg,proto3" json:"tcp_max_seg,omitempty"`
|
||||
Penetrate bool `protobuf:"varint,18,opt,name=penetrate,proto3" json:"penetrate,omitempty"`
|
||||
TcpMptcp bool `protobuf:"varint,19,opt,name=tcp_mptcp,json=tcpMptcp,proto3" json:"tcp_mptcp,omitempty"`
|
||||
CustomSockopt []*CustomSockopt `protobuf:"bytes,20,rep,name=customSockopt,proto3" json:"customSockopt,omitempty"`
|
||||
AddressPortStrategy AddressPortStrategy `protobuf:"varint,21,opt,name=address_port_strategy,json=addressPortStrategy,proto3,enum=xray.transport.internet.AddressPortStrategy" json:"address_port_strategy,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SocketConfig) Reset() {
|
||||
@@ -623,6 +685,13 @@ func (x *SocketConfig) GetCustomSockopt() []*CustomSockopt {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SocketConfig) GetAddressPortStrategy() AddressPortStrategy {
|
||||
if x != nil {
|
||||
return x.AddressPortStrategy
|
||||
}
|
||||
return AddressPortStrategy_None
|
||||
}
|
||||
|
||||
var File_transport_internet_config_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_transport_internet_config_proto_rawDesc = []byte{
|
||||
@@ -678,7 +747,7 @@ var file_transport_internet_config_proto_rawDesc = []byte{
|
||||
0x28, 0x09, 0x52, 0x03, 0x6f, 0x70, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,
|
||||
0x65, 0x22, 0x9b, 0x07, 0x0a, 0x0c, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x65, 0x22, 0xfd, 0x07, 0x0a, 0x0c, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x66, 0x6f, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x03, 0x74, 0x66, 0x6f, 0x12, 0x48, 0x0a, 0x06, 0x74, 0x70, 0x72, 0x6f,
|
||||
@@ -732,28 +801,44 @@ var file_transport_internet_config_proto_rawDesc = []byte{
|
||||
0x74, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74,
|
||||
0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
|
||||
0x74, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x6f, 0x63, 0x6b, 0x6f, 0x70, 0x74, 0x52,
|
||||
0x0d, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x6f, 0x63, 0x6b, 0x6f, 0x70, 0x74, 0x22, 0x2f,
|
||||
0x0a, 0x0a, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x07, 0x0a, 0x03,
|
||||
0x4f, 0x66, 0x66, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x10,
|
||||
0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, 0x2a,
|
||||
0xa9, 0x01, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
|
||||
0x67, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x5f, 0x49, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a,
|
||||
0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45,
|
||||
0x5f, 0x49, 0x50, 0x34, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50,
|
||||
0x36, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x36, 0x10,
|
||||
0x04, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x34, 0x10, 0x05, 0x12,
|
||||
0x0c, 0x0a, 0x08, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x06, 0x12, 0x0d, 0x0a,
|
||||
0x09, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09,
|
||||
0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x08, 0x12, 0x0e, 0x0a, 0x0a, 0x46,
|
||||
0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x36, 0x10, 0x09, 0x12, 0x0e, 0x0a, 0x0a, 0x46,
|
||||
0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x34, 0x10, 0x0a, 0x42, 0x67, 0x0a, 0x1b, 0x63,
|
||||
0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72,
|
||||
0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, 0x17, 0x58, 0x72, 0x61,
|
||||
0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x0d, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x6f, 0x63, 0x6b, 0x6f, 0x70, 0x74, 0x12, 0x60,
|
||||
0x0a, 0x15, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73,
|
||||
0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e,
|
||||
0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50,
|
||||
0x6f, 0x72, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x13, 0x61, 0x64, 0x64,
|
||||
0x72, 0x65, 0x73, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
|
||||
0x22, 0x2f, 0x0a, 0x0a, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x07,
|
||||
0x0a, 0x03, 0x4f, 0x66, 0x66, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x50, 0x72, 0x6f, 0x78,
|
||||
0x79, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10,
|
||||
0x02, 0x2a, 0xa9, 0x01, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61,
|
||||
0x74, 0x65, 0x67, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x5f, 0x49, 0x53, 0x10, 0x00, 0x12,
|
||||
0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55,
|
||||
0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f,
|
||||
0x49, 0x50, 0x36, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34,
|
||||
0x36, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x34, 0x10,
|
||||
0x05, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x06, 0x12,
|
||||
0x0d, 0x0a, 0x09, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x07, 0x12, 0x0d,
|
||||
0x0a, 0x09, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x08, 0x12, 0x0e, 0x0a,
|
||||
0x0a, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x36, 0x10, 0x09, 0x12, 0x0e, 0x0a,
|
||||
0x0a, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x34, 0x10, 0x0a, 0x2a, 0x97, 0x01,
|
||||
0x0a, 0x13, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x72,
|
||||
0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12,
|
||||
0x0f, 0x0a, 0x0b, 0x53, 0x72, 0x76, 0x50, 0x6f, 0x72, 0x74, 0x4f, 0x6e, 0x6c, 0x79, 0x10, 0x01,
|
||||
0x12, 0x12, 0x0a, 0x0e, 0x53, 0x72, 0x76, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x6e,
|
||||
0x6c, 0x79, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x72, 0x76, 0x50, 0x6f, 0x72, 0x74, 0x41,
|
||||
0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x54,
|
||||
0x78, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x4f, 0x6e, 0x6c, 0x79, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e,
|
||||
0x54, 0x78, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x10, 0x05,
|
||||
0x12, 0x15, 0x0a, 0x11, 0x54, 0x78, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x6e, 0x64, 0x41, 0x64,
|
||||
0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x06, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78,
|
||||
0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, 0x17, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -768,33 +853,35 @@ func file_transport_internet_config_proto_rawDescGZIP() []byte {
|
||||
return file_transport_internet_config_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_transport_internet_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||
var file_transport_internet_config_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
|
||||
var file_transport_internet_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_transport_internet_config_proto_goTypes = []any{
|
||||
(DomainStrategy)(0), // 0: xray.transport.internet.DomainStrategy
|
||||
(SocketConfig_TProxyMode)(0), // 1: xray.transport.internet.SocketConfig.TProxyMode
|
||||
(*TransportConfig)(nil), // 2: xray.transport.internet.TransportConfig
|
||||
(*StreamConfig)(nil), // 3: xray.transport.internet.StreamConfig
|
||||
(*ProxyConfig)(nil), // 4: xray.transport.internet.ProxyConfig
|
||||
(*CustomSockopt)(nil), // 5: xray.transport.internet.CustomSockopt
|
||||
(*SocketConfig)(nil), // 6: xray.transport.internet.SocketConfig
|
||||
(*serial.TypedMessage)(nil), // 7: xray.common.serial.TypedMessage
|
||||
(*net.IPOrDomain)(nil), // 8: xray.common.net.IPOrDomain
|
||||
(AddressPortStrategy)(0), // 1: xray.transport.internet.AddressPortStrategy
|
||||
(SocketConfig_TProxyMode)(0), // 2: xray.transport.internet.SocketConfig.TProxyMode
|
||||
(*TransportConfig)(nil), // 3: xray.transport.internet.TransportConfig
|
||||
(*StreamConfig)(nil), // 4: xray.transport.internet.StreamConfig
|
||||
(*ProxyConfig)(nil), // 5: xray.transport.internet.ProxyConfig
|
||||
(*CustomSockopt)(nil), // 6: xray.transport.internet.CustomSockopt
|
||||
(*SocketConfig)(nil), // 7: xray.transport.internet.SocketConfig
|
||||
(*serial.TypedMessage)(nil), // 8: xray.common.serial.TypedMessage
|
||||
(*net.IPOrDomain)(nil), // 9: xray.common.net.IPOrDomain
|
||||
}
|
||||
var file_transport_internet_config_proto_depIdxs = []int32{
|
||||
7, // 0: xray.transport.internet.TransportConfig.settings:type_name -> xray.common.serial.TypedMessage
|
||||
8, // 1: xray.transport.internet.StreamConfig.address:type_name -> xray.common.net.IPOrDomain
|
||||
2, // 2: xray.transport.internet.StreamConfig.transport_settings:type_name -> xray.transport.internet.TransportConfig
|
||||
7, // 3: xray.transport.internet.StreamConfig.security_settings:type_name -> xray.common.serial.TypedMessage
|
||||
6, // 4: xray.transport.internet.StreamConfig.socket_settings:type_name -> xray.transport.internet.SocketConfig
|
||||
1, // 5: xray.transport.internet.SocketConfig.tproxy:type_name -> xray.transport.internet.SocketConfig.TProxyMode
|
||||
8, // 0: xray.transport.internet.TransportConfig.settings:type_name -> xray.common.serial.TypedMessage
|
||||
9, // 1: xray.transport.internet.StreamConfig.address:type_name -> xray.common.net.IPOrDomain
|
||||
3, // 2: xray.transport.internet.StreamConfig.transport_settings:type_name -> xray.transport.internet.TransportConfig
|
||||
8, // 3: xray.transport.internet.StreamConfig.security_settings:type_name -> xray.common.serial.TypedMessage
|
||||
7, // 4: xray.transport.internet.StreamConfig.socket_settings:type_name -> xray.transport.internet.SocketConfig
|
||||
2, // 5: xray.transport.internet.SocketConfig.tproxy:type_name -> xray.transport.internet.SocketConfig.TProxyMode
|
||||
0, // 6: xray.transport.internet.SocketConfig.domain_strategy:type_name -> xray.transport.internet.DomainStrategy
|
||||
5, // 7: xray.transport.internet.SocketConfig.customSockopt:type_name -> xray.transport.internet.CustomSockopt
|
||||
8, // [8:8] is the sub-list for method output_type
|
||||
8, // [8:8] is the sub-list for method input_type
|
||||
8, // [8:8] is the sub-list for extension type_name
|
||||
8, // [8:8] is the sub-list for extension extendee
|
||||
0, // [0:8] is the sub-list for field type_name
|
||||
6, // 7: xray.transport.internet.SocketConfig.customSockopt:type_name -> xray.transport.internet.CustomSockopt
|
||||
1, // 8: xray.transport.internet.SocketConfig.address_port_strategy:type_name -> xray.transport.internet.AddressPortStrategy
|
||||
9, // [9:9] is the sub-list for method output_type
|
||||
9, // [9:9] is the sub-list for method input_type
|
||||
9, // [9:9] is the sub-list for extension type_name
|
||||
9, // [9:9] is the sub-list for extension extendee
|
||||
0, // [0:9] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_transport_internet_config_proto_init() }
|
||||
@@ -807,7 +894,7 @@ func file_transport_internet_config_proto_init() {
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_transport_internet_config_proto_rawDesc,
|
||||
NumEnums: 2,
|
||||
NumEnums: 3,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user