Update On Sat Mar 29 19:34:35 CET 2025

This commit is contained in:
github-action[bot]
2025-03-29 19:34:36 +01:00
parent 14c5ce1c9c
commit f8e389e7bb
86 changed files with 2461 additions and 1335 deletions
+1
View File
@@ -956,3 +956,4 @@ Update On Tue Mar 25 19:35:52 CET 2025
Update On Wed Mar 26 19:37:44 CET 2025
Update On Thu Mar 27 19:36:04 CET 2025
Update On Fri Mar 28 19:38:10 CET 2025
Update On Sat Mar 29 19:34:26 CET 2025
+444 -431
View File
File diff suppressed because it is too large Load Diff
@@ -22,8 +22,8 @@ parking_lot = "0.12"
image = { version = "0.25", features = ["jpeg", "png"] }
humansize = "2"
# for svg currentColor replacement
resvg = "0.44" # for svg rendering
usvg = "0.44" # for svg parsing
resvg = "0.45" # for svg rendering
usvg = "0.45" # for svg parsing
csscolorparser = "0.7" # for color conversion
ipc-channel = "0.19" # for IPC between the Widget process and the GUI process
serde = { version = "1", features = ["derive"] }
+10 -9
View File
@@ -15,7 +15,7 @@ crate-type = ["staticlib", "cdylib", "rlib"]
doctest = false
[build-dependencies]
tauri-build = { version = "2.0.1", features = [] }
tauri-build = { version = "2.1", features = [] }
serde = "1"
serde_json = { version = "1.0", features = ["preserve_order"] }
chrono = "0.4"
@@ -167,11 +167,12 @@ display-info = "0.5.0" # should be removed after upgrading to tauri v2
# OXC (The Oxidation Compiler)
# We use it to parse and transpile the old script profile to esm based script profile
oxc_parser = "0.53"
oxc_allocator = "0.53"
oxc_span = "0.53"
oxc_ast = "0.53"
oxc_syntax = "0.53"
oxc_parser = "0.61"
oxc_allocator = "0.61"
oxc_span = "0.61"
oxc_ast = "0.61"
oxc_syntax = "0.61"
oxc_ast_visit = "0.61"
# Lua Integration
mlua = { version = "0.10", features = [
@@ -187,7 +188,7 @@ boa_utils = { path = "../boa_utils" } # should be removed wh
boa_engine = { workspace = true, features = ["annex-b"] }
# Tauri Dependencies
tauri = { version = "2.2", features = ["tray-icon", "image-png", "image-ico"] }
tauri = { version = "2.4", features = ["tray-icon", "image-png", "image-ico"] }
tauri-plugin-deep-link = { path = "../tauri-plugin-deep-link", version = "0.1.2" } # This should be migrated to official tauri plugin
tauri-plugin-os = "2.2"
tauri-plugin-clipboard-manager = "2.2"
@@ -236,14 +237,14 @@ nix = { version = "0.29.0", features = ["user", "fs"] }
[target.'cfg(windows)'.dependencies]
deelevate = "0.2.0"
winreg = { version = "0.55", features = ["transactions"] }
windows-registry = "0.5"
windows-registry = "0.5.1"
windows-sys = { version = "0.59", features = [
"Win32_System_LibraryLoader",
"Win32_System_SystemInformation",
"Win32_UI_WindowsAndMessaging",
"Win32_System_Shutdown",
] }
windows-core = "0.60.0"
windows-core = "0.60"
webview2-com = "0.36"
[features]
File diff suppressed because one or more lines are too long
@@ -37,7 +37,7 @@
],
"definitions": {
"Capability": {
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```",
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows' and webviews' fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```",
"type": "object",
"required": [
"identifier",
@@ -70,14 +70,14 @@
"type": "boolean"
},
"windows": {
"description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`",
"description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nIf a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [`Self::webviews`].\n\nOn multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`",
"type": "array",
"items": {
"type": "string"
}
},
"webviews": {
"description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThis is only required when using on multiwebview contexts, by default all child webviews of a window that matches [`Self::windows`] are linked.\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`",
"description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThe capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`",
"type": "array",
"items": {
"type": "string"
@@ -1977,11 +1977,26 @@
"type": "string",
"const": "core:app:allow-default-window-icon"
},
{
"description": "Enables the fetch_data_store_identifiers command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-fetch-data-store-identifiers"
},
{
"description": "Enables the identifier command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-identifier"
},
{
"description": "Enables the name command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-name"
},
{
"description": "Enables the remove_data_store command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-remove-data-store"
},
{
"description": "Enables the set_app_theme command without any pre-configured scope.",
"type": "string",
@@ -2012,11 +2027,26 @@
"type": "string",
"const": "core:app:deny-default-window-icon"
},
{
"description": "Denies the fetch_data_store_identifiers command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-fetch-data-store-identifiers"
},
{
"description": "Denies the identifier command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-identifier"
},
{
"description": "Denies the name command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-name"
},
{
"description": "Denies the remove_data_store command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-remove-data-store"
},
{
"description": "Denies the set_app_theme command without any pre-configured scope.",
"type": "string",
@@ -2812,6 +2842,11 @@
"type": "string",
"const": "core:window:allow-internal-toggle-maximize"
},
{
"description": "Enables the is_always_on_top command without any pre-configured scope.",
"type": "string",
"const": "core:window:allow-is-always-on-top"
},
{
"description": "Enables the is_closable command without any pre-configured scope.",
"type": "string",
@@ -3177,6 +3212,11 @@
"type": "string",
"const": "core:window:deny-internal-toggle-maximize"
},
{
"description": "Denies the is_always_on_top command without any pre-configured scope.",
"type": "string",
"const": "core:window:deny-is-always-on-top"
},
{
"description": "Denies the is_closable command without any pre-configured scope.",
"type": "string",
@@ -37,7 +37,7 @@
],
"definitions": {
"Capability": {
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows fine grained access to the Tauri core, application, or plugin commands. If a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```",
"description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows' and webviews' fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```",
"type": "object",
"required": [
"identifier",
@@ -70,14 +70,14 @@
"type": "boolean"
},
"windows": {
"description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`",
"description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nIf a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [`Self::webviews`].\n\nOn multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`",
"type": "array",
"items": {
"type": "string"
}
},
"webviews": {
"description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThis is only required when using on multiwebview contexts, by default all child webviews of a window that matches [`Self::windows`] are linked.\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`",
"description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThe capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`",
"type": "array",
"items": {
"type": "string"
@@ -1977,11 +1977,26 @@
"type": "string",
"const": "core:app:allow-default-window-icon"
},
{
"description": "Enables the fetch_data_store_identifiers command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-fetch-data-store-identifiers"
},
{
"description": "Enables the identifier command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-identifier"
},
{
"description": "Enables the name command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-name"
},
{
"description": "Enables the remove_data_store command without any pre-configured scope.",
"type": "string",
"const": "core:app:allow-remove-data-store"
},
{
"description": "Enables the set_app_theme command without any pre-configured scope.",
"type": "string",
@@ -2012,11 +2027,26 @@
"type": "string",
"const": "core:app:deny-default-window-icon"
},
{
"description": "Denies the fetch_data_store_identifiers command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-fetch-data-store-identifiers"
},
{
"description": "Denies the identifier command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-identifier"
},
{
"description": "Denies the name command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-name"
},
{
"description": "Denies the remove_data_store command without any pre-configured scope.",
"type": "string",
"const": "core:app:deny-remove-data-store"
},
{
"description": "Denies the set_app_theme command without any pre-configured scope.",
"type": "string",
@@ -2812,6 +2842,11 @@
"type": "string",
"const": "core:window:allow-internal-toggle-maximize"
},
{
"description": "Enables the is_always_on_top command without any pre-configured scope.",
"type": "string",
"const": "core:window:allow-is-always-on-top"
},
{
"description": "Enables the is_closable command without any pre-configured scope.",
"type": "string",
@@ -3177,6 +3212,11 @@
"type": "string",
"const": "core:window:deny-internal-toggle-maximize"
},
{
"description": "Denies the is_always_on_top command without any pre-configured scope.",
"type": "string",
"const": "core:window:deny-is-always-on-top"
},
{
"description": "Denies the is_closable command without any pre-configured scope.",
"type": "string",
@@ -281,9 +281,9 @@ impl Runner for JSRunner {
mod utils {
use oxc_allocator::Allocator;
use oxc_ast::{
use oxc_ast_visit::{
Visit,
visit::walk::{walk_function, walk_module_export_name},
walk::{walk_function, walk_module_export_name},
};
use oxc_parser::Parser;
use oxc_span::{SourceType, Span};
@@ -11,7 +11,7 @@
"build": "tsc"
},
"dependencies": {
"@tanstack/react-query": "5.69.0",
"@tanstack/react-query": "5.70.0",
"@tauri-apps/api": "2.3.0",
"ahooks": "3.8.4",
"dayjs": "1.11.13",
@@ -16,9 +16,9 @@
"@emotion/styled": "11.14.0",
"@juggle/resize-observer": "3.4.0",
"@material/material-color-utilities": "0.3.0",
"@mui/icons-material": "6.4.8",
"@mui/lab": "6.0.0-beta.31",
"@mui/material": "6.4.8",
"@mui/icons-material": "6.4.9",
"@mui/lab": "6.0.0-dev.240424162023-9968b4889d",
"@mui/material": "6.4.9",
"@nyanpasu/interface": "workspace:^",
"@nyanpasu/ui": "workspace:^",
"@tailwindcss/postcss": "4.0.15",
@@ -55,7 +55,7 @@
"@emotion/react": "11.14.0",
"@iconify/json": "2.2.321",
"@monaco-editor/react": "4.7.0",
"@tanstack/react-query": "5.69.0",
"@tanstack/react-query": "5.70.0",
"@tanstack/react-router": "1.114.29",
"@tanstack/router-devtools": "1.114.29",
"@tanstack/router-plugin": "1.114.29",
+3 -3
View File
@@ -17,9 +17,9 @@
},
"dependencies": {
"@material/material-color-utilities": "0.3.0",
"@mui/icons-material": "6.4.8",
"@mui/lab": "6.0.0-beta.31",
"@mui/material": "6.4.8",
"@mui/icons-material": "6.4.9",
"@mui/lab": "6.0.0-dev.240424162023-9968b4889d",
"@mui/material": "6.4.9",
"@radix-ui/react-portal": "1.1.4",
"@radix-ui/react-scroll-area": "1.2.3",
"@tauri-apps/api": "2.3.0",
+3 -3
View File
@@ -2,10 +2,10 @@
"manifest_version": 1,
"latest": {
"mihomo": "v1.19.3",
"mihomo_alpha": "alpha-f615346",
"mihomo_alpha": "alpha-025ff19",
"clash_rs": "v0.7.6",
"clash_premium": "2023-09-05-gdcc8d87",
"clash_rs_alpha": "0.7.6-alpha+sha.fa04093"
"clash_rs_alpha": "0.7.6-alpha+sha.5af4aa5"
},
"arch_template": {
"mihomo": {
@@ -69,5 +69,5 @@
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
}
},
"updated_at": "2025-03-27T22:20:52.189Z"
"updated_at": "2025-03-28T22:20:53.543Z"
}
+1 -1
View File
@@ -85,7 +85,7 @@
"eslint-plugin-react-compiler": "19.0.0-beta-e552027-20250112",
"eslint-plugin-react-hooks": "5.2.0",
"globals": "16.0.0",
"knip": "5.46.2",
"knip": "5.46.3",
"lint-staged": "15.5.0",
"neostandard": "0.12.1",
"npm-run-all2": "7.0.2",
+151 -70
View File
@@ -103,8 +103,8 @@ importers:
specifier: 16.0.0
version: 16.0.0
knip:
specifier: 5.46.2
version: 5.46.2(@types/node@22.13.11)(typescript@5.8.2)
specifier: 5.46.3
version: 5.46.3(@types/node@22.13.11)(typescript@5.8.2)
lint-staged:
specifier: 15.5.0
version: 15.5.0
@@ -175,8 +175,8 @@ importers:
frontend/interface:
dependencies:
'@tanstack/react-query':
specifier: 5.69.0
version: 5.69.0(react@19.0.0)
specifier: 5.70.0
version: 5.70.0(react@19.0.0)
'@tauri-apps/api':
specifier: 2.3.0
version: 2.3.0
@@ -227,14 +227,14 @@ importers:
specifier: 0.3.0
version: 0.3.0
'@mui/icons-material':
specifier: 6.4.8
version: 6.4.8(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
specifier: 6.4.9
version: 6.4.9(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/lab':
specifier: 6.0.0-beta.31
version: 6.0.0-beta.31(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
specifier: 6.0.0-dev.240424162023-9968b4889d
version: 6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material':
specifier: 6.4.8
version: 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
specifier: 6.4.9
version: 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@nyanpasu/interface':
specifier: workspace:^
version: link:../interface
@@ -279,13 +279,13 @@ importers:
version: 0.4.0
material-react-table:
specifier: 3.2.1
version: 3.2.1(2b16bb54767bc65498934150c630abc0)
version: 3.2.1(f429e377318d933f6ce47a69cfc264b6)
monaco-editor:
specifier: 0.52.2
version: 0.52.2
mui-color-input:
specifier: 5.0.1
version: 5.0.1(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
version: 5.0.1(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react:
specifier: 19.0.0
version: 19.0.0
@@ -300,7 +300,7 @@ importers:
version: 1.6.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react-hook-form-mui:
specifier: 7.5.0
version: 7.5.0(fee9744d8c06e9649bd4f90cf648ba7a)
version: 7.5.0(955f0535f6c4c5192b0e58ba5093aae5)
react-i18next:
specifier: 15.4.1
version: 15.4.1(i18next@24.2.3(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -339,8 +339,8 @@ importers:
specifier: 4.7.0
version: 4.7.0(monaco-editor@0.52.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@tanstack/react-query':
specifier: 5.69.0
version: 5.69.0(react@19.0.0)
specifier: 5.70.0
version: 5.70.0(react@19.0.0)
'@tanstack/react-router':
specifier: 1.114.29
version: 1.114.29(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -453,14 +453,14 @@ importers:
specifier: 0.3.0
version: 0.3.0
'@mui/icons-material':
specifier: 6.4.8
version: 6.4.8(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
specifier: 6.4.9
version: 6.4.9(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/lab':
specifier: 6.0.0-beta.31
version: 6.0.0-beta.31(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
specifier: 6.0.0-dev.240424162023-9968b4889d
version: 6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material':
specifier: 6.4.8
version: 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
specifier: 6.4.9
version: 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-portal':
specifier: 1.1.4
version: 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.12))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -1744,6 +1744,18 @@ packages:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
'@mui/base@5.0.0-beta.42':
resolution: {integrity: sha512-fWRiUJVCHCPF+mxd5drn08bY2qRw3jj5f1SSQdUXmaJ/yKpk23ys8MgLO2KGVTRtbks/+ctRfgffGPbXifj0Ug==}
engines: {node: '>=12.0.0'}
deprecated: This package has been replaced by @base-ui-components/react
peerDependencies:
'@types/react': ^17.0.0 || ^18.0.0
react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0
peerDependenciesMeta:
'@types/react':
optional: true
'@mui/base@5.0.0-beta.70':
resolution: {integrity: sha512-Tb/BIhJzb0pa5zv/wu7OdokY9ZKEDqcu1BDFnohyvGCoHuSXbEr90rPq1qeNW3XvTBIbNWHEF7gqge+xpUo6tQ==}
engines: {node: '>=14.0.0'}
@@ -1756,48 +1768,45 @@ packages:
'@types/react':
optional: true
'@mui/core-downloads-tracker@6.4.8':
resolution: {integrity: sha512-vjP4+A1ybyCRhDZC7r5EPWu/gLseFZxaGyPdDl94vzVvk6Yj6gahdaqcjbhkaCrJjdZj90m3VioltWPAnWF/zw==}
'@mui/core-downloads-tracker@6.4.9':
resolution: {integrity: sha512-3UvsvOjqZJcokHKSzA1lskj2XMM/G5GBgge6ykwmAij2pGGxydGxAXirQlLaeoMwTKDS6BcrLqPZyPVwzri20A==}
'@mui/icons-material@6.4.8':
resolution: {integrity: sha512-LKGWiLWRyoOw3dWxZQ+lV//mK+4DVTTAiLd2ljmJdD6XV0rDB8JFKjRD9nyn9cJAU5XgWnii7ZR3c93ttUnMKg==}
'@mui/icons-material@6.4.9':
resolution: {integrity: sha512-a8l63VIscBteJlh31R88aVgHelCcrhl3Rk0GnN8znTsGhcam9mFeo4Xlw+gLUYQP7mxVcVt3WP9XJkwXWZflnw==}
engines: {node: '>=14.0.0'}
peerDependencies:
'@mui/material': ^6.4.8
'@mui/material': ^6.4.9
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
'@mui/lab@6.0.0-beta.31':
resolution: {integrity: sha512-iZjchha0XznSqp5fKtgsozz/zZEjJFG8s4EeBypdlZEIcHvRKx3hUKBuaFM6B/PiC2kJrNMQSi5W2Fjio5sLKQ==}
engines: {node: '>=14.0.0'}
'@mui/lab@6.0.0-dev.240424162023-9968b4889d':
resolution: {integrity: sha512-iKFAz7/EeWI4PaFsP4jK2FcYJmUYDBkn3XZwpQSAl5806yYq5J2U2mPQLuZBdhrH50gT2O98p95i3vwL4YBwAg==}
engines: {node: '>=12.0.0'}
peerDependencies:
'@emotion/react': ^11.5.0
'@emotion/styled': ^11.3.0
'@mui/material': ^6.4.8
'@mui/material-pigment-css': ^6.4.8
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
'@mui/material': ^6.0.0-dev.240424162023-9968b4889d
'@types/react': ^17.0.0 || ^18.0.0
react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0
peerDependenciesMeta:
'@emotion/react':
optional: true
'@emotion/styled':
optional: true
'@mui/material-pigment-css':
optional: true
'@types/react':
optional: true
'@mui/material@6.4.8':
resolution: {integrity: sha512-5S9UTjKZZBd9GfbcYh/nYfD9cv6OXmj5Y7NgKYfk7JcSoshp8/pW5zP4wecRiroBSZX8wcrywSgogpVNO+5W0Q==}
'@mui/material@6.4.9':
resolution: {integrity: sha512-+5dExw9xUUFujIW889gB3qrfjeNo3YjYW7aWVZ6BlBIJnKpJ0jNcYZJpBUFoXt/FUV5Wy1V+/+XzR3Is2mXX2w==}
engines: {node: '>=14.0.0'}
peerDependencies:
'@emotion/react': ^11.5.0
'@emotion/styled': ^11.3.0
'@mui/material-pigment-css': ^6.4.8
'@mui/material-pigment-css': ^6.4.9
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -1857,6 +1866,19 @@ packages:
'@emotion/styled':
optional: true
'@mui/styled-engine@6.4.9':
resolution: {integrity: sha512-qZRWO0cT407NI4ZRjZcH+1SOu8f3JzLHqdMlg52GyEufM9pkSZFnf7xjpwnlvkixcGjco6wLlMD0VB43KRcBuA==}
engines: {node: '>=14.0.0'}
peerDependencies:
'@emotion/react': ^11.4.1
'@emotion/styled': ^11.3.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/react':
optional: true
'@emotion/styled':
optional: true
'@mui/system@5.16.7':
resolution: {integrity: sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==}
engines: {node: '>=12.0.0'}
@@ -1889,6 +1911,22 @@ packages:
'@types/react':
optional: true
'@mui/system@6.4.9':
resolution: {integrity: sha512-JOj7efXGtZn+NIzX8KDyMpO1QKc0DhilPBsxvci1xAvI1e5AtAtfzrEuV5ZvN+lz2BDuzngCWlllnqQ/cg40RQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
'@emotion/react': ^11.5.0
'@emotion/styled': ^11.3.0
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
react: ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/react':
optional: true
'@emotion/styled':
optional: true
'@types/react':
optional: true
'@mui/types@7.2.24':
resolution: {integrity: sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==}
peerDependencies:
@@ -2738,11 +2776,11 @@ packages:
resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==}
engines: {node: '>=12'}
'@tanstack/query-core@5.69.0':
resolution: {integrity: sha512-Kn410jq6vs1P8Nm+ZsRj9H+U3C0kjuEkYLxbiCyn3MDEiYor1j2DGVULqAz62SLZtUZ/e9Xt6xMXiJ3NJ65WyQ==}
'@tanstack/query-core@5.70.0':
resolution: {integrity: sha512-ZkkjQAZjI6nS5OyAmaSQafQXK180Xvp0lZYk4BzrnskkTV8On3zSJUxOIXnh0h/8EgqRkCA9i879DiJovA1kGw==}
'@tanstack/react-query@5.69.0':
resolution: {integrity: sha512-Ift3IUNQqTcaFa1AiIQ7WCb/PPy8aexZdq9pZWLXhfLcLxH0+PZqJ2xFImxCpdDZrFRZhLJrh76geevS5xjRhA==}
'@tanstack/react-query@5.70.0':
resolution: {integrity: sha512-z0tx1zz2CQ6nTm+fCaOp93FqsFjNgXtOy+4mC5ifQ4B+rJiMD0AGfJrYSGh/OuefhrzTYDAbkGUAGw6JzkWy8g==}
peerDependencies:
react: ^18 || ^19
@@ -5615,8 +5653,8 @@ packages:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
knip@5.46.2:
resolution: {integrity: sha512-QGVkUVUwNv1zDOmb9ob4jraWNZu06O5xPa5cl97wzHmGGqJHkLfuvAzGTpuVxgujq+FKOXTbD8vv1TfimKTPAQ==}
knip@5.46.3:
resolution: {integrity: sha512-DpxZYvFDh0POjgnfXie39zd4SCxmw3iQTSLPgnf1Umq+k+sCHjcv553UmI3hfo39qlVIq2c8XSsjS3IeZfdAoA==}
engines: {node: '>=18.18.0'}
hasBin: true
peerDependencies:
@@ -9584,6 +9622,20 @@ snapshots:
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
'@mui/base@5.0.0-beta.42(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
'@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/types': 7.2.24(@types/react@19.0.12)
'@mui/utils': 6.4.8(@types/react@19.0.12)(react@19.0.0)
'@popperjs/core': 2.11.8
clsx: 2.1.1
prop-types: 15.8.1
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.12
'@mui/base@5.0.0-beta.70(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
@@ -9598,21 +9650,21 @@ snapshots:
optionalDependencies:
'@types/react': 19.0.12
'@mui/core-downloads-tracker@6.4.8': {}
'@mui/core-downloads-tracker@6.4.9': {}
'@mui/icons-material@6.4.8(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)':
'@mui/icons-material@6.4.9(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/material': 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material': 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.12
'@mui/lab@6.0.0-beta.31(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
'@mui/lab@6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/base': 5.0.0-beta.70(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material': 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/base': 5.0.0-beta.42(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material': 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/system': 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/types': 7.2.24(@types/react@19.0.12)
'@mui/utils': 6.4.8(@types/react@19.0.12)(react@19.0.0)
@@ -9625,11 +9677,11 @@ snapshots:
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@types/react': 19.0.12
'@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
'@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/core-downloads-tracker': 6.4.8
'@mui/system': 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/core-downloads-tracker': 6.4.9
'@mui/system': 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/types': 7.2.24(@types/react@19.0.12)
'@mui/utils': 6.4.8(@types/react@19.0.12)(react@19.0.0)
'@popperjs/core': 2.11.8
@@ -9688,6 +9740,19 @@ snapshots:
'@emotion/react': 11.14.0(@types/react@19.0.12)(react@19.0.0)
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/styled-engine@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
'@emotion/cache': 11.14.0
'@emotion/serialize': 1.3.3
'@emotion/sheet': 1.4.0
csstype: 3.1.3
prop-types: 15.8.1
react: 19.0.0
optionalDependencies:
'@emotion/react': 11.14.0(@types/react@19.0.12)(react@19.0.0)
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/system@5.16.7(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
@@ -9720,6 +9785,22 @@ snapshots:
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@types/react': 19.0.12
'@mui/system@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/private-theming': 6.4.8(@types/react@19.0.12)(react@19.0.0)
'@mui/styled-engine': 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(react@19.0.0)
'@mui/types': 7.2.24(@types/react@19.0.12)
'@mui/utils': 6.4.8(@types/react@19.0.12)(react@19.0.0)
clsx: 2.1.1
csstype: 3.1.3
prop-types: 15.8.1
react: 19.0.0
optionalDependencies:
'@emotion/react': 11.14.0(@types/react@19.0.12)(react@19.0.0)
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@types/react': 19.0.12
'@mui/types@7.2.24(@types/react@19.0.12)':
optionalDependencies:
'@types/react': 19.0.12
@@ -9748,11 +9829,11 @@ snapshots:
optionalDependencies:
'@types/react': 19.0.12
'@mui/x-date-pickers@7.9.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
'@mui/x-date-pickers@7.9.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.10
'@mui/base': 5.0.0-beta.70(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material': 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material': 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/system': 5.16.7(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/utils': 5.16.6(@types/react@19.0.12)(react@19.0.0)
'@types/react-transition-group': 4.4.12(@types/react@19.0.12)
@@ -10507,11 +10588,11 @@ snapshots:
dependencies:
remove-accents: 0.5.0
'@tanstack/query-core@5.69.0': {}
'@tanstack/query-core@5.70.0': {}
'@tanstack/react-query@5.69.0(react@19.0.0)':
'@tanstack/react-query@5.70.0(react@19.0.0)':
dependencies:
'@tanstack/query-core': 5.69.0
'@tanstack/query-core': 5.70.0
react: 19.0.0
'@tanstack/react-router-devtools@1.114.29(@tanstack/react-router@1.114.29(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.29)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)':
@@ -13771,7 +13852,7 @@ snapshots:
kind-of@6.0.3: {}
knip@5.46.2(@types/node@22.13.11)(typescript@5.8.2):
knip@5.46.3(@types/node@22.13.11)(typescript@5.8.2):
dependencies:
'@nodelib/fs.walk': 3.0.1
'@snyk/github-codeowners': 1.1.0
@@ -13999,13 +14080,13 @@ snapshots:
escape-string-regexp: 4.0.0
optional: true
material-react-table@3.2.1(2b16bb54767bc65498934150c630abc0):
material-react-table@3.2.1(f429e377318d933f6ce47a69cfc264b6):
dependencies:
'@emotion/react': 11.14.0(@types/react@19.0.12)(react@19.0.0)
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/icons-material': 6.4.8(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/material': 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/icons-material': 6.4.9(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/material': 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@tanstack/match-sorter-utils': 8.19.4
'@tanstack/react-table': 8.20.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@tanstack/react-virtual': 3.11.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -14356,12 +14437,12 @@ snapshots:
muggle-string@0.4.1: {}
mui-color-input@5.0.1(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
mui-color-input@5.0.1(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@ctrl/tinycolor': 4.1.0
'@emotion/react': 11.14.0(@types/react@19.0.12)(react@19.0.0)
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/material': 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material': 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
@@ -14929,14 +15010,14 @@ snapshots:
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
react-hook-form-mui@7.5.0(fee9744d8c06e9649bd4f90cf648ba7a):
react-hook-form-mui@7.5.0(955f0535f6c4c5192b0e58ba5093aae5):
dependencies:
'@mui/material': 6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/material': 6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
react-hook-form: 7.52.1(react@19.0.0)
optionalDependencies:
'@mui/icons-material': 6.4.8(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.8(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@mui/icons-material': 6.4.9(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(react@19.0.0)
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@mui/material@6.4.9(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react@19.0.0))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.12)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react-hook-form@7.52.1(react@19.0.0):
dependencies:
+19 -2
View File
@@ -25,7 +25,7 @@ jobs:
with:
fetch-depth: 2
- name: Check if version changed
- name: Check if version changed or src changed
id: check
run: |
# For manual workflow_dispatch, always run
@@ -50,8 +50,25 @@ jobs:
if [ "$CURRENT_VERSION" != "$PREVIOUS_VERSION" ]; then
echo "Version changed from $PREVIOUS_VERSION to $CURRENT_VERSION"
echo "should_run=true" >> $GITHUB_OUTPUT
exit 0
fi
# Check if src or src-tauri directories changed
CURRENT_SRC_HASH=$(git rev-parse HEAD:src)
PREVIOUS_SRC_HASH=$(git rev-parse HEAD~1:src 2>/dev/null || echo "")
CURRENT_TAURI_HASH=$(git rev-parse HEAD:src-tauri 2>/dev/null || echo "")
PREVIOUS_TAURI_HASH=$(git rev-parse HEAD~1:src-tauri 2>/dev/null || echo "")
echo "Current src hash: $CURRENT_SRC_HASH"
echo "Previous src hash: $PREVIOUS_SRC_HASH"
echo "Current tauri hash: $CURRENT_TAURI_HASH"
echo "Previous tauri hash: $PREVIOUS_TAURI_HASH"
if [ "$CURRENT_SRC_HASH" != "$PREVIOUS_SRC_HASH" ] || [ "$CURRENT_TAURI_HASH" != "$PREVIOUS_TAURI_HASH" ]; then
echo "Source directories changed"
echo "should_run=true" >> $GITHUB_OUTPUT
else
echo "Version unchanged: $CURRENT_VERSION"
echo "Version and source directories unchanged"
echo "should_run=false" >> $GITHUB_OUTPUT
fi
+2 -1
View File
@@ -14,8 +14,9 @@
- Linux 在系统服务模式下无法拉起 Mihomo 内核
#### 新增了:
- ClashVergeRev 从现在开始不再强依赖系统服务和管理权限
- Clash Verge Rev 从现在开始不再强依赖系统服务和管理权限
- 支持根据用户偏好选择Sidecar(用户空间)模式或安装服务
- 增加载入初始配置文件的错误提示
#### 优化了:
- 重构了后端内核管理逻辑,更轻量化和有效的管理内核,提高了性能和稳定性
+2 -2
View File
@@ -6,7 +6,7 @@ pub type CmdResult<T = ()> = Result<T, String>;
// Command modules
pub mod app;
pub mod clash;
pub mod lighteweight;
pub mod lightweight;
pub mod media_unlock_checker;
pub mod network;
pub mod profile;
@@ -23,7 +23,7 @@ pub mod webdav;
// Re-export all command functions for backwards compatibility
pub use app::*;
pub use clash::*;
pub use lighteweight::*;
pub use lightweight::*;
pub use media_unlock_checker::*;
pub use network::*;
pub use profile::*;
+2 -1
View File
@@ -85,7 +85,8 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
// 更新profiles配置
logging!(info, Type::Cmd, true, "正在更新配置草稿");
wrap_err!({ Config::profiles().draft().patch_config(profiles) })?;
let _ = Config::profiles().draft().patch_config(profiles);
// 更新配置并进行验证
match CoreManager::global().update_config().await {
Ok((true, _)) => {
@@ -1,10 +1,12 @@
use super::{prfitem::PrfItem, PrfOption};
use crate::utils::{dirs, help};
use crate::{
logging,
utils::{dirs, help, logging::Type},
};
use anyhow::{bail, Context, Result};
use serde::{Deserialize, Serialize};
use serde_yaml::Mapping;
use serde_yaml::{Mapping, Value};
use std::{fs, io::Write};
/// Define the `profiles.yaml` schema
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct IProfiles {
@@ -382,16 +384,92 @@ impl IProfiles {
pub fn current_mapping(&self) -> Result<Mapping> {
match (self.current.as_ref(), self.items.as_ref()) {
(Some(current), Some(items)) => {
logging!(
info,
Type::Config,
true,
"开始获取当前配置文件 current_uid={}",
current
);
logging!(info, Type::Core, true, "服务可用,直接使用服务模式");
if let Some(item) = items.iter().find(|e| e.uid.as_ref() == Some(current)) {
let file_path = match item.file.as_ref() {
Some(file) => dirs::app_profiles_dir()?.join(file),
None => bail!("failed to get the file field"),
Some(file) => {
let path = dirs::app_profiles_dir()?.join(file);
logging!(
info,
Type::Config,
true,
"找到配置文件路径: {}",
path.display()
);
path
}
None => {
logging!(
error,
Type::Config,
true,
"配置项缺少file字段 uid={}",
current
);
bail!("failed to get the file field");
}
};
return help::read_mapping(&file_path);
if !file_path.exists() {
logging!(
error,
Type::Config,
true,
"配置文件不存在: {}",
file_path.display()
);
}
match help::read_mapping(&file_path) {
Ok(mapping) => {
let key_count = mapping.len();
logging!(
info,
Type::Config,
true,
"成功读取配置文件, 包含{}个键值对",
key_count
);
// 打印主要的配置键
let important_keys = ["proxies", "proxy-groups", "rules"];
for key in important_keys.iter() {
if mapping.contains_key(&Value::from(*key)) {
logging!(info, Type::Config, true, "配置包含关键字段: {}", key);
} else {
logging!(warn, Type::Config, true, "配置缺少关键字段: {}", key);
}
}
return Ok(mapping);
}
Err(e) => {
logging!(error, Type::Config, true, "读取配置文件失败: {}", e);
// 将错误发送到前端显示
crate::core::handle::Handle::notice_message(
"config_validate::yaml_syntax_error",
&format!("{}", e),
);
return Err(e);
}
}
}
logging!(
error,
Type::Config,
true,
"未找到当前配置项 uid={}",
current
);
bail!("failed to find the current profile \"uid:{current}\"");
}
_ => Ok(Mapping::new()),
_ => {
logging!(warn, Type::Config, true, "没有当前配置项,返回空配置");
Ok(Mapping::new())
}
}
}
+3 -14
View File
@@ -148,6 +148,7 @@ impl CoreManager {
}
/// 验证运行时配置
pub async fn validate_config(&self) -> Result<(bool, String)> {
logging!(info, Type::Config, true, "生成临时配置文件用于验证");
let config_path = Config::generate_file(ConfigType::Check)?;
let config_path = dirs::path_to_str(&config_path)?;
self.validate_config_internal(config_path).await
@@ -377,20 +378,8 @@ impl CoreManager {
logging!(info, Type::Config, true, "开始更新配置");
// 1. 先生成新的配置内容
logging!(info, Type::Config, true, "生成新的配置内容");
Config::generate().await?;
// 2. 生成临时文件并进行验证
logging!(info, Type::Config, true, "生成临时配置文件用于验证");
let temp_config = Config::generate_file(ConfigType::Check)?;
let temp_config = dirs::path_to_str(&temp_config)?;
logging!(
info,
Type::Config,
true,
"临时配置文件路径: {}",
temp_config
);
// logging!(info, Type::Config, true, "生成新的配置内容");
// Config::generate().await?;
// 3. 验证配置
match self.validate_config().await {
@@ -13,13 +13,13 @@ use crate::{
const LIGHT_WEIGHT_TASK_UID: &str = "light_weight_task";
pub fn enable_auto_light_weight_mode() {
logging!(info, Type::Lightweight, True, "开启自动轻量模式");
logging!(info, Type::Lightweight, true, "开启自动轻量模式");
setup_window_close_listener();
setup_webview_focus_listener();
}
pub fn disable_auto_light_weight_mode() {
logging!(info, Type::Lightweight, True, "关闭自动轻量模式");
logging!(info, Type::Lightweight, true, "关闭自动轻量模式");
let _ = cancel_light_weight_timer();
cancel_window_close_listener();
}
@@ -34,7 +34,7 @@ pub fn entry_lightweight_mode() {
}
#[cfg(target_os = "macos")]
AppHandleManager::global().set_activation_policy_accessory();
logging!(info, Type::Lightweight, True, "轻量模式已开启");
logging!(info, Type::Lightweight, true, "轻量模式已开启");
}
let _ = cancel_light_weight_timer();
}
@@ -46,7 +46,7 @@ fn setup_window_close_listener() -> u32 {
logging!(
info,
Type::Lightweight,
True,
true,
"监听到关闭请求,开始轻量模式计时"
);
});
@@ -62,7 +62,7 @@ fn setup_webview_focus_listener() -> u32 {
logging!(
info,
Type::Lightweight,
True,
true,
"监听到窗口获得焦点,取消轻量模式计时"
);
});
@@ -74,7 +74,7 @@ fn setup_webview_focus_listener() -> u32 {
fn cancel_window_close_listener() {
if let Some(window) = handle::Handle::global().get_window() {
window.unlisten(setup_window_close_listener());
logging!(info, Type::Lightweight, True, "取消了窗口关闭监听");
logging!(info, Type::Lightweight, true, "取消了窗口关闭监听");
}
}
@@ -98,7 +98,7 @@ fn setup_light_weight_timer() -> Result<()> {
.set_maximum_parallel_runnable_num(1)
.set_frequency_once_by_minutes(once_by_minutes)
.spawn_async_routine(move || async move {
logging!(info, Type::Timer, True, "计时器到期,开始进入轻量模式");
logging!(info, Type::Timer, true, "计时器到期,开始进入轻量模式");
entry_lightweight_mode();
})
.context("failed to create timer task")?;
@@ -118,7 +118,7 @@ fn setup_light_weight_timer() -> Result<()> {
logging!(
info,
Type::Timer,
True,
true,
"计时器已设置,{} 分钟后将自动进入轻量模式",
once_by_minutes
);
@@ -134,7 +134,7 @@ fn cancel_light_weight_timer() -> Result<()> {
delay_timer
.remove_task(task.task_id)
.context("failed to remove timer task")?;
logging!(info, Type::Timer, True, "计时器已取消");
logging!(info, Type::Timer, true, "计时器已取消");
}
Ok(())
+1 -1
View File
@@ -24,6 +24,6 @@
package main
const (
VERSION = "2.3.9"
VERSION = "2.3.10"
USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
)
+1 -1
View File
@@ -24,6 +24,6 @@
package main
const (
VERSION = "2.3.9"
VERSION = "2.3.10"
USER_AGENT = "DNS-over-HTTPS/" + VERSION + " (+https://github.com/m13253/dns-over-https)"
)
+3 -3
View File
@@ -11,10 +11,10 @@ require (
)
require (
github.com/felixge/httpsnoop v1.0.3 // indirect
golang.org/x/mod v0.23.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/tools v0.30.0 // indirect
golang.org/x/tools v0.31.0 // indirect
)
+6 -6
View File
@@ -1,7 +1,7 @@
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
@@ -12,8 +12,8 @@ github.com/miekg/dns v1.1.64 h1:wuZgD9wwCE6XMT05UU/mlSko71eRSXEAm2EbjQXLKnQ=
github.com/miekg/dns v1.1.64/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
@@ -22,7 +22,7 @@ golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -0,0 +1,134 @@
From 2f3ce7a56c6e02bc0b258507f3a82b7511f62f9e Mon Sep 17 00:00:00 2001
From: Marek Behún <kabel@kernel.org>
Date: Tue, 21 Nov 2023 18:20:24 +0100
Subject: net: sfp: rework the RollBall PHY waiting code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RollBall SFP modules allow the access to PHY registers only after a
certain time has passed. Until then, the registers read 0xffff.
Currently we have quirks for modules where we need to wait either 25
seconds or 4 seconds, but recently I got hands on another module where
the wait is even shorter.
Instead of hardcoding different wait times, lets rework the code:
- increase the PHY retry count to 25
- when RollBall module is detected, increase the PHY retry time from
50ms to 1s
Signed-off-by: Marek Behún <kabel@kernel.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/sfp.c | 41 +++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -191,7 +191,7 @@ static const enum gpiod_flags gpio_flags
* R_PHY_RETRY is the number of attempts.
*/
#define T_PHY_RETRY msecs_to_jiffies(50)
-#define R_PHY_RETRY 12
+#define R_PHY_RETRY 25
/* SFP module presence detection is poor: the three MOD DEF signals are
* the same length on the PCB, which means it's possible for MOD DEF 0 to
@@ -273,7 +273,7 @@ struct sfp {
struct sfp_eeprom_id id;
unsigned int module_power_mW;
unsigned int module_t_start_up;
- unsigned int module_t_wait;
+ unsigned int phy_t_retry;
unsigned int rate_kbd;
unsigned int rs_threshold_kbd;
@@ -357,18 +357,22 @@ static void sfp_fixup_10gbaset_30m(struc
sfp->id.base.extended_cc = SFF8024_ECC_10GBASE_T_SR;
}
-static void sfp_fixup_rollball_proto(struct sfp *sfp, unsigned int secs)
+static void sfp_fixup_rollball(struct sfp *sfp)
{
sfp->mdio_protocol = MDIO_I2C_ROLLBALL;
- sfp->module_t_wait = msecs_to_jiffies(secs * 1000);
+
+ /* RollBall modules may disallow access to PHY registers for up to 25
+ * seconds, and the reads return 0xffff before that. Increase the time
+ * between PHY probe retries from 50ms to 1s so that we will wait for
+ * the PHY for a sufficient amount of time.
+ */
+ sfp->phy_t_retry = msecs_to_jiffies(1000);
}
static void sfp_fixup_fs_10gt(struct sfp *sfp)
{
sfp_fixup_10gbaset_30m(sfp);
-
- // These SFPs need 4 seconds before the PHY can be accessed
- sfp_fixup_rollball_proto(sfp, 4);
+ sfp_fixup_rollball(sfp);
}
static void sfp_fixup_halny_gsfp(struct sfp *sfp)
@@ -380,12 +384,6 @@ static void sfp_fixup_halny_gsfp(struct
sfp->state_hw_mask &= ~(SFP_F_TX_FAULT | SFP_F_LOS);
}
-static void sfp_fixup_rollball(struct sfp *sfp)
-{
- // Rollball SFPs need 25 seconds before the PHY can be accessed
- sfp_fixup_rollball_proto(sfp, 25);
-}
-
static void sfp_fixup_rollball_cc(struct sfp *sfp)
{
sfp_fixup_rollball(sfp);
@@ -2319,7 +2317,7 @@ static int sfp_sm_mod_probe(struct sfp *
mask |= SFP_F_RS1;
sfp->module_t_start_up = T_START_UP;
- sfp->module_t_wait = T_WAIT;
+ sfp->phy_t_retry = T_PHY_RETRY;
sfp->tx_fault_ignore = false;
@@ -2553,10 +2551,9 @@ static void sfp_sm_main(struct sfp *sfp,
/* We need to check the TX_FAULT state, which is not defined
* while TX_DISABLE is asserted. The earliest we want to do
- * anything (such as probe for a PHY) is 50ms (or more on
- * specific modules).
+ * anything (such as probe for a PHY) is 50ms.
*/
- sfp_sm_next(sfp, SFP_S_WAIT, sfp->module_t_wait);
+ sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT);
break;
case SFP_S_WAIT:
@@ -2570,8 +2567,8 @@ static void sfp_sm_main(struct sfp *sfp,
* deasserting.
*/
timeout = sfp->module_t_start_up;
- if (timeout > sfp->module_t_wait)
- timeout -= sfp->module_t_wait;
+ if (timeout > T_WAIT)
+ timeout -= T_WAIT;
else
timeout = 1;
@@ -2614,7 +2611,11 @@ static void sfp_sm_main(struct sfp *sfp,
ret = sfp_sm_probe_for_phy(sfp);
if (ret == -ENODEV) {
if (--sfp->sm_phy_retries) {
- sfp_sm_next(sfp, SFP_S_INIT_PHY, T_PHY_RETRY);
+ sfp_sm_next(sfp, SFP_S_INIT_PHY,
+ sfp->phy_t_retry);
+ dev_dbg(sfp->dev,
+ "no PHY detected, %u tries left\n",
+ sfp->sm_phy_retries);
break;
} else {
dev_info(sfp->dev, "no PHY detected\n");
@@ -0,0 +1,85 @@
From e9301af385e7864dea353f5e58cad7339dd6c718 Mon Sep 17 00:00:00 2001
From: Marek Behún <kabel@kernel.org>
Date: Tue, 19 Dec 2023 17:24:15 +0100
Subject: net: sfp: fix PHY discovery for FS SFP-10G-T module
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit 2f3ce7a56c6e ("net: sfp: rework the RollBall PHY waiting code")
changed the long wait before accessing RollBall / FS modules into
probing for PHY every 1 second, and trying 25 times.
Wei Lei reports that this does not work correctly on FS modules: when
initializing, they may report values different from 0xffff in PHY ID
registers for some MMDs, causing get_phy_c45_ids() to find some bogus
MMD.
Fix this by adding the module_t_wait member back, and setting it to 4
seconds for FS modules.
Fixes: 2f3ce7a56c6e ("net: sfp: rework the RollBall PHY waiting code")
Reported-by: Wei Lei <quic_leiwei@quicinc.com>
Signed-off-by: Marek Behún <kabel@kernel.org>
Tested-by: Lei Wei <quic_leiwei@quicinc.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/sfp.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -273,6 +273,7 @@ struct sfp {
struct sfp_eeprom_id id;
unsigned int module_power_mW;
unsigned int module_t_start_up;
+ unsigned int module_t_wait;
unsigned int phy_t_retry;
unsigned int rate_kbd;
@@ -373,6 +374,12 @@ static void sfp_fixup_fs_10gt(struct sfp
{
sfp_fixup_10gbaset_30m(sfp);
sfp_fixup_rollball(sfp);
+
+ /* The RollBall fixup is not enough for FS modules, the AQR chip inside
+ * them does not return 0xffff for PHY ID registers in all MMDs for the
+ * while initializing. They need a 4 second wait before accessing PHY.
+ */
+ sfp->module_t_wait = msecs_to_jiffies(4000);
}
static void sfp_fixup_halny_gsfp(struct sfp *sfp)
@@ -2317,6 +2324,7 @@ static int sfp_sm_mod_probe(struct sfp *
mask |= SFP_F_RS1;
sfp->module_t_start_up = T_START_UP;
+ sfp->module_t_wait = T_WAIT;
sfp->phy_t_retry = T_PHY_RETRY;
sfp->tx_fault_ignore = false;
@@ -2551,9 +2559,10 @@ static void sfp_sm_main(struct sfp *sfp,
/* We need to check the TX_FAULT state, which is not defined
* while TX_DISABLE is asserted. The earliest we want to do
- * anything (such as probe for a PHY) is 50ms.
+ * anything (such as probe for a PHY) is 50ms (or more on
+ * specific modules).
*/
- sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT);
+ sfp_sm_next(sfp, SFP_S_WAIT, sfp->module_t_wait);
break;
case SFP_S_WAIT:
@@ -2567,8 +2576,8 @@ static void sfp_sm_main(struct sfp *sfp,
* deasserting.
*/
timeout = sfp->module_t_start_up;
- if (timeout > T_WAIT)
- timeout -= T_WAIT;
+ if (timeout > sfp->module_t_wait)
+ timeout -= sfp->module_t_wait;
else
timeout = 1;
@@ -0,0 +1,36 @@
From 6999e0fc9a552ce98fcc66bee3dca7e55fba0ed3 Mon Sep 17 00:00:00 2001
From: Marek Behún <kabel@kernel.org>
Date: Tue, 23 Apr 2024 10:50:38 +0200
Subject: net: sfp: update comment for FS SFP-10G-T quirk
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Update the comment for the Fibrestore SFP-10G-T module: since commit
e9301af385e7 ("net: sfp: fix PHY discovery for FS SFP-10G-T module")
we also do a 4 second wait before probing the PHY.
Fixes: e9301af385e7 ("net: sfp: fix PHY discovery for FS SFP-10G-T module")
Signed-off-by: Marek Behún <kabel@kernel.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20240423085039.26957-1-kabel@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/sfp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -454,8 +454,9 @@ static const struct sfp_quirk sfp_quirks
SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex,
sfp_fixup_long_startup),
- // Fiberstore SFP-10G-T doesn't identify as copper, and uses the
- // Rollball protocol to talk to the PHY.
+ // Fiberstore SFP-10G-T doesn't identify as copper, uses the Rollball
+ // protocol to talk to the PHY and needs 4 sec wait before probing the
+ // PHY.
SFP_QUIRK_F("FS", "SFP-10G-T", sfp_fixup_fs_10gt),
// Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd
@@ -0,0 +1,77 @@
From cd4a32e60061789676f7f018a94fcc9ec56732a0 Mon Sep 17 00:00:00 2001
From: Marek Behún <kabel@kernel.org>
Date: Tue, 23 Apr 2024 10:50:39 +0200
Subject: net: sfp: enhance quirk for Fibrestore 2.5G copper SFP module
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Enhance the quirk for Fibrestore 2.5G copper SFP module. The original
commit e27aca3760c0 ("net: sfp: add quirk for FS's 2.5G copper SFP")
introducing the quirk says that the PHY is inaccessible, but that is
not true.
The module uses Rollball protocol to talk to the PHY, and needs a 4
second wait before probing it, same as FS 10G module.
The PHY inside the module is Realtek RTL8221B-VB-CG PHY. The realtek
driver recently gained support to set it up via clause 45 accesses.
Signed-off-by: Marek Behún <kabel@kernel.org>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20240423085039.26957-2-kabel@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/sfp.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -370,18 +370,23 @@ static void sfp_fixup_rollball(struct sf
sfp->phy_t_retry = msecs_to_jiffies(1000);
}
-static void sfp_fixup_fs_10gt(struct sfp *sfp)
+static void sfp_fixup_fs_2_5gt(struct sfp *sfp)
{
- sfp_fixup_10gbaset_30m(sfp);
sfp_fixup_rollball(sfp);
- /* The RollBall fixup is not enough for FS modules, the AQR chip inside
+ /* The RollBall fixup is not enough for FS modules, the PHY chip inside
* them does not return 0xffff for PHY ID registers in all MMDs for the
* while initializing. They need a 4 second wait before accessing PHY.
*/
sfp->module_t_wait = msecs_to_jiffies(4000);
}
+static void sfp_fixup_fs_10gt(struct sfp *sfp)
+{
+ sfp_fixup_10gbaset_30m(sfp);
+ sfp_fixup_fs_2_5gt(sfp);
+}
+
static void sfp_fixup_halny_gsfp(struct sfp *sfp)
{
/* Ignore the TX_FAULT and LOS signals on this module.
@@ -459,6 +464,10 @@ static const struct sfp_quirk sfp_quirks
// PHY.
SFP_QUIRK_F("FS", "SFP-10G-T", sfp_fixup_fs_10gt),
+ // Fiberstore SFP-2.5G-T uses Rollball protocol to talk to the PHY and
+ // needs 4 sec wait before probing the PHY.
+ SFP_QUIRK_F("FS", "SFP-2.5G-T", sfp_fixup_fs_2_5gt),
+
// Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd
// NRZ in their EEPROM
SFP_QUIRK("FS", "GPON-ONU-34-20BI", sfp_quirk_2500basex,
@@ -475,9 +484,6 @@ static const struct sfp_quirk sfp_quirks
SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
sfp_fixup_ignore_tx_fault),
- // FS 2.5G Base-T
- SFP_QUIRK_M("FS", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
-
// Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
// 2500MBd NRZ in their EEPROM
SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
@@ -0,0 +1,50 @@
From 05ec5c085eb7ae044d49e04a3cff194a0b2a3251 Mon Sep 17 00:00:00 2001
From: Martin Schiller <ms@dev.tdt.de>
Date: Thu, 27 Feb 2025 08:10:58 +0100
Subject: net: sfp: add quirk for FS SFP-10GM-T copper SFP+ module
Add quirk for a copper SFP that identifies itself as "FS" "SFP-10GM-T".
It uses RollBall protocol to talk to the PHY and needs 4 sec wait before
probing the PHY.
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
Link: https://patch.msgid.link/20250227071058.1520027-1-ms@dev.tdt.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/sfp.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -370,7 +370,7 @@ static void sfp_fixup_rollball(struct sf
sfp->phy_t_retry = msecs_to_jiffies(1000);
}
-static void sfp_fixup_fs_2_5gt(struct sfp *sfp)
+static void sfp_fixup_rollball_wait4s(struct sfp *sfp)
{
sfp_fixup_rollball(sfp);
@@ -384,7 +384,7 @@ static void sfp_fixup_fs_2_5gt(struct sf
static void sfp_fixup_fs_10gt(struct sfp *sfp)
{
sfp_fixup_10gbaset_30m(sfp);
- sfp_fixup_fs_2_5gt(sfp);
+ sfp_fixup_rollball_wait4s(sfp);
}
static void sfp_fixup_halny_gsfp(struct sfp *sfp)
@@ -464,9 +464,10 @@ static const struct sfp_quirk sfp_quirks
// PHY.
SFP_QUIRK_F("FS", "SFP-10G-T", sfp_fixup_fs_10gt),
- // Fiberstore SFP-2.5G-T uses Rollball protocol to talk to the PHY and
- // needs 4 sec wait before probing the PHY.
- SFP_QUIRK_F("FS", "SFP-2.5G-T", sfp_fixup_fs_2_5gt),
+ // Fiberstore SFP-2.5G-T and SFP-10GM-T uses Rollball protocol to talk
+ // to the PHY and needs 4 sec wait before probing the PHY.
+ SFP_QUIRK_F("FS", "SFP-2.5G-T", sfp_fixup_rollball_wait4s),
+ SFP_QUIRK_F("FS", "SFP-10GM-T", sfp_fixup_rollball_wait4s),
// Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd
// NRZ in their EEPROM
@@ -26,9 +26,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -472,6 +472,9 @@ static const struct sfp_quirk sfp_quirks
// FS 2.5G Base-T
SFP_QUIRK_M("FS", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
@@ -485,6 +485,9 @@ static const struct sfp_quirk sfp_quirks
SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
sfp_fixup_ignore_tx_fault),
+ // OEM SFP-GE-T is 1000Base-T module
+ SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
@@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
// Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
// 2500MBd NRZ in their EEPROM
SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
@@ -2590,7 +2593,8 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -2604,7 +2607,8 @@ static void sfp_sm_main(struct sfp *sfp,
* or t_start_up, so assume there is a fault.
*/
sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
@@ -46,7 +46,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
init_done:
/* Create mdiobus and start trying for PHY */
@@ -2844,10 +2848,12 @@ static void sfp_check_state(struct sfp *
@@ -2862,10 +2866,12 @@ static void sfp_check_state(struct sfp *
mutex_lock(&sfp->st_mutex);
state = sfp_get_state(sfp);
changed = state ^ sfp->state;
@@ -26,5 +26,8 @@
"outbound": "mieru-out"
}
]
},
"log": {
"level": "warn"
}
}
@@ -95,7 +95,7 @@ m.uci:foreach(appname, "socks", function(s)
end)
-- 负载均衡列表
local o = s:option(DynamicList, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
local o = s:option(DynamicList, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://xtls.github.io/config/routing.html#balancerobject'>document</a>"))
o:depends({ [_n("protocol")] = "_balancing" })
for k, v in pairs(nodes_table) do o:value(v.id, v.remark) end
@@ -104,7 +104,8 @@ o:depends({ [_n("protocol")] = "_balancing" })
o:value("random")
o:value("roundRobin")
o:value("leastPing")
o.default = "leastPing"
o:value("leastLoad")
o.default = "leastLoad"
-- Fallback Node
if api.compare_versions(xray_version, ">=", "1.8.10") then
@@ -133,6 +134,7 @@ end
-- 探测地址
local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
ucpu:depends({ [_n("balancingStrategy")] = "leastLoad" })
local pu = s:option(Value, _n("probeUrl"), translate("Probe URL"))
pu:depends({ [_n("useCustomProbeUrl")] = true })
@@ -148,8 +150,9 @@ pu.description = translate("The URL used to detect the connection status.")
-- 探测间隔
local pi = s:option(Value, _n("probeInterval"), translate("Probe Interval"))
pi:depends({ [_n("balancingStrategy")] = "leastPing" })
pi:depends({ [_n("balancingStrategy")] = "leastLoad" })
pi.default = "1m"
pi.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
pi.description = translate("The interval between initiating probes. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
if api.compare_versions(xray_version, ">=", "1.8.12") then
ucpu:depends({ [_n("protocol")] = "_balancing" })
@@ -159,6 +162,12 @@ else
pi:depends({ [_n("balancingStrategy")] = "leastPing" })
end
o = s:option(Value, _n("expected"), translate("Preferred Node Count"))
o:depends({ [_n("balancingStrategy")] = "leastLoad" })
o.datatype = "uinteger"
o.default = "2"
o.description = translate("The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them.")
-- [[ 分流模块 ]]
if #nodes_table > 0 then
@@ -581,7 +581,8 @@ function gen_config(var)
local dns = nil
local fakedns = nil
local routing = nil
local observatory = nil
local burstObservatory = nil
local strategy = nil
local inbounds = {}
local outbounds = {}
local COMMON = {}
@@ -761,19 +762,33 @@ function gen_config(var)
end
end
end
if _node.balancingStrategy == "leastLoad" then
strategy = {
type = _node.balancingStrategy,
settings = {
expected = _node.expected and tonumber(_node.expected) and tonumber(_node.expected) or 2,
maxRTT = "1s"
}
}
else
strategy = { type = _node.balancingStrategy or "random" }
end
table.insert(balancers, {
tag = balancer_tag,
selector = valid_nodes,
fallbackTag = fallback_node_tag,
strategy = { type = _node.balancingStrategy or "random" }
strategy = strategy
})
if _node.balancingStrategy == "leastPing" or fallback_node_tag then
if not observatory then
observatory = {
if _node.balancingStrategy == "leastPing" or _node.balancingStrategy == "leastLoad" or fallback_node_tag then
if not burstObservatory then
burstObservatory = {
subjectSelector = { "blc-" },
probeUrl = _node.useCustomProbeUrl and _node.probeUrl or nil,
probeInterval = _node.probeInterval or "1m",
enableConcurrency = true
pingConfig = {
destination = _node.useCustomProbeUrl and _node.probeUrl or nil,
interval = _node.probeInterval or "1m",
sampling = 3,
timeout = "5s"
}
}
end
end
@@ -1358,7 +1373,7 @@ function gen_config(var)
-- 传出连接
outbounds = outbounds,
-- 连接观测
observatory = observatory,
burstObservatory = burstObservatory,
-- 路由
routing = routing,
-- 本地策略
@@ -445,8 +445,14 @@ msgstr "用于检测连接状态的网址。"
msgid "Probe Interval"
msgstr "探测间隔"
msgid "The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively."
msgstr "发起探测的间隔。每经过这个时间,就会对一个服务器进行服务器状态检测。时间格式为数字+单位,比如<code>&quot;10s&quot;</code>, <code>&quot;2h45m&quot;</code>,支持的时间单位有 <code>ns</code><code>us</code><code>ms</code><code>s</code><code>m</code><code>h</code>,分别对应纳秒、微秒、毫秒、秒、分、时。"
msgid "The interval between initiating probes. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively."
msgstr "发起探测的间隔。时间格式为数字+单位,比如<code>&quot;10s&quot;</code>, <code>&quot;2h45m&quot;</code>,支持的时间单位有 <code>ns</code><code>us</code><code>ms</code><code>s</code><code>m</code><code>h</code>,分别对应纳秒、微秒、毫秒、秒、分、时。"
msgid "Preferred Node Count"
msgstr "优选节点数量"
msgid "The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them."
msgstr "负载均衡器选出最优节点的个数,流量将在这几个节点中随机分配。"
msgid "Shunt"
msgstr "分流"
@@ -508,8 +514,8 @@ msgstr "仅 IPv6"
msgid "Load balancing node list"
msgstr "负载均衡节点列表"
msgid "Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"
msgstr "负载均衡节点列表,<a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>文档原理</a>"
msgid "Load balancing node list, <a target='_blank' href='https://xtls.github.io/config/routing.html#balancerobject'>document</a>"
msgstr "负载均衡节点列表,<a target='_blank' href='https://xtls.github.io/config/routing.html#balancerobject'>文档原理</a>"
msgid "From Share URL"
msgstr "导入分享URL"
+2 -2
View File
@@ -2325,9 +2325,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.21.2"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2806eaa3524762875e21c3dcd057bc4b7bfa01ce4da8d46be1cd43649e1cc6b"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
dependencies = [
"critical-section",
"portable-atomic",
+1 -4
View File
@@ -27,11 +27,8 @@ func main() {
)
if flagRunNightly {
var version badversion.Version
version, err = build_shared.ReadTagVersionRev()
version, err = build_shared.ReadTagVersion()
if err == nil {
if version.PreReleaseIdentifier == "" {
version.Patch++
}
versionStr = version.String()
}
} else {
+2
View File
@@ -15,6 +15,8 @@ func TruncateDNSMessage(request *dns.Msg, response *dns.Msg, headroom int) (*buf
}
responseLen := response.Len()
if responseLen > maxLen {
copyResponse := *response
response = &copyResponse
response.Truncate(maxLen)
}
buffer := buf.NewSize(headroom*2 + 1 + responseLen)
+1 -1
View File
@@ -2,7 +2,7 @@
icon: material/alert-decagram
---
#### 1.12.0-alpha.22
#### 1.12.0-alpha.23
* Fixes and improvements
-2
View File
@@ -196,8 +196,6 @@ github.com/sagernet/sing-vmess v0.2.0 h1:pCMGUXN2k7RpikQV65/rtXtDHzb190foTfF9IGT
github.com/sagernet/sing-vmess v0.2.0/go.mod h1:jDAZ0A0St1zVRkyvhAPRySOFfhC+4SQtO5VYyeFotgA=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
github.com/sagernet/tailscale v1.80.3-mod.0.0.20250328151259-bb65814a421c h1:cMPygRHsxYLhZI9seRycLALhAlj004IUvQ7is3N30xk=
github.com/sagernet/tailscale v1.80.3-mod.0.0.20250328151259-bb65814a421c/go.mod h1:EBxXsWu4OH2ELbQLq32WoBeIubG8KgDrg4/Oaxjs6lI=
github.com/sagernet/tailscale v1.80.3-mod.2 h1:hT0CI74q727EuCcgQ+T4pvon8V0aoi4vTAxah7GsNMQ=
github.com/sagernet/tailscale v1.80.3-mod.2/go.mod h1:EBxXsWu4OH2ELbQLq32WoBeIubG8KgDrg4/Oaxjs6lI=
github.com/sagernet/utls v1.6.7 h1:Ep3+aJ8FUGGta+II2IEVNUc3EDhaRCZINWkj/LloIA8=
+51 -1
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json"
)
@@ -31,7 +32,7 @@ func (o *Options) UnmarshalJSONContext(ctx context.Context, content []byte) erro
return err
}
o.RawMessage = content
return nil
return checkOptions(o)
}
type LogOptions struct {
@@ -43,3 +44,52 @@ type LogOptions struct {
}
type StubOptions struct{}
func checkOptions(options *Options) error {
err := checkInbounds(options.Inbounds)
if err != nil {
return err
}
err = checkOutbounds(options.Outbounds, options.Endpoints)
if err != nil {
return err
}
return nil
}
func checkInbounds(inbounds []Inbound) error {
seen := make(map[string]bool)
for _, inbound := range inbounds {
if inbound.Tag == "" {
continue
}
if seen[inbound.Tag] {
return E.New("duplicate inbound tag: ", inbound.Tag)
}
seen[inbound.Tag] = true
}
return nil
}
func checkOutbounds(outbounds []Outbound, endpoints []Endpoint) error {
seen := make(map[string]bool)
for _, outbound := range outbounds {
if outbound.Tag == "" {
continue
}
if seen[outbound.Tag] {
return E.New("duplicate outbound/endpoint tag: ", outbound.Tag)
}
seen[outbound.Tag] = true
}
for _, endpoint := range endpoints {
if endpoint.Tag == "" {
continue
}
if seen[endpoint.Tag] {
return E.New("duplicate outbound/endpoint tag: ", endpoint.Tag)
}
seen[endpoint.Tag] = true
}
return nil
}
@@ -95,7 +95,7 @@ m.uci:foreach(appname, "socks", function(s)
end)
-- 负载均衡列表
local o = s:option(DynamicList, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
local o = s:option(DynamicList, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://xtls.github.io/config/routing.html#balancerobject'>document</a>"))
o:depends({ [_n("protocol")] = "_balancing" })
for k, v in pairs(nodes_table) do o:value(v.id, v.remark) end
@@ -104,7 +104,8 @@ o:depends({ [_n("protocol")] = "_balancing" })
o:value("random")
o:value("roundRobin")
o:value("leastPing")
o.default = "leastPing"
o:value("leastLoad")
o.default = "leastLoad"
-- Fallback Node
if api.compare_versions(xray_version, ">=", "1.8.10") then
@@ -133,6 +134,7 @@ end
-- 探测地址
local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
ucpu:depends({ [_n("balancingStrategy")] = "leastLoad" })
local pu = s:option(Value, _n("probeUrl"), translate("Probe URL"))
pu:depends({ [_n("useCustomProbeUrl")] = true })
@@ -148,8 +150,9 @@ pu.description = translate("The URL used to detect the connection status.")
-- 探测间隔
local pi = s:option(Value, _n("probeInterval"), translate("Probe Interval"))
pi:depends({ [_n("balancingStrategy")] = "leastPing" })
pi:depends({ [_n("balancingStrategy")] = "leastLoad" })
pi.default = "1m"
pi.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
pi.description = translate("The interval between initiating probes. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
if api.compare_versions(xray_version, ">=", "1.8.12") then
ucpu:depends({ [_n("protocol")] = "_balancing" })
@@ -159,6 +162,12 @@ else
pi:depends({ [_n("balancingStrategy")] = "leastPing" })
end
o = s:option(Value, _n("expected"), translate("Preferred Node Count"))
o:depends({ [_n("balancingStrategy")] = "leastLoad" })
o.datatype = "uinteger"
o.default = "2"
o.description = translate("The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them.")
-- [[ 分流模块 ]]
if #nodes_table > 0 then
@@ -581,7 +581,8 @@ function gen_config(var)
local dns = nil
local fakedns = nil
local routing = nil
local observatory = nil
local burstObservatory = nil
local strategy = nil
local inbounds = {}
local outbounds = {}
local COMMON = {}
@@ -761,19 +762,33 @@ function gen_config(var)
end
end
end
if _node.balancingStrategy == "leastLoad" then
strategy = {
type = _node.balancingStrategy,
settings = {
expected = _node.expected and tonumber(_node.expected) and tonumber(_node.expected) or 2,
maxRTT = "1s"
}
}
else
strategy = { type = _node.balancingStrategy or "random" }
end
table.insert(balancers, {
tag = balancer_tag,
selector = valid_nodes,
fallbackTag = fallback_node_tag,
strategy = { type = _node.balancingStrategy or "random" }
strategy = strategy
})
if _node.balancingStrategy == "leastPing" or fallback_node_tag then
if not observatory then
observatory = {
if _node.balancingStrategy == "leastPing" or _node.balancingStrategy == "leastLoad" or fallback_node_tag then
if not burstObservatory then
burstObservatory = {
subjectSelector = { "blc-" },
probeUrl = _node.useCustomProbeUrl and _node.probeUrl or nil,
probeInterval = _node.probeInterval or "1m",
enableConcurrency = true
pingConfig = {
destination = _node.useCustomProbeUrl and _node.probeUrl or nil,
interval = _node.probeInterval or "1m",
sampling = 3,
timeout = "5s"
}
}
end
end
@@ -1358,7 +1373,7 @@ function gen_config(var)
-- 传出连接
outbounds = outbounds,
-- 连接观测
observatory = observatory,
burstObservatory = burstObservatory,
-- 路由
routing = routing,
-- 本地策略
+10 -4
View File
@@ -445,8 +445,14 @@ msgstr "用于检测连接状态的网址。"
msgid "Probe Interval"
msgstr "探测间隔"
msgid "The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively."
msgstr "发起探测的间隔。每经过这个时间,就会对一个服务器进行服务器状态检测。时间格式为数字+单位,比如<code>&quot;10s&quot;</code>, <code>&quot;2h45m&quot;</code>,支持的时间单位有 <code>ns</code><code>us</code><code>ms</code><code>s</code><code>m</code><code>h</code>,分别对应纳秒、微秒、毫秒、秒、分、时。"
msgid "The interval between initiating probes. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively."
msgstr "发起探测的间隔。时间格式为数字+单位,比如<code>&quot;10s&quot;</code>, <code>&quot;2h45m&quot;</code>,支持的时间单位有 <code>ns</code><code>us</code><code>ms</code><code>s</code><code>m</code><code>h</code>,分别对应纳秒、微秒、毫秒、秒、分、时。"
msgid "Preferred Node Count"
msgstr "优选节点数量"
msgid "The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them."
msgstr "负载均衡器选出最优节点的个数,流量将在这几个节点中随机分配。"
msgid "Shunt"
msgstr "分流"
@@ -508,8 +514,8 @@ msgstr "仅 IPv6"
msgid "Load balancing node list"
msgstr "负载均衡节点列表"
msgid "Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"
msgstr "负载均衡节点列表,<a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>文档原理</a>"
msgid "Load balancing node list, <a target='_blank' href='https://xtls.github.io/config/routing.html#balancerobject'>document</a>"
msgstr "负载均衡节点列表,<a target='_blank' href='https://xtls.github.io/config/routing.html#balancerobject'>文档原理</a>"
msgid "From Share URL"
msgstr "导入分享URL"
+2 -2
View File
@@ -21,13 +21,13 @@ define Download/geoip
HASH:=83337c712b04d8c16351cf5a5394eae5cb9cfa257fb4773485945dce65dcea76
endef
GEOSITE_VER:=20250328032133
GEOSITE_VER:=20250329145339
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:=eab972bb19773e10cf960f99b1733a54dd3d56063382fcd505fc646a4d5dacf9
HASH:=d0f0e5c954f65775d1f5b34a813a64cb8868ad61a78ea183386d5bf84b3c8fca
endef
GEOSITE_IRAN_VER:=202503240038
+2 -2
View File
@@ -18,8 +18,8 @@
<PackageVersion Include="ReactiveUI" Version="20.2.45" />
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
<PackageVersion Include="ReactiveUI.WPF" Version="20.2.45" />
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.5" />
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.5" />
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.6" />
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.6" />
<PackageVersion Include="Splat.NLog" Version="15.3.1" />
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
<PackageVersion Include="TaskScheduler" Version="2.12.1" />
@@ -0,0 +1,10 @@
namespace ServiceLib.Enums
{
public enum EMultipleLoad
{
Random,
RoundRobin,
LeastPing,
LeastLoad
}
}
@@ -1005,12 +1005,12 @@ namespace ServiceLib.Handler
return 0;
}
public static async Task<RetResult> AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, ECoreType coreType)
public static async Task<RetResult> AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, ECoreType coreType, EMultipleLoad multipleLoad)
{
var indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName);
var configPath = Utils.GetConfigPath(Global.CoreMultipleLoadConfigFileName);
var result = await CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType);
var result = await CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType, multipleLoad);
if (result.Success != true)
{
return result;
@@ -1023,7 +1023,14 @@ namespace ServiceLib.Handler
var profileItem = await AppHandler.Instance.GetProfileItem(indexId) ?? new();
profileItem.IndexId = indexId;
profileItem.Remarks = coreType == ECoreType.sing_box ? ResUI.menuSetDefaultMultipleServer : ResUI.menuSetDefaultLoadBalanceServer;
profileItem.Remarks = multipleLoad switch
{
EMultipleLoad.Random => ResUI.menuSetDefaultMultipleServerXrayRandom,
EMultipleLoad.RoundRobin => ResUI.menuSetDefaultMultipleServerXrayRoundRobin,
EMultipleLoad.LeastPing => ResUI.menuSetDefaultMultipleServerXrayLeastPing,
EMultipleLoad.LeastLoad => ResUI.menuSetDefaultMultipleServerXrayLeastLoad,
_ => ResUI.menuSetDefaultMultipleServerXrayRoundRobin,
};
profileItem.Address = Global.CoreMultipleLoadConfigFileName;
profileItem.ConfigType = EConfigType.Custom;
profileItem.CoreType = coreType;
@@ -1,3 +1,7 @@
using DynamicData;
using ServiceLib.Enums;
using ServiceLib.Models;
namespace ServiceLib.Handler
{
/// <summary>
@@ -133,16 +137,16 @@ namespace ServiceLib.Handler
return result;
}
public static async Task<RetResult> GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType)
public static async Task<RetResult> GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType, EMultipleLoad multipleLoad)
{
var result = new RetResult();
if (coreType == ECoreType.sing_box)
{
result = await new CoreConfigSingboxService(config).GenerateClientMultipleLoadConfig(selecteds);
}
else if (coreType == ECoreType.Xray)
else
{
result = await new CoreConfigV2rayService(config).GenerateClientMultipleLoadConfig(selecteds);
result = await new CoreConfigV2rayService(config).GenerateClientMultipleLoadConfig(selecteds, multipleLoad);
}
if (result.Success != true)
@@ -12,6 +12,8 @@ namespace ServiceLib.Models
public Metrics4Ray? metrics { get; set; }
public Policy4Ray? policy { get; set; }
public Stats4Ray? stats { get; set; }
public Observatory4Ray? observatory { get; set; }
public BurstObservatory4Ray? burstObservatory { get; set; }
public string? remarks { get; set; }
}
@@ -232,6 +234,46 @@ namespace ServiceLib.Models
public class BalancersStrategy4Ray
{
public string? type { get; set; }
public BalancersStrategySettings4Ray? settings { get; set; }
}
public class BalancersStrategySettings4Ray
{
public int? expected { get; set; }
public string? maxRTT { get; set; }
public float? tolerance { get; set; }
public List<string>? baselines { get; set; }
public List<BalancersStrategySettingsCosts4Ray>? costs { get; set; }
}
public class BalancersStrategySettingsCosts4Ray
{
public bool? regexp { get; set; }
public string? match { get; set; }
public float? value { get; set; }
}
public class Observatory4Ray
{
public List<string>? subjectSelector { get; set; }
public string? probeUrl { get; set; }
public string? probeInterval { get; set; }
public bool? enableConcurrency { get; set; }
}
public class BurstObservatory4Ray
{
public List<string>? subjectSelector { get; set; }
public BurstObservatoryPingConfig4Ray? pingConfig { get; set; }
}
public class BurstObservatoryPingConfig4Ray
{
public string? destination { get; set; }
public string? connectivity { get; set; }
public string? interval { get; set; }
public int? sampling { get; set; }
public string? timeout { get; set; }
}
public class StreamSettings4Ray
+42 -6
View File
@@ -1474,20 +1474,56 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Multi-server load balancing 的本地化字符串。
/// 查找类似 Multi-Server lowest latency sing-box 的本地化字符串。
/// </summary>
public static string menuSetDefaultLoadBalanceServer {
public static string menuSetDefaultMultipleServerSingBoxLeastPing {
get {
return ResourceManager.GetString("menuSetDefaultLoadBalanceServer", resourceCulture);
return ResourceManager.GetString("menuSetDefaultMultipleServerSingBoxLeastPing", resourceCulture);
}
}
/// <summary>
/// 查找类似 Multi-Server lowest latency 的本地化字符串。
/// 查找类似 Multi-Server Xray 的本地化字符串。
/// </summary>
public static string menuSetDefaultMultipleServer {
public static string menuSetDefaultMultipleServerXray {
get {
return ResourceManager.GetString("menuSetDefaultMultipleServer", resourceCulture);
return ResourceManager.GetString("menuSetDefaultMultipleServerXray", resourceCulture);
}
}
/// <summary>
/// 查找类似 Multi-Server LeastLoad 的本地化字符串。
/// </summary>
public static string menuSetDefaultMultipleServerXrayLeastLoad {
get {
return ResourceManager.GetString("menuSetDefaultMultipleServerXrayLeastLoad", resourceCulture);
}
}
/// <summary>
/// 查找类似 Multi-Server LeastPing 的本地化字符串。
/// </summary>
public static string menuSetDefaultMultipleServerXrayLeastPing {
get {
return ResourceManager.GetString("menuSetDefaultMultipleServerXrayLeastPing", resourceCulture);
}
}
/// <summary>
/// 查找类似 Multi-Server Random 的本地化字符串。
/// </summary>
public static string menuSetDefaultMultipleServerXrayRandom {
get {
return ResourceManager.GetString("menuSetDefaultMultipleServerXrayRandom", resourceCulture);
}
}
/// <summary>
/// 查找类似 Multi-Server RoundRobin 的本地化字符串。
/// </summary>
public static string menuSetDefaultMultipleServerXrayRoundRobin {
get {
return ResourceManager.GetString("menuSetDefaultMultipleServerXrayRoundRobin", resourceCulture);
}
}
+234 -222
View File
@@ -936,21 +936,219 @@
<data name="TbSettingsTunMode" xml:space="preserve">
<value>تنظیمات TunMode</value>
</data>
<data name="menuMoveToGroup" xml:space="preserve">
<value>انتقال به گروه</value>
</data>
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
<value>فعال کردن مرتب‌سازی سرورها با کشیدن و رها کردن (نیاز به راه‌اندازی مجدد)</value>
</data>
<data name="TbAutoRefresh" xml:space="preserve">
<value>بازخوانی خودکار</value>
</data>
<data name="SpeedtestingSkip" xml:space="preserve">
<value>رد شدن از آزمون</value>
</data>
<data name="menuEditServer" xml:space="preserve">
<value>ویرایش سرور (Ctrl+D)</value>
</data>
<data name="TbSettingsDoubleClick2Activate" xml:space="preserve">
<value>دوبار کلیک کردن سرور باعث فعال شدن آن می شود</value>
</data>
<data name="SpeedtestingCompleted" xml:space="preserve">
<value>تست تکمیل شد</value>
</data>
<data name="TbSettingsDefFingerprint" xml:space="preserve">
<value>اثر انگشت tls پیش فرض</value>
</data>
<data name="TbSettingsDefUserAgent" xml:space="preserve">
<value>User-Agent</value>
</data>
<data name="TbSettingsDefUserAgentTips" xml:space="preserve">
<value>این پارامتر فقط برای tcp/http و ws معتبر است</value>
</data>
<data name="TbSettingsCurrentFontFamily" xml:space="preserve">
<value>FontFamily (نیاز به راه اندازی مجدد)</value>
</data>
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>فایل TTF/TTC فونت را در دایرکتوری guiFonts کپی کنید. پنجره تنظیمات را دوباره باز کنید</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>پورت Pac = +3; پورت Xray API = +4; پورت mihomo API = +5;</value>
</data>
<data name="TbSettingsStartBootTip" xml:space="preserve">
<value>این را با امتیازات ادمین تنظیم کنید، پس از راه اندازی، امتیازات مدیر را دریافت کنید</value>
</data>
<data name="TbSettingsFontSize" xml:space="preserve">
<value>اندازه فونت</value>
</data>
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
<value>یمقدار تاخیر تست سرعت منفرد</value>
</data>
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>/آدرس اینترنتی SpeedTest</value>
</data>
<data name="menuMoveTo" xml:space="preserve">
<value>بالا و پایین حرکت کنید</value>
</data>
<data name="TbPublicKey" xml:space="preserve">
<value>PublicKey</value>
</data>
<data name="TbShortId" xml:space="preserve">
<value>ShortId</value>
</data>
<data name="TbSpiderX" xml:space="preserve">
<value>SpiderX</value>
</data>
<data name="TbSettingsEnableHWA" xml:space="preserve">
<value>فعال‌ سازی شتاب‌ دهنده سخت‌ افزاری (نیاز به راه‌اندازی مجدد)</value>
</data>
<data name="SpeedtestingWait" xml:space="preserve">
<value>در انتظار آزمایش (برای پایان دادن به ESC فشار دهید)...</value>
</data>
<data name="TipDisplayLog" xml:space="preserve">
<value>لطفاً در صورت قطع غیرعادی آن را خاموش کنید</value>
</data>
<data name="MsgSkipSubscriptionUpdate" xml:space="preserve">
<value>به روز رسانی ها فعال نیستند، از این اشتراک رد شوید</value>
</data>
<data name="menuRebootAsAdmin" xml:space="preserve">
<value>به عنوان مدیر راه اندازی مجدد</value>
</data>
<data name="LvMoreUrl" xml:space="preserve">
<value>نشانی‌های وب بیشتر که با کاما از هم جدا شده‌اند. تبدیل اشتراک نامعتبر خواهد بود</value>
</data>
<data name="SpeedDisplayText" xml:space="preserve">
<value>{0} : {1}/s↑ | {2}/s↓</value>
</data>
<data name="LvAutoUpdateInterval" xml:space="preserve">
<value>فاصله به روز رسانی خودکار (دقیقه)</value>
</data>
<data name="TbSettingsLogEnabledToFile" xml:space="preserve">
<value>فعال کردن ورود به فایل</value>
</data>
<data name="LvConvertTarget" xml:space="preserve">
<value>تبدیل نوع هدف</value>
</data>
<data name="LvConvertTargetTip" xml:space="preserve">
<value>اگر نیازی به تبدیل نیست، لطفاً خالی بگذارید</value>
</data>
<data name="menuDNSSetting" xml:space="preserve">
<value>تنظیمات DNS</value>
</data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
<value>تنظیمات DNS sing-box</value>
</data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>لطفا ساختار DNS را پر کنید، برای مشاهده سند کلیک کنید</value>
</data>
<data name="TbSettingDnsImportDefConfig" xml:space="preserve">
<value>برای وارد کردن تنظیمات پیش‌فرض DNS کلیک کنید</value>
</data>
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
<value>استراتژی دامنه sing-box</value>
</data>
<data name="TbSettingsMux4SboxProtocol" xml:space="preserve">
<value>پروتکل sing-box Mux</value>
</data>
<data name="TbRoutingRuleProcess" xml:space="preserve">
<value>نام کامل فرانید (حالت Tun)</value>
</data>
<data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP or IP CIDR</value>
</data>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>دامنه</value>
</data>
<data name="menuAddHysteria2Server" xml:space="preserve">
<value>Add [Hysteria2] server</value>
</data>
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
<value>حداکتر پهنای باند هیستریا (آپلود/دانلود)</value>
</data>
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
<value>استفاده کردن از System Hosts</value>
</data>
<data name="menuAddTuicServer" xml:space="preserve">
<value>افزودن سرور [TUIC]</value>
</data>
<data name="TbHeaderType8" xml:space="preserve">
<value>کنترل تراکم</value>
</data>
<data name="LvPrevProfile" xml:space="preserve">
<value>نام مستعار پروکسی قبلی</value>
</data>
<data name="LvNextProfile" xml:space="preserve">
<value>نام مستعار پروکسی بعدی</value>
</data>
<data name="LvPrevProfileTip" xml:space="preserve">
<value>لطفاً مطمئن شوید که ملاحظات وجود دارند و منحصر به فرد هستند</value>
</data>
<data name="TbSettingsEnableExInbound" xml:space="preserve">
<value>فعال سازی additional Inbound</value>
</data>
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
<value>فعال سازی آدرس IPv6</value>
</data>
<data name="menuAddWireguardServer" xml:space="preserve">
<value>افزودن سرور [WireGuard]</value>
</data>
<data name="TbPrivateKey" xml:space="preserve">
<value>کلید خصوصی</value>
</data>
<data name="TbReserved" xml:space="preserve">
<value>Reserved (2,3,4)</value>
</data>
<data name="TbLocalAddress" xml:space="preserve">
<value>آدرس (IPv4, IPv6)</value>
</data>
<data name="TbPath7" xml:space="preserve">
<value>پسورد obfs</value>
</data>
<data name="TbRuleMatchingTips" xml:space="preserve">
<value>(Domain or IP or ProcName) and Port and Protocol and InboundTag =&gt; OutboundTag</value>
</data>
<data name="TbAutoScrollToEnd" xml:space="preserve">
<value>خودکار ScrollToEnd</value>
</data>
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
<value>آدرس اینترنتی تست پینگ سرعت</value>
</data>
<data name="TbSettingsEnableUpdateSubOnlyRemarksExist" xml:space="preserve">
<value>اشتراک در حال به‌روزرسانی، فقط مشخص کنید که ملاحظاتی آیا وجود دارد!</value>
</data>
<data name="SpeedtestingStop" xml:space="preserve">
<value>پایان تست...</value>
</data>
<data name="TransportRequestHostTip5" xml:space="preserve">
<value>*grpc Authority</value>
</data>
<data name="menuAddHttpServer" xml:space="preserve">
<value>افزودن سرور [HTTP]</value>
</data>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>از Xray استفاده کنید و حالت non-Tun را فعال کنید، که با پراکسی قبلی گروه در تضاد است</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>فعال کردن فرگمنت</value>
</data>
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
<value>فعال کردن کش فایل مجموعه قوانین برای sing-box</value>
</data>
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
<value>سفارش سازی مجموعه قوانین sing box</value>
</data>
<data name="NeedRebootTips" xml:space="preserve">
<value>عملکرد موفقیت آمیز بود، روی منوی تنظیمات کلیک کنید تا برنامه راه اندازی مجدد شود.</value>
</data>
<data name="menuOpenTheFileLocation" xml:space="preserve">
<value>باز کردن محل ذخیره سازی</value>
</data>
<data name="TbSorting" xml:space="preserve">
<value>مرتب سازی</value>
</data>
<data name="TbSortingChain" xml:space="preserve">
<value>Chain</value>
</data>
<data name="TbSortingDefault" xml:space="preserve">
<value>پیش فرض</value>
</data>
@@ -963,12 +1161,21 @@
<data name="TbSortingDownTraffic" xml:space="preserve">
<value>ترافیک دانلود</value>
</data>
<data name="TbSortingHost" xml:space="preserve">
<value>هاست</value>
</data>
<data name="TbSortingName" xml:space="preserve">
<value>نام</value>
</data>
<data name="TbSortingNetwork" xml:space="preserve">
<value>شبکه</value>
</data>
<data name="TbSortingTime" xml:space="preserve">
<value>زمان</value>
</data>
<data name="TbSortingType" xml:space="preserve">
<value>نوع</value>
</data>
<data name="TbSortingUpSpeed" xml:space="preserve">
<value>سرعت اپلود</value>
</data>
@@ -1008,27 +1215,18 @@
<data name="menuProxiesDelaytestPart" xml:space="preserve">
<value>تست تاخیر قسمت گره (نقطه اتصال)</value>
</data>
<data name="menuProxiesReload" xml:space="preserve">
<value>تازه سازی پروکسی ها</value>
</data>
<data name="menuProxiesSelectActivity" xml:space="preserve">
<value>انتخاب گره فعال (Enter)</value>
</data>
<data name="menuRemoteBackup" xml:space="preserve">
<value>پشتیبان گیری از راه دور (WebDAV)</value>
</data>
<data name="menuRemoteRestore" xml:space="preserve">
<value>بازیابی از راه دور (WebDAV)</value>
</data>
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>استراتژی دامنه پیش فرض برای خروجی</value>
</data>
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
<value>کمترین تأخیر چند سروره</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>جهت چیدمان اصلی (نیاز به راه اندازی مجدد)</value>
</data>
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
<value>تعادل بار چند سروره</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>آدرس DNS خروجی</value>
</data>
@@ -1056,6 +1254,12 @@
<data name="menuLocalRestore" xml:space="preserve">
<value>بازیابی از محلی</value>
</data>
<data name="menuRemoteBackup" xml:space="preserve">
<value>پشتیبان گیری از راه دور (WebDAV)</value>
</data>
<data name="menuRemoteRestore" xml:space="preserve">
<value>بازیابی از راه دور (WebDAV)</value>
</data>
<data name="menuLocalBackupAndRestore" xml:space="preserve">
<value>محلی</value>
</data>
@@ -1131,216 +1335,6 @@
<data name="LvMemo" xml:space="preserve">
<value>یادداشت ملاحظات</value>
</data>
<data name="TbSettingsLogEnabledToFile" xml:space="preserve">
<value>فعال کردن ورود به فایل</value>
</data>
<data name="MsgSkipSubscriptionUpdate" xml:space="preserve">
<value>به روز رسانی ها فعال نیستند، از این اشتراک رد شوید</value>
</data>
<data name="menuRebootAsAdmin" xml:space="preserve">
<value>به عنوان مدیر راه اندازی مجدد</value>
</data>
<data name="LvMoreUrl" xml:space="preserve">
<value>نشانی‌های وب بیشتر که با کاما از هم جدا شده‌اند. تبدیل اشتراک نامعتبر خواهد بود</value>
</data>
<data name="SpeedDisplayText" xml:space="preserve">
<value>{0} : {1}/s↑ | {2}/s↓</value>
</data>
<data name="LvAutoUpdateInterval" xml:space="preserve">
<value>فاصله به روز رسانی خودکار (دقیقه)</value>
</data>
<data name="LvConvertTarget" xml:space="preserve">
<value>تبدیل نوع هدف</value>
</data>
<data name="LvConvertTargetTip" xml:space="preserve">
<value>اگر نیازی به تبدیل نیست، لطفاً خالی بگذارید</value>
</data>
<data name="TipDisplayLog" xml:space="preserve">
<value>لطفاً در صورت قطع غیرعادی آن را خاموش کنید</value>
</data>
<data name="menuDNSSetting" xml:space="preserve">
<value>تنظیمات DNS</value>
</data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>لطفا ساختار DNS را پر کنید، برای مشاهده سند کلیک کنید</value>
</data>
<data name="TbSettingDnsImportDefConfig" xml:space="preserve">
<value>برای وارد کردن تنظیمات پیش‌فرض DNS کلیک کنید</value>
</data>
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
<value>استراتژی دامنه sing-box</value>
</data>
<data name="TbSettingsMux4SboxProtocol" xml:space="preserve">
<value>پروتکل sing-box Mux</value>
</data>
<data name="TbRoutingRuleProcess" xml:space="preserve">
<value>نام کامل فرانید (حالت Tun)</value>
</data>
<data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP or IP CIDR</value>
</data>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>دامنه</value>
</data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
<value>تنظیمات DNS sing-box</value>
</data>
<data name="SpeedtestingWait" xml:space="preserve">
<value>در انتظار آزمایش (برای پایان دادن به ESC فشار دهید)...</value>
</data>
<data name="TbSpiderX" xml:space="preserve">
<value>SpiderX</value>
</data>
<data name="TbShortId" xml:space="preserve">
<value>ShortId</value>
</data>
<data name="menuMoveToGroup" xml:space="preserve">
<value>انتقال به گروه</value>
</data>
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
<value>فعال کردن مرتب‌سازی سرورها با کشیدن و رها کردن (نیاز به راه‌اندازی مجدد)</value>
</data>
<data name="TbAutoRefresh" xml:space="preserve">
<value>بازخوانی خودکار</value>
</data>
<data name="SpeedtestingSkip" xml:space="preserve">
<value>رد شدن از آزمون</value>
</data>
<data name="menuEditServer" xml:space="preserve">
<value>ویرایش سرور (Ctrl+D)</value>
</data>
<data name="TbSettingsDoubleClick2Activate" xml:space="preserve">
<value>دوبار کلیک کردن سرور باعث فعال شدن آن می شود</value>
</data>
<data name="SpeedtestingCompleted" xml:space="preserve">
<value>تست تکمیل شد</value>
</data>
<data name="TbSettingsDefFingerprint" xml:space="preserve">
<value>اثر انگشت tls پیش فرض</value>
</data>
<data name="TbSettingsCurrentFontFamily" xml:space="preserve">
<value>FontFamily (نیاز به راه اندازی مجدد)</value>
</data>
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>فایل TTF/TTC فونت را در دایرکتوری guiFonts کپی کنید. پنجره تنظیمات را دوباره باز کنید</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>پورت Pac = +3; پورت Xray API = +4; پورت mihomo API = +5;</value>
</data>
<data name="TbSettingsStartBootTip" xml:space="preserve">
<value>این را با امتیازات ادمین تنظیم کنید، پس از راه اندازی، امتیازات مدیر را دریافت کنید</value>
</data>
<data name="TbSettingsFontSize" xml:space="preserve">
<value>اندازه فونت</value>
</data>
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
<value>یمقدار تاخیر تست سرعت منفرد</value>
</data>
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>/آدرس اینترنتی SpeedTest</value>
</data>
<data name="menuMoveTo" xml:space="preserve">
<value>بالا و پایین حرکت کنید</value>
</data>
<data name="TbPublicKey" xml:space="preserve">
<value>PublicKey</value>
</data>
<data name="menuAddHysteria2Server" xml:space="preserve">
<value>Add [Hysteria2] server</value>
</data>
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
<value>حداکتر پهنای باند هیستریا (آپلود/دانلود)</value>
</data>
<data name="menuAddTuicServer" xml:space="preserve">
<value>افزودن سرور [TUIC]</value>
</data>
<data name="TbSettingsEnableUpdateSubOnlyRemarksExist" xml:space="preserve">
<value>اشتراک در حال به‌روزرسانی، فقط مشخص کنید که ملاحظاتی آیا وجود دارد!</value>
</data>
<data name="menuProxiesReload" xml:space="preserve">
<value>تازه سازی پروکسی ها</value>
</data>
<data name="TbSortingNetwork" xml:space="preserve">
<value>شبکه</value>
</data>
<data name="TbSortingType" xml:space="preserve">
<value>نوع</value>
</data>
<data name="TransportRequestHostTip5" xml:space="preserve">
<value>*grpc Authority</value>
</data>
<data name="menuAddHttpServer" xml:space="preserve">
<value>افزودن سرور [HTTP]</value>
</data>
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
<value>آدرس اینترنتی تست پینگ سرعت</value>
</data>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>از Xray استفاده کنید و حالت non-Tun را فعال کنید، که با پراکسی قبلی گروه در تضاد است</value>
</data>
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
<value>سفارش سازی مجموعه قوانین sing box</value>
</data>
<data name="NeedRebootTips" xml:space="preserve">
<value>عملکرد موفقیت آمیز بود، روی منوی تنظیمات کلیک کنید تا برنامه راه اندازی مجدد شود.</value>
</data>
<data name="menuOpenTheFileLocation" xml:space="preserve">
<value>باز کردن محل ذخیره سازی</value>
</data>
<data name="TbSortingChain" xml:space="preserve">
<value>Chain</value>
</data>
<data name="TbSortingHost" xml:space="preserve">
<value>هاست</value>
</data>
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
<value>استفاده کردن از System Hosts</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>فعال کردن فرگمنت</value>
</data>
<data name="TbAutoScrollToEnd" xml:space="preserve">
<value>خودکار ScrollToEnd</value>
</data>
<data name="SpeedtestingStop" xml:space="preserve">
<value>پایان تست...</value>
</data>
<data name="LvNextProfile" xml:space="preserve">
<value>نام مستعار پروکسی بعدی</value>
</data>
<data name="TbPath7" xml:space="preserve">
<value>پسورد obfs</value>
</data>
<data name="TbHeaderType8" xml:space="preserve">
<value>کنترل تراکم</value>
</data>
<data name="LvPrevProfile" xml:space="preserve">
<value>نام مستعار پروکسی قبلی</value>
</data>
<data name="TbLocalAddress" xml:space="preserve">
<value>آدرس (IPv4, IPv6)</value>
</data>
<data name="TbReserved" xml:space="preserve">
<value>Reserved (2,3,4)</value>
</data>
<data name="TbPrivateKey" xml:space="preserve">
<value>کلید خصوصی</value>
</data>
<data name="menuAddWireguardServer" xml:space="preserve">
<value>افزودن سرور [WireGuard]</value>
</data>
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
<value>فعال سازی آدرس IPv6</value>
</data>
<data name="TbSettingsEnableExInbound" xml:space="preserve">
<value>فعال سازی additional Inbound</value>
</data>
<data name="LvPrevProfileTip" xml:space="preserve">
<value>لطفاً مطمئن شوید که ملاحظات وجود دارند و منحصر به فرد هستند</value>
</data>
<data name="TbRuleMatchingTips" xml:space="preserve">
<value>(Domain or IP or ProcName) and Port and Protocol and InboundTag =&gt; OutboundTag</value>
</data>
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
<value>رمز عبور sudo سیستم</value>
</data>
@@ -1401,4 +1395,22 @@
<data name="TbPorts7Tips" xml:space="preserve">
<value>مخفی و پورت می شود، با کاما (،) جدا می شود</value>
</data>
<data name="menuSetDefaultMultipleServerXray" xml:space="preserve">
<value>چند سرور Xray (چند انتخابی)</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRandom" xml:space="preserve">
<value>چند سرور تصادفی</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRoundRobin" xml:space="preserve">
<value>چند سرور گردشی</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastPing" xml:space="preserve">
<value>چند سرور کمترین تأخیر</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastLoad" xml:space="preserve">
<value>چند سرور پایدارترین</value>
</data>
<data name="menuSetDefaultMultipleServerSingBoxLeastPing" xml:space="preserve">
<value>چند سرور کمترین تأخیر sing-box (چند انتخابی)</value>
</data>
</root>
+18 -6
View File
@@ -1224,15 +1224,9 @@
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Alapértelmezett domain stratégia a kimenő forgalomhoz</value>
</data>
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
<value>Multi-szerver alacsony késleltetés</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>Fő elrendezés irányítása (indítás szükséges)</value>
</data>
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
<value>Multi-szerver terheléselosztás</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>Kimenő DNS cím</value>
</data>
@@ -1401,4 +1395,22 @@
<data name="TbPorts7Tips" xml:space="preserve">
<value>Will cover the port, separate with commas (,)</value>
</data>
<data name="menuSetDefaultMultipleServerXray" xml:space="preserve">
<value>Többszerveres Xray (többválasztásos)</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRandom" xml:space="preserve">
<value>Többszerveres véletlenszerű</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRoundRobin" xml:space="preserve">
<value>Többszerveres körforgásos</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastPing" xml:space="preserve">
<value>Többszerveres legkisebb késleltetésű</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastLoad" xml:space="preserve">
<value>Többszerveres legstabilabb</value>
</data>
<data name="menuSetDefaultMultipleServerSingBoxLeastPing" xml:space="preserve">
<value>Többszerveres legkisebb késleltetésű sing-box (többválasztásos)</value>
</data>
</root>
+19 -7
View File
@@ -1224,15 +1224,9 @@
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Default domain strategy for outbound</value>
</data>
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
<value>Multi-Server lowest latency</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>Main layout orientation (requires restart)</value>
</data>
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
<value>Multi-server load balancing</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>Outbound DNS address</value>
</data>
@@ -1401,4 +1395,22 @@
<data name="TbPorts7Tips" xml:space="preserve">
<value>Will cover the port, separate with commas (,)</value>
</data>
</root>
<data name="menuSetDefaultMultipleServerXray" xml:space="preserve">
<value>Multi-Server Xray</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRandom" xml:space="preserve">
<value>Multi-Server Random</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRoundRobin" xml:space="preserve">
<value>Multi-Server RoundRobin</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastPing" xml:space="preserve">
<value>Multi-Server LeastPing</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastLoad" xml:space="preserve">
<value>Multi-Server LeastLoad</value>
</data>
<data name="menuSetDefaultMultipleServerSingBoxLeastPing" xml:space="preserve">
<value>Multi-Server lowest latency sing-box</value>
</data>
</root>
+230 -218
View File
@@ -681,18 +681,12 @@
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>Интервал автоматического обновления Geo в часах</value>
</data>
<data name="LvAutoUpdateInterval" xml:space="preserve">
<value>Интервал автоматического обновления в минутах</value>
</data>
<data name="TbSettingsCore" xml:space="preserve">
<value>Ядро: базовые настройки</value>
</data>
<data name="TbSettingsCoreDns" xml:space="preserve">
<value>Настройки DNS V2ray</value>
</data>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
<value>Настройки DNS sing-box</value>
</data>
<data name="TbSettingsCoreKcp" xml:space="preserve">
<value>Ядро: настройки KCP</value>
</data>
@@ -978,137 +972,146 @@
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>Скопируйте файл шрифта TTF/TTC в каталог guiFonts, перезапустите настройки</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>Pac порт = +3; Xray API порт = +4; mihomo API порт = +5;</value>
</data>
<data name="TbSettingsStartBootTip" xml:space="preserve">
<value>Установите это с правами администратора</value>
</data>
<data name="TbSettingsFontSize" xml:space="preserve">
<value>Размер шрифта</value>
</data>
<data name="TbSettingsEnableHWA" xml:space="preserve">
<value>Включить аппаратное ускорение (требуется перезагрузка)</value>
</data>
<data name="menuRebootAsAdmin" xml:space="preserve">
<value>Перезагрузить как администратор</value>
</data>
<data name="menuDNSSetting" xml:space="preserve">
<value>Настройки DNS</value>
</data>
<data name="TbSettingsLogEnabledToFile" xml:space="preserve">
<value>Включить логгирование в файл</value>
</data>
<data name="TbSettingsSpeedTestTimeout" xml:space="preserve">
<value>Таймаут одиночного спидтеста</value>
</data>
<data name="TbSettingsSpeedTestUrl" xml:space="preserve">
<value>URL спидтеста</value>
</data>
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Источник geo файлов</value>
<data name="menuMoveTo" xml:space="preserve">
<value>Move up and down</value>
</data>
<data name="TbSettingsSrsFilesSource" xml:space="preserve">
<value>Источник sing-box srs файлов</value>
<data name="TbPublicKey" xml:space="preserve">
<value>PublicKey</value>
</data>
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
<value>Источник правил маршрутизации</value>
<data name="TbShortId" xml:space="preserve">
<value>ShortId</value>
</data>
<data name="menuRegionalPresets" xml:space="preserve">
<value>Региональные пресеты</value>
<data name="TbSpiderX" xml:space="preserve">
<value>SpiderX</value>
</data>
<data name="menuRegionalPresetsDefault" xml:space="preserve">
<value>По умолчанию (Китай)</value>
<data name="TbSettingsEnableHWA" xml:space="preserve">
<value>Включить аппаратное ускорение (требуется перезагрузка)</value>
</data>
<data name="menuRegionalPresetsRussia" xml:space="preserve">
<value>Россия</value>
<data name="SpeedtestingWait" xml:space="preserve">
<value>Ожидание тестирования (нажмите ESC для отмены)...</value>
</data>
<data name="menuRegionalPresetsIran" xml:space="preserve">
<value>Иран</value>
<data name="TipDisplayLog" xml:space="preserve">
<value>Please turn off when there is an abnormal disconnection</value>
</data>
<data name="TbSettingsChinaUserTip" xml:space="preserve">
<value>Используйте Настройки -&gt; Региональные пресеты вместо изменения этого поля</value>
<data name="MsgSkipSubscriptionUpdate" xml:space="preserve">
<value>Updates are not enabled, skip this subscription</value>
</data>
<data name="LvMemo" xml:space="preserve">
<value>Remarks Memo</value>
<data name="menuRebootAsAdmin" xml:space="preserve">
<value>Перезагрузить как администратор</value>
</data>
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
<value>URL-адрес для проверки скорости пинга</value>
<data name="LvMoreUrl" xml:space="preserve">
<value>More URLs, separated by commas; Subscription conversion will be invalid</value>
</data>
<data name="menuProxiesDelaytestPart" xml:space="preserve">
<value>Part Node Latency Test</value>
<data name="SpeedDisplayText" xml:space="preserve">
<value>{0} : {1}/s↑ | {2}/s↓</value>
</data>
<data name="menuProxiesReload" xml:space="preserve">
<value>Обновить прокси</value>
<data name="LvAutoUpdateInterval" xml:space="preserve">
<value>Интервал автоматического обновления в минутах</value>
</data>
<data name="TbAutoScrollToEnd" xml:space="preserve">
<value>Автоматическая прокрутка в конец</value>
<data name="TbSettingsLogEnabledToFile" xml:space="preserve">
<value>Включить логгирование в файл</value>
</data>
<data name="menuProxiesSelectActivity" xml:space="preserve">
<value>Активировать узел (Enter)</value>
<data name="LvConvertTarget" xml:space="preserve">
<value>Преобразовать тип цели</value>
</data>
<data name="TbRuleMatchingTips" xml:space="preserve">
<value>(Domain or IP or ProcName) and Port and Protocol and InboundTag =&gt; OutboundTag</value>
<data name="LvConvertTargetTip" xml:space="preserve">
<value>Если преобразование не требуется, оставьте поле пустым.</value>
</data>
<data name="TbPath7" xml:space="preserve">
<value>obfs password</value>
<data name="menuDNSSetting" xml:space="preserve">
<value>Настройки DNS</value>
</data>
<data name="TbLocalAddress" xml:space="preserve">
<value>Адрес(Ipv4,Ipv6)</value>
<data name="TbSettingsCoreDnsSingbox" xml:space="preserve">
<value>Настройки DNS sing-box</value>
</data>
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Стратегия домена по умолчанию для исходящих</value>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>Пожалуйста, заполните структуру DNS. Нажмите, чтобы просмотреть документ.</value>
</data>
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
<value>Multi-Server lowest latency</value>
<data name="TbSettingDnsImportDefConfig" xml:space="preserve">
<value>Нажмите, чтобы импортировать конфигурацию DNS по умолчанию</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>Основная ориентация макета (требуется перезагрузка)</value>
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
<value>Стратегия домена для sing-box</value>
</data>
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
<value>Multi-server load balancing</value>
<data name="TbSettingsMux4SboxProtocol" xml:space="preserve">
<value>sing-box Mux Protocol</value>
</data>
<data name="menuProxiesDelaytest" xml:space="preserve">
<value>Тест задержки</value>
<data name="TbRoutingRuleProcess" xml:space="preserve">
<value>Full process name (Tun mode)</value>
</data>
<data name="TbReserved" xml:space="preserve">
<value>Reserved(2,3,4)</value>
<data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP or IP CIDR</value>
</data>
<data name="TbPrivateKey" xml:space="preserve">
<value>PrivateKey</value>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>Домен</value>
</data>
<data name="menuAddWireguardServer" xml:space="preserve">
<value>Добавить [WireGuard] сервер</value>
<data name="menuAddHysteria2Server" xml:space="preserve">
<value>Добавить [Hysteria2] сервер</value>
</data>
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
<value>Автоматическая регулировка ширины столбца</value>
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
<value>Hysteria Max bandwidth (Up/Dw)</value>
</data>
<data name="menuExport2ShareUrlBase64" xml:space="preserve">
<value>Export Base64-encoded Share Links to Clipboard</value>
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
<value>Использовать системные узлы</value>
</data>
<data name="TbSortingDelay" xml:space="preserve">
<value>Задержка</value>
</data>
<data name="TbSettingsEnableExInbound" xml:space="preserve">
<value>Enable additional Inbound</value>
</data>
<data name="LvPrevProfileTip" xml:space="preserve">
<value>Пожалуйста, убедитесь, что примечание существует и является уникальным.</value>
</data>
<data name="menuExport2ClientConfigClipboard" xml:space="preserve">
<value>Экспортировать выбранный сервер для полной конфигурации в буфер обмена</value>
</data>
<data name="LvNextProfile" xml:space="preserve">
<value>Next proxy remarks</value>
</data>
<data name="menuShowOrHideMainWindow" xml:space="preserve">
<value>Показать или скрыть главное окно</value>
</data>
<data name="LvPrevProfile" xml:space="preserve">
<value>Previous proxy remarks</value>
<data name="menuAddTuicServer" xml:space="preserve">
<value>Добавить [TUIC] сервер</value>
</data>
<data name="TbHeaderType8" xml:space="preserve">
<value>Контроль перегрузок</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>Исходящий DNS адрес</value>
<data name="LvPrevProfile" xml:space="preserve">
<value>Previous proxy remarks</value>
</data>
<data name="LvNextProfile" xml:space="preserve">
<value>Next proxy remarks</value>
</data>
<data name="LvPrevProfileTip" xml:space="preserve">
<value>Пожалуйста, убедитесь, что примечание существует и является уникальным.</value>
</data>
<data name="TbSettingsEnableExInbound" xml:space="preserve">
<value>Enable additional Inbound</value>
</data>
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
<value>Включить IPv6 адреса</value>
</data>
<data name="menuAddWireguardServer" xml:space="preserve">
<value>Добавить [WireGuard] сервер</value>
</data>
<data name="TbPrivateKey" xml:space="preserve">
<value>PrivateKey</value>
</data>
<data name="TbReserved" xml:space="preserve">
<value>Reserved(2,3,4)</value>
</data>
<data name="TbLocalAddress" xml:space="preserve">
<value>Адрес(Ipv4,Ipv6)</value>
</data>
<data name="TbPath7" xml:space="preserve">
<value>obfs password</value>
</data>
<data name="TbRuleMatchingTips" xml:space="preserve">
<value>(Domain or IP or ProcName) and Port and Protocol and InboundTag =&gt; OutboundTag</value>
</data>
<data name="TbAutoScrollToEnd" xml:space="preserve">
<value>Автоматическая прокрутка в конец</value>
</data>
<data name="TbSettingsSpeedPingTestUrl" xml:space="preserve">
<value>URL-адрес для проверки скорости пинга</value>
</data>
<data name="TbSettingsEnableUpdateSubOnlyRemarksExist" xml:space="preserve">
<value>Updating subscription, only determine remarks exists</value>
@@ -1119,23 +1122,41 @@
<data name="TransportRequestHostTip5" xml:space="preserve">
<value>*grpc Authority</value>
</data>
<data name="TbSortingDefault" xml:space="preserve">
<value>По умолчанию</value>
<data name="menuAddHttpServer" xml:space="preserve">
<value>Добавить [HTTP] сервер</value>
</data>
<data name="TbSortingChain" xml:space="preserve">
<value>Chain</value>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>Use Xray and enable non-Tun mode, which conflicts with the group previous proxy</value>
</data>
<data name="TbSorting" xml:space="preserve">
<value>Сортировка</value>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>Включить фрагмент</value>
</data>
<data name="menuOpenTheFileLocation" xml:space="preserve">
<value>Открыть место хранения</value>
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
<value>Включить файл кэша для sing-box (файлы наборов правил)</value>
</data>
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
<value>Пользовательский набор правил для sing-box</value>
</data>
<data name="NeedRebootTips" xml:space="preserve">
<value>Successful operation. Click the settings menu to reboot the app.</value>
</data>
<data name="LvCustomRulesetPath4Singbox" xml:space="preserve">
<value>Пользовательский набор правил для sing-box</value>
<data name="menuOpenTheFileLocation" xml:space="preserve">
<value>Открыть место хранения</value>
</data>
<data name="TbSorting" xml:space="preserve">
<value>Сортировка</value>
</data>
<data name="TbSortingChain" xml:space="preserve">
<value>Chain</value>
</data>
<data name="TbSortingDefault" xml:space="preserve">
<value>По умолчанию</value>
</data>
<data name="TbSortingDelay" xml:space="preserve">
<value>Задержка</value>
</data>
<data name="TbSortingDownSpeed" xml:space="preserve">
<value>Скорость загрузки</value>
</data>
<data name="TbSortingDownTraffic" xml:space="preserve">
<value>Download Traffic</value>
@@ -1155,9 +1176,6 @@
<data name="TbSortingType" xml:space="preserve">
<value>Тип</value>
</data>
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
<value>Включить файл кэша для sing-box (файлы наборов правил)</value>
</data>
<data name="TbSortingUpSpeed" xml:space="preserve">
<value>Скорость загрузки</value>
</data>
@@ -1188,158 +1206,134 @@
<data name="menuModeNothing" xml:space="preserve">
<value>Do not change</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>Включить фрагмент</value>
</data>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>Use Xray and enable non-Tun mode, which conflicts with the group previous proxy</value>
</data>
<data name="menuModeRule" xml:space="preserve">
<value>Правила</value>
</data>
<data name="menuAddHttpServer" xml:space="preserve">
<value>Добавить [HTTP] сервер</value>
<data name="menuProxiesDelaytest" xml:space="preserve">
<value>Тест задержки</value>
</data>
<data name="menuAddTuicServer" xml:space="preserve">
<value>Добавить [TUIC] сервер</value>
<data name="menuProxiesDelaytestPart" xml:space="preserve">
<value>Part Node Latency Test</value>
</data>
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
<value>Включить IPv6 адреса</value>
<data name="menuProxiesReload" xml:space="preserve">
<value>Обновить прокси</value>
</data>
<data name="menuProxiesSelectActivity" xml:space="preserve">
<value>Активировать узел (Enter)</value>
</data>
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Стратегия домена по умолчанию для исходящих</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>Основная ориентация макета (требуется перезагрузка)</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>Исходящий DNS адрес</value>
</data>
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
<value>Автоматическая регулировка ширины столбца</value>
</data>
<data name="menuExport2ShareUrlBase64" xml:space="preserve">
<value>Export Base64-encoded Share Links to Clipboard</value>
</data>
<data name="menuExport2ClientConfigClipboard" xml:space="preserve">
<value>Экспортировать выбранный сервер для полной конфигурации в буфер обмена</value>
</data>
<data name="menuShowOrHideMainWindow" xml:space="preserve">
<value>Показать или скрыть главное окно</value>
</data>
<data name="TbPreSocksPort4Sub" xml:space="preserve">
<value>Пользовательская конфигурация порта socks</value>
</data>
<data name="menuBackupAndRestore" xml:space="preserve">
<value>Резервное копирование и восстановление</value>
</data>
<data name="menuLocalBackup" xml:space="preserve">
<value>Сохранить в файл</value>
</data>
<data name="menuLocalRestore" xml:space="preserve">
<value>Восстановить из файла</value>
</data>
<data name="menuRemoteBackup" xml:space="preserve">
<value>Backup to remote (WebDAV)</value>
</data>
<data name="menuRemoteRestore" xml:space="preserve">
<value>Restore from remote (WebDAV)</value>
</data>
<data name="menuLocalBackupAndRestore" xml:space="preserve">
<value>Local</value>
</data>
<data name="menuRemoteBackupAndRestore" xml:space="preserve">
<value>Remote (WebDAV)</value>
</data>
<data name="LvWebDavUrl" xml:space="preserve">
<value>WebDav Url</value>
</data>
<data name="LvWebDavUserName" xml:space="preserve">
<value>WebDav User Name</value>
</data>
<data name="LvWebDavPassword" xml:space="preserve">
<value>WebDav Password</value>
</data>
<data name="LvWebDavCheck" xml:space="preserve">
<value>WebDav Check</value>
</data>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>Домен</value>
</data>
<data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP or IP CIDR</value>
</data>
<data name="TbRoutingRuleProcess" xml:space="preserve">
<value>Full process name (Tun mode)</value>
</data>
<data name="TbSettingsMux4SboxProtocol" xml:space="preserve">
<value>sing-box Mux Protocol</value>
<data name="LvWebDavDirName" xml:space="preserve">
<value>Имя удаленной папки (необязательно)</value>
</data>
<data name="LocalRestoreInvalidZipTips" xml:space="preserve">
<value>Неверный файл резервной копии</value>
</data>
<data name="TbdomainStrategy4Singbox" xml:space="preserve">
<value>Стратегия домена для sing-box</value>
</data>
<data name="ConnectionsHostFilterTitle" xml:space="preserve">
<value>Host filter</value>
</data>
<data name="TbSettingDnsImportDefConfig" xml:space="preserve">
<value>Нажмите, чтобы импортировать конфигурацию DNS по умолчанию</value>
</data>
<data name="TipActiveServer" xml:space="preserve">
<value>Active</value>
</data>
<data name="TbDnsSingboxObjectDoc" xml:space="preserve">
<value>Пожалуйста, заполните структуру DNS. Нажмите, чтобы просмотреть документ.</value>
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Источник geo файлов</value>
</data>
<data name="LvConvertTargetTip" xml:space="preserve">
<value>Если преобразование не требуется, оставьте поле пустым.</value>
</data>
<data name="LvConvertTarget" xml:space="preserve">
<value>Преобразовать тип цели</value>
</data>
<data name="SpeedDisplayText" xml:space="preserve">
<value>{0} : {1}/s↑ | {2}/s↓</value>
</data>
<data name="LvMoreUrl" xml:space="preserve">
<value>More URLs, separated by commas; Subscription conversion will be invalid</value>
</data>
<data name="MsgSkipSubscriptionUpdate" xml:space="preserve">
<value>Updates are not enabled, skip this subscription</value>
<data name="TbSettingsSrsFilesSource" xml:space="preserve">
<value>Источник sing-box srs файлов</value>
</data>
<data name="UpgradeAppNotExistTip" xml:space="preserve">
<value>Программы для обновления не существует</value>
</data>
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
<value>Источник правил маршрутизации</value>
</data>
<data name="menuRegionalPresets" xml:space="preserve">
<value>Региональные пресеты</value>
</data>
<data name="menuRegionalPresetsDefault" xml:space="preserve">
<value>По умолчанию (Китай)</value>
</data>
<data name="menuRegionalPresetsRussia" xml:space="preserve">
<value>Россия</value>
</data>
<data name="menuRegionalPresetsIran" xml:space="preserve">
<value>Иран</value>
</data>
<data name="TbSettingsChinaUserTip" xml:space="preserve">
<value>Используйте Настройки -&gt; Региональные пресеты вместо изменения этого поля</value>
</data>
<data name="menuAddServerViaImage" xml:space="preserve">
<value>Сканировать QR-код с изображения</value>
</data>
<data name="TipDisplayLog" xml:space="preserve">
<value>Please turn off when there is an abnormal disconnection</value>
</data>
<data name="SpeedtestingWait" xml:space="preserve">
<value>Ожидание тестирования (нажмите ESC для отмены)...</value>
</data>
<data name="TbSpiderX" xml:space="preserve">
<value>SpiderX</value>
</data>
<data name="TbShortId" xml:space="preserve">
<value>ShortId</value>
</data>
<data name="InvalidUrlTip" xml:space="preserve">
<value>Неверный адрес (Url)</value>
</data>
<data name="InsecureUrlProtocol" xml:space="preserve">
<value>Пожалуйста, не используйте небезопасный адрес подписки по протоколу HTTP.</value>
</data>
<data name="TbPublicKey" xml:space="preserve">
<value>PublicKey</value>
</data>
<data name="menuMoveTo" xml:space="preserve">
<value>Move up and down</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>Pac порт = +3; Xray API порт = +4; mihomo API порт = +5;</value>
</data>
<data name="TbSettingsCurrentFontFamilyLinuxTip" xml:space="preserve">
<value>Установите шрифт в систему и перезапустите настройки</value>
</data>
<data name="menuAddHysteria2Server" xml:space="preserve">
<value>Добавить [Hysteria2] сервер</value>
</data>
<data name="LvWebDavPassword" xml:space="preserve">
<value>WebDav Password</value>
</data>
<data name="LvWebDavDirName" xml:space="preserve">
<value>Имя удаленной папки (необязательно)</value>
</data>
<data name="TbSortingDownSpeed" xml:space="preserve">
<value>Скорость загрузки</value>
</data>
<data name="menuRemoteRestore" xml:space="preserve">
<value>Restore from remote (WebDAV)</value>
</data>
<data name="menuRemoteBackup" xml:space="preserve">
<value>Backup to remote (WebDAV)</value>
</data>
<data name="LvWebDavUserName" xml:space="preserve">
<value>WebDav User Name</value>
</data>
<data name="menuLocalRestore" xml:space="preserve">
<value>Восстановить из файла</value>
</data>
<data name="menuLocalBackup" xml:space="preserve">
<value>Сохранить в файл</value>
</data>
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
<value>Использовать системные узлы</value>
</data>
<data name="menuBackupAndRestore" xml:space="preserve">
<value>Резервное копирование и восстановление</value>
</data>
<data name="menuLocalBackupAndRestore" xml:space="preserve">
<value>Local</value>
</data>
<data name="menuExitTips" xml:space="preserve">
<value>Вы уверены, что хотите выйти?</value>
</data>
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
<value>Hysteria Max bandwidth (Up/Dw)</value>
</data>
<data name="LvWebDavUrl" xml:space="preserve">
<value>WebDav Url</value>
</data>
<data name="menuRemoteBackupAndRestore" xml:space="preserve">
<value>Remote (WebDAV)</value>
<data name="LvMemo" xml:space="preserve">
<value>Remarks Memo</value>
</data>
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
<value>System sudo password</value>
@@ -1401,4 +1395,22 @@
<data name="TbPorts7Tips" xml:space="preserve">
<value>Will cover the port, separate with commas (,)</value>
</data>
</root>
<data name="menuSetDefaultMultipleServerXray" xml:space="preserve">
<value>Мультисерверный Xray (множественный выбор)</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRandom" xml:space="preserve">
<value>Мультисерверный случайный</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRoundRobin" xml:space="preserve">
<value>Мультисерверный круговой</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastPing" xml:space="preserve">
<value>Мультисерверная минимальная задержка</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastLoad" xml:space="preserve">
<value>Мультисерверный наиболее стабильный</value>
</data>
<data name="menuSetDefaultMultipleServerSingBoxLeastPing" xml:space="preserve">
<value>Мультисерверная минимальная задержка sing-box (множественный выбор)</value>
</data>
</root>
@@ -1050,12 +1050,12 @@
<data name="TbRoutingRuleProcess" xml:space="preserve">
<value>进程名全称 (Tun 模式)</value>
</data>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>Domain</value>
</data>
<data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP 或 IP CIDR</value>
</data>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>Domain</value>
</data>
<data name="menuAddHysteria2Server" xml:space="preserve">
<value>添加 [Hysteria2] 服务器</value>
</data>
@@ -1122,12 +1122,12 @@
<data name="menuAddHttpServer" xml:space="preserve">
<value>添加 [HTTP] 服务器</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>启用分片(Fragment</value>
</data>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>使用 Xray 且非 Tun 模式启用,和分组前置代理冲突</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>启用分片(Fragment</value>
</data>
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
<value>启用 sing-box(规则集文件)的缓存文件</value>
</data>
@@ -1221,15 +1221,9 @@
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Outbound 默认解析策略</value>
</data>
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
<value>多服务器最低延迟 (多选)</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>主界面布局方向(需重启)</value>
</data>
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
<value>多服务器负载均衡 (多选)</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>Outbound 域名解析地址</value>
</data>
@@ -1269,17 +1263,17 @@
<data name="menuRemoteBackupAndRestore" xml:space="preserve">
<value>远程 (WebDAV)</value>
</data>
<data name="LvWebDavUrl" xml:space="preserve">
<value>WebDav 服务器地址</value>
</data>
<data name="LvWebDavUserName" xml:space="preserve">
<value>WebDav 账户</value>
</data>
<data name="LvWebDavCheck" xml:space="preserve">
<value>WebDav 可用检查</value>
</data>
<data name="LvWebDavPassword" xml:space="preserve">
<value>WebDav 密码</value>
</data>
<data name="LvWebDavUrl" xml:space="preserve">
<value>WebDav 服务器地址</value>
<data name="LvWebDavCheck" xml:space="preserve">
<value>WebDav 可用检查</value>
</data>
<data name="LvWebDavDirName" xml:space="preserve">
<value>远程文件夹名称 (可选)</value>
@@ -1296,18 +1290,15 @@
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo 文件来源 (可选)</value>
</data>
<data name="UpgradeAppNotExistTip" xml:space="preserve">
<value>升级工具 App 不存在</value>
</data>
<data name="TbSettingsSrsFilesSource" xml:space="preserve">
<value>sing-box ruleset 文件来源 (可选)</value>
</data>
<data name="UpgradeAppNotExistTip" xml:space="preserve">
<value>升级工具 App 不存在</value>
</data>
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
<value>路由规则集来源 (可选)</value>
</data>
<data name="TbSettingsChinaUserTip" xml:space="preserve">
<value>中国区域用户可忽略此项</value>
</data>
<data name="menuRegionalPresets" xml:space="preserve">
<value>区域预置设置</value>
</data>
@@ -1320,6 +1311,9 @@
<data name="menuRegionalPresetsIran" xml:space="preserve">
<value>伊朗</value>
</data>
<data name="TbSettingsChinaUserTip" xml:space="preserve">
<value>中国区域用户可忽略此项</value>
</data>
<data name="menuAddServerViaImage" xml:space="preserve">
<value>扫描图片中的二维码</value>
</data>
@@ -1398,4 +1392,22 @@
<data name="TbPorts7Tips" xml:space="preserve">
<value>会覆盖端口,多组时用逗号 (,) 隔开</value>
</data>
</root>
<data name="menuSetDefaultMultipleServerXray" xml:space="preserve">
<value>多服务器 Xray (多选)</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRandom" xml:space="preserve">
<value>多服务器随机</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRoundRobin" xml:space="preserve">
<value>多服务器轮询</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastPing" xml:space="preserve">
<value>多服务器最低延迟</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastLoad" xml:space="preserve">
<value>多服务器最稳定</value>
</data>
<data name="menuSetDefaultMultipleServerSingBoxLeastPing" xml:space="preserve">
<value>多服务器最低延迟 sing-box (多选)</value>
</data>
</root>
+149 -138
View File
@@ -663,7 +663,6 @@
<data name="TipPreSocksPort" xml:space="preserve">
<value>*自訂設定的 Socks 埠值,可不設定;當設定此值後,將使用 Xray/sing-box (Tun) 額外啟動一個前置 Socks 服務,提供分流和速度顯示等功能</value>
</data>
<!--********************************************-->
<data name="TbBrowse" xml:space="preserve">
<value>瀏覽</value>
</data>
@@ -1051,15 +1050,27 @@
<data name="TbRoutingRuleProcess" xml:space="preserve">
<value>行程名全稱 (Tun 模式)</value>
</data>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>Domain</value>
</data>
<data name="TbRoutingRuleIP" xml:space="preserve">
<value>IP 或 IP CIDR</value>
</data>
<data name="TbRoutingRuleDomain" xml:space="preserve">
<value>Domain</value>
</data>
<data name="menuAddHysteria2Server" xml:space="preserve">
<value>添加 [Hysteria2] 伺服器</value>
</data>
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
<value>Hysteria 最大頻寬 (Up/Dw)</value>
</data>
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
<value>使用系統 hosts</value>
</data>
<data name="menuAddTuicServer" xml:space="preserve">
<value>新增 [TUIC] 伺服器</value>
</data>
<data name="TbHeaderType8" xml:space="preserve">
<value>擁塞控制算法</value>
</data>
<data name="LvPrevProfile" xml:space="preserve">
<value>前置代理別名</value>
</data>
@@ -1075,6 +1086,21 @@
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
<value>啟用 IPv6</value>
</data>
<data name="menuAddWireguardServer" xml:space="preserve">
<value>添加 [WireGuard] 伺服器</value>
</data>
<data name="TbPrivateKey" xml:space="preserve">
<value>PrivateKey</value>
</data>
<data name="TbReserved" xml:space="preserve">
<value>Reserved (2,3,4)</value>
</data>
<data name="TbLocalAddress" xml:space="preserve">
<value>Address (Ipv4,Ipv6)</value>
</data>
<data name="TbPath7" xml:space="preserve">
<value>混淆密碼 (obfs password)</value>
</data>
<data name="TbRuleMatchingTips" xml:space="preserve">
<value>(Domain 或 IP 或 行程名) 与 Port 与 Protocol 与 InboundTag =&gt; OutboundTag</value>
</data>
@@ -1096,12 +1122,12 @@
<data name="menuAddHttpServer" xml:space="preserve">
<value>新增 [HTTP] 伺服器</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>啟用分片(Fragment</value>
</data>
<data name="TbSettingsEnableFragmentTips" xml:space="preserve">
<value>使用 Xray 且非 Tun 模式啟用,和分組前置代理衝突</value>
</data>
<data name="TbSettingsEnableFragment" xml:space="preserve">
<value>啟用分片(Fragment</value>
</data>
<data name="TbSettingsEnableCacheFile4Sbox" xml:space="preserve">
<value>啟用 sing-box(規則集檔案)的快取檔案</value>
</data>
@@ -1114,6 +1140,93 @@
<data name="menuOpenTheFileLocation" xml:space="preserve">
<value>打開儲存所在的位置</value>
</data>
<data name="TbSorting" xml:space="preserve">
<value>排序</value>
</data>
<data name="TbSortingChain" xml:space="preserve">
<value>路由鏈</value>
</data>
<data name="TbSortingDefault" xml:space="preserve">
<value>預設</value>
</data>
<data name="TbSortingDelay" xml:space="preserve">
<value>延遲</value>
</data>
<data name="TbSortingDownSpeed" xml:space="preserve">
<value>下載速度</value>
</data>
<data name="TbSortingDownTraffic" xml:space="preserve">
<value>下載流量</value>
</data>
<data name="TbSortingHost" xml:space="preserve">
<value>主機</value>
</data>
<data name="TbSortingName" xml:space="preserve">
<value>名稱</value>
</data>
<data name="TbSortingNetwork" xml:space="preserve">
<value>網路</value>
</data>
<data name="TbSortingTime" xml:space="preserve">
<value>時間</value>
</data>
<data name="TbSortingType" xml:space="preserve">
<value>類型</value>
</data>
<data name="TbSortingUpSpeed" xml:space="preserve">
<value>上傳速度</value>
</data>
<data name="TbSortingUpTraffic" xml:space="preserve">
<value>上傳流量</value>
</data>
<data name="TbConnections" xml:space="preserve">
<value>目前連線</value>
</data>
<data name="menuConnectionClose" xml:space="preserve">
<value>關閉連線</value>
</data>
<data name="menuConnectionCloseAll" xml:space="preserve">
<value>關閉所有連線</value>
</data>
<data name="TbProxies" xml:space="preserve">
<value>目前代理</value>
</data>
<data name="menuRulemode" xml:space="preserve">
<value>規則模式</value>
</data>
<data name="menuModeDirect" xml:space="preserve">
<value>直連</value>
</data>
<data name="menuModeGlobal" xml:space="preserve">
<value>全局</value>
</data>
<data name="menuModeNothing" xml:space="preserve">
<value>随原配置</value>
</data>
<data name="menuModeRule" xml:space="preserve">
<value>規則</value>
</data>
<data name="menuProxiesDelaytest" xml:space="preserve">
<value>延遲測試</value>
</data>
<data name="menuProxiesDelaytestPart" xml:space="preserve">
<value>目前部分節點延遲測試</value>
</data>
<data name="menuProxiesReload" xml:space="preserve">
<value>重新整理</value>
</data>
<data name="menuProxiesSelectActivity" xml:space="preserve">
<value>設為活動節點 (Enter)</value>
</data>
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Outbound 預設解析策略</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>主界面佈局方向 (需重啟)</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>Outbound 域名解析位址</value>
</data>
<data name="menuProfileAutofitColumnWidth" xml:space="preserve">
<value>自動調整列寬</value>
</data>
@@ -1150,17 +1263,17 @@
<data name="menuRemoteBackupAndRestore" xml:space="preserve">
<value>遠端 (WebDAV)</value>
</data>
<data name="LvWebDavUrl" xml:space="preserve">
<value>WebDav 伺服器位址</value>
</data>
<data name="LvWebDavUserName" xml:space="preserve">
<value>WebDav 賬戶</value>
</data>
<data name="LvWebDavCheck" xml:space="preserve">
<value>WebDav 可用檢查</value>
</data>
<data name="LvWebDavPassword" xml:space="preserve">
<value>WebDav 密碼</value>
</data>
<data name="LvWebDavUrl" xml:space="preserve">
<value>WebDav 伺服器位址</value>
<data name="LvWebDavCheck" xml:space="preserve">
<value>WebDav 可用檢查</value>
</data>
<data name="LvWebDavDirName" xml:space="preserve">
<value>遠端資料夾名稱 (可選)</value>
@@ -1177,18 +1290,15 @@
<data name="TbSettingsGeoFilesSource" xml:space="preserve">
<value>Geo 檔案來源 (可選)</value>
</data>
<data name="UpgradeAppNotExistTip" xml:space="preserve">
<value>升級工具 App 不存在</value>
</data>
<data name="TbSettingsSrsFilesSource" xml:space="preserve">
<value>sing-box ruleset 檔案來源 (可選)</value>
</data>
<data name="UpgradeAppNotExistTip" xml:space="preserve">
<value>升級工具 App 不存在</value>
</data>
<data name="TbSettingsRoutingRulesSource" xml:space="preserve">
<value>路由規則集來源 (可選)</value>
</data>
<data name="TbSettingsChinaUserTip" xml:space="preserve">
<value>中國區域用戶可忽略此項</value>
</data>
<data name="menuRegionalPresets" xml:space="preserve">
<value>區域預置設定</value>
</data>
@@ -1201,6 +1311,9 @@
<data name="menuRegionalPresetsIran" xml:space="preserve">
<value>伊朗</value>
</data>
<data name="TbSettingsChinaUserTip" xml:space="preserve">
<value>中國區域用戶可忽略此項</value>
</data>
<data name="menuAddServerViaImage" xml:space="preserve">
<value>掃描圖片中的二維碼</value>
</data>
@@ -1219,126 +1332,6 @@
<data name="LvMemo" xml:space="preserve">
<value>備註備忘</value>
</data>
<data name="TbHeaderType8" xml:space="preserve">
<value>擁塞控制算法</value>
</data>
<data name="menuProxiesSelectActivity" xml:space="preserve">
<value>設為活動節點 (Enter)</value>
</data>
<data name="menuProxiesReload" xml:space="preserve">
<value>重新整理</value>
</data>
<data name="TbSorting" xml:space="preserve">
<value>排序</value>
</data>
<data name="menuProxiesDelaytest" xml:space="preserve">
<value>延遲測試</value>
</data>
<data name="menuModeRule" xml:space="preserve">
<value>規則</value>
</data>
<data name="menuModeNothing" xml:space="preserve">
<value>随原配置</value>
</data>
<data name="menuModeGlobal" xml:space="preserve">
<value>全局</value>
</data>
<data name="menuModeDirect" xml:space="preserve">
<value>直連</value>
</data>
<data name="menuRulemode" xml:space="preserve">
<value>規則模式</value>
</data>
<data name="TbProxies" xml:space="preserve">
<value>目前代理</value>
</data>
<data name="menuConnectionCloseAll" xml:space="preserve">
<value>關閉所有連線</value>
</data>
<data name="TbSettingsDomainStrategy4Out" xml:space="preserve">
<value>Outbound 預設解析策略</value>
</data>
<data name="menuConnectionClose" xml:space="preserve">
<value>關閉連線</value>
</data>
<data name="TbSortingUpTraffic" xml:space="preserve">
<value>上傳流量</value>
</data>
<data name="TbSortingUpSpeed" xml:space="preserve">
<value>上傳速度</value>
</data>
<data name="TbSortingType" xml:space="preserve">
<value>類型</value>
</data>
<data name="TbSortingTime" xml:space="preserve">
<value>時間</value>
</data>
<data name="TbSortingNetwork" xml:space="preserve">
<value>網路</value>
</data>
<data name="TbSortingName" xml:space="preserve">
<value>名稱</value>
</data>
<data name="TbSortingHost" xml:space="preserve">
<value>主機</value>
</data>
<data name="TbSortingDownTraffic" xml:space="preserve">
<value>下載流量</value>
</data>
<data name="TbSortingDownSpeed" xml:space="preserve">
<value>下載速度</value>
</data>
<data name="TbSortingDelay" xml:space="preserve">
<value>延遲</value>
</data>
<data name="TbSortingDefault" xml:space="preserve">
<value>預設</value>
</data>
<data name="TbConnections" xml:space="preserve">
<value>目前連線</value>
</data>
<data name="menuSetDefaultMultipleServer" xml:space="preserve">
<value>多伺服器最低延遲 (多選)</value>
</data>
<data name="menuProxiesDelaytestPart" xml:space="preserve">
<value>目前部分節點延遲測試</value>
</data>
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
<value>多伺服器負載平衡 (多選)</value>
</data>
<data name="menuAddHysteria2Server" xml:space="preserve">
<value>添加 [Hysteria2] 伺服器</value>
</data>
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
<value>Hysteria 最大頻寬 (Up/Dw)</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>主界面佈局方向 (需重啟)</value>
</data>
<data name="menuAddWireguardServer" xml:space="preserve">
<value>添加 [WireGuard] 伺服器</value>
</data>
<data name="TbPrivateKey" xml:space="preserve">
<value>PrivateKey</value>
</data>
<data name="TbReserved" xml:space="preserve">
<value>Reserved (2,3,4)</value>
</data>
<data name="TbLocalAddress" xml:space="preserve">
<value>Address (Ipv4,Ipv6)</value>
</data>
<data name="TbSettingsUseSystemHosts" xml:space="preserve">
<value>使用系統 hosts</value>
</data>
<data name="TbSortingChain" xml:space="preserve">
<value>路由鏈</value>
</data>
<data name="TbSettingsDomainDNSAddress" xml:space="preserve">
<value>Outbound 域名解析位址</value>
</data>
<data name="TbPath7" xml:space="preserve">
<value>混淆密碼 (obfs password)</value>
</data>
<data name="TbSettingsLinuxSudoPassword" xml:space="preserve">
<value>系統的 sudo 密碼</value>
</data>
@@ -1399,4 +1392,22 @@
<data name="TbPorts7Tips" xml:space="preserve">
<value>會覆蓋端口,多組時用逗號 (,) 隔開</value>
</data>
<data name="menuSetDefaultMultipleServerXray" xml:space="preserve">
<value>多伺服器 Xray (多選)</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRandom" xml:space="preserve">
<value>多伺服器隨機</value>
</data>
<data name="menuSetDefaultMultipleServerXrayRoundRobin" xml:space="preserve">
<value>多伺服器輪詢</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastPing" xml:space="preserve">
<value>多伺服器最低延遲</value>
</data>
<data name="menuSetDefaultMultipleServerXrayLeastLoad" xml:space="preserve">
<value>多伺服器最穩定</value>
</data>
<data name="menuSetDefaultMultipleServerSingBoxLeastPing" xml:space="preserve">
<value>多伺服器最低延遲 sing-box (多選)</value>
</data>
</root>
@@ -77,7 +77,7 @@ namespace ServiceLib.Services.CoreConfig
}
}
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, EMultipleLoad multipleLoad)
{
var ret = new RetResult();
@@ -164,13 +164,9 @@ namespace ServiceLib.Services.CoreConfig
}
//add balancers
var balancer = new BalancersItem4Ray
{
selector = [Global.ProxyTag],
strategy = new() { type = "roundRobin" },
tag = $"{Global.ProxyTag}-round",
};
v2rayConfig.routing.balancers = [balancer];
await GenBalancer(v2rayConfig, multipleLoad);
var balancer = v2rayConfig.routing.balancers.First();
//add rule
var rules = v2rayConfig.routing.rules.Where(t => t.outboundTag == Global.ProxyTag).ToList();
@@ -1316,6 +1312,36 @@ namespace ServiceLib.Services.CoreConfig
return 0;
}
private async Task<int> GenBalancer(V2rayConfig v2rayConfig, EMultipleLoad multipleLoad)
{
if (multipleLoad is EMultipleLoad.LeastLoad or EMultipleLoad.LeastPing)
{
var observatory = new Observatory4Ray
{
subjectSelector = [Global.ProxyTag],
probeUrl = AppHandler.Instance.Config.SpeedTestItem.SpeedPingTestUrl,
probeInterval = "3m"
};
v2rayConfig.observatory = observatory;
}
var strategyType = multipleLoad switch
{
EMultipleLoad.Random => "random",
EMultipleLoad.RoundRobin => "roundRobin",
EMultipleLoad.LeastPing => "leastPing",
EMultipleLoad.LeastLoad => "leastLoad",
_ => "roundRobin",
};
var balancer = new BalancersItem4Ray
{
selector = [Global.ProxyTag],
strategy = new() { type = strategyType },
tag = $"{Global.ProxyTag}-round",
};
v2rayConfig.routing.balancers = [balancer];
return await Task.FromResult(0);
}
#endregion private gen function
}
}
@@ -62,8 +62,11 @@ namespace ServiceLib.ViewModels
public ReactiveCommand<Unit, Unit> CopyServerCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultServerCmd { get; }
public ReactiveCommand<Unit, Unit> ShareServerCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultMultipleServerCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultLoadBalanceServerCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultMultipleServerXrayRandomCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultMultipleServerXrayRoundRobinCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultMultipleServerXrayLeastPingCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultMultipleServerXrayLeastLoadCmd { get; }
public ReactiveCommand<Unit, Unit> SetDefaultMultipleServerSingBoxLeastPingCmd { get; }
//servers move
public ReactiveCommand<Unit, Unit> MoveTopCmd { get; }
@@ -150,13 +153,25 @@ namespace ServiceLib.ViewModels
{
await ShareServerAsync();
}, canEditRemove);
SetDefaultMultipleServerCmd = ReactiveCommand.CreateFromTask(async () =>
SetDefaultMultipleServerXrayRandomCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SetDefaultMultipleServer(ECoreType.sing_box);
await SetDefaultMultipleServer(ECoreType.Xray, EMultipleLoad.Random);
}, canEditRemove);
SetDefaultLoadBalanceServerCmd = ReactiveCommand.CreateFromTask(async () =>
SetDefaultMultipleServerXrayRoundRobinCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SetDefaultMultipleServer(ECoreType.Xray);
await SetDefaultMultipleServer(ECoreType.Xray, EMultipleLoad.RoundRobin);
}, canEditRemove);
SetDefaultMultipleServerXrayLeastPingCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SetDefaultMultipleServer(ECoreType.Xray, EMultipleLoad.LeastPing);
}, canEditRemove);
SetDefaultMultipleServerXrayLeastLoadCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SetDefaultMultipleServer(ECoreType.Xray, EMultipleLoad.LeastLoad);
}, canEditRemove);
SetDefaultMultipleServerSingBoxLeastPingCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SetDefaultMultipleServer(ECoreType.sing_box, EMultipleLoad.LeastPing);
}, canEditRemove);
//servers move
@@ -621,7 +636,7 @@ namespace ServiceLib.ViewModels
await _updateView?.Invoke(EViewAction.ShareServer, url);
}
private async Task SetDefaultMultipleServer(ECoreType coreType)
private async Task SetDefaultMultipleServer(ECoreType coreType, EMultipleLoad multipleLoad)
{
var lstSelected = await GetProfileItems(true);
if (lstSelected == null)
@@ -629,7 +644,7 @@ namespace ServiceLib.ViewModels
return;
}
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelected, coreType);
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelected, coreType, multipleLoad);
if (ret.Success != true)
{
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
@@ -141,7 +141,7 @@ namespace ServiceLib.ViewModels
{
if (blNew)
{
_rules.Add(item);
_rules.Insert(0, item);
}
RefreshRulesItems();
}
@@ -7,10 +7,19 @@
<Style Selector="DataGrid">
<Setter Property="RowHeight" Value="24" />
<Setter Property="ScrollViewer.AllowAutoHide" Value="False" />
</Style>
<Style Selector="PathIcon">
<Setter Property="Width" Value="16" />
<Setter Property="Height" Value="16" />
</Style>
<Style Selector="TextBox">
<Setter Property="ScrollViewer.AllowAutoHide" Value="False" />
</Style>
<Style Selector="ScrollViewer">
<Setter Property="AllowAutoHide" Value="False" />
</Style>
</Styles>
@@ -81,11 +81,11 @@
BorderThickness="1"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
Classes.InsetContent="True"
GridLinesVisibility="All"
HeadersVisibility="All"
IsReadOnly="True"
ItemsSource="{Binding ProfileItems}"
ScrollViewer.AllowAutoHide="False">
ItemsSource="{Binding ProfileItems}">
<DataGrid.KeyBindings>
<KeyBinding Command="{Binding Export2ShareUrlCmd}" Gesture="Ctrl+C" />
<KeyBinding Command="{Binding SetDefaultServerCmd}" Gesture="Enter" />
@@ -99,8 +99,13 @@
<MenuItem x:Name="menuCopyServer" Header="{x:Static resx:ResUI.menuCopyServer}" />
<MenuItem x:Name="menuShareServer" Header="{x:Static resx:ResUI.menuShareServer}" />
<Separator />
<MenuItem x:Name="menuSetDefaultMultipleServer" Header="{x:Static resx:ResUI.menuSetDefaultMultipleServer}" />
<MenuItem x:Name="menuSetDefaultLoadBalanceServer" Header="{x:Static resx:ResUI.menuSetDefaultLoadBalanceServer}" />
<MenuItem Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXray}">
<MenuItem x:Name="menuSetDefaultMultipleServerXrayRandom" Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXrayRandom}" />
<MenuItem x:Name="menuSetDefaultMultipleServerXrayRoundRobin" Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXrayRoundRobin}" />
<MenuItem x:Name="menuSetDefaultMultipleServerXrayLeastPing" Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXrayLeastPing}" />
<MenuItem x:Name="menuSetDefaultMultipleServerXrayLeastLoad" Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXrayLeastLoad}" />
</MenuItem>
<MenuItem x:Name="menuSetDefaultMultipleServerSingBoxLeastPing" Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerSingBoxLeastPing}" />
<Separator />
<MenuItem x:Name="menuMixedTestServer" Header="{x:Static resx:ResUI.menuMixedTestServer}" />
<MenuItem x:Name="menuTcpingServer" Header="{x:Static resx:ResUI.menuTcpingServer}" />
@@ -67,8 +67,11 @@ namespace v2rayN.Desktop.Views
this.BindCommand(ViewModel, vm => vm.CopyServerCmd, v => v.menuCopyServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultServerCmd, v => v.menuSetDefaultServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ShareServerCmd, v => v.menuShareServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerCmd, v => v.menuSetDefaultMultipleServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultLoadBalanceServerCmd, v => v.menuSetDefaultLoadBalanceServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerXrayRandomCmd, v => v.menuSetDefaultMultipleServerXrayRandom).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerXrayRoundRobinCmd, v => v.menuSetDefaultMultipleServerXrayRoundRobin).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerXrayLeastPingCmd, v => v.menuSetDefaultMultipleServerXrayLeastPing).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerXrayLeastLoadCmd, v => v.menuSetDefaultMultipleServerXrayLeastLoad).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerSingBoxLeastPingCmd, v => v.menuSetDefaultMultipleServerSingBoxLeastPing).DisposeWith(disposables);
//servers move
//this.OneWayBind(ViewModel, vm => vm.SubItems, v => v.cmbMoveToGroup.ItemsSource).DisposeWith(disposables);
+21
View File
@@ -13,6 +13,27 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AmazTool", "AmazTool\AmazTo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GlobalHotKeys", "GlobalHotKeys\src\GlobalHotKeys\GlobalHotKeys.csproj", "{CB3DE54F-3A26-AE02-1299-311132C32156}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution Files", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
Directory.Packages.props = Directory.Packages.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub Action", "GitHub Action", "{1EACFDC8-ADD8-4F29-AF60-92AA55D59908}"
ProjectSection(SolutionItems) = preProject
..\.github\workflows\build-all.yml = ..\.github\workflows\build-all.yml
..\.github\workflows\build-linux.yml = ..\.github\workflows\build-linux.yml
..\.github\workflows\build-osx.yml = ..\.github\workflows\build-osx.yml
..\.github\workflows\build-windows-desktop.yml = ..\.github\workflows\build-windows-desktop.yml
..\.github\workflows\build-windows.yml = ..\.github\workflows\build-windows.yml
..\package-appimage.sh = ..\package-appimage.sh
..\package-debian.sh = ..\package-debian.sh
..\package-osx.sh = ..\package-osx.sh
..\package-release-zip.sh = ..\package-release-zip.sh
..\pkg2appimage.yml = ..\pkg2appimage.yml
..\.github\workflows\winget-publish.yml = ..\.github\workflows\winget-publish.yml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+20 -7
View File
@@ -120,15 +120,28 @@
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuShareServer}" />
<Separator />
<MenuItem Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXray}">
<MenuItem
x:Name="menuSetDefaultMultipleServerXrayRandom"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXrayRandom}" />
<MenuItem
x:Name="menuSetDefaultMultipleServerXrayRoundRobin"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXrayRoundRobin}" />
<MenuItem
x:Name="menuSetDefaultMultipleServerXrayLeastPing"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXrayLeastPing}" />
<MenuItem
x:Name="menuSetDefaultMultipleServerXrayLeastLoad"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerXrayLeastLoad}" />
</MenuItem>
<MenuItem
x:Name="menuSetDefaultMultipleServer"
x:Name="menuSetDefaultMultipleServerSingBoxLeastPing"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSetDefaultMultipleServer}" />
<MenuItem
x:Name="menuSetDefaultLoadBalanceServer"
Height="{StaticResource MenuItemHeight}"
Header="{x:Static resx:ResUI.menuSetDefaultLoadBalanceServer}" />
Header="{x:Static resx:ResUI.menuSetDefaultMultipleServerSingBoxLeastPing}" />
<Separator />
<MenuItem
x:Name="menuMixedTestServer"
@@ -61,8 +61,11 @@ namespace v2rayN.Views
this.BindCommand(ViewModel, vm => vm.CopyServerCmd, v => v.menuCopyServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultServerCmd, v => v.menuSetDefaultServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ShareServerCmd, v => v.menuShareServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerCmd, v => v.menuSetDefaultMultipleServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultLoadBalanceServerCmd, v => v.menuSetDefaultLoadBalanceServer).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerXrayRandomCmd, v => v.menuSetDefaultMultipleServerXrayRandom).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerXrayRoundRobinCmd, v => v.menuSetDefaultMultipleServerXrayRoundRobin).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerXrayLeastPingCmd, v => v.menuSetDefaultMultipleServerXrayLeastPing).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerXrayLeastLoadCmd, v => v.menuSetDefaultMultipleServerXrayLeastLoad).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SetDefaultMultipleServerSingBoxLeastPingCmd, v => v.menuSetDefaultMultipleServerSingBoxLeastPing).DisposeWith(disposables);
//servers move
this.OneWayBind(ViewModel, vm => vm.SubItems, v => v.cmbMoveToGroup.ItemsSource).DisposeWith(disposables);
+1 -1
View File
@@ -13,4 +13,4 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Validate Fastlane Supply Metadata
uses: ashutoshgngwr/validate-fastlane-supply-metadata@v2.0.0
uses: ashutoshgngwr/validate-fastlane-supply-metadata@v2.1.0
+1 -1
View File
@@ -21,7 +21,7 @@ A V2Ray client for Android, support [Xray core](https://github.com/XTLS/Xray-cor
#### Geoip and Geosite
- geoip.dat and geosite.dat files are in `Android/data/com.v2ray.ang/files/assets` (path may differ on some Android device)
- download feature will get enhanced version in this [repo](https://github.com/Loyalsoldier/v2ray-rules-dat) (Note it need a working proxy)
- latest official [domain list](https://github.com/v2fly/domain-list-community) and [ip list](https://github.com/v2fly/geoip) can be imported manually
- latest official [domain list](https://github.com/Loyalsoldier/v2ray-rules-dat) and [ip list](https://github.com/Loyalsoldier/geoip) can be imported manually
- possible to use third party dat file in the same folder, like [h2y](https://guide.v2fly.org/routing/sitedata.html#%E5%A4%96%E7%BD%AE%E7%9A%84%E5%9F%9F%E5%90%8D%E6%96%87%E4%BB%B6)
### More in our [wiki](https://github.com/2dust/v2rayNG/wiki)
@@ -8,6 +8,7 @@ enum class Language(val code: String) {
VIETNAMESE("vi"),
RUSSIAN("ru"),
PERSIAN("fa"),
ARABIC("ar"),
BANGLA("bn"),
BAKHTIARI("bqi-rIR");
@@ -22,7 +22,7 @@ data class V2rayConfig(
var policy: PolicyBean?,
val inbounds: ArrayList<InboundBean>,
var outbounds: ArrayList<OutboundBean>,
var dns: DnsBean,
var dns: DnsBean? = null,
val routing: RoutingBean,
val api: Any? = null,
val transport: Any? = null,
@@ -343,6 +343,7 @@ object SettingsManager {
Language.VIETNAMESE -> Locale("vi")
Language.RUSSIAN -> Locale("ru")
Language.PERSIAN -> Locale("fa")
Language.ARABIC -> Locale("ar")
Language.BANGLA -> Locale("bn")
Language.BAKHTIARI -> Locale("bqi", "IR")
}
@@ -52,6 +52,7 @@ import com.v2ray.ang.util.JsonUtil
import com.v2ray.ang.util.Utils
object V2rayConfigManager {
private var initConfigCache: String? = null
/**
* Retrieves the V2ray configuration for the given GUID.
@@ -63,16 +64,11 @@ object V2rayConfigManager {
fun getV2rayConfig(context: Context, guid: String): ConfigResult {
try {
val config = MmkvManager.decodeServerConfig(guid) ?: return ConfigResult(false)
if (config.configType == EConfigType.CUSTOM) {
val raw = MmkvManager.decodeServerRaw(guid) ?: return ConfigResult(false)
val domainPort = config.getServerAddressAndPort()
return ConfigResult(true, guid, raw, domainPort)
return if (config.configType == EConfigType.CUSTOM) {
getV2rayCustomConfig(guid, config)
} else {
getV2rayNormalConfig(context, guid, config)
}
val result = getV2rayNonCustomConfig(context, config)
//Log.d(ANG_PACKAGE, result.content)
result.guid = guid
return result
} catch (e: Exception) {
e.printStackTrace()
return ConfigResult(false)
@@ -80,13 +76,48 @@ object V2rayConfigManager {
}
/**
* Retrieves the non-custom V2ray configuration.
* Retrieves the speedtest V2ray configuration for the given GUID.
*
* @param context The context in which the function is called.
* @param context The context of the caller.
* @param guid The unique identifier for the V2ray configuration.
* @return A ConfigResult object containing the configuration details or indicating failure.
*/
fun getV2rayConfig4Speedtest(context: Context, guid: String): ConfigResult {
try {
val config = MmkvManager.decodeServerConfig(guid) ?: return ConfigResult(false)
return if (config.configType == EConfigType.CUSTOM) {
getV2rayCustomConfig(guid, config)
} else {
getV2rayNormalConfig4Speedtest(context, guid, config)
}
} catch (e: Exception) {
e.printStackTrace()
return ConfigResult(false)
}
}
/**
* Retrieves the custom V2ray configuration.
*
* @param guid The unique identifier for the V2ray configuration.
* @param config The profile item containing the configuration details.
* @return A ConfigResult object containing the result of the configuration retrieval.
*/
private fun getV2rayNonCustomConfig(context: Context, config: ProfileItem): ConfigResult {
private fun getV2rayCustomConfig(guid: String, config: ProfileItem): ConfigResult {
val raw = MmkvManager.decodeServerRaw(guid) ?: return ConfigResult(false)
val domainPort = config.getServerAddressAndPort()
return ConfigResult(true, guid, raw, domainPort)
}
/**
* Retrieves the normal V2ray configuration.
*
* @param context The context in which the function is called.
* @param guid The unique identifier for the V2ray configuration.
* @param config The profile item containing the configuration details.
* @return A ConfigResult object containing the result of the configuration retrieval.
*/
private fun getV2rayNormalConfig(context: Context, guid: String, config: ProfileItem): ConfigResult {
val result = ConfigResult(false)
val address = config.server ?: return result
@@ -97,13 +128,8 @@ object V2rayConfigManager {
}
}
val assets = Utils.readTextFromAssets(context, "v2ray_config.json")
if (TextUtils.isEmpty(assets)) {
return result
}
val v2rayConfig = JsonUtil.fromJson(assets, V2rayConfig::class.java) ?: return result
v2rayConfig.log.loglevel =
MmkvManager.decodeSettingsString(AppConfig.PREF_LOGLEVEL) ?: "warning"
val v2rayConfig = initV2rayConfig(context) ?: return result
v2rayConfig.log.loglevel = MmkvManager.decodeSettingsString(AppConfig.PREF_LOGLEVEL) ?: "warning"
v2rayConfig.remarks = config.remarks
inbounds(v2rayConfig)
@@ -129,9 +155,75 @@ object V2rayConfigManager {
result.status = true
result.content = v2rayConfig.toPrettyPrinting()
result.domainPort = if (retMore.first) retMore.second else retOut.second
result.guid = guid
return result
}
/**
* Retrieves the normal V2ray configuration for speedtest.
*
* @param context The context in which the function is called.
* @param guid The unique identifier for the V2ray configuration.
* @param config The profile item containing the configuration details.
* @return A ConfigResult object containing the result of the configuration retrieval.
*/
private fun getV2rayNormalConfig4Speedtest(context: Context, guid: String, config: ProfileItem): ConfigResult {
val result = ConfigResult(false)
val address = config.server ?: return result
if (!Utils.isIpAddress(address)) {
if (!Utils.isValidUrl(address)) {
Log.d(ANG_PACKAGE, "$address is an invalid ip or domain")
return result
}
}
val v2rayConfig = initV2rayConfig(context) ?: return result
val isPlugin = config.configType == EConfigType.HYSTERIA2
val retOut = outbounds(v2rayConfig, config, isPlugin) ?: return result
val retMore = moreOutbounds(v2rayConfig, config.subscriptionId, isPlugin)
v2rayConfig.log.loglevel = MmkvManager.decodeSettingsString(AppConfig.PREF_LOGLEVEL) ?: "warning"
v2rayConfig.inbounds.clear()
v2rayConfig.routing.rules.clear()
v2rayConfig.dns = null
v2rayConfig.fakedns = null
v2rayConfig.stats = null
v2rayConfig.policy = null
v2rayConfig.outbounds.forEach { key ->
key.mux = null
}
result.status = true
result.content = v2rayConfig.toPrettyPrinting()
result.domainPort = if (retMore.first) retMore.second else retOut.second
result.guid = guid
return result
}
/**
* Initializes V2ray configuration.
*
* This function loads the V2ray configuration from assets or from a cached value.
* It first attempts to use the cached configuration if available, otherwise reads
* the configuration from the "v2ray_config.json" asset file.
*
* @param context Android context used to access application assets
* @return V2rayConfig object parsed from the JSON configuration, or null if the configuration is empty
*/
private fun initV2rayConfig(context: Context): V2rayConfig? {
val assets = initConfigCache ?: Utils.readTextFromAssets(context, "v2ray_config.json")
if (TextUtils.isEmpty(assets)) {
return null
}
initConfigCache = assets
val config = JsonUtil.fromJson(assets, V2rayConfig::class.java)
return config
}
private fun inbounds(v2rayConfig: V2rayConfig): Boolean {
try {
val socksPort = SettingsManager.getSocksPort()
@@ -274,7 +366,7 @@ object V2rayConfigManager {
val proxyDomain = userRule2Domain(TAG_PROXY)
val directDomain = userRule2Domain(TAG_DIRECT)
// fakedns with all domains to make it always top priority
v2rayConfig.dns.servers?.add(
v2rayConfig.dns?.servers?.add(
0,
V2rayConfig.DnsBean.ServersBean(
address = "fakedns",
@@ -81,11 +81,11 @@ class V2RayTestService : Service() {
val delay = PluginUtil.realPingHy2(this, config)
return delay
} else {
val config = V2rayConfigManager.getV2rayConfig(this, guid)
if (!config.status) {
val configResult = V2rayConfigManager.getV2rayConfig4Speedtest(this, guid)
if (!configResult.status) {
return retFailure
}
return SpeedtestManager.realPing(config.content)
return SpeedtestManager.realPing(configResult.content)
}
}
}
@@ -265,7 +265,7 @@
<string name="title_sub_update">به‌روزرسانی گروه فعلی اشتراک</string>
<string name="title_ping_all_server">TCPING کانفیگ های گروه فعلی</string>
<string name="title_real_ping_all_server">تاخیر واقعی کانفیگ های گروه فعلی</string>
<string name="title_user_asset_setting">Asset files</string>
<string name="title_user_asset_setting">فایل های منبع جغرافیایی</string>
<string name="title_sort_by_test_results">مرتب‌ سازی بر اساس نتایج آزمایش</string>
<string name="title_filter_config">فیلتر کردن کانفیگ‌ها</string>
<string name="filter_config_all">همه گروه‌های اشتراک</string>
@@ -267,7 +267,7 @@
<string name="title_sub_update">Обновить подписку группы</string>
<string name="title_ping_all_server">Проверка профилей группы</string>
<string name="title_real_ping_all_server">Время отклика профилей группы</string>
<string name="title_user_asset_setting">Asset files</string>
<string name="title_user_asset_setting">Файлы ресурсов</string>
<string name="title_sort_by_test_results">Сортировка по результатам теста</string>
<string name="title_filter_config">Фильтр групп</string>
<string name="filter_config_all">Все группы</string>
+1 -1
View File
@@ -1,5 +1,5 @@
[versions]
agp = "8.9.0"
agp = "8.9.1"
desugar_jdk_libs = "2.1.5"
gradleLicensePlugin = "0.9.8"
kotlin = "2.1.20"
+15 -2
View File
@@ -14,10 +14,18 @@
# Dependency directories (remove the comment below to include it)
# vendor/
# macOS specific files
*.DS_Store
.idea
# IDE specific files
.idea/
.vscode/
# Archive files
*.zip
*.tar.gz
# Binaries
xray
xray_softfloat
mockgen
@@ -26,8 +34,13 @@ vprotogen
errorgen
!common/errors/errorgen/
*.dat
.vscode
# Build assets
/build_assets
# Output from dlv test
**/debug.*
# Certificates
*.crt
*.key
+1 -1
View File
@@ -357,7 +357,7 @@ func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, clientIP net
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
} else {
ips, ttl, err := s.findIPsForDomain(fqdn, option)
if err == nil || err == dns_feature.ErrEmptyResponse {
if err == nil || err == dns_feature.ErrEmptyResponse || dns_feature.RCodeFromError(err) == 3 {
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, ttl, err
+1 -1
View File
@@ -300,7 +300,7 @@ func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP ne
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
} else {
ips, ttl, err := s.findIPsForDomain(fqdn, option)
if err == nil || err == dns_feature.ErrEmptyResponse {
if err == nil || err == dns_feature.ErrEmptyResponse || dns_feature.RCodeFromError(err) == 3 {
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, ttl, err
+1 -1
View File
@@ -325,7 +325,7 @@ func (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
} else {
ips, ttl, err := s.findIPsForDomain(fqdn, option)
if err == nil || err == dns_feature.ErrEmptyResponse {
if err == nil || err == dns_feature.ErrEmptyResponse || dns_feature.RCodeFromError(err) == 3 {
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, ttl, err
+1 -1
View File
@@ -282,7 +282,7 @@ func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, clientIP
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
} else {
ips, ttl, err := s.findIPsForDomain(fqdn, option)
if err == nil || err == dns_feature.ErrEmptyResponse {
if err == nil || err == dns_feature.ErrEmptyResponse || dns_feature.RCodeFromError(err) == 3 {
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, ttl, err
@@ -1,2 +0,0 @@
*.crt
*.key
+1 -1
View File
@@ -23,7 +23,7 @@ require (
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.36.0
golang.org/x/net v0.37.0
golang.org/x/net v0.38.0
golang.org/x/sync v0.12.0
golang.org/x/sys v0.31.0
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
+2 -2
View File
@@ -107,8 +107,8 @@ golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
+7 -5
View File
@@ -803,12 +803,14 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
@classmethod
def _extract_continuation_ep_data(cls, continuation_ep: dict):
if isinstance(continuation_ep, dict):
continuation = try_get(
continuation_ep, lambda x: x['continuationCommand']['token'], str)
continuation_commands = traverse_obj(
continuation_ep, ('commandExecutorCommand', 'commands', ..., {dict}))
continuation_commands.append(continuation_ep)
for command in continuation_commands:
continuation = traverse_obj(command, ('continuationCommand', 'token', {str}))
if not continuation:
return
ctp = continuation_ep.get('clickTrackingParams')
continue
ctp = command.get('clickTrackingParams')
return cls._build_api_continuation_query(continuation, ctp)
@classmethod