diff --git a/.github/update.log b/.github/update.log index 0c131bc17e..ac24ebed8f 100644 --- a/.github/update.log +++ b/.github/update.log @@ -933,3 +933,4 @@ Update On Sun Mar 2 19:33:02 CET 2025 Update On Mon Mar 3 19:34:32 CET 2025 Update On Tue Mar 4 19:36:12 CET 2025 Update On Wed Mar 5 19:38:24 CET 2025 +Update On Thu Mar 6 19:35:59 CET 2025 diff --git a/clash-nyanpasu/backend/Cargo.lock b/clash-nyanpasu/backend/Cargo.lock index df6391b035..7ee60c9fdf 100644 --- a/clash-nyanpasu/backend/Cargo.lock +++ b/clash-nyanpasu/backend/Cargo.lock @@ -8128,9 +8128,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" dependencies = [ "proc-macro2", ] diff --git a/clash-nyanpasu/frontend/nyanpasu/package.json b/clash-nyanpasu/frontend/nyanpasu/package.json index 5eb697d549..0a9790d13c 100644 --- a/clash-nyanpasu/frontend/nyanpasu/package.json +++ b/clash-nyanpasu/frontend/nyanpasu/package.json @@ -29,7 +29,7 @@ "allotment": "1.20.3", "country-code-emoji": "2.3.0", "dayjs": "1.11.13", - "framer-motion": "12.4.7", + "framer-motion": "12.4.10", "i18next": "24.2.2", "jotai": "2.12.1", "json-schema": "0.4.0", @@ -42,7 +42,7 @@ "react-fast-marquee": "1.6.5", "react-hook-form-mui": "7.5.0", "react-i18next": "15.4.1", - "react-markdown": "10.0.0", + "react-markdown": "10.0.1", "react-split-grid": "1.0.4", "react-use": "17.6.0", "swr": "2.3.2", @@ -53,12 +53,12 @@ "@csstools/normalize.css": "12.1.1", "@emotion/babel-plugin": "11.13.5", "@emotion/react": "11.14.0", - "@iconify/json": "2.2.313", + "@iconify/json": "2.2.314", "@monaco-editor/react": "4.7.0", "@tanstack/react-query": "5.66.11", - "@tanstack/react-router": "1.112.0", - "@tanstack/router-devtools": "1.112.6", - "@tanstack/router-plugin": "1.112.3", + "@tanstack/react-router": "1.112.17", + "@tanstack/router-devtools": "1.112.17", + "@tanstack/router-plugin": "1.112.17", "@tauri-apps/plugin-clipboard-manager": "2.2.1", "@tauri-apps/plugin-dialog": "2.2.0", "@tauri-apps/plugin-fs": "2.2.0", diff --git a/clash-nyanpasu/frontend/ui/package.json b/clash-nyanpasu/frontend/ui/package.json index 3161e9caff..3ab2966fd3 100644 --- a/clash-nyanpasu/frontend/ui/package.json +++ b/clash-nyanpasu/frontend/ui/package.json @@ -28,7 +28,7 @@ "@vitejs/plugin-react": "4.3.4", "ahooks": "3.8.4", "d3": "7.9.0", - "framer-motion": "12.4.7", + "framer-motion": "12.4.10", "react": "19.0.0", "react-dom": "19.0.0", "react-error-boundary": "5.0.0", diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index f083c158bb..36d4a71185 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -246,7 +246,7 @@ importers: version: 4.0.9 '@tanstack/router-zod-adapter': specifier: 1.81.5 - version: 1.81.5(@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.2) + version: 1.81.5(@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.2) '@tauri-apps/api': specifier: 2.2.0 version: 2.2.0 @@ -266,8 +266,8 @@ importers: specifier: 1.11.13 version: 1.11.13 framer-motion: - specifier: 12.4.7 - version: 12.4.7(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: 12.4.10 + version: 12.4.10(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) i18next: specifier: 24.2.2 version: 24.2.2(typescript@5.8.2) @@ -305,8 +305,8 @@ importers: specifier: 15.4.1 version: 15.4.1(i18next@24.2.2(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-markdown: - specifier: 10.0.0 - version: 10.0.0(@types/react@19.0.10)(react@19.0.0) + specifier: 10.0.1 + version: 10.0.1(@types/react@19.0.10)(react@19.0.0) react-split-grid: specifier: 1.0.4 version: 1.0.4(react@19.0.0) @@ -333,8 +333,8 @@ importers: specifier: 11.14.0 version: 11.14.0(@types/react@19.0.10)(react@19.0.0) '@iconify/json': - specifier: 2.2.313 - version: 2.2.313 + specifier: 2.2.314 + version: 2.2.314 '@monaco-editor/react': 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) @@ -342,14 +342,14 @@ importers: specifier: 5.66.11 version: 5.66.11(react@19.0.0) '@tanstack/react-router': - specifier: 1.112.0 - version: 1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: 1.112.17 + version: 1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@tanstack/router-devtools': - specifier: 1.112.6 - version: 1.112.6(@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: 1.112.17 + version: 1.112.17(@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@tanstack/router-plugin': - specifier: 1.112.3 - version: 1.112.3(@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.0(@types/node@22.13.9)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.1)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0)) + specifier: 1.112.17 + version: 1.112.17(@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.0(@types/node@22.13.9)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.1)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0)) '@tauri-apps/plugin-clipboard-manager': specifier: 2.2.1 version: 2.2.1 @@ -486,8 +486,8 @@ importers: specifier: 7.9.0 version: 7.9.0 framer-motion: - specifier: 12.4.7 - version: 12.4.7(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: 12.4.10 + version: 12.4.10(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react: specifier: 19.0.0 version: 19.0.0 @@ -1666,8 +1666,8 @@ packages: '@vue/compiler-sfc': optional: true - '@iconify/json@2.2.313': - resolution: {integrity: sha512-lzZ0KFpb0/IN4TVp/9lkUQQx6pmDqe6UD6lWiwkjnPMUVfFXYFMOfy6Qna5zb2cKwVQLTcOUgKk82Ah4qilKlw==} + '@iconify/json@2.2.314': + resolution: {integrity: sha512-yikVmts2jl9Z5ozNekFhEv5ovZBGOC24ugMrcobOr6gnOHuRrr9XCZvpY5lmUT2TIT0NGWKVAaPbhmRkJIukUw==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -2722,8 +2722,8 @@ packages: '@tailwindcss/postcss@4.0.9': resolution: {integrity: sha512-BT/E+pdMqulavEAVM5NCpxmGEwHiLDPpkmg/c/X25ZBW+izTe+aZ+v1gf/HXTrihRoCxrUp5U4YyHsBTzspQKQ==} - '@tanstack/history@1.99.13': - resolution: {integrity: sha512-JMd7USmnp8zV8BRGIjALqzPxazvKtQ7PGXQC7n39HpbqdsmfV2ePCzieO84IvN+mwsTrXErpbjI4BfKCa+ZNCg==} + '@tanstack/history@1.112.8': + resolution: {integrity: sha512-+EPOvUtnA3PnIBF2oUhggdy7UrVimLZd1SpULhV1UiesNgKtmLjArO7ZdGPrRq7pRXhc8V0ZAWTI9vfplhZfeA==} engines: {node: '>=12'} '@tanstack/match-sorter-utils@8.19.4': @@ -2738,8 +2738,8 @@ packages: peerDependencies: react: ^18 || ^19 - '@tanstack/react-router@1.112.0': - resolution: {integrity: sha512-05WEtCy9NNLfaQKJUdLjFz/g8FBTeWO9C1LbZasEXAyA2u+TkR/bBbH/VV/roaFvWC8Nn7o3urbZT1CxPtuvXw==} + '@tanstack/react-router@1.112.17': + resolution: {integrity: sha512-UYd9FspQAFs9uxSwHBWQ7LIO1M7FcKVCpYm+vdYJABj6RRMelWuBOOIXgYhMJaGBPazQO3wZVytkW+RW+iwA1A==} engines: {node: '>=12'} peerDependencies: react: '>=18.0.0 || >=19.0.0' @@ -2764,15 +2764,15 @@ 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 - '@tanstack/router-core@1.112.0': - resolution: {integrity: sha512-kmpMiBuz17Hxyl+ZO+B6/F98p07NSEmgr2JlZkKXcdupLIBAWqcXw+bjowFXNcTEwe9RWsS/WjAC/bBTftr0rA==} + '@tanstack/router-core@1.112.12': + resolution: {integrity: sha512-nuKEl7qEDO/F4+d7RdAHmxGAq6Sc1SJyCRthnxycSANMTK8bAT6gVoAaag/BJgl4aKgmP1iSHPVv8slcVpmPrQ==} engines: {node: '>=12'} - '@tanstack/router-devtools@1.112.6': - resolution: {integrity: sha512-OhLZsDnrItA+8BiVdmyyWB2VgQyoCZAjSRshQJpbZdeAV69OvT2rqN2TtiLJsbSAJWmqL4/UcY/13DI9Iv+k3Q==} + '@tanstack/router-devtools@1.112.17': + resolution: {integrity: sha512-BfbmYGY3pqAO5Z3qKzW+ei5cjkd1Lb4xXhzIVU8r2kGTREfAenxVtheIcV4mu2HZ0Jgs85D4T7upDGJZyogxXw==} engines: {node: '>=12'} peerDependencies: - '@tanstack/react-router': ^1.112.0 + '@tanstack/react-router': ^1.112.17 csstype: ^3.0.10 react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' @@ -2780,21 +2780,21 @@ packages: csstype: optional: true - '@tanstack/router-generator@1.112.3': - resolution: {integrity: sha512-RUT+O/j7YIjbemVJjkP4qM8MYaaOltKYhyp9VGtcWxWGS8U2QDwC9UsskjBVOj7QV7aq3UcnExicABwK/AMCCQ==} + '@tanstack/router-generator@1.112.17': + resolution: {integrity: sha512-UPpRyKMWlHG56KoUOYSM6JwJkj31+CXw9nrIiHjhSSyyR6Quk0fY+DPACGKM2Qh+3kUgQ9GXUhXahTdUyjWNyQ==} engines: {node: '>=12'} peerDependencies: - '@tanstack/react-router': ^1.112.0 + '@tanstack/react-router': ^1.112.17 peerDependenciesMeta: '@tanstack/react-router': optional: true - '@tanstack/router-plugin@1.112.3': - resolution: {integrity: sha512-XhKXFoJ7eajqghAPwHXfggyB8khopr5yVXiYQRiL+9Gek2q5M8N4z9+Uh2MM31KjTuiaJ72lZpUgT5FDj1m6Tg==} + '@tanstack/router-plugin@1.112.17': + resolution: {integrity: sha512-EIm+T4S3c1R180OAK1VviyUJmM5Z1Iagwu0E3oHs4vCc4fDVP55IEPpYp7C1rNP8HjobmErv+CN7a6h1YDiFQQ==} engines: {node: '>=12'} peerDependencies: '@rsbuild/core': '>=1.0.2' - '@tanstack/react-router': ^1.112.0 + '@tanstack/react-router': ^1.112.17 vite: '>=5.0.0 || >=6.0.0' vite-plugin-solid: ^2.11.2 webpack: '>=5.92.0' @@ -4753,8 +4753,8 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@12.4.7: - resolution: {integrity: sha512-VhrcbtcAMXfxlrjeHPpWVu2+mkcoR31e02aNSR7OUS/hZAciKa8q6o3YN2mA1h+jjscRsSyKvX6E1CiY/7OLMw==} + framer-motion@12.4.10: + resolution: {integrity: sha512-3Msuyjcr1Pb5hjkn4EJcRe1HumaveP0Gbv4DBMKTPKcV/1GSMkQXj+Uqgneys+9DPcZM18Hac9qY9iUEF5LZtg==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -6030,11 +6030,11 @@ packages: peerDependencies: monaco-editor: '>=0.36' - motion-dom@12.4.5: - resolution: {integrity: sha512-Q2xmhuyYug1CGTo0jdsL05EQ4RhIYXlggFS/yPhQQRNzbrhjKQ1tbjThx5Plv68aX31LsUQRq4uIkuDxdO5vRQ==} + motion-dom@12.4.10: + resolution: {integrity: sha512-ISP5u6FTceoD6qKdLupIPU/LyXBrxGox+P2e3mBbm1+pLdlBbwv01YENJr7+1WZnW5ucVKzFScYsV1eXTCG4Xg==} - motion-utils@12.0.0: - resolution: {integrity: sha512-MNFiBKbbqnmvOjkPyOKgHUp3Q6oiokLkI1bEwm5QA28cxMZrv0CbbBGDNmhF6DIXsi1pCQBSs0dX8xjeER1tmA==} + motion-utils@12.4.10: + resolution: {integrity: sha512-NPwZd94V013SwRf++jMrk2+HEBgPkeIE2RiOzhAuuQlqxMJPkKt/LXVh6Upl+iN8oarSGD2dlY5/bqgsYXDABA==} ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -6697,8 +6697,8 @@ packages: react-is@19.0.0: resolution: {integrity: sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==} - react-markdown@10.0.0: - resolution: {integrity: sha512-4mTz7Sya/YQ1jYOrkwO73VcFdkFJ8L8I9ehCxdcV0XrClHyOJGKbBk5FR4OOOG+HnyKw5u+C/Aby9TwinCteYA==} + react-markdown@10.0.1: + resolution: {integrity: sha512-Qt9TWsQJ75np2AVoKftns5eI7r50H6u3qwp+TSihlxOcw8ZaStmR0FEeeENU+mWSxyAgOmqMYjiIKn7ibMheKA==} peerDependencies: '@types/react': '>=18' react: '>=18' @@ -8071,6 +8071,7 @@ packages: yaeti@0.0.6: resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==} engines: {node: '>=0.10.32'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. yallist@2.1.2: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} @@ -9426,7 +9427,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@iconify/json@2.2.313': + '@iconify/json@2.2.314': dependencies: '@iconify/types': 2.0.0 pathe: 1.1.2 @@ -10452,7 +10453,7 @@ snapshots: postcss: 8.5.3 tailwindcss: 4.0.9 - '@tanstack/history@1.99.13': {} + '@tanstack/history@1.112.8': {} '@tanstack/match-sorter-utils@8.19.4': dependencies: @@ -10465,11 +10466,11 @@ snapshots: '@tanstack/query-core': 5.66.11 react: 19.0.0 - '@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@tanstack/history': 1.99.13 + '@tanstack/history': 1.112.8 '@tanstack/react-store': 0.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@tanstack/router-core': 1.112.0 + '@tanstack/router-core': 1.112.12 jsesc: 3.1.0 react: 19.0.0 react-dom: 19.0.0(react@19.0.0) @@ -10495,14 +10496,14 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - '@tanstack/router-core@1.112.0': + '@tanstack/router-core@1.112.12': dependencies: - '@tanstack/history': 1.99.13 + '@tanstack/history': 1.112.8 '@tanstack/store': 0.7.0 - '@tanstack/router-devtools@1.112.6(@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@tanstack/router-devtools@1.112.17(@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@tanstack/react-router': 1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@tanstack/react-router': 1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0) clsx: 2.1.1 goober: 2.1.16(csstype@3.1.3) react: 19.0.0 @@ -10510,16 +10511,16 @@ snapshots: optionalDependencies: csstype: 3.1.3 - '@tanstack/router-generator@1.112.3(@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))': + '@tanstack/router-generator@1.112.17(@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0))': dependencies: '@tanstack/virtual-file-routes': 1.99.0 prettier: 3.5.2 tsx: 4.19.3 zod: 3.24.2 optionalDependencies: - '@tanstack/react-router': 1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@tanstack/react-router': 1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@tanstack/router-plugin@1.112.3(@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.0(@types/node@22.13.9)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.1)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0))': + '@tanstack/router-plugin@1.112.17(@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.0(@types/node@22.13.9)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.1)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0))': dependencies: '@babel/core': 7.26.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) @@ -10527,8 +10528,8 @@ snapshots: '@babel/template': 7.26.9 '@babel/traverse': 7.26.9 '@babel/types': 7.26.9 - '@tanstack/router-core': 1.112.0 - '@tanstack/router-generator': 1.112.3(@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)) + '@tanstack/router-core': 1.112.12 + '@tanstack/router-generator': 1.112.17(@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0)) '@tanstack/router-utils': 1.102.2 '@tanstack/virtual-file-routes': 1.99.0 '@types/babel__core': 7.20.5 @@ -10539,7 +10540,7 @@ snapshots: unplugin: 2.2.0 zod: 3.24.2 optionalDependencies: - '@tanstack/react-router': 1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@tanstack/react-router': 1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0) vite: 6.2.0(@types/node@22.13.9)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.1)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0) transitivePeerDependencies: - supports-color @@ -10551,9 +10552,9 @@ snapshots: ansis: 3.12.0 diff: 7.0.0 - '@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.2)': + '@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.2)': dependencies: - '@tanstack/react-router': 1.112.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@tanstack/react-router': 1.112.17(react-dom@19.0.0(react@19.0.0))(react@19.0.0) zod: 3.24.2 '@tanstack/store@0.7.0': {} @@ -12872,10 +12873,10 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@12.4.7(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + framer-motion@12.4.10(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: - motion-dom: 12.4.5 - motion-utils: 12.0.0 + motion-dom: 12.4.10 + motion-utils: 12.4.10 tslib: 2.7.0 optionalDependencies: '@emotion/is-prop-valid': 1.3.0 @@ -14266,11 +14267,11 @@ snapshots: vscode-uri: 3.0.8 yaml: 2.7.0 - motion-dom@12.4.5: + motion-dom@12.4.10: dependencies: - motion-utils: 12.0.0 + motion-utils: 12.4.10 - motion-utils@12.0.0: {} + motion-utils@12.4.10: {} ms@2.0.0: {} @@ -14878,7 +14879,7 @@ snapshots: react-is@19.0.0: {} - react-markdown@10.0.0(@types/react@19.0.10)(react@19.0.0): + react-markdown@10.0.1(@types/react@19.0.10)(react@19.0.0): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.3 diff --git a/clash-verge-rev/src-tauri/Cargo.lock b/clash-verge-rev/src-tauri/Cargo.lock index 5830c57de8..43ce006cc0 100644 --- a/clash-verge-rev/src-tauri/Cargo.lock +++ b/clash-verge-rev/src-tauri/Cargo.lock @@ -2,6 +2,16 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ab_glyph" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser 0.25.0", +] + [[package]] name = "ab_glyph_rasterizer" version = "0.1.8" @@ -68,7 +78,7 @@ dependencies = [ "getrandom 0.2.15", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -80,6 +90,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -168,9 +184,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "approx" @@ -198,11 +214,11 @@ checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" dependencies = [ "clipboard-win", "core-graphics 0.23.2", - "image 0.25.5", + "image", "log", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", "parking_lot", "windows-sys 0.48.0", "x11rb", @@ -214,6 +230,17 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "arrayvec" version = "0.7.6" @@ -487,9 +514,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.86" +version = "0.1.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" +checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97" dependencies = [ "proc-macro2", "quote", @@ -542,6 +569,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom 7.1.3", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98922d6a4cfbcb08820c69d8eeccc05bb1f29bfa06b4f5b1dbfe9a868bd7608e" +dependencies = [ + "arrayvec", +] + [[package]] name = "axum" version = "0.6.20" @@ -641,6 +691,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + [[package]] name = "block" version = "0.1.6" @@ -671,7 +727,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2", + "objc2 0.5.2", +] + +[[package]] +name = "block2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d59b4c170e16f0405a2e95aff44432a0d41aa97675f3d52623effe95792a037" +dependencies = [ + "objc2 0.6.0", ] [[package]] @@ -847,6 +912,12 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "built" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b" + [[package]] name = "bumpalo" version = "3.17.0" @@ -896,22 +967,20 @@ dependencies = [ [[package]] name = "bzip2" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" dependencies = [ "bzip2-sys", - "libc", ] [[package]] name = "bzip2-sys" -version = "0.1.11+1.0.8" +version = "0.1.13+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" dependencies = [ "cc", - "libc", "pkg-config", ] @@ -979,7 +1048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fbd1fe9db3ebf71b89060adaf7b0504c2d6a425cf061313099547e382c2e472" dependencies = [ "serde", - "toml 0.8.19", + "toml", ] [[package]] @@ -1034,9 +1103,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1044,7 +1113,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -1061,6 +1130,7 @@ dependencies = [ name = "clash-verge" version = "2.1.2" dependencies = [ + "ab_glyph", "aes-gcm", "anyhow", "async-trait", @@ -1073,8 +1143,8 @@ dependencies = [ "dunce", "env_logger", "futures", - "getrandom 0.2.15", - "image 0.24.9", + "getrandom 0.3.1", + "image", "imageproc", "log", "log4rs", @@ -1113,7 +1183,7 @@ dependencies = [ "tauri-plugin-window-state", "tempfile", "tokio", - "tokio-tungstenite 0.26.1", + "tokio-tungstenite 0.26.2", "url", "users", "warp", @@ -1268,15 +1338,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" -[[package]] -name = "conv" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" -dependencies = [ - "custom_derive", -] - [[package]] name = "convert_case" version = "0.4.0" @@ -1508,12 +1569,6 @@ dependencies = [ "cipher", ] -[[package]] -name = "custom_derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" - [[package]] name = "darling" version = "0.20.10" @@ -1762,15 +1817,6 @@ dependencies = [ "dirs-sys 0.3.7", ] -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys 0.4.1", -] - [[package]] name = "dirs" version = "6.0.0" @@ -1801,18 +1847,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users 0.4.6", - "windows-sys 0.48.0", -] - [[package]] name = "dirs-sys" version = "0.5.0" @@ -1944,14 +1978,14 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "embed-resource" -version = "2.5.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68b6f9f63a0b6a38bc447d4ce84e2b388f3ec95c99c641c8ff0dd3ef89a6379" +checksum = "7fbc6e0d8e0c03a655b53ca813f0463d2c956bc4db8138dbc89f120b066551e3" dependencies = [ "cc", "memchr", "rustc_version 0.4.1", - "toml 0.8.19", + "toml", "vswhom", "winreg 0.52.0", ] @@ -2652,8 +2686,8 @@ checksum = "b00d88f1be7bf4cd2e61623ce08e84be2dfa4eab458e5d632d3dab95f16c1f64" dependencies = [ "crossbeam-channel", "keyboard-types", - "objc2", - "objc2-app-kit", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", "once_cell", "serde", "thiserror 1.0.69", @@ -3116,9 +3150,9 @@ dependencies = [ [[package]] name = "ico" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3804960be0bb5e4edb1e1ad67afd321a9ecfd875c3e65c099468fd2717d7cae" +checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" dependencies = [ "byteorder", "png", @@ -3269,24 +3303,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "image" -version = "0.24.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif", - "jpeg-decoder", - "num-traits", - "png", - "qoi", - "tiff", -] - [[package]] name = "image" version = "0.25.5" @@ -3295,29 +3311,55 @@ checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", "num-traits", "png", + "qoi", + "ravif", + "rayon", + "rgb", "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" +dependencies = [ + "byteorder-lite", + "quick-error", ] [[package]] name = "imageproc" -version = "0.23.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aee993351d466301a29655d628bfc6f5a35a0d062b6160ca0808f425805fd7" +checksum = "2393fb7808960751a52e8a154f67e7dd3f8a2ef9bd80d1553078a7b4e8ed3f0d" dependencies = [ + "ab_glyph", "approx", - "conv", - "image 0.24.9", - "itertools 0.10.5", + "getrandom 0.2.15", + "image", + "itertools 0.12.1", "nalgebra", "num", - "rand 0.7.3", + "rand 0.8.5", "rand_distr", "rayon", - "rusttype", ] +[[package]] +name = "imgref" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" + [[package]] name = "indexmap" version = "1.9.3" @@ -3342,9 +3384,9 @@ dependencies = [ [[package]] name = "infer" -version = "0.16.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847" +checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" dependencies = [ "cfb", ] @@ -3383,6 +3425,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "intrusive-collections" version = "0.9.7" @@ -3445,15 +3498,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.12.1" @@ -3543,9 +3587,6 @@ name = "jpeg-decoder" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" -dependencies = [ - "rayon", -] [[package]] name = "js-sys" @@ -3645,6 +3686,16 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "libfuzzer-sys" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75" +dependencies = [ + "arbitrary", + "cc", +] + [[package]] name = "libloading" version = "0.7.4" @@ -3665,6 +3716,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + [[package]] name = "libredox" version = "0.1.3" @@ -3765,6 +3822,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "lru" version = "0.12.5" @@ -3857,6 +3923,16 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "md-5" version = "0.10.6" @@ -3958,9 +4034,9 @@ dependencies = [ [[package]] name = "mockito" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "652cd6d169a36eaf9d1e6bce1a221130439a966d7f27858af66a33a66e9c4ee2" +checksum = "7760e0e418d9b7e5777c0374009ca4c93861b9066f18cb334a20ce50ab63aa48" dependencies = [ "assert-json-diff", "bytes", @@ -3972,7 +4048,7 @@ dependencies = [ "hyper 1.6.0", "hyper-util", "log", - "rand 0.8.5", + "rand 0.9.0", "regex", "serde_json", "serde_urlencoded", @@ -3982,21 +4058,22 @@ dependencies = [ [[package]] name = "muda" -version = "0.15.3" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdae9c00e61cc0579bcac625e8ad22104c60548a025bfc972dc83868a28e1484" +checksum = "4de14a9b5d569ca68d7c891d613b390cf5ab4f851c77aaa2f9e435555d3d9492" dependencies = [ "crossbeam-channel", "dpi", "gtk", "keyboard-types", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", "once_cell", "png", "serde", - "thiserror 1.0.69", + "thiserror 2.0.11", "windows-sys 0.59.0", ] @@ -4020,9 +4097,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.30.1" +version = "0.32.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be" +checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" dependencies = [ "approx", "matrixmultiply", @@ -4185,6 +4262,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "notify-rust" version = "4.11.4" @@ -4268,6 +4351,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -4306,6 +4400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -4363,9 +4458,6 @@ name = "objc-sys" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" -dependencies = [ - "cc", -] [[package]] name = "objc2" @@ -4377,6 +4469,16 @@ dependencies = [ "objc2-encode", ] +[[package]] +name = "objc2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3531f65190d9cff863b77a99857e74c314dd16bf56c538c4b57c7cbc3f3a6e59" +dependencies = [ + "objc2-encode", + "objc2-exception-helper", +] + [[package]] name = "objc2-app-kit" version = "0.2.2" @@ -4384,37 +4486,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "libc", - "objc2", - "objc2-core-data", - "objc2-core-image", - "objc2-foundation", - "objc2-quartz-core", + "objc2 0.5.2", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5906f93257178e2f7ae069efb89fbd6ee94f0592740b5f8a1512ca498814d0fb" +dependencies = [ + "bitflags 2.8.0", + "block2 0.6.0", + "libc", + "objc2 0.6.0", + "objc2-cloud-kit", + "objc2-core-data 0.3.0", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image 0.3.0", + "objc2-foundation 0.3.0", + "objc2-quartz-core 0.3.0", ] [[package]] name = "objc2-cloud-kit" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +checksum = "6c1948a9be5f469deadbd6bcb86ad7ff9e47b4f632380139722f7d9840c0d42c" dependencies = [ "bitflags 2.8.0", - "block2", - "objc2", - "objc2-core-location", - "objc2-foundation", -] - -[[package]] -name = "objc2-contacts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" -dependencies = [ - "block2", - "objc2", - "objc2-foundation", + "objc2 0.6.0", + "objc2-foundation 0.3.0", ] [[package]] @@ -4424,9 +4532,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.8.0", - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f860f8e841f6d32f754836f51e6bc7777cd7e7053cf18528233f6811d3eceb4" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.0", + "objc2-foundation 0.3.0", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.0", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dca602628b65356b6513290a21a6405b4d4027b8b250f0b98dddbb28b7de02" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.0", + "objc2-core-foundation", + "objc2-io-surface", ] [[package]] @@ -4435,22 +4576,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] [[package]] -name = "objc2-core-location" -version = "0.2.2" +name = "objc2-core-image" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +checksum = "6ffa6bea72bf42c78b0b34e89c0bafac877d5f80bf91e159a5d96ea7f693ca56" dependencies = [ - "block2", - "objc2", - "objc2-contacts", - "objc2-foundation", + "objc2 0.6.0", + "objc2-foundation 0.3.0", ] [[package]] @@ -4459,6 +4598,15 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" +[[package]] +name = "objc2-exception-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +dependencies = [ + "cc", +] + [[package]] name = "objc2-foundation" version = "0.2.2" @@ -4466,22 +4614,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.8.0", - "block2", + "block2 0.5.1", "dispatch", "libc", - "objc2", + "objc2 0.5.2", ] [[package]] -name = "objc2-link-presentation" -version = "0.2.2" +name = "objc2-foundation" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +checksum = "3a21c6c9014b82c39515db5b396f91645182611c97d24637cf56ac01e5f8d998" dependencies = [ - "block2", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "bitflags 2.8.0", + "block2 0.6.0", + "libc", + "objc2 0.6.0", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161a8b87e32610086e1a7a9e9ec39f84459db7b3a0881c1f16ca5a2605581c19" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.0", + "objc2-core-foundation", ] [[package]] @@ -4491,9 +4651,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.8.0", - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-osa-kit" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ac59da3ceebc4a82179b35dc550431ad9458f9cc326e053f49ba371ce76c5a" +dependencies = [ + "bitflags 2.8.0", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-foundation 0.3.0", ] [[package]] @@ -4503,78 +4675,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.8.0", - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] [[package]] -name = "objc2-symbols" -version = "0.2.2" +name = "objc2-quartz-core" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +checksum = "6fb3794501bb1bee12f08dcad8c61f2a5875791ad1c6f47faa71a0f033f20071" dependencies = [ - "objc2", - "objc2-foundation", + "bitflags 2.8.0", + "objc2 0.6.0", + "objc2-foundation 0.3.0", ] [[package]] name = "objc2-ui-kit" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +checksum = "777a571be14a42a3990d4ebedaeb8b54cd17377ec21b92e8200ac03797b3bee1" dependencies = [ "bitflags 2.8.0", - "block2", - "objc2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", - "objc2-core-location", - "objc2-foundation", - "objc2-link-presentation", - "objc2-quartz-core", - "objc2-symbols", - "objc2-uniform-type-identifiers", - "objc2-user-notifications", -] - -[[package]] -name = "objc2-uniform-type-identifiers" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" -dependencies = [ - "block2", - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-user-notifications" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" -dependencies = [ - "bitflags 2.8.0", - "block2", - "objc2", - "objc2-core-location", - "objc2-foundation", + "objc2 0.6.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", ] [[package]] name = "objc2-web-kit" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65" +checksum = "b717127e4014b0f9f3e8bba3d3f2acec81f1bde01f656823036e823ed2c94dce" dependencies = [ "bitflags 2.8.0", - "block2", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "block2 0.6.0", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", ] [[package]] @@ -4597,9 +4738,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "opaque-debug" @@ -4708,6 +4849,20 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "osakit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" +dependencies = [ + "objc2 0.6.0", + "objc2-foundation 0.3.0", + "objc2-osa-kit", + "serde", + "serde_json", + "thiserror 2.0.11", +] + [[package]] name = "overload" version = "0.1.1" @@ -4720,7 +4875,16 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb" dependencies = [ - "ttf-parser", + "ttf-parser 0.15.2", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser 0.25.1", ] [[package]] @@ -5152,7 +5316,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -5228,6 +5392,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn 2.0.98", +] + [[package]] name = "prost" version = "0.12.6" @@ -5388,6 +5571,17 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy 0.8.22", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -5408,6 +5602,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -5427,12 +5631,22 @@ dependencies = [ ] [[package]] -name = "rand_distr" -version = "0.2.2" +name = "rand_core" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "rand 0.7.3", + "getrandom 0.3.1", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", ] [[package]] @@ -5453,6 +5667,56 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.12.1", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive 0.4.2", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha 0.3.1", + "simd_helpers", + "system-deps", + "thiserror 1.0.69", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -5654,7 +5918,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a24763657bff09769a8ccf12c8b8a50416fb035fe199263b4c5071e4e3f006f" dependencies = [ "ashpd", - "block2", + "block2 0.5.1", "core-foundation 0.10.0", "core-foundation-sys", "glib-sys", @@ -5662,9 +5926,9 @@ dependencies = [ "gtk-sys", "js-sys", "log", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", "raw-window-handle 0.6.2", "wasm-bindgen", "wasm-bindgen-futures", @@ -5672,6 +5936,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" + [[package]] name = "ring" version = "0.17.8" @@ -5833,7 +6103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ff8374aa04134254b7995b63ad3dc41c7f7236f69528b28553da7d72efaa967" dependencies = [ "ab_glyph_rasterizer", - "owned_ttf_parser", + "owned_ttf_parser 0.15.2", ] [[package]] @@ -6279,9 +6549,9 @@ dependencies = [ [[package]] name = "simba" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3fd720c48c53cace224ae62bef1bbff363a70c68c4802a78b5cc6159618176" +checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" dependencies = [ "approx", "num-complex", @@ -6296,6 +6566,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "similar" version = "2.7.0" @@ -6378,9 +6657,9 @@ dependencies = [ "foreign-types 0.5.0", "js-sys", "log", - "objc2", - "objc2-foundation", - "objc2-quartz-core", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", "raw-window-handle 0.6.2", "redox_syscall", "wasm-bindgen", @@ -6601,18 +6880,17 @@ dependencies = [ "cfg-expr", "heck 0.5.0", "pkg-config", - "toml 0.8.19", + "toml", "version-compare", ] [[package]] name = "tao" -version = "0.31.1" +version = "0.32.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3731d04d4ac210cd5f344087733943b9bfb1a32654387dad4d1c70de21aee2c9" +checksum = "7e7f38988a68dfb559899ea307b97577f008d3254f6cfdd219a67e27ce34c95b" dependencies = [ "bitflags 2.8.0", - "cocoa 0.26.0", "core-foundation 0.10.0", "core-graphics 0.24.0", "crossbeam-channel", @@ -6629,7 +6907,9 @@ dependencies = [ "ndk", "ndk-context", "ndk-sys", - "objc", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-foundation 0.3.0", "once_cell", "parking_lot", "raw-window-handle 0.6.2", @@ -6637,8 +6917,8 @@ dependencies = [ "tao-macros", "unicode-segmentation", "url", - "windows 0.58.0", - "windows-core 0.58.0", + "windows 0.60.0", + "windows-core 0.60.1", "windows-version", "x11-dl", ] @@ -6679,9 +6959,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.2.5" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58a998b6be84104ca05c7e9a21f2180ddec020c8b84ea59a8fc8530a2a19588d" +checksum = "3be747b26bf28674977fac47bdf6963fd9c7578271c3fbeb25d8686de6596f35" dependencies = [ "anyhow", "bytes", @@ -6695,15 +6975,15 @@ dependencies = [ "heck 0.5.0", "http 1.2.0", "http-range", - "image 0.25.5", + "image", "jni", "libc", "log", "mime", "muda", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-foundation 0.3.0", "percent-encoding", "plist", "raw-window-handle 0.6.2", @@ -6727,18 +7007,18 @@ dependencies = [ "webkit2gtk", "webview2-com", "window-vibrancy", - "windows 0.58.0", + "windows 0.60.0", ] [[package]] name = "tauri-build" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e950124f6779c6cf98e3260c7a6c8488a74aa6350dd54c6950fdaa349bca2df" +checksum = "51a2e96f3c0baa0581656bb58e6fdd0f7c9c31eaf6721a0c08689d938fe85f2d" dependencies = [ "anyhow", "cargo_toml", - "dirs 5.0.1", + "dirs 6.0.0", "glob", "heck 0.5.0", "json-patch", @@ -6748,15 +7028,15 @@ dependencies = [ "serde_json", "tauri-utils", "tauri-winres", - "toml 0.8.19", + "toml", "walkdir", ] [[package]] name = "tauri-codegen" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77894f9ddb5cb6c04fcfe8c8869ebe0aded4dabf19917118d48be4a95599ab5" +checksum = "e357ec3daf8faad1029bc7109e7f5b308ceb63b6073d110d7388923a4cce5e55" dependencies = [ "base64 0.22.1", "brotli", @@ -6781,9 +7061,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3240a5caed760a532e8f687be6f05b2c7d11a1d791fb53ccc08cfeb3e5308736" +checksum = "447ee4dd94690d77f1422f2b57e783c654ba75c535ad6f6e727887330804fff2" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -6806,7 +7086,7 @@ dependencies = [ "serde", "serde_json", "tauri-utils", - "toml 0.8.19", + "toml", "walkdir", ] @@ -6922,7 +7202,7 @@ dependencies = [ "tauri-plugin", "tauri-utils", "thiserror 2.0.11", - "toml 0.8.19", + "toml", "url", "uuid", ] @@ -6994,17 +7274,18 @@ dependencies = [ [[package]] name = "tauri-plugin-updater" -version = "2.4.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad3de2b9203bb00b9765e637a9878aaace34df40ae484878b8cea7a5bd5f9188" +checksum = "69b7db616844d73d55e4d00190be101b29de463d5cb70321c2840fa4e9c414c4" dependencies = [ "base64 0.22.1", - "dirs 5.0.1", + "dirs 6.0.0", "flate2", "futures-util", "http 1.2.0", "infer", "minisign-verify", + "osakit", "percent-encoding", "reqwest", "semver 1.0.25", @@ -7039,9 +7320,9 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2274ef891ccc0a8d318deffa9d70053f947664d12d58b9c0d1ae5e89237e01f7" +checksum = "e758a405ab39e25f4d1235c5f06fe563f44b01ee18bbe38ddec5356d4f581908" dependencies = [ "dpi", "gtk", @@ -7053,22 +7334,23 @@ dependencies = [ "tauri-utils", "thiserror 2.0.11", "url", - "windows 0.58.0", + "windows 0.60.0", ] [[package]] name = "tauri-runtime-wry" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3707b40711d3b9f6519150869e358ffbde7c57567fb9b5a8b51150606939b2a0" +checksum = "8b2beb90decade4c71e8b09c9e4a9245837a8a97693f945b77e32baf13f51fec" dependencies = [ "gtk", "http 1.2.0", "jni", "log", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-foundation 0.3.0", + "once_cell", "percent-encoding", "raw-window-handle 0.6.2", "softbuffer", @@ -7079,15 +7361,15 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows 0.58.0", + "windows 0.60.0", "wry", ] [[package]] name = "tauri-utils" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fb10e7cc97456b2d5b9c03e335b5de5da982039a303a20d10006885e4523a0" +checksum = "107a959dbd5ff53d89a98f6f2e3e987c611334141a43630caae1d80e79446dd6" dependencies = [ "brotli", "cargo_metadata", @@ -7113,7 +7395,7 @@ dependencies = [ "serde_with", "swift-rs", "thiserror 2.0.11", - "toml 0.8.19", + "toml", "url", "urlpattern", "uuid", @@ -7122,12 +7404,12 @@ dependencies = [ [[package]] name = "tauri-winres" -version = "0.1.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb" +checksum = "56eaa45f707bedf34d19312c26d350bc0f3c59a47e58e8adbeecdc850d2c13a0" dependencies = [ "embed-resource", - "toml 0.7.8", + "toml", ] [[package]] @@ -7204,7 +7486,7 @@ dependencies = [ "libc", "log", "memmem", - "num-derive", + "num-derive 0.3.3", "num-traits", "ordered-float", "regex", @@ -7456,14 +7738,14 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4bf6fecd69fcdede0ec680aaf474cdab988f9de6bc73d3758f0160e3b7025a" +checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.26.1", + "tungstenite 0.26.2", ] [[package]] @@ -7479,18 +7761,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.19.15", -] - [[package]] name = "toml" version = "0.8.19" @@ -7519,8 +7789,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.7.1", - "serde", - "serde_spanned", "toml_datetime", "winnow 0.5.40", ] @@ -7738,22 +8006,23 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48a05076dd272615d03033bf04f480199f7d1b66a8ac64d75c625fc4a70c06b" +checksum = "d433764348e7084bad2c5ea22c96c71b61b17afe3a11645710f533bd72b6a2b5" dependencies = [ - "core-graphics 0.24.0", "crossbeam-channel", - "dirs 5.0.1", + "dirs 6.0.0", "libappindicator", "muda", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.0", "once_cell", "png", "serde", - "thiserror 1.0.69", + "thiserror 2.0.11", "windows-sys 0.59.0", ] @@ -7775,6 +8044,12 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + [[package]] name = "tungstenite" version = "0.21.0" @@ -7796,17 +8071,16 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ - "byteorder", "bytes", "data-encoding", "http 1.2.0", "httparse", "log", - "rand 0.8.5", + "rand 0.9.0", "sha1", "thiserror 2.0.11", "utf-8", @@ -8008,6 +8282,17 @@ dependencies = [ "serde", ] +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" @@ -8355,16 +8640,16 @@ dependencies = [ [[package]] name = "webview2-com" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "823e7ebcfaea51e78f72c87fc3b65a1e602c321f407a0b36dbb327d7bb7cd921" +checksum = "b0d606f600e5272b514dbb66539dd068211cc20155be8d3958201b4b5bd79ed3" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows 0.58.0", - "windows-core 0.58.0", - "windows-implement 0.58.0", - "windows-interface 0.58.0", + "windows 0.60.0", + "windows-core 0.60.1", + "windows-implement 0.59.0", + "windows-interface 0.59.0", ] [[package]] @@ -8380,13 +8665,13 @@ dependencies = [ [[package]] name = "webview2-com-sys" -version = "0.34.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a82bce72db6e5ee83c68b5de1e2cd6ea195b9fbff91cb37df5884cbe3222df4" +checksum = "bfb27fccd3c27f68e9a6af1bcf48c2d82534b8675b83608a4d81446d095a17ac" dependencies = [ - "thiserror 1.0.69", - "windows 0.58.0", - "windows-core 0.58.0", + "thiserror 2.0.11", + "windows 0.60.0", + "windows-core 0.60.1", ] [[package]] @@ -8462,13 +8747,14 @@ dependencies = [ [[package]] name = "window-vibrancy" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea403deff7b51fff19e261330f71608ff2cdef5721d72b64180bb95be7c4150" +checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" dependencies = [ - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", "raw-window-handle 0.6.2", "windows-sys 0.59.0", "windows-version", @@ -8504,6 +8790,28 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf874e74c7a99773e62b1c671427abf01a425e77c3d3fb9fb1e4883ea934529" +dependencies = [ + "windows-collections", + "windows-core 0.60.1", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5467f79cc1ba3f52ebb2ed41dbb459b8e7db636cc3429458d9a852e15bc24dec" +dependencies = [ + "windows-core 0.60.1", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -8550,6 +8858,29 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247" +dependencies = [ + "windows-implement 0.59.0", + "windows-interface 0.59.0", + "windows-link", + "windows-result 0.3.1", + "windows-strings 0.3.1", +] + +[[package]] +name = "windows-future" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a787db4595e7eb80239b74ce8babfb1363d8e343ab072f2ffe901400c03349f0" +dependencies = [ + "windows-core 0.60.1", + "windows-link", +] + [[package]] name = "windows-implement" version = "0.56.0" @@ -8583,6 +8914,17 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "windows-implement" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "windows-interface" version = "0.56.0" @@ -8616,6 +8958,33 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "windows-interface" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + +[[package]] +name = "windows-numerics" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005dea54e2f6499f2cee279b8f703b3cf3b5734a2d8d21867c8f44003182eeed" +dependencies = [ + "windows-core 0.60.1", + "windows-link", +] + [[package]] name = "windows-registry" version = "0.2.0" @@ -8656,6 +9025,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-strings" version = "0.1.0" @@ -8675,6 +9053,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -9041,12 +9428,12 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "wry" -version = "0.48.1" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2e33c08b174442ff80d5c791020696f9f8b4e4a87b8cfc7494aad6167ec44e1" +checksum = "d2ec139df5102db821f92a42033c3fa0467c5ab434511e79c65881d6bdf2b369" dependencies = [ "base64 0.22.1", - "block2", + "block2 0.6.0", "cookie", "crossbeam-channel", "dpi", @@ -9060,9 +9447,10 @@ dependencies = [ "kuchikiki", "libc", "ndk", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.0", + "objc2-app-kit 0.3.0", + "objc2-core-foundation", + "objc2-foundation 0.3.0", "objc2-ui-kit", "objc2-web-kit", "once_cell", @@ -9077,8 +9465,8 @@ dependencies = [ "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows 0.58.0", - "windows-core 0.58.0", + "windows 0.60.0", + "windows-core 0.60.1", "windows-version", "x11-dl", ] @@ -9249,7 +9637,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09612fda0b63f7cb9e0af7e5916fe5a1f8cdcb066829f10f36883207628a4872" +dependencies = [ + "zerocopy-derive 0.8.22", ] [[package]] @@ -9263,6 +9660,17 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79f81d38d7a2ed52d8f034e62c568e111df9bf8aba2f7cf19ddc5bf7bd89d520" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "zerofrom" version = "0.1.5" @@ -9328,9 +9736,9 @@ dependencies = [ [[package]] name = "zip" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9c1ea7b3a5e1f4b922ff856a129881167511563dc219869afe3787fc0c1a45" +checksum = "b280484c454e74e5fff658bbf7df8fdbe7a07c6b2de4a53def232c15ef138f3a" dependencies = [ "aes", "arbitrary", @@ -9397,6 +9805,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + [[package]] name = "zune-inflate" version = "0.2.54" @@ -9406,6 +9820,15 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "zune-jpeg" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" +dependencies = [ + "zune-core", +] + [[package]] name = "zvariant" version = "5.2.0" diff --git a/clash-verge-rev/src-tauri/Cargo.toml b/clash-verge-rev/src-tauri/Cargo.toml index cb71a46f84..947884981d 100755 --- a/clash-verge-rev/src-tauri/Cargo.toml +++ b/clash-verge-rev/src-tauri/Cargo.toml @@ -13,23 +13,23 @@ build = "build.rs" identifier = "io.github.clash-verge-rev.clash-verge-rev" [build-dependencies] -tauri-build = { version = "2.0.5", features = [] } +tauri-build = { version = "2.0.6", features = [] } [dependencies] warp = "0.3" -anyhow = "1.0" +anyhow = "1.0.97" dirs = "6.0" open = "5.1" log = "0.4" dunce = "1.0" log4rs = "1" nanoid = "0.4" -chrono = "0.4" +chrono = "0.4.40" sysinfo = "0.33.1" boa_engine = "0.20.0" serde_json = "1.0" serde_yaml = "0.9" -once_cell = "1.19" +once_cell = "1.20.3" port_scanner = "0.1.5" delay_timer = "0.11.6" parking_lot = "0.12" @@ -39,10 +39,10 @@ tokio = { version = "1.43", features = ["full"] } serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.12", features = ["json", "rustls-tls"] } sysproxy = { git = "https://github.com/clash-verge-rev/sysproxy-rs", rev = "3d748b5" } -image = "0.24" -imageproc = "0.23" +image = "0.25.5" +imageproc = "0.25.0" rusttype = "0.9" -tauri = { version = "2.2.5", features = [ +tauri = { version = "2.3.1", features = [ "protocol-asset", "devtools", "tray-icon", @@ -59,16 +59,17 @@ tauri-plugin-clipboard-manager = "2.2.1" tauri-plugin-deep-link = "2.2.0" tauri-plugin-devtools = "2.0.0-rc" url = "2.5.4" -zip = "2.2.2" +zip = "2.2.3" reqwest_dav = "0.1.14" aes-gcm = { version = "0.10.3", features = ["std"] } base64 = "0.22.1" -getrandom = "0.2" -tokio-tungstenite = "0.26.1" +getrandom = "0.3.1" +tokio-tungstenite = "0.26.2" futures = "0.3" sys-locale = "0.3.1" -async-trait = "0.1.86" +async-trait = "0.1.87" mihomo_api = { path = "./src/crate_mihomo_api" } +ab_glyph = "0.2.29" [target.'cfg(windows)'.dependencies] runas = "=1.2.0" @@ -76,14 +77,13 @@ deelevate = "0.2.0" winreg = "0.55.0" url = "2.5.4" - [target.'cfg(target_os = "linux")'.dependencies] users = "0.11.0" [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] tauri-plugin-autostart = "2.2.0" tauri-plugin-global-shortcut = "2.2.0" -tauri-plugin-updater = "2.3.0" +tauri-plugin-updater = "2.5.1" tauri-plugin-window-state = "2.2.1" #openssl @@ -125,7 +125,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] [dev-dependencies] env_logger = "0.11.0" -mockito = "1.2.0" +mockito = "1.7.0" tempfile = "3.17.1" [workspace] diff --git a/clash-verge-rev/src-tauri/src/config/clash.rs b/clash-verge-rev/src-tauri/src/config/clash.rs index 89412b2cd5..8a42e1fc11 100644 --- a/clash-verge-rev/src-tauri/src/config/clash.rs +++ b/clash-verge-rev/src-tauri/src/config/clash.rs @@ -38,6 +38,56 @@ impl IClashTemp { tun.insert("strict-route".into(), false.into()); tun.insert("auto-detect-interface".into(), true.into()); tun.insert("dns-hijack".into(), vec!["any:53"].into()); + + // 添加默认的DNS配置 + let mut dns = Mapping::new(); + dns.insert("enable".into(), true.into()); + dns.insert("listen".into(), ":53".into()); + dns.insert("enhanced-mode".into(), "fake-ip".into()); + dns.insert("fake-ip-range".into(), "198.18.0.1/16".into()); + dns.insert("fake-ip-filter-mode".into(), "blacklist".into()); + dns.insert("prefer-h3".into(), false.into()); + dns.insert("respect-rules".into(), false.into()); + dns.insert("use-hosts".into(), false.into()); + dns.insert("use-system-hosts".into(), false.into()); + + // 添加fake-ip-filter + dns.insert("fake-ip-filter".into(), vec![ + "*.lan", "*.local", "*.arpa", "time.*.com", "ntp.*.com", "time.*.com", + "+.market.xiaomi.com", "localhost.ptlogin2.qq.com", "*.msftncsi.com", "www.msftconnecttest.com" + ].into()); + + // 添加nameserver相关配置 + dns.insert("default-nameserver".into(), vec!["223.6.6.6", "8.8.8.8"].into()); + dns.insert("nameserver".into(), vec![ + "8.8.8.8", "https://doh.pub/dns-query", "https://dns.alidns.com/dns-query" + ].into()); + + // 添加fallback配置 + dns.insert("fallback".into(), vec![ + "https://dns.alidns.com/dns-query", "https://dns.google/dns-query", "https://cloudflare-dns.com/dns-query" + ].into()); + + // 添加proxy-server-nameserver + dns.insert("proxy-server-nameserver".into(), vec![ + "https://doh.pub/dns-query", "https://dns.alidns.com/dns-query" + ].into()); + + // 添加direct-nameserver + dns.insert("direct-nameserver".into(), Vec::::new().into()); + dns.insert("direct-nameserver-follow-policy".into(), false.into()); + + // 添加nameserver-policy (空对象) + dns.insert("nameserver-policy".into(), Mapping::new().into()); + + // 添加fallback-filter + let mut fallback_filter = Mapping::new(); + fallback_filter.insert("geoip".into(), true.into()); + fallback_filter.insert("geoip-code".into(), "CN".into()); + fallback_filter.insert("ipcidr".into(), vec!["240.0.0.0/4", "0.0.0.0/32"].into()); + fallback_filter.insert("domain".into(), vec!["+.google.com", "+.facebook.com", "+.youtube.com"].into()); + dns.insert("fallback-filter".into(), fallback_filter.into()); + #[cfg(not(target_os = "windows"))] map.insert("redir-port".into(), 7895.into()); #[cfg(target_os = "linux")] @@ -54,6 +104,7 @@ impl IClashTemp { cors_map.insert("allow-origins".into(), vec!["*"].into()); map.insert("secret".into(), "".into()); map.insert("tun".into(), tun.into()); + map.insert("dns".into(), dns.into()); map.insert("external-controller-cors".into(), cors_map.into()); map.insert("unified-delay".into(), true.into()); Self(map) diff --git a/clash-verge-rev/src-tauri/src/config/encrypt.rs b/clash-verge-rev/src-tauri/src/config/encrypt.rs index ef475f0e42..1ae5e106f8 100644 --- a/clash-verge-rev/src-tauri/src/config/encrypt.rs +++ b/clash-verge-rev/src-tauri/src/config/encrypt.rs @@ -16,7 +16,7 @@ pub fn encrypt_data(data: &str) -> Result> { // Generate random nonce let mut nonce = vec![0u8; NONCE_LENGTH]; - getrandom::getrandom(&mut nonce)?; + getrandom::fill(&mut nonce)?; // Encrypt data let ciphertext = cipher diff --git a/clash-verge-rev/src-tauri/src/core/tray/speed_rate.rs b/clash-verge-rev/src-tauri/src/core/tray/speed_rate.rs index fd09d12768..59a00ea530 100644 --- a/clash-verge-rev/src-tauri/src/core/tray/speed_rate.rs +++ b/clash-verge-rev/src-tauri/src/core/tray/speed_rate.rs @@ -1,11 +1,11 @@ use crate::core::clash_api::{get_traffic_ws_url, Rate}; use crate::utils::help::format_bytes_speed; +use ab_glyph::FontArc; use anyhow::Result; use futures::Stream; -use image::{Rgba, GenericImageView, RgbaImage}; +use image::{GenericImageView, Rgba, RgbaImage}; use imageproc::drawing::draw_text_mut; use parking_lot::Mutex; -use rusttype::{Font, Scale}; use std::io::Cursor; use std::sync::Arc; use tokio_tungstenite::tungstenite::Message; @@ -29,7 +29,7 @@ impl SpeedRate { let mut rates = self.rate.lock(); let mut last_update = self.last_update.lock(); let now = std::time::Instant::now(); - + // 限制更新频率为每秒最多2次(500ms) if now.duration_since(*last_update).as_millis() < 500 { return None; @@ -40,7 +40,8 @@ impl SpeedRate { // 如果速率变化不大(小于10%),则不更新 let should_update = { let up_change = (current.up as f64 - up as f64).abs() / (current.up as f64 + 1.0); - let down_change = (current.down as f64 - down as f64).abs() / (current.down as f64 + 1.0); + let down_change = + (current.down as f64 - down as f64).abs() / (current.down as f64 + 1.0); up_change > 0.1 || down_change > 0.1 }; @@ -69,21 +70,22 @@ impl SpeedRate { // 分离图标加载和速率渲染 pub fn add_speed_text(icon_bytes: Vec, rate: Option) -> Result> { let rate = rate.unwrap_or(Rate { up: 0, down: 0 }); - + // 加载原始图标 let icon_image = image::load_from_memory(&icon_bytes)?; let (icon_width, icon_height) = (icon_image.width(), icon_image.height()); - + // 判断是否为彩色图标 - let is_colorful = !crate::utils::help::is_monochrome_image_from_bytes(&icon_bytes).unwrap_or(false); - + let is_colorful = + !crate::utils::help::is_monochrome_image_from_bytes(&icon_bytes).unwrap_or(false); + // 增加文本宽度和间距 - let text_width = 580; // 文本区域宽度 + let text_width = 580; // 文本区域宽度 let total_width = icon_width + text_width; - + // 创建新的透明画布 let mut combined_image = RgbaImage::new(total_width, icon_height); - + // 将原始图标绘制到新画布的左侧 for y in 0..icon_height { for x in 0..icon_width { @@ -91,43 +93,49 @@ impl SpeedRate { combined_image.put_pixel(x, y, pixel); } } - + // 选择文本颜色 let (text_color, shadow_color) = if is_colorful { // 彩色图标使用黑色文本和轻微白色阴影 - (Rgba([255u8, 255u8, 255u8, 255u8]), Rgba([0u8, 0u8, 0u8, 160u8])) + ( + Rgba([255u8, 255u8, 255u8, 255u8]), + Rgba([0u8, 0u8, 0u8, 160u8]), + ) } else { // 单色图标使用白色文本和轻微黑色阴影 - (Rgba([255u8, 255u8, 255u8, 255u8]), Rgba([0u8, 0u8, 0u8, 120u8])) + ( + Rgba([255u8, 255u8, 255u8, 255u8]), + Rgba([0u8, 0u8, 0u8, 120u8]), + ) }; - // 减小字体大小以适应文本区域 - let font = Font::try_from_bytes(include_bytes!("../../../assets/fonts/SF-Pro.ttf")).unwrap(); - let font_size = icon_height as f32 * 0.6; // 稍微减小字体 - let scale = Scale::uniform(font_size); - + let font_data = include_bytes!("../../../assets/fonts/SF-Pro.ttf"); + let font = FontArc::try_from_vec(font_data.to_vec()).unwrap(); + let font_size = icon_height as f32 * 0.6; // 稍微减小字体 + let scale = ab_glyph::PxScale::from(font_size); + // 使用更简洁的速率格式 let up_text = format_bytes_speed(rate.up); let down_text = format_bytes_speed(rate.down); - + // 计算文本位置,确保垂直间距合适 // 修改文本位置为居右显示 let up_text_width = imageproc::drawing::text_size(scale, &font, &up_text).0 as u32; let down_text_width = imageproc::drawing::text_size(scale, &font, &down_text).0 as u32; - + // 计算右对齐的文本位置 let up_text_x = total_width - up_text_width; let down_text_x = total_width - down_text_width; - + // 优化垂直位置,使速率显示的高度和上下间距正好等于图标大小 let text_height = font_size as i32; let total_text_height = text_height * 2; let up_y = (icon_height as i32 - total_text_height) / 2; let down_y = up_y + text_height; - + // 绘制速率文本(先阴影后文字) let shadow_offset = 1; - + // 绘制上行速率 draw_text_mut( &mut combined_image, @@ -147,7 +155,7 @@ impl SpeedRate { &font, &up_text, ); - + // 绘制下行速率 draw_text_mut( &mut combined_image, @@ -167,13 +175,12 @@ impl SpeedRate { &font, &down_text, ); - + // 将结果转换为 PNG 数据 let mut bytes = Vec::new(); combined_image.write_to(&mut Cursor::new(&mut bytes), image::ImageFormat::Png)?; Ok(bytes) } - } #[derive(Debug, Clone)] diff --git a/clash-verge-rev/src-tauri/src/utils/dirs.rs b/clash-verge-rev/src-tauri/src/utils/dirs.rs index d4d8ddbfcf..5c5d2b84cc 100644 --- a/clash-verge-rev/src-tauri/src/utils/dirs.rs +++ b/clash-verge-rev/src-tauri/src/utils/dirs.rs @@ -137,7 +137,7 @@ pub fn get_encryption_key() -> Result> { } else { // Generate and save new key let mut key = vec![0u8; 32]; - getrandom::getrandom(&mut key)?; + getrandom::fill(&mut key)?; // Ensure directory exists if let Some(parent) = key_path.parent() { diff --git a/clash-verge-rev/src/components/layout/use-custom-theme.ts b/clash-verge-rev/src/components/layout/use-custom-theme.ts index a58e7c730c..3894e14283 100644 --- a/clash-verge-rev/src/components/layout/use-custom-theme.ts +++ b/clash-verge-rev/src/components/layout/use-custom-theme.ts @@ -92,7 +92,7 @@ export const useCustomTheme = () => { // css const backgroundColor = mode === "light" ? "#ECECEC" : "#2e303d"; const selectColor = mode === "light" ? "#f5f5f5" : "#d5d5d5"; - const scrollColor = mode === "light" ? "#90939980" : "#54545480"; + const scrollColor = mode === "light" ? "#90939980" : "#3E3E3Eee"; const dividerColor = mode === "light" ? "rgba(0, 0, 0, 0.06)" : "rgba(255, 255, 255, 0.06)"; diff --git a/clash-verge-rev/src/components/setting/mods/dns-viewer.tsx b/clash-verge-rev/src/components/setting/mods/dns-viewer.tsx new file mode 100644 index 0000000000..488843396e --- /dev/null +++ b/clash-verge-rev/src/components/setting/mods/dns-viewer.tsx @@ -0,0 +1,854 @@ +import { forwardRef, useImperativeHandle, useState, useEffect } from "react"; +import { useLockFn } from "ahooks"; +import { useTranslation } from "react-i18next"; +import { + Box, + Button, + FormControl, + List, + ListItem, + ListItemText, + MenuItem, + Select, + styled, + Switch, + TextField, + Typography, +} from "@mui/material"; +import { RestartAltRounded } from "@mui/icons-material"; +import { useClash } from "@/hooks/use-clash"; +import { BaseDialog, DialogRef, Notice } from "@/components/base"; +import yaml from "js-yaml"; +import MonacoEditor from "react-monaco-editor"; +import { useThemeMode } from "@/services/states"; +import getSystem from "@/utils/get-system"; + +const Item = styled(ListItem)(({ theme }) => ({ + padding: "8px 0", + borderBottom: `1px solid ${theme.palette.divider}`, + "& textarea": { + lineHeight: 1.5, + fontSize: 14, + resize: "vertical", + }, +})); + +// 默认DNS配置 +const DEFAULT_DNS_CONFIG = { + enable: true, + listen: ":53", + "enhanced-mode": "fake-ip" as "fake-ip" | "redir-host", + "fake-ip-range": "198.18.0.1/16", + "fake-ip-filter-mode": "blacklist" as "blacklist" | "whitelist", + "prefer-h3": false, + "respect-rules": false, + "use-hosts": false, + "use-system-hosts": false, + "fake-ip-filter": [ + "*.lan", + "*.local", + "*.arpa", + "time.*.com", + "ntp.*.com", + "time.*.com", + "+.market.xiaomi.com", + "localhost.ptlogin2.qq.com", + "*.msftncsi.com", + "www.msftconnecttest.com", + ], + "default-nameserver": ["223.6.6.6", "8.8.8.8"], + nameserver: [ + "8.8.8.8", + "https://doh.pub/dns-query", + "https://dns.alidns.com/dns-query", + ], + fallback: [ + "https://dns.alidns.com/dns-query", + "https://dns.google/dns-query", + "https://cloudflare-dns.com/dns-query", + ], + "nameserver-policy": {}, + "proxy-server-nameserver": [ + "https://doh.pub/dns-query", + "https://dns.alidns.com/dns-query", + ], + "direct-nameserver": [], + "direct-nameserver-follow-policy": false, + "fallback-filter": { + geoip: true, + "geoip-code": "CN", + ipcidr: ["240.0.0.0/4", "0.0.0.0/32"], + domain: ["+.google.com", "+.facebook.com", "+.youtube.com"], + }, +}; + +export const DnsViewer = forwardRef((props, ref) => { + const { t } = useTranslation(); + const { clash, mutateClash, patchClash } = useClash(); + const themeMode = useThemeMode(); + + const [open, setOpen] = useState(false); + const [visualization, setVisualization] = useState(true); + const [values, setValues] = useState<{ + enable: boolean; + listen: string; + enhancedMode: "fake-ip" | "redir-host"; + fakeIpRange: string; + fakeIpFilterMode: "blacklist" | "whitelist"; + preferH3: boolean; + respectRules: boolean; + fakeIpFilter: string; + nameserver: string; + fallback: string; + defaultNameserver: string; + useHosts: boolean; + useSystemHosts: boolean; + proxyServerNameserver: string; + directNameserver: string; + directNameserverFollowPolicy: boolean; + fallbackGeoip: boolean; + fallbackGeoipCode: string; + fallbackIpcidr: string; + fallbackDomain: string; + nameserverPolicy: string; + }>({ + enable: DEFAULT_DNS_CONFIG.enable, + listen: DEFAULT_DNS_CONFIG.listen, + enhancedMode: DEFAULT_DNS_CONFIG["enhanced-mode"], + fakeIpRange: DEFAULT_DNS_CONFIG["fake-ip-range"], + fakeIpFilterMode: DEFAULT_DNS_CONFIG["fake-ip-filter-mode"], + preferH3: DEFAULT_DNS_CONFIG["prefer-h3"], + respectRules: DEFAULT_DNS_CONFIG["respect-rules"], + fakeIpFilter: DEFAULT_DNS_CONFIG["fake-ip-filter"].join(", "), + defaultNameserver: DEFAULT_DNS_CONFIG["default-nameserver"].join(", "), + nameserver: DEFAULT_DNS_CONFIG.nameserver.join(", "), + fallback: DEFAULT_DNS_CONFIG.fallback.join(", "), + useHosts: DEFAULT_DNS_CONFIG["use-hosts"], + useSystemHosts: DEFAULT_DNS_CONFIG["use-system-hosts"], + proxyServerNameserver: + DEFAULT_DNS_CONFIG["proxy-server-nameserver"]?.join(", ") || "", + directNameserver: DEFAULT_DNS_CONFIG["direct-nameserver"]?.join(", ") || "", + directNameserverFollowPolicy: + DEFAULT_DNS_CONFIG["direct-nameserver-follow-policy"] || false, + fallbackGeoip: DEFAULT_DNS_CONFIG["fallback-filter"].geoip, + fallbackGeoipCode: DEFAULT_DNS_CONFIG["fallback-filter"]["geoip-code"], + fallbackIpcidr: + DEFAULT_DNS_CONFIG["fallback-filter"].ipcidr?.join(", ") || "", + fallbackDomain: + DEFAULT_DNS_CONFIG["fallback-filter"].domain?.join(", ") || "", + nameserverPolicy: "", + }); + + // 用于YAML编辑模式 + const [yamlContent, setYamlContent] = useState(""); + + useImperativeHandle(ref, () => ({ + open: () => { + setOpen(true); + resetToDefaults(); + }, + close: () => setOpen(false), + })); + + // 重置为默认值 + const resetToDefaults = () => { + setValues({ + enable: DEFAULT_DNS_CONFIG.enable, + listen: DEFAULT_DNS_CONFIG.listen, + enhancedMode: DEFAULT_DNS_CONFIG["enhanced-mode"], + fakeIpRange: DEFAULT_DNS_CONFIG["fake-ip-range"], + fakeIpFilterMode: DEFAULT_DNS_CONFIG["fake-ip-filter-mode"], + preferH3: DEFAULT_DNS_CONFIG["prefer-h3"], + respectRules: DEFAULT_DNS_CONFIG["respect-rules"], + fakeIpFilter: DEFAULT_DNS_CONFIG["fake-ip-filter"].join(", "), + defaultNameserver: DEFAULT_DNS_CONFIG["default-nameserver"].join(", "), + nameserver: DEFAULT_DNS_CONFIG.nameserver.join(", "), + fallback: DEFAULT_DNS_CONFIG.fallback.join(", "), + useHosts: DEFAULT_DNS_CONFIG["use-hosts"], + useSystemHosts: DEFAULT_DNS_CONFIG["use-system-hosts"], + proxyServerNameserver: + DEFAULT_DNS_CONFIG["proxy-server-nameserver"]?.join(", ") || "", + directNameserver: + DEFAULT_DNS_CONFIG["direct-nameserver"]?.join(", ") || "", + directNameserverFollowPolicy: + DEFAULT_DNS_CONFIG["direct-nameserver-follow-policy"] || false, + fallbackGeoip: DEFAULT_DNS_CONFIG["fallback-filter"].geoip, + fallbackGeoipCode: DEFAULT_DNS_CONFIG["fallback-filter"]["geoip-code"], + fallbackIpcidr: + DEFAULT_DNS_CONFIG["fallback-filter"].ipcidr?.join(", ") || "", + fallbackDomain: + DEFAULT_DNS_CONFIG["fallback-filter"].domain?.join(", ") || "", + nameserverPolicy: "", + }); + + // 更新YAML编辑器内容 + updateYamlFromValues(DEFAULT_DNS_CONFIG); + }; + + // 从表单值更新YAML内容 + const updateYamlFromValues = (dnsConfig: any = null) => { + // 如果提供了dnsConfig,直接使用它 + if (dnsConfig) { + setYamlContent(yaml.dump(dnsConfig, { forceQuotes: true })); + return; + } + + // 否则从当前表单值生成 + const config = generateDnsConfig(); + setYamlContent(yaml.dump(config, { forceQuotes: true })); + }; + + // 从YAML更新表单值 + const updateValuesFromYaml = () => { + try { + const dnsConfig = yaml.load(yamlContent) as any; + if (!dnsConfig) return; + + const enhancedMode = + dnsConfig["enhanced-mode"] || DEFAULT_DNS_CONFIG["enhanced-mode"]; + // 确保enhancedMode只能是"fake-ip"或"redir-host" + const validEnhancedMode = + enhancedMode === "fake-ip" || enhancedMode === "redir-host" + ? enhancedMode + : DEFAULT_DNS_CONFIG["enhanced-mode"]; + + const fakeIpFilterMode = + dnsConfig["fake-ip-filter-mode"] || + DEFAULT_DNS_CONFIG["fake-ip-filter-mode"]; + // 确保fakeIpFilterMode只能是"blacklist"或"whitelist" + const validFakeIpFilterMode = + fakeIpFilterMode === "blacklist" || fakeIpFilterMode === "whitelist" + ? fakeIpFilterMode + : DEFAULT_DNS_CONFIG["fake-ip-filter-mode"]; + + setValues({ + enable: dnsConfig.enable ?? DEFAULT_DNS_CONFIG.enable, + listen: dnsConfig.listen ?? DEFAULT_DNS_CONFIG.listen, + enhancedMode: validEnhancedMode, + fakeIpRange: + dnsConfig["fake-ip-range"] ?? DEFAULT_DNS_CONFIG["fake-ip-range"], + fakeIpFilterMode: validFakeIpFilterMode, + preferH3: dnsConfig["prefer-h3"] ?? DEFAULT_DNS_CONFIG["prefer-h3"], + respectRules: + dnsConfig["respect-rules"] ?? DEFAULT_DNS_CONFIG["respect-rules"], + fakeIpFilter: + dnsConfig["fake-ip-filter"]?.join(", ") ?? + DEFAULT_DNS_CONFIG["fake-ip-filter"].join(", "), + defaultNameserver: + dnsConfig["default-nameserver"]?.join(", ") ?? + DEFAULT_DNS_CONFIG["default-nameserver"].join(", "), + nameserver: + dnsConfig.nameserver?.join(", ") ?? + DEFAULT_DNS_CONFIG.nameserver.join(", "), + fallback: + dnsConfig.fallback?.join(", ") ?? + DEFAULT_DNS_CONFIG.fallback.join(", "), + useHosts: dnsConfig["use-hosts"] ?? DEFAULT_DNS_CONFIG["use-hosts"], + useSystemHosts: + dnsConfig["use-system-hosts"] ?? + DEFAULT_DNS_CONFIG["use-system-hosts"], + proxyServerNameserver: + dnsConfig["proxy-server-nameserver"]?.join(", ") ?? + (DEFAULT_DNS_CONFIG["proxy-server-nameserver"]?.join(", ") || ""), + directNameserver: + dnsConfig["direct-nameserver"]?.join(", ") ?? + (DEFAULT_DNS_CONFIG["direct-nameserver"]?.join(", ") || ""), + directNameserverFollowPolicy: + dnsConfig["direct-nameserver-follow-policy"] ?? + DEFAULT_DNS_CONFIG["direct-nameserver-follow-policy"], + fallbackGeoip: + dnsConfig["fallback-filter"]?.geoip ?? + DEFAULT_DNS_CONFIG["fallback-filter"].geoip, + fallbackGeoipCode: + dnsConfig["fallback-filter"]?.["geoip-code"] ?? + DEFAULT_DNS_CONFIG["fallback-filter"]["geoip-code"], + fallbackIpcidr: + dnsConfig["fallback-filter"]?.ipcidr?.join(", ") ?? + DEFAULT_DNS_CONFIG["fallback-filter"].ipcidr.join(", "), + fallbackDomain: + dnsConfig["fallback-filter"]?.domain?.join(", ") ?? + DEFAULT_DNS_CONFIG["fallback-filter"].domain.join(", "), + nameserverPolicy: + formatNameserverPolicy(dnsConfig["nameserver-policy"]) || "", + }); + } catch (err: any) { + Notice.error(t("Invalid YAML format")); + } + }; + + // 格式化nameserver-policy为字符串 + const formatNameserverPolicy = (policy: any): string => { + if (!policy) return ""; + + let result: string[] = []; + + Object.entries(policy).forEach(([domain, servers]) => { + if (Array.isArray(servers)) { + // 处理数组格式的服务器 + const serversStr = servers.join(";"); + result.push(`${domain}=${serversStr}`); + } else { + // 处理单个服务器 + result.push(`${domain}=${servers}`); + } + }); + + return result.join(", "); + }; + + // 解析nameserver-policy为对象 + const parseNameserverPolicy = (str: string): Record => { + const result: Record = {}; + if (!str) return result; + + str.split(",").forEach((item) => { + const parts = item.trim().split("="); + if (parts.length < 2) return; + + const domain = parts[0].trim(); + const serversStr = parts.slice(1).join("=").trim(); + + // 检查是否包含多个分号分隔的服务器 + if (serversStr.includes(";")) { + // 多个服务器,作为数组处理 + result[domain] = serversStr + .split(";") + .map((s) => s.trim()) + .filter(Boolean); + } else { + // 单个服务器 + result[domain] = serversStr; + } + }); + + return result; + }; + + // 初始化时设置默认YAML + useEffect(() => { + updateYamlFromValues(DEFAULT_DNS_CONFIG); + }, []); + + // 切换编辑模式时的处理 + useEffect(() => { + if (visualization) { + // 从YAML更新表单值 + updateValuesFromYaml(); + } else { + // 从表单值更新YAML + updateYamlFromValues(); + } + }, [visualization]); + + // 解析列表字符串为数组 + const parseList = (str: string): string[] => { + if (!str) return []; + return str + .split(",") + .map((item) => item.trim()) + .filter(Boolean); + }; + + // 生成DNS配置对象 + const generateDnsConfig = () => { + const dnsConfig: any = { + enable: values.enable, + listen: values.listen, + "enhanced-mode": values.enhancedMode, + "fake-ip-range": values.fakeIpRange, + "fake-ip-filter-mode": values.fakeIpFilterMode, + "prefer-h3": values.preferH3, + "respect-rules": values.respectRules, + "fake-ip-filter": parseList(values.fakeIpFilter), + "default-nameserver": parseList(values.defaultNameserver), + nameserver: parseList(values.nameserver), + fallback: parseList(values.fallback), + "use-hosts": values.useHosts, + "use-system-hosts": values.useSystemHosts, + "fallback-filter": { + geoip: values.fallbackGeoip, + "geoip-code": values.fallbackGeoipCode, + ipcidr: parseList(values.fallbackIpcidr), + domain: parseList(values.fallbackDomain), + }, + }; + + // 只在有nameserverPolicy时添加 + const policy = parseNameserverPolicy(values.nameserverPolicy); + if (Object.keys(policy).length > 0) { + dnsConfig["nameserver-policy"] = policy; + } + + // 只在有值时添加其他可选字段 + if (values.proxyServerNameserver) { + dnsConfig["proxy-server-nameserver"] = parseList( + values.proxyServerNameserver, + ); + } + + if (values.directNameserver) { + dnsConfig["direct-nameserver"] = parseList(values.directNameserver); + } + + dnsConfig["direct-nameserver-follow-policy"] = + values.directNameserverFollowPolicy; + + return dnsConfig; + }; + + const onSave = useLockFn(async () => { + try { + let dnsConfig; + + if (visualization) { + // 使用表单值 + dnsConfig = generateDnsConfig(); + } else { + // 使用YAML编辑器的值 + const parsedConfig = yaml.load(yamlContent); + if (typeof parsedConfig !== "object" || parsedConfig === null) { + throw new Error(t("Invalid DNS configuration")); + } + dnsConfig = parsedConfig; + } + + await patchClash({ dns: dnsConfig }); + mutateClash(); + setOpen(false); + Notice.success(t("DNS settings saved")); + } catch (err: any) { + Notice.error(err.message || err.toString()); + } + }); + + // YAML编辑器内容变更处理 + const handleYamlChange = (value: string) => { + setYamlContent(value || ""); + + // 允许YAML编辑后立即分析和更新表单值 + try { + const dnsConfig = yaml.load(value) as any; + if (dnsConfig && typeof dnsConfig === "object") { + // 稍微延迟更新,以避免性能问题 + setTimeout(() => { + updateValuesFromYaml(); + }, 300); + } + } catch (err) { + // 忽略解析错误,只有当YAML有效时才更新表单 + console.log("YAML解析错误,忽略自动更新", err); + } + }; + + // 处理表单值变化 + const handleChange = (field: string) => (event: any) => { + const value = + event.target.type === "checkbox" + ? event.target.checked + : event.target.value; + + setValues((prev) => { + const newValues = { + ...prev, + [field]: value, + }; + + // 当可视化编辑模式下的值变化时,自动更新YAML + if (visualization) { + setTimeout(() => { + updateYamlFromValues(null); + }, 0); + } + + return newValues; + }); + }; + + return ( + + {t("DNS Settings")} + + + + + + } + contentSx={{ + width: 550, + overflow: "auto", + ...(visualization + ? {} + : { padding: 0, display: "flex", flexDirection: "column" }), + }} + okBtn={t("Save")} + cancelBtn={t("Cancel")} + onClose={() => setOpen(false)} + onCancel={() => setOpen(false)} + onOk={onSave} + > + {/* Warning message */} + + {t("DNS Settings Warning")} + + + {visualization ? ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {t("Fallback Filter Settings")} + + + + + + + + + + + + + + + + + + + + + + + ) : ( + = 1500, + }, + mouseWheelZoom: true, + quickSuggestions: { + strings: true, + comments: true, + other: true, + }, + padding: { + top: 33, + }, + fontFamily: `Fira Code, JetBrains Mono, Roboto Mono, "Source Code Pro", Consolas, Menlo, Monaco, monospace, "Courier New", "Apple Color Emoji"${ + getSystem() === "windows" ? ", twemoji mozilla" : "" + }`, + fontLigatures: true, + smoothScrolling: true, + }} + onChange={handleYamlChange} + /> + )} + + ); +}); diff --git a/clash-verge-rev/src/components/setting/mods/network-interface-viewer.tsx b/clash-verge-rev/src/components/setting/mods/network-interface-viewer.tsx index 5c24eded2c..bd574b9ba3 100644 --- a/clash-verge-rev/src/components/setting/mods/network-interface-viewer.tsx +++ b/clash-verge-rev/src/components/setting/mods/network-interface-viewer.tsx @@ -47,7 +47,7 @@ export const NetworkInterfaceViewer = forwardRef((props, ref) => { } - contentSx={{ width: 450, maxHeight: 330 }} + contentSx={{ width: 450 }} disableOk cancelBtn={t("Close")} onCancel={() => setOpen(false)} @@ -66,7 +66,7 @@ export const NetworkInterfaceViewer = forwardRef((props, ref) => { label={t("Ip Address")} content={address.V4.ip} /> - ) + ), )} ((props, ref) => { label={t("Ip Address")} content={address.V6.ip} /> - ) + ), )} { "allow-lan": allowLan, "log-level": logLevel, "unified-delay": unifiedDelay, + dns, } = clash ?? {}; const { enable_random_port = false, verge_mixed_port } = verge ?? {}; @@ -47,6 +50,7 @@ const SettingClash = ({ onError }: Props) => { const ctrlRef = useRef(null); const coreRef = useRef(null); const networkRef = useRef(null); + const dnsRef = useRef(null); const onSwitchFormat = (_e: any, value: boolean) => value; const onChangeData = (patch: Partial) => { @@ -71,6 +75,7 @@ const SettingClash = ({ onError }: Props) => { + { + dnsRef.current?.open()} + /> + } + > + onChangeData({ dns: { ...dns, enable: e } })} + onGuard={(e) => patchClash({ dns: { enable: e } })} + > + + + + ; + "use-hosts"?: boolean; + "use-system-hosts"?: boolean; + "fallback-filter"?: { + geoip?: boolean; + "geoip-code"?: string; + ipcidr?: string[]; + domain?: string[]; + }; + }; } interface IRuleItem { diff --git a/lede/target/linux/generic/pending-6.6/155-usbnet-restore-usb%d-name-exception-for-local-mac-addresses.patch b/lede/target/linux/generic/pending-6.6/155-usbnet-restore-usb%d-name-exception-for-local-mac-addresses.patch new file mode 100644 index 0000000000..0d32800cbc --- /dev/null +++ b/lede/target/linux/generic/pending-6.6/155-usbnet-restore-usb%d-name-exception-for-local-mac-addresses.patch @@ -0,0 +1,63 @@ +From linux-netdev Tue Dec 03 13:04:55 2024 +From: Dominique Martinet +Date: Tue, 03 Dec 2024 13:04:55 +0000 +To: linux-netdev +Subject: [PATCH] net: usb: usbnet: restore usb%d name exception for local mac addresses +Message-Id: <20241203130457.904325-1-asmadeus () codewreck ! org> +X-MARC-Message: https://marc.info/?l=linux-netdev&m=173323431631309 + +From: Dominique Martinet + +The previous commit assumed that local addresses always came from the +kernel, but some devices hand out local mac addresses so we ended up +with point-to-point devices with a mac set by the driver, renaming to +eth%d when they used to be named usb%d. + +Userspace should not rely on device name, but for the sake of stability +restore the local mac address check portion of the naming exception: +point to point devices which either have no mac set by the driver or +have a local mac handed out by the driver will keep the usb%d name. + +Fixes: 8a7d12d674ac ("net: usb: usbnet: fix name regression") +Signed-off-by: Dominique Martinet +--- + drivers/net/usb/usbnet.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -178,6 +178,17 @@ int usbnet_get_ethernet_addr(struct usbn + } + EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr); + ++static bool usbnet_needs_usb_name_format(struct usbnet *dev, struct net_device *net) ++{ ++ /* Point to point devices which don't have a real MAC address ++ * (or report a fake local one) have historically used the usb%d ++ * naming. Preserve this.. ++ */ ++ return (dev->driver_info->flags & FLAG_POINTTOPOINT) != 0 && ++ (is_zero_ether_addr(net->dev_addr) || ++ is_local_ether_addr(net->dev_addr)); ++} ++ + static void intr_complete (struct urb *urb) + { + struct usbnet *dev = urb->context; +@@ -1766,13 +1777,10 @@ usbnet_probe (struct usb_interface *udev + if (status < 0) + goto out1; + +- // heuristic: "usb%d" for links we know are two-host, +- // else "eth%d" when there's reasonable doubt. userspace +- // can rename the link if it knows better. ++ /* heuristic: rename to "eth%d" if we are not sure this link ++ * is two-host (these links keep "usb%d") */ + if ((dev->driver_info->flags & FLAG_ETHER) != 0 && +- ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || +- /* somebody touched it*/ +- !is_zero_ether_addr(net->dev_addr))) ++ !usbnet_needs_usb_name_format(dev, net)) + strscpy(net->name, "eth%d", sizeof(net->name)); + /* WLAN devices should always be named "wlan%d" */ + if ((dev->driver_info->flags & FLAG_WLAN) != 0) diff --git a/naiveproxy/src/build/linux/sysroot_scripts/reversion_glibc.py b/naiveproxy/src/build/linux/sysroot_scripts/reversion_glibc.py index a20e5023f4..9b44c18d23 100644 --- a/naiveproxy/src/build/linux/sysroot_scripts/reversion_glibc.py +++ b/naiveproxy/src/build/linux/sysroot_scripts/reversion_glibc.py @@ -12,7 +12,7 @@ import subprocess # //chrome/installer/linux/rpm/dist_package_provides.json MAX_ALLOWED_GLIBC_VERSION = [2, 26] -VERSION_PATTERN = re.compile("GLIBC_([0-9\.]+)") +VERSION_PATTERN = re.compile(r"GLIBC_([0-9\.]+)") SECTION_PATTERN = re.compile(r"^ *\[ *[0-9]+\] +(\S+) +\S+ + ([0-9a-f]+) .*$") # Some otherwise disallowed symbols are referenced in the linux-chromeos build. @@ -34,7 +34,7 @@ def reversion_glibc(bin_file: str) -> None: stdout = subprocess.check_output( ["readelf", "--dyn-syms", "--wide", bin_file]) for line in stdout.decode("utf-8").split("\n"): - cols = re.split("\s+", line) + cols = re.split(r"\s+", line) # Skip the preamble. if len(cols) < 9: continue diff --git a/naiveproxy/src/build/linux/sysroot_scripts/sysroot_creator.py b/naiveproxy/src/build/linux/sysroot_scripts/sysroot_creator.py index 7239801092..a6ce7f5038 100755 --- a/naiveproxy/src/build/linux/sysroot_scripts/sysroot_creator.py +++ b/naiveproxy/src/build/linux/sysroot_scripts/sysroot_creator.py @@ -350,9 +350,6 @@ def hacks_and_patches(install_root: str, script_dir: str, arch: str) -> None: lib_path = os.path.join(install_root, "lib", TRIPLES[arch], lib) reversion_glibc.reversion_glibc(lib_path) - # Remove a cyclic symlink: /usr/bin/X11 -> /usr/bin - os.remove(os.path.join(install_root, "usr/bin/X11")) - def replace_in_file(file_path: str, search_pattern: str, replace_pattern: str) -> None: @@ -480,10 +477,8 @@ def removing_unnecessary_files(install_root, arch): # Preserve these files. gcc_triple = "i686-linux-gnu" if arch == "i386" else TRIPLES[arch] ALLOWLIST = { - "usr/bin/cups-config", f"usr/lib/gcc/{gcc_triple}/10/libgcc.a", f"usr/lib/{TRIPLES[arch]}/libc_nonshared.a", - f"usr/lib/{TRIPLES[arch]}/libffi_pic.a", } for file in ALLOWLIST: @@ -625,7 +620,6 @@ def build_sysroot(arch: str) -> None: hacks_and_patches(install_root, SCRIPT_DIR, arch) cleanup_jail_symlinks(install_root) removing_unnecessary_files(install_root, arch) - strip_sections(install_root, arch) restore_metadata(install_root, old_metadata) diff --git a/openwrt-packages/alist/Makefile b/openwrt-packages/alist/Makefile index e09576516b..7aec0f76bf 100644 --- a/openwrt-packages/alist/Makefile +++ b/openwrt-packages/alist/Makefile @@ -7,13 +7,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=alist -PKG_VERSION:=3.42.0 +PKG_VERSION:=null PKG_WEB_VERSION:=3.42.0 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/AlistGo/alist/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=e9d0370c6bbeaf7e3d25b8865b000892bcc1d61f3604b744b6778ba46281dc9a +PKG_HASH:=d5558cd419c8d46bdc958064cb97f963d1ea793866414c025906ec15033512ed PKG_LICENSE:=GPL-3.0 PKG_LICENSE_FILE:=LICENSE diff --git a/shadowsocks-rust/Cargo.lock b/shadowsocks-rust/Cargo.lock index 408c876144..e29e7e75b8 100644 --- a/shadowsocks-rust/Cargo.lock +++ b/shadowsocks-rust/Cargo.lock @@ -427,9 +427,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "c2rust-bitfields" @@ -3699,9 +3699,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.38" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb041120f25f8fbe8fd2dbe4671c7c2ed74d83be2e7a77529bf7e0790ae3f472" +checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" dependencies = [ "deranged", "itoa", diff --git a/sing-box/dns/transport/udp.go b/sing-box/dns/transport/udp.go index 5099c6f6d8..289b1fe2e8 100644 --- a/sing-box/dns/transport/udp.go +++ b/sing-box/dns/transport/udp.go @@ -110,13 +110,6 @@ func (t *UDPTransport) exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M conn.access.Lock() delete(conn.callbacks, messageId) conn.access.Unlock() - callback.access.Lock() - select { - case <-callback.done: - default: - close(callback.done) - } - callback.access.Unlock() }() rawMessage, err := exMessage.PackBuffer(buffer.FreeBytes()) if err != nil { diff --git a/sing-box/docs/configuration/dns/rule.md b/sing-box/docs/configuration/dns/rule.md index 3039bffce3..5d5cb7c3a1 100644 --- a/sing-box/docs/configuration/dns/rule.md +++ b/sing-box/docs/configuration/dns/rule.md @@ -4,6 +4,7 @@ icon: material/alert-decagram !!! quote "Changes in sing-box 1.12.0" + :material-plus: [ip_accept_any](#ip_accept_any) :material-delete-clock: [outbound](#outbound) !!! quote "Changes in sing-box 1.11.0" @@ -77,15 +78,6 @@ icon: material/alert-decagram "domain_regex": [ "^stun\\..+" ], - "geosite": [ - "cn" - ], - "source_geoip": [ - "private" - ], - "geoip": [ - "cn" - ], "source_ip_cidr": [ "10.0.0.0/24", "192.168.0.1" @@ -96,6 +88,7 @@ icon: material/alert-decagram "192.168.0.1" ], "ip_is_private": false, + "ip_accept_any": false, "source_port": [ 12345 ], @@ -147,8 +140,6 @@ icon: material/alert-decagram "geoip-cn", "geosite-cn" ], - // deprecated - "rule_set_ipcidr_match_source": false, "rule_set_ip_cidr_match_source": false, "rule_set_ip_cidr_accept_empty": false, "invert": false, @@ -156,7 +147,20 @@ icon: material/alert-decagram "direct" ], "action": "route", - "server": "local" + "server": "local", + + // Deprecated + + "rule_set_ipcidr_match_source": false, + "geosite": [ + "cn" + ], + "source_geoip": [ + "private" + ], + "geoip": [ + "cn" + ] }, { "type": "logical", @@ -451,7 +455,9 @@ Only takes effect for address requests (A/AAAA/HTTPS). When the query results do #### geoip -!!! question "Since sing-box 1.9.0" +!!! failure "Removed in sing-box 1.12.0" + + GeoIP is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0, check [Migration](/migration/#migrate-geoip-to-rule-sets). Match GeoIP with query response. @@ -473,6 +479,12 @@ Match private IP with query response. Make `ip_cidr` rules in rule-sets accept empty query response. +#### ip_accept_any + +!!! question "Since sing-box 1.12.0" + +Match any IP with query response. + ### Logical Fields #### type diff --git a/sing-box/docs/configuration/dns/rule.zh.md b/sing-box/docs/configuration/dns/rule.zh.md index 94ca453509..8973eba2bc 100644 --- a/sing-box/docs/configuration/dns/rule.zh.md +++ b/sing-box/docs/configuration/dns/rule.zh.md @@ -4,6 +4,7 @@ icon: material/alert-decagram !!! quote "sing-box 1.12.0 中的更改" + :material-plus: [ip_accept_any](#ip_accept_any) :material-delete-clock: [outbound](#outbound) !!! quote "sing-box 1.11.0 中的更改" @@ -77,15 +78,6 @@ icon: material/alert-decagram "domain_regex": [ "^stun\\..+" ], - "geosite": [ - "cn" - ], - "source_geoip": [ - "private" - ], - "geoip": [ - "cn" - ], "source_ip_cidr": [ "10.0.0.0/24", "192.168.0.1" @@ -96,6 +88,7 @@ icon: material/alert-decagram "192.168.0.1" ], "ip_is_private": false, + "ip_accept_any": false, "source_port": [ 12345 ], @@ -147,8 +140,6 @@ icon: material/alert-decagram "geoip-cn", "geosite-cn" ], - // 已弃用 - "rule_set_ipcidr_match_source": false, "rule_set_ip_cidr_match_source": false, "rule_set_ip_cidr_accept_empty": false, "invert": false, @@ -156,7 +147,19 @@ icon: material/alert-decagram "direct" ], "action": "route", - "server": "local" + "server": "local", + + // 已弃用 + "rule_set_ipcidr_match_source": false, + "geosite": [ + "cn" + ], + "source_geoip": [ + "private" + ], + "geoip": [ + "cn" + ] }, { "type": "logical", @@ -232,17 +235,17 @@ DNS 查询类型。值可以为整数或者类型名称字符串。 #### geosite -!!! failure "已在 sing-box 1.8.0 废弃" +!!! failure "已在 sing-box 1.12.0 中被移除" - Geosite 已废弃且可能在不久的将来移除,参阅 [迁移指南](/zh/migration/#geosite)。 + GeoSite 已在 sing-box 1.8.0 废弃且在 sing-box 1.12.0 中被移除,参阅 [迁移指南](/zh/migration/#geosite)。 匹配 Geosite。 #### source_geoip -!!! failure "已在 sing-box 1.8.0 废弃" +!!! failure "已在 sing-box 1.12.0 中被移除" - GeoIP 已废弃且可能在不久的将来移除,参阅 [迁移指南](/zh/migration/#geoip)。 + GeoIP 已在 sing-box 1.8.0 废弃且在 sing-box 1.12.0 中被移除,参阅 [迁移指南](/zh/migration/#geoip)。 匹配源 GeoIP。 @@ -451,7 +454,10 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`. #### geoip -!!! question "自 sing-box 1.9.0 起" +!!! failure "已在 sing-box 1.12.0 中被移除" + + GeoIP 已在 sing-box 1.8.0 废弃且在 sing-box 1.12.0 中被移除,参阅 [迁移指南](/zh/migration/#geoip)。 + 与查询响应匹配 GeoIP。 @@ -467,6 +473,12 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`. 与查询响应匹配非公开 IP。 +#### ip_accept_any + +!!! question "自 sing-box 1.12.0 起" + +匹配任意 IP。 + #### rule_set_ip_cidr_accept_empty !!! question "自 sing-box 1.10.0 起" diff --git a/sing-box/docs/configuration/dns/rule_action.zh.md b/sing-box/docs/configuration/dns/rule_action.zh.md index 7aa3da6dad..c2921ace26 100644 --- a/sing-box/docs/configuration/dns/rule_action.zh.md +++ b/sing-box/docs/configuration/dns/rule_action.zh.md @@ -13,8 +13,7 @@ icon: material/new-box ```json { - "action": "route", - // 默认 + "action": "route", // 默认 "server": "", "strategy": "", "disable_cache": false, diff --git a/sing-box/experimental/clashapi/server_resources.go b/sing-box/experimental/clashapi/server_resources.go index f480ebf0a2..ad9fff5369 100644 --- a/sing-box/experimental/clashapi/server_resources.go +++ b/sing-box/experimental/clashapi/server_resources.go @@ -77,15 +77,15 @@ func (s *Server) downloadExternalUI() error { if response.StatusCode != http.StatusOK { return E.New("download external ui failed: ", response.Status) } - err = s.downloadZIP(filepath.Base(downloadURL), response.Body, s.externalUI) + err = s.downloadZIP(response.Body, s.externalUI) if err != nil { removeAllInDirectory(s.externalUI) } return err } -func (s *Server) downloadZIP(name string, body io.Reader, output string) error { - tempFile, err := filemanager.CreateTemp(s.ctx, name) +func (s *Server) downloadZIP(body io.Reader, output string) error { + tempFile, err := filemanager.CreateTemp(s.ctx, "external-ui.zip") if err != nil { return err } diff --git a/small/ipt2socks/Makefile b/small/ipt2socks/Makefile index 781991b7fc..806766776c 100644 --- a/small/ipt2socks/Makefile +++ b/small/ipt2socks/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ipt2socks -PKG_VERSION:=1.1.5 +PKG_VERSION:=1.1.4 PKG_RELEASE:=3 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/zfl9/ipt2socks/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=762c3e24962c0b4a46ea8285ae36b0a3123ddbd062681a67779c26905132026c +PKG_HASH:=68dc76e63951d655c2fd9b420e175b5a75a50014d6db6e729398b41f2c988356 PKG_BUILD_PARALLEL:=1 PKG_USE_MIPS16:=0 diff --git a/small/luci-app-fchomo/docs/Ruleset-URI-Scheme.md b/small/luci-app-fchomo/docs/Ruleset-URI-Scheme.md index e76070b38b..e13cdfc992 100644 --- a/small/luci-app-fchomo/docs/Ruleset-URI-Scheme.md +++ b/small/luci-app-fchomo/docs/Ruleset-URI-Scheme.md @@ -2,9 +2,9 @@ ## Structure -**remote:** `http[s]://[auth@]?fmt=&behav=[&key=value][#label]` -**local:** `file://[host]?fmt=&behav=[&fill=][#label]` -**inline:** `inline://?behav=[#label]` +**remote:** `http[s]://[auth@]?fmt=&behav=[&key=value][#label]`\ +**local:** `file://[host]?fmt=&behav=[&fill=][#label]`\ +**inline:** `inline://?behav=[#label]` ## Components @@ -18,8 +18,8 @@ Add it only if required by the target host. ### Host -The format is `hostname[:port]`. -`hostname` can be **Domain** or **IP Address**. +The format is `hostname[:port]`.\ +`hostname` can be **Domain** or **IP Address**.\ `:port` is optional, add it only if required by the target host. ### Path @@ -48,7 +48,7 @@ The update interval for the Rule set, in seconds or /^(\d+)(s|m|h|d)?$/. #### rawQuery -This parameter is required if the original link contains a url query. +This parameter is required if the original link contains a url query.\ Encrypt the part `key1=value1&key2=value2` after `?` in the original link with `encodeURIComponent` and use it as the payload of this parameter. #### filler @@ -65,5 +65,5 @@ Generation steps: ### URIFragment -Ruleset label. Empty strings are not recommended. +Ruleset label. Empty strings are not recommended.\ Need encoded by `encodeURIComponent`. diff --git a/small/luci-app-fchomo/docs/example/bypasscn.config b/small/luci-app-fchomo/docs/example/bypasscn.config index a3ab75a688..5ec0394b9d 100644 --- a/small/luci-app-fchomo/docs/example/bypasscn.config +++ b/small/luci-app-fchomo/docs/example/bypasscn.config @@ -5,6 +5,8 @@ config fchomo 'config' option common_udpport '20-21,22,53,80,110,143,443,853,993,995,8080,8443,9418' option stun_port '3478,19302' option turn_port '5349' + option steam_client_port '27015-27050' + option steam_p2p_udpport '3478,4379,4380,27000-27100' option tun_name 'hmtun0' option tun_addr4 '198.19.0.1/30' option tun_addr6 'fdfe:dcba:9877::1/126' diff --git a/small/luci-app-fchomo/docs/example/gfwlist.config b/small/luci-app-fchomo/docs/example/gfwlist.config index 55d472664e..16df6d821c 100644 --- a/small/luci-app-fchomo/docs/example/gfwlist.config +++ b/small/luci-app-fchomo/docs/example/gfwlist.config @@ -5,6 +5,8 @@ config fchomo 'config' option common_udpport '20-21,22,53,80,110,143,443,853,993,995,8080,8443,9418' option stun_port '3478,19302' option turn_port '5349' + option steam_client_port '27015-27050' + option steam_p2p_udpport '3478,4379,4380,27000-27100' option tun_name 'hmtun0' option tun_addr4 '198.19.0.1/30' option tun_addr6 'fdfe:dcba:9877::1/126' diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js b/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js index 6f6ceab386..577402de2d 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js @@ -142,6 +142,8 @@ const routing_port_type = [ ['common_udpport', _('Common ports (bypass P2P traffic)'), uci.get('fchomo', 'routing', 'common_udpport') || '20-21,22,53,80,110,143,443,853,993,995,8080,8443,9418'], ['stun_port', _('STUN ports'), uci.get('fchomo', 'routing', 'stun_port') || '3478,19302'], ['turn_port', _('TURN ports'), uci.get('fchomo', 'routing', 'turn_port') || '5349'], + ['steam_client_port', _('Steam Client ports'), uci.get('fchomo', 'routing', 'steam_client_port') || '27015-27050'], + ['steam_p2p_udpport', _('Steam P2P ports'), uci.get('fchomo', 'routing', 'steam_p2p_udpport') || '3478,4379,4380,27000-27100'], ]; const rules_type = [ diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/client.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/client.js index d34a5a932b..102bd328e6 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/client.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/client.js @@ -799,6 +799,17 @@ return view.extend({ .format('https://wiki.metacubex.one/config/proxy-groups/#exclude-type')); so.placeholder = 'Shadowsocks|Trojan'; so.modalonly = true; + + so = ss.taboption('field_general', form.Flag, 'hidden', _('Hidden'), + _('Returns hidden status in the API to hide the display of this proxy group.') + '
' + + _('requires front-end adaptation using the API.')); + so.default = so.disabled; + so.modalonly = true; + + so = ss.taboption('field_general', form.Value, 'icon', _('Icon'), + _('Returns the string input for icon in the API to display in this proxy group.') + '
' + + _('requires front-end adaptation using the API.')); + so.modalonly = true; /* Proxy Group END */ /* Routing rules START */ diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/global.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/global.js index 92158d0b54..ef7e92583e 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/global.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/global.js @@ -168,9 +168,9 @@ return view.extend({ return E('strong', [features.core_version || _('Unknown')]); } - so = ss.option(form.DummyValue, '_luciapp_version', _('Application version')); + so = ss.option(form.DummyValue, '_app_version', _('Application version')); so.cfgvalue = function() { - return E('strong', [features.luciapp_version || _('Unknown')]); + return E('strong', [features.app_version || _('Unknown')]); } so = ss.option(form.DummyValue, '_client_status', _('Client status')); @@ -231,7 +231,7 @@ return view.extend({ so.value.apply(so, res); }) so.rmempty = false; - if (!features.hm_has_stunclient) { + if (!features.has_stunclient) { so.description = _('To check NAT Behavior you need to install stuntman-client first') .format('https://github.com/muink/openwrt-stuntman'); so.readonly = true; @@ -475,9 +475,9 @@ return view.extend({ so = ss.option(form.ListValue, 'proxy_mode', _('Proxy mode')); so.value('redir', _('Redirect TCP')); - if (features.hm_has_tproxy) + if (features.has_tproxy) so.value('redir_tproxy', _('Redirect TCP + TProxy UDP')); - if (features.hm_has_ip_full && features.hm_has_tun) { + if (features.has_ip_full && features.has_tun) { so.value('redir_tun', _('Redirect TCP + Tun UDP')); so.value('tun', _('Tun TCP/UDP')); } else @@ -757,7 +757,7 @@ return view.extend({ _('Specify target ports to be proxied. Multiple ports must be separated by commas.')); so.create = true; hm.routing_port_type.forEach((res) => { - if (res[0] !== 'common_udpport') + if (!res[0].match(/_udpport$/)) so.value.apply(so, res); }) so.validate = L.bind(hm.validateCommonPort, so); @@ -766,7 +766,7 @@ return view.extend({ _('Specify target ports to be proxied. Multiple ports must be separated by commas.')); so.create = true; hm.routing_port_type.forEach((res) => { - if (res[0] !== 'common_tcpport') + if (!res[0].match(/_tcpport$/)) so.value.apply(so, res); }) so.validate = L.bind(hm.validateCommonPort, so); @@ -782,7 +782,7 @@ return view.extend({ _('Please ensure that the DNS query of the domains to be processed in the DNS policy
' + 'are send via DIRECT/Proxy Node in the same semantics as Routing mode.')); so.default = so.disabled; - if (!features.hm_has_dnsmasq_full) { + if (!features.has_dnsmasq_full) { so.description = _('To enable, you need to install dnsmasq-full.'); so.readonly = true; uci.set(data[0], so.section.section, so.option, ''); diff --git a/small/luci-app-fchomo/po/templates/fchomo.pot b/small/luci-app-fchomo/po/templates/fchomo.pot index e6678d175d..b4f878e8ce 100644 --- a/small/luci-app-fchomo/po/templates/fchomo.pot +++ b/small/luci-app-fchomo/po/templates/fchomo.pot @@ -1010,6 +1010,10 @@ msgstr "" msgid "Heartbeat interval" msgstr "" +#: htdocs/luci-static/resources/view/fchomo/client.js:803 +msgid "Hidden" +msgstr "" + #: htdocs/luci-static/resources/view/fchomo/node.js:441 msgid "Host that supports TLS 1.3" msgstr "" @@ -1063,6 +1067,10 @@ msgstr "" msgid "IPv6 support" msgstr "" +#: htdocs/luci-static/resources/view/fchomo/client.js:809 +msgid "Icon" +msgstr "" + #: htdocs/luci-static/resources/view/fchomo/node.js:289 msgid "Idle session check interval" msgstr "" @@ -1891,6 +1899,16 @@ msgstr "" msgid "Restls script" msgstr "" +#: htdocs/luci-static/resources/view/fchomo/client.js:804 +msgid "" +"Returns hidden status in the API to hide the display of this proxy group." +msgstr "" + +#: htdocs/luci-static/resources/view/fchomo/client.js:810 +msgid "" +"Returns the string input for icon in the API to display in this proxy group." +msgstr "" + #: htdocs/luci-static/resources/view/fchomo/global.js:754 msgid "Routing Control" msgstr "" @@ -2118,6 +2136,14 @@ msgstr "" msgid "Stack" msgstr "" +#: htdocs/luci-static/resources/fchomo.js:145 +msgid "Steam Client ports" +msgstr "" + +#: htdocs/luci-static/resources/fchomo.js:146 +msgid "Steam P2P ports" +msgstr "" + #: htdocs/luci-static/resources/view/fchomo/client.js:776 #: htdocs/luci-static/resources/view/fchomo/client.js:778 msgid "Strategy" @@ -2684,6 +2710,11 @@ msgstr "" msgid "razord-meta" msgstr "" +#: htdocs/luci-static/resources/view/fchomo/client.js:805 +#: htdocs/luci-static/resources/view/fchomo/client.js:811 +msgid "requires front-end adaptation using the API." +msgstr "" + #: htdocs/luci-static/resources/view/fchomo/node.js:430 msgid "restls" msgstr "" diff --git a/small/luci-app-fchomo/po/zh_Hans/fchomo.po b/small/luci-app-fchomo/po/zh_Hans/fchomo.po index ff3c1d25ee..d6276691c1 100644 --- a/small/luci-app-fchomo/po/zh_Hans/fchomo.po +++ b/small/luci-app-fchomo/po/zh_Hans/fchomo.po @@ -1030,6 +1030,10 @@ msgstr "健康字段" msgid "Heartbeat interval" msgstr "心跳间隔" +#: htdocs/luci-static/resources/view/fchomo/client.js:803 +msgid "Hidden" +msgstr "隐藏" + #: htdocs/luci-static/resources/view/fchomo/node.js:441 msgid "Host that supports TLS 1.3" msgstr "主机名称 (支援 TLS 1.3)" @@ -1083,6 +1087,10 @@ msgstr "仅 IPv6" msgid "IPv6 support" msgstr "IPv6 支持" +#: htdocs/luci-static/resources/view/fchomo/client.js:809 +msgid "Icon" +msgstr "图标" + #: htdocs/luci-static/resources/view/fchomo/node.js:289 msgid "Idle session check interval" msgstr "空闲会话检查间隔" @@ -1918,6 +1926,16 @@ msgstr "资源管理" msgid "Restls script" msgstr "Restls 剧本" +#: htdocs/luci-static/resources/view/fchomo/client.js:804 +msgid "" +"Returns hidden status in the API to hide the display of this proxy group." +msgstr "在 API 返回 hidden 状态,以隐藏该代理组显示" + +#: htdocs/luci-static/resources/view/fchomo/client.js:810 +msgid "" +"Returns the string input for icon in the API to display in this proxy group." +msgstr "在 API 返回 icon 所输入的字符串,以在该代理组显示" + #: htdocs/luci-static/resources/view/fchomo/global.js:754 msgid "Routing Control" msgstr "路由控制" @@ -2145,6 +2163,14 @@ msgstr "指定需要被代理的目标端口。多个端口必须用逗号隔开 msgid "Stack" msgstr "堆栈" +#: htdocs/luci-static/resources/fchomo.js:145 +msgid "Steam Client ports" +msgstr "Steam 客户端 端口" + +#: htdocs/luci-static/resources/fchomo.js:146 +msgid "Steam P2P ports" +msgstr "Steam P2P 端口" + #: htdocs/luci-static/resources/view/fchomo/client.js:776 #: htdocs/luci-static/resources/view/fchomo/client.js:778 msgid "Strategy" @@ -2718,6 +2744,11 @@ msgstr "私钥" msgid "razord-meta" msgstr "razord-meta" +#: htdocs/luci-static/resources/view/fchomo/client.js:805 +#: htdocs/luci-static/resources/view/fchomo/client.js:811 +msgid "requires front-end adaptation using the API." +msgstr "需要使用 API 的前端适配" + #: htdocs/luci-static/resources/view/fchomo/node.js:430 msgid "restls" msgstr "" diff --git a/small/luci-app-fchomo/po/zh_Hant/fchomo.po b/small/luci-app-fchomo/po/zh_Hant/fchomo.po index 6d517d49a1..3c0638b04a 100644 --- a/small/luci-app-fchomo/po/zh_Hant/fchomo.po +++ b/small/luci-app-fchomo/po/zh_Hant/fchomo.po @@ -1030,6 +1030,10 @@ msgstr "健康欄位" msgid "Heartbeat interval" msgstr "心跳間隔" +#: htdocs/luci-static/resources/view/fchomo/client.js:803 +msgid "Hidden" +msgstr "隱藏" + #: htdocs/luci-static/resources/view/fchomo/node.js:441 msgid "Host that supports TLS 1.3" msgstr "主機名稱 (支援 TLS 1.3)" @@ -1083,6 +1087,10 @@ msgstr "僅 IPv6" msgid "IPv6 support" msgstr "IPv6 支援" +#: htdocs/luci-static/resources/view/fchomo/client.js:809 +msgid "Icon" +msgstr "圖標" + #: htdocs/luci-static/resources/view/fchomo/node.js:289 msgid "Idle session check interval" msgstr "空閒會話檢查間隔" @@ -1918,6 +1926,16 @@ msgstr "資源管理" msgid "Restls script" msgstr "Restls 劇本" +#: htdocs/luci-static/resources/view/fchomo/client.js:804 +msgid "" +"Returns hidden status in the API to hide the display of this proxy group." +msgstr "在 API 傳回 hidden 狀態,以隱藏該代理組顯示" + +#: htdocs/luci-static/resources/view/fchomo/client.js:810 +msgid "" +"Returns the string input for icon in the API to display in this proxy group." +msgstr "在 API 傳回 icon 所輸入的字串,以在該代理組顯示" + #: htdocs/luci-static/resources/view/fchomo/global.js:754 msgid "Routing Control" msgstr "路由控制" @@ -2145,6 +2163,14 @@ msgstr "指定需要被代理的目標連接埠。多個連接埠必須以逗號 msgid "Stack" msgstr "堆栈" +#: htdocs/luci-static/resources/fchomo.js:145 +msgid "Steam Client ports" +msgstr "Steam 客戶端 連接埠" + +#: htdocs/luci-static/resources/fchomo.js:146 +msgid "Steam P2P ports" +msgstr "Steam P2P 連接埠" + #: htdocs/luci-static/resources/view/fchomo/client.js:776 #: htdocs/luci-static/resources/view/fchomo/client.js:778 msgid "Strategy" @@ -2718,6 +2744,11 @@ msgstr "私鑰" msgid "razord-meta" msgstr "razord-meta" +#: htdocs/luci-static/resources/view/fchomo/client.js:805 +#: htdocs/luci-static/resources/view/fchomo/client.js:811 +msgid "requires front-end adaptation using the API." +msgstr "需要使用 API 的前端適配" + #: htdocs/luci-static/resources/view/fchomo/node.js:430 msgid "restls" msgstr "" diff --git a/small/luci-app-fchomo/root/etc/config/fchomo b/small/luci-app-fchomo/root/etc/config/fchomo index 35909cd8b3..35e55997f6 100644 --- a/small/luci-app-fchomo/root/etc/config/fchomo +++ b/small/luci-app-fchomo/root/etc/config/fchomo @@ -5,6 +5,8 @@ config fchomo 'config' option common_udpport '20-21,22,53,80,110,143,443,853,993,995,8080,8443,9418' option stun_port '3478,19302' option turn_port '5349' + option steam_client_port '27015-27050' + option steam_p2p_udpport '3478,4379,4380,27000-27100' option tun_name 'hmtun0' option tun_addr4 '198.19.0.1/30' option tun_addr6 'fdfe:dcba:9877::1/126' diff --git a/small/luci-app-fchomo/root/usr/share/fchomo/firewall_post.ut b/small/luci-app-fchomo/root/usr/share/fchomo/firewall_post.ut index f84d2ede46..f51164a2a0 100644 --- a/small/luci-app-fchomo/root/usr/share/fchomo/firewall_post.ut +++ b/small/luci-app-fchomo/root/usr/share/fchomo/firewall_post.ut @@ -4,7 +4,7 @@ {%- import { readfile } from 'fs'; import { cursor } from 'uci'; - import { isEmpty, yqRead } from 'fchomo'; + import { isEmpty, yqReadFile } from 'fchomo'; const fw4 = require('fw4'); @@ -57,11 +57,16 @@ const uci = cursor(); uci.load(cfgname); - const common_tcpport = uci.get(cfgname, 'config', 'common_tcpport') || '20-21,22,53,80,110,143,443,465,853,873,993,995,5222,8080,8443,9418', - common_udpport = uci.get(cfgname, 'config', 'common_udpport') || '20-21,22,53,80,110,143,443,853,993,995,8080,8443,9418', - stun_port = uci.get(cfgname, 'config', 'stun_port') || '3478,19302', - turn_port = uci.get(cfgname, 'config', 'turn_port') || '5349', - tun_name = uci.get(cfgname, 'config', 'tun_name') || 'hmtun0', + const port_presets = { + common_tcpport: uci.get(cfgname, 'config', 'common_tcpport') || '20-21,22,53,80,110,143,443,465,853,873,993,995,5222,8080,8443,9418', + common_udpport: uci.get(cfgname, 'config', 'common_udpport') || '20-21,22,53,80,110,143,443,853,993,995,8080,8443,9418', + stun_port: uci.get(cfgname, 'config', 'stun_port') || '3478,19302', + turn_port: uci.get(cfgname, 'config', 'turn_port') || '5349', + steam_client_port: uci.get(cfgname, 'config', 'steam_client_port') || '27015-27050', + steam_p2p_udpport: uci.get(cfgname, 'config', 'steam_p2p_udpport') || '3478,4379,4380,27000-27100', + }; + + const tun_name = uci.get(cfgname, 'config', 'tun_name') || 'hmtun0', self_mark = uci.get(cfgname, 'config', 'self_mark') || '200', tproxy_mark = resolve_mark(uci.get(cfgname, 'config', 'tproxy_mark') || '201'), tun_mark = resolve_mark(uci.get(cfgname, 'config', 'tun_mark') || '202'); @@ -95,10 +100,7 @@ return null; return join(',', map(arr, (val) => { - if (val === 'common_tcpport') return common_tcpport; - if (val === 'common_udpport') return common_udpport; - if (val === 'stun_port') return stun_port; - if (val === 'turn_port') return turn_port; + if (port_presets[val]) return port_presets[val]; return val; })); } @@ -120,10 +122,10 @@ for (let i in control_options) control_info[i] = uci.get(cfgname, 'routing', i); - control_info.wan_direct_ipv4_ips = json(trim(yqRead('-oj', '.IPCIDR', resources_dir + '/direct_list.yaml')) || '[]'); - control_info.wan_direct_ipv6_ips = json(trim(yqRead('-oj', '.IPCIDR6', resources_dir + '/direct_list.yaml')) || '[]'); - control_info.wan_proxy_ipv4_ips = json(trim(yqRead('-oj', '.IPCIDR', resources_dir + '/proxy_list.yaml')) || '[]'); - control_info.wan_proxy_ipv6_ips = json(trim(yqRead('-oj', '.IPCIDR6', resources_dir + '/proxy_list.yaml')) || '[]'); + control_info.wan_direct_ipv4_ips = json(trim(yqReadFile('-oj', '.IPCIDR', resources_dir + '/direct_list.yaml')) || '[]'); + control_info.wan_direct_ipv6_ips = json(trim(yqReadFile('-oj', '.IPCIDR6', resources_dir + '/direct_list.yaml')) || '[]'); + control_info.wan_proxy_ipv4_ips = json(trim(yqReadFile('-oj', '.IPCIDR', resources_dir + '/proxy_list.yaml')) || '[]'); + control_info.wan_proxy_ipv6_ips = json(trim(yqReadFile('-oj', '.IPCIDR6', resources_dir + '/proxy_list.yaml')) || '[]'); /* UCI config end */ -%} diff --git a/small/luci-app-fchomo/root/usr/share/fchomo/generate_client.uc b/small/luci-app-fchomo/root/usr/share/fchomo/generate_client.uc index 3568a425b9..8a90455030 100644 --- a/small/luci-app-fchomo/root/usr/share/fchomo/generate_client.uc +++ b/small/luci-app-fchomo/root/usr/share/fchomo/generate_client.uc @@ -46,10 +46,14 @@ const ucisniff = 'sniff', ucisubro = 'subrules'; /* Hardcode options */ -const common_tcpport = uci.get(uciconf, ucifchm, 'common_tcpport') || '20-21,22,53,80,110,143,443,465,853,873,993,995,5222,8080,8443,9418', - common_udpport = uci.get(uciconf, ucifchm, 'common_udpport') || '20-21,22,53,80,110,143,443,853,993,995,8080,8443,9418', - stun_port = uci.get(uciconf, ucifchm, 'stun_port') || '3478,19302', - turn_port = uci.get(uciconf, ucifchm, 'turn_port') || '5349', +const port_presets = { + common_tcpport: uci.get(uciconf, ucifchm, 'common_tcpport') || '20-21,22,53,80,110,143,443,465,853,873,993,995,5222,8080,8443,9418', + common_udpport: uci.get(uciconf, ucifchm, 'common_udpport') || '20-21,22,53,80,110,143,443,853,993,995,8080,8443,9418', + stun_port: uci.get(uciconf, ucifchm, 'stun_port') || '3478,19302', + turn_port: uci.get(uciconf, ucifchm, 'turn_port') || '5349', + steam_client_port: uci.get(uciconf, ucifchm, 'steam_client_port') || '27015-27050', + steam_p2p_udpport: uci.get(uciconf, ucifchm, 'steam_p2p_udpport') || '3478,4379,4380,27000-27100', + }, tun_name = uci.get(uciconf, ucifchm, 'tun_name') || 'hmtun0', tun_addr4 = uci.get(uciconf, ucifchm, 'tun_addr4') || '198.19.0.1/30', tun_addr6 = uci.get(uciconf, ucifchm, 'tun_addr6') || 'fdfe:dcba:9877::1/126', @@ -662,9 +666,12 @@ uci.foreach(uciconf, ucipgrp, (cfg) => { lazy: (cfg.lazy === '0') ? false : null, "expected-status": cfg.url ? cfg.expected_status || '204' : null, "max-failed-times": cfg.url ? strToInt(cfg.max_failed_times) ?? 5 : null, + // General fields filter: parse_filter(cfg.filter), "exclude-filter": parse_filter(cfg.exclude_filter), - "exclude-type": parse_filter(cfg.exclude_type) + "exclude-type": parse_filter(cfg.exclude_type), + hidden: strToBool(cfg.hidden), + icon: cfg.icon }); }); /* Proxy Group END */ diff --git a/small/luci-app-fchomo/root/usr/share/rpcd/ucode/luci.fchomo b/small/luci-app-fchomo/root/usr/share/rpcd/ucode/luci.fchomo index 4c07bb7d4e..903c934e4c 100644 --- a/small/luci-app-fchomo/root/usr/share/rpcd/ucode/luci.fchomo +++ b/small/luci-app-fchomo/root/usr/share/rpcd/ucode/luci.fchomo @@ -4,17 +4,9 @@ import { access, lsdir, lstat, popen, readfile, writefile } from 'fs'; import { - shellQuote, yqRead, + shellQuote, isBinary, yqReadFile, HM_DIR, EXE_DIR, SDL_DIR, RUN_DIR -} from '/usr/share/fchomo/fchomo.uc'; - -function isBinary(str) { - for (let off = 0, byte = ord(str); off < length(str); byte = ord(str, ++off)) - if (byte <= 8 || (byte >= 14 && byte <= 31)) - return true; - - return false; -} +} from 'fchomo'; function hasKernelModule(kmod) { return (system(sprintf('[ -e "/lib/modules/$(uname -r)"/%s ]', shellQuote(kmod))) === 0); @@ -100,20 +92,15 @@ const methods = { fd.close(); } - const fp = popen(`${use_apk ? 'apk list -I' : 'opkg list-installed'} luci-app-fchomo | ` + - `awk '{print $${use_apk ? '1' : 'NF'}}'`); - if (fp) { - features.luciapp_version = trim(fp.read('line')) || null; + features.app_version = trim(popen(`${use_apk ? 'apk list -I' : 'opkg list-installed'} luci-app-fchomo | ` + + `awk '{print $${use_apk ? '1' : 'NF'}}'`).read('all')) || null; - fp.close(); - } - - features.hm_has_dnsmasq_full = system(`[ -n "$(${use_apk ? 'apk list -qI' : 'opkg list-installed'} dnsmasq-full)" ]`) == 0 || null; - features.hm_has_ip_full = access('/usr/libexec/ip-full'); - features.hm_has_stunclient = access('/usr/bin/stunclient'); - features.hm_has_tcp_brutal = hasKernelModule('brutal.ko'); - features.hm_has_tproxy = hasKernelModule('nft_tproxy.ko') || access('/etc/modules.d/nft-tproxy'); - features.hm_has_tun = hasKernelModule('tun.ko') || access('/etc/modules.d/30-tun'); + features.has_dnsmasq_full = system(`[ -n "$(${use_apk ? 'apk list -qI' : 'opkg list-installed'} dnsmasq-full)" ]`) == 0 || null; + features.has_ip_full = access('/usr/libexec/ip-full'); + features.has_stunclient = access('/usr/bin/stunclient'); + features.has_tcp_brutal = hasKernelModule('brutal.ko'); + features.has_tproxy = hasKernelModule('nft_tproxy.ko') || access('/etc/modules.d/nft-tproxy'); + features.has_tun = hasKernelModule('tun.ko') || access('/etc/modules.d/30-tun'); return features; } @@ -125,7 +112,7 @@ const methods = { if (req.args?.instance) { const instance = req.args?.instance; - let config = json(trim(yqRead('-oj', '.[] |= with(select(type == "!!map"); del(.)) |= with(select(type == "!!seq"); del(.))', `${RUN_DIR}/${instance}.yaml`)) || '{}'); + let config = json(trim(yqReadFile('-oj', '.[] |= with(select(type == "!!map"); del(.)) |= with(select(type == "!!seq"); del(.))', `${RUN_DIR}/${instance}.yaml`)) || '{}'); return { http: config['external-controller'], @@ -144,13 +131,7 @@ const methods = { if (!req.args?.url) return { httpcode: null, error: 'illegal url' }; - let httpcode = '-1'; - const fd = popen("wget --spider -t1 -ST3 '" + req.args?.url + "' 2>&1 | awk '/^\\s*HTTP\\//{print $2}'"); - if (fd) { - httpcode = trim(fd.read('line')) || httpcode; - - fd.close(); - } + const httpcode = trim(popen(`wget --spider -t1 -ST3 '${req.args?.url}' 2>&1 | awk '/^\\s*HTTP\\//{print $2}'`).read('all')) || '-1'; return { httpcode: httpcode }; } diff --git a/small/luci-app-fchomo/root/usr/share/fchomo/fchomo.uc b/small/luci-app-fchomo/root/usr/share/ucode/fchomo.uc similarity index 77% rename from small/luci-app-fchomo/root/usr/share/fchomo/fchomo.uc rename to small/luci-app-fchomo/root/usr/share/ucode/fchomo.uc index 58cd1c3737..9f7eb0d70e 100644 --- a/small/luci-app-fchomo/root/usr/share/fchomo/fchomo.uc +++ b/small/luci-app-fchomo/root/usr/share/ucode/fchomo.uc @@ -27,16 +27,44 @@ export function shellQuote(s) { return `'${replace(s, "'", "'\\''")}'`; }; -export function yqRead(flags, command, filepath) { - let out = ''; +export function isBinary(str) { + for (let off = 0, byte = ord(str); off < length(str); byte = ord(str, ++off)) + if (byte <= 8 || (byte >= 14 && byte <= 31)) + return true; - const fd = popen(`yq ${flags} ${shellQuote(command)} ${filepath}`); - if (fd) { - out = fd.read('all'); - fd.close(); - } + return false; +}; - return out; +export function executeCommand(...args) { + let outfd = mkstemp(); + let errfd = mkstemp(); + + const exitcode = system(`${join(' ', args)} >&${outfd.fileno()} 2>&${errfd.fileno()}`); + + outfd.seek(); + errfd.seek(); + + const stdout = outfd.read(1024 * 1024) ?? ''; + const stderr = errfd.read(1024 * 1024) ?? ''; + + outfd.close(); + errfd.close(); + + const binary = isBinary(stdout); + + return { + command: join(' ', args), + stdout: binary ? null : stdout, + stderr, + exitcode, + binary + }; +}; + +export function yqReadFile(flags, command, filepath) { + const out = executeCommand('yq', flags, shellQuote(command), filepath); + + return out.stdout; }; /* Utilities end */ diff --git a/small/xray-core/Makefile b/small/xray-core/Makefile index a32fe91338..f6b0a94f69 100644 --- a/small/xray-core/Makefile +++ b/small/xray-core/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=xray-core -PKG_VERSION:=25.2.21 +PKG_VERSION:=25.3.6 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/XTLS/Xray-core/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=a565db518d2da12fabb74e123d9bf2bdbc34420b81373938f8fcbc7004fda3ba +PKG_HASH:=d62305348deff713767fe1b3c23538e3f8bfe0c96d092f1f95f48c17bc2f5943 PKG_MAINTAINER:=Tianling Shen PKG_LICENSE:=MPL-2.0 diff --git a/v2rayn/v2rayN/Directory.Build.props b/v2rayn/v2rayN/Directory.Build.props index d87fcc7fd3..3bf10e0908 100644 --- a/v2rayn/v2rayN/Directory.Build.props +++ b/v2rayn/v2rayN/Directory.Build.props @@ -1,7 +1,7 @@ - 7.10.3 + 7.10.4 diff --git a/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys.Test/HotKeyManagerTests.cs b/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys.Test/HotKeyManagerTests.cs index a5d7aab1e9..1be437b9ae 100644 --- a/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys.Test/HotKeyManagerTests.cs +++ b/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys.Test/HotKeyManagerTests.cs @@ -26,8 +26,8 @@ public class HotKeyManagerTests using var s1 = manager.Register(VirtualKeyCode.KEY_0, Modifiers.Shift); using var s2 = manager.Register(VirtualKeyCode.KEY_1, Modifiers.Shift); // assert - Assert.AreEqual(0, s1.Id); - Assert.AreEqual(1, s2.Id); + Assert.That(s1.Id, Is.EqualTo(0)); + Assert.That(s2.Id, Is.EqualTo(1)); } [Test] @@ -40,7 +40,7 @@ public class HotKeyManagerTests s1.Dispose(); using var s2 = manager.Register(VirtualKeyCode.KEY_1, Modifiers.Shift); // assert - Assert.AreEqual(0, s1.Id); - Assert.AreEqual(0, s2.Id); + Assert.That(s1.Id, Is.EqualTo(0)); + Assert.That(s2.Id, Is.EqualTo(0)); } -} \ No newline at end of file +} diff --git a/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys/NativeFunctions.cs b/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys/NativeFunctions.cs index 8ac479ac23..f45fc486cd 100644 --- a/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys/NativeFunctions.cs +++ b/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys/NativeFunctions.cs @@ -4,42 +4,42 @@ namespace GlobalHotKeys; public class NativeFunctions { - [DllImport("user32.dll", SetLastError = true)] + [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern bool RegisterHotKey(IntPtr hWnd, int id, Modifiers fsModifiers, VirtualKeyCode vk); - [DllImport("user32.dll", SetLastError = true)] + [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); - [DllImport("user32.dll", SetLastError = true)] + [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam); - [DllImport("user32.dll", SetLastError = true)] + [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern int RegisterClassEx(ref WNDCLASSEX lpwcx); - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern IntPtr CreateWindowEx(int dwExStyle, uint regResult, string lpWindowName, WindowStyle dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam); - [DllImport("user32.dll", SetLastError = true)] + [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern bool DestroyWindow(IntPtr hWnd); - [DllImport("user32.dll", SetLastError = true)] + [DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] public static extern bool UnregisterClass(string lpClassName, IntPtr hInstance); - [DllImport("user32.dll")] + [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern int GetMessage(ref TagMSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); - [DllImport("user32.dll")] + [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern bool TranslateMessage(ref TagMSG lpMsg); - [DllImport("user32.dll")] + [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern IntPtr DispatchMessage(ref TagMSG lpmsg); - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr GetModuleHandle(string lpModuleName); + [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr GetModuleHandle(string? lpModuleName); - [DllImport("user32.dll")] + [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - [DllImport("user32.dll")] + [DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)] public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); -} \ No newline at end of file +} diff --git a/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys/NativeTypes.cs b/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys/NativeTypes.cs index e81027a5b5..60da241035 100644 --- a/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys/NativeTypes.cs +++ b/v2rayn/v2rayN/GlobalHotKeys/src/GlobalHotKeys/NativeTypes.cs @@ -35,7 +35,7 @@ public struct WNDCLASSEX public IntPtr hIcon; public IntPtr hCursor; public IntPtr hbrBackground; - public string lpszMenuName; + public string? lpszMenuName; public string lpszClassName; public IntPtr hIconSm; @@ -258,4 +258,4 @@ public enum VirtualKeyCode VK_ZOOM = 0xFB, VK_NONAME = 0xFC, VK_PA1 = 0xFD -} \ No newline at end of file +} diff --git a/v2rayn/v2rayN/ServiceLib/Common/DownloaderHelper.cs b/v2rayn/v2rayN/ServiceLib/Common/DownloaderHelper.cs index a7870041cf..03dcf8e384 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/DownloaderHelper.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/DownloaderHelper.cs @@ -10,7 +10,7 @@ namespace ServiceLib.Common public async Task DownloadStringAsync(IWebProxy? webProxy, string url, string? userAgent, int timeout) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { return null; } @@ -18,7 +18,7 @@ namespace ServiceLib.Common Uri uri = new(url); //Authorization Header var headers = new WebHeaderCollection(); - if (Utils.IsNotEmpty(uri.UserInfo)) + if (uri.UserInfo.IsNotEmpty()) { headers.Add(HttpRequestHeader.Authorization, "Basic " + Utils.Base64Encode(uri.UserInfo)); } @@ -56,7 +56,7 @@ namespace ServiceLib.Common public async Task DownloadDataAsync4Speed(IWebProxy webProxy, string url, IProgress progress, int timeout) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(url)); } @@ -86,7 +86,7 @@ namespace ServiceLib.Common //}; downloader.DownloadProgressChanged += (sender, value) => { - var ts = (DateTime.Now - totalDatetime); + var ts = DateTime.Now - totalDatetime; if (progress != null && ts.Seconds > totalSecond) { hasValue = true; @@ -119,11 +119,11 @@ namespace ServiceLib.Common public async Task DownloadFileAsync(IWebProxy? webProxy, string url, string fileName, IProgress progress, int timeout) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(url)); } - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(fileName)); } @@ -146,10 +146,7 @@ namespace ServiceLib.Common var progressPercentage = 0; var hasValue = false; await using var downloader = new Downloader.DownloadService(downloadOpt); - downloader.DownloadStarted += (sender, value) => - { - progress?.Report(0); - }; + downloader.DownloadStarted += (sender, value) => progress?.Report(0); downloader.DownloadProgressChanged += (sender, value) => { hasValue = true; diff --git a/v2rayn/v2rayN/ServiceLib/Common/FileManager.cs b/v2rayn/v2rayN/ServiceLib/Common/FileManager.cs index 4431fbeaa0..2f452899c5 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/FileManager.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/FileManager.cs @@ -1,4 +1,4 @@ -using System.Formats.Tar; +using System.Formats.Tar; using System.IO.Compression; using System.Text; @@ -99,7 +99,7 @@ namespace ServiceLib.Common } try { - if (Utils.IsNotEmpty(ignoredName) && entry.Name.Contains(ignoredName)) + if (ignoredName.IsNotEmpty() && entry.Name.Contains(ignoredName)) { continue; } @@ -163,18 +163,20 @@ namespace ServiceLib.Common // Check if the source directory exists if (!dir.Exists) + { throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}"); + } // Cache directories before we start copying var dirs = dir.GetDirectories(); // Create the destination directory - Directory.CreateDirectory(destinationDir); + _ = Directory.CreateDirectory(destinationDir); // Get the files in the source directory and copy to the destination directory foreach (var file in dir.GetFiles()) { - if (Utils.IsNotEmpty(ignoredName) && file.Name.Contains(ignoredName)) + if (ignoredName.IsNotEmpty() && file.Name.Contains(ignoredName)) { continue; } @@ -187,7 +189,7 @@ namespace ServiceLib.Common { continue; } - file.CopyTo(targetFilePath, overwrite); + _ = file.CopyTo(targetFilePath, overwrite); } // If recursive and copying subdirectories, recursively call this method @@ -222,4 +224,4 @@ namespace ServiceLib.Common } } } -} \ No newline at end of file +} diff --git a/v2rayn/v2rayN/ServiceLib/Common/HttpClientHelper.cs b/v2rayn/v2rayN/ServiceLib/Common/HttpClientHelper.cs index 9c8082a02d..f532062ea7 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/HttpClientHelper.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/HttpClientHelper.cs @@ -18,12 +18,17 @@ namespace ServiceLib.Common public static HttpClientHelper Instance => _instance.Value; private readonly HttpClient httpClient; - private HttpClientHelper(HttpClient httpClient) => this.httpClient = httpClient; + private HttpClientHelper(HttpClient httpClient) + { + this.httpClient = httpClient; + } public async Task TryGetAsync(string url) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) + { return null; + } try { @@ -38,15 +43,19 @@ namespace ServiceLib.Common public async Task GetAsync(string url) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) + { return null; + } return await httpClient.GetStringAsync(url); } public async Task GetAsync(HttpClient client, string url, CancellationToken token = default) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) + { return null; + } return await client.GetStringAsync(url, token); } @@ -55,13 +64,13 @@ namespace ServiceLib.Common var jsonContent = JsonUtils.Serialize(headers); var content = new StringContent(jsonContent, Encoding.UTF8, MediaTypeNames.Application.Json); - var result = await httpClient.PutAsync(url, content); + await httpClient.PutAsync(url, content); } public async Task PatchAsync(string url, Dictionary headers) { var myContent = JsonUtils.Serialize(headers); - var buffer = System.Text.Encoding.UTF8.GetBytes(myContent); + var buffer = Encoding.UTF8.GetBytes(myContent); var byteContent = new ByteArrayContent(buffer); byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); @@ -78,12 +87,16 @@ namespace ServiceLib.Common ArgumentNullException.ThrowIfNull(url); ArgumentNullException.ThrowIfNull(fileName); if (File.Exists(fileName)) + { File.Delete(fileName); + } using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token); if (!response.IsSuccessStatusCode) + { throw new Exception(response.StatusCode.ToString()); + } var total = response.Content.Headers.ContentLength ?? -1L; var canReportProgress = total != -1 && progress != null; @@ -102,7 +115,9 @@ namespace ServiceLib.Common totalRead += read; if (read == 0) + { break; + } await file.WriteAsync(buffer.AsMemory(0, read), token); if (canReportProgress) @@ -123,7 +138,7 @@ namespace ServiceLib.Common public async Task DownloadDataAsync4Speed(HttpClient client, string url, IProgress progress, CancellationToken token = default) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(url)); } @@ -173,7 +188,7 @@ namespace ServiceLib.Common totalRead += read; - var ts = (DateTime.Now - totalDatetime); + var ts = DateTime.Now - totalDatetime; if (progress != null && ts.Seconds > totalSecond) { totalSecond = ts.Seconds; diff --git a/v2rayn/v2rayN/ServiceLib/Common/Job.cs b/v2rayn/v2rayN/ServiceLib/Common/Job.cs index 5b0276f377..fdbc8dbf65 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/Job.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/Job.cs @@ -15,27 +15,29 @@ namespace ServiceLib.Common public Job() { handle = CreateJobObject(IntPtr.Zero, null); - IntPtr extendedInfoPtr = IntPtr.Zero; - JOBOBJECT_BASIC_LIMIT_INFORMATION info = new() + var extendedInfoPtr = IntPtr.Zero; + var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION { LimitFlags = 0x2000 }; - JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new() + var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION { BasicLimitInformation = info }; try { - int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); + var length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); extendedInfoPtr = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false); if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length)) + { throw new Exception(string.Format("Unable to set information. Error: {0}", Marshal.GetLastWin32Error())); + } } finally { @@ -48,7 +50,7 @@ namespace ServiceLib.Common public bool AddProcess(IntPtr processHandle) { - bool succ = AssignProcessToJobObject(handle, processHandle); + var succ = AssignProcessToJobObject(handle, processHandle); if (!succ) { @@ -76,7 +78,9 @@ namespace ServiceLib.Common private void Dispose(bool disposing) { if (disposed) + { return; + } disposed = true; if (disposing) @@ -104,7 +108,7 @@ namespace ServiceLib.Common private static extern IntPtr CreateJobObject(IntPtr a, string? lpName); [DllImport("kernel32.dll", SetLastError = true)] - private static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength); + private static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process); @@ -121,34 +125,34 @@ namespace ServiceLib.Common [StructLayout(LayoutKind.Sequential)] internal struct IO_COUNTERS { - public UInt64 ReadOperationCount; - public UInt64 WriteOperationCount; - public UInt64 OtherOperationCount; - public UInt64 ReadTransferCount; - public UInt64 WriteTransferCount; - public UInt64 OtherTransferCount; + public ulong ReadOperationCount; + public ulong WriteOperationCount; + public ulong OtherOperationCount; + public ulong ReadTransferCount; + public ulong WriteTransferCount; + public ulong OtherTransferCount; } [StructLayout(LayoutKind.Sequential)] internal struct JOBOBJECT_BASIC_LIMIT_INFORMATION { - public Int64 PerProcessUserTimeLimit; - public Int64 PerJobUserTimeLimit; - public UInt32 LimitFlags; + public long PerProcessUserTimeLimit; + public long PerJobUserTimeLimit; + public uint LimitFlags; public UIntPtr MinimumWorkingSetSize; public UIntPtr MaximumWorkingSetSize; - public UInt32 ActiveProcessLimit; + public uint ActiveProcessLimit; public UIntPtr Affinity; - public UInt32 PriorityClass; - public UInt32 SchedulingClass; + public uint PriorityClass; + public uint SchedulingClass; } [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { - public UInt32 nLength; + public uint nLength; public IntPtr lpSecurityDescriptor; - public Int32 bInheritHandle; + public int bInheritHandle; } [StructLayout(LayoutKind.Sequential)] diff --git a/v2rayn/v2rayN/ServiceLib/Common/Logging.cs b/v2rayn/v2rayN/ServiceLib/Common/Logging.cs index 16c9228ae1..7f7089b752 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/Logging.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/Logging.cs @@ -28,7 +28,9 @@ namespace ServiceLib.Common public static void SaveLog(string strContent) { if (!LogManager.IsLoggingEnabled()) + { return; + } LogManager.GetLogger("Log1").Info(strContent); } @@ -36,7 +38,9 @@ namespace ServiceLib.Common public static void SaveLog(string strTitle, Exception ex) { if (!LogManager.IsLoggingEnabled()) + { return; + } var logger = LogManager.GetLogger("Log2"); logger.Debug($"{strTitle},{ex.Message}"); diff --git a/v2rayn/v2rayN/ServiceLib/Common/ProcUtils.cs b/v2rayn/v2rayN/ServiceLib/Common/ProcUtils.cs index 70b6f3c6d4..561278ce0a 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/ProcUtils.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/ProcUtils.cs @@ -8,7 +8,7 @@ public static class ProcUtils public static void ProcessStart(string? fileName, string arguments = "") { - ProcessStart(fileName, arguments, null); + _ = ProcessStart(fileName, arguments, null); } public static int? ProcessStart(string? fileName, string arguments, string? dir) @@ -38,7 +38,7 @@ public static class ProcUtils WorkingDirectory = dir ?? string.Empty } }; - proc.Start(); + _ = proc.Start(); return dir is null ? null : proc.Id; } catch (Exception ex) @@ -60,7 +60,7 @@ public static class ProcUtils FileName = Utils.GetExePath().AppendQuotes(), Verb = blAdmin ? "runas" : null, }; - Process.Start(startInfo); + _ = Process.Start(startInfo); } catch (Exception ex) { @@ -138,7 +138,9 @@ public static class ProcUtils fileName = null; processName = null; if (!review) + { return; + } try { procId = proc?.Id; diff --git a/v2rayn/v2rayN/ServiceLib/Common/QRCodeHelper.cs b/v2rayn/v2rayN/ServiceLib/Common/QRCodeHelper.cs index 7a024a3ece..5cd5ac2541 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/QRCodeHelper.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/QRCodeHelper.cs @@ -60,7 +60,7 @@ namespace ServiceLib.Common var reader = new BarcodeReader(); var result = reader.Decode(bitmap); - if (result != null && Utils.IsNotEmpty(result.Text)) + if (result != null && result.Text.IsNotEmpty()) { return result.Text; } diff --git a/v2rayn/v2rayN/ServiceLib/Common/SemanticVersion.cs b/v2rayn/v2rayN/ServiceLib/Common/SemanticVersion.cs index 0a5bd5b9dd..5bfc96929c 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/SemanticVersion.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/SemanticVersion.cs @@ -1,29 +1,29 @@ -namespace ServiceLib.Common +namespace ServiceLib.Common { public class SemanticVersion { - private int major; - private int minor; - private int patch; - private string version; + private readonly int major; + private readonly int minor; + private readonly int patch; + private readonly string version; public SemanticVersion(int major, int minor, int patch) { this.major = major; this.minor = minor; this.patch = patch; - this.version = $"{major}.{minor}.{patch}"; + version = $"{major}.{minor}.{patch}"; } public SemanticVersion(string? version) { try { - if (version.IsNullOrEmpty()) + if (string.IsNullOrEmpty(version)) { - this.major = 0; - this.minor = 0; - this.patch = 0; + major = 0; + minor = 0; + patch = 0; return; } this.version = version.RemovePrefix('v'); @@ -31,15 +31,15 @@ var parts = this.version.Split('.'); if (parts.Length == 2) { - this.major = int.Parse(parts.First()); - this.minor = int.Parse(parts.Last()); - this.patch = 0; + major = int.Parse(parts.First()); + minor = int.Parse(parts.Last()); + patch = 0; } else if (parts.Length is 3 or 4) { - this.major = int.Parse(parts[0]); - this.minor = int.Parse(parts[1]); - this.patch = int.Parse(parts[2]); + major = int.Parse(parts[0]); + minor = int.Parse(parts[1]); + patch = int.Parse(parts[2]); } else { @@ -48,9 +48,9 @@ } catch { - this.major = 0; - this.minor = 0; - this.patch = 0; + major = 0; + minor = 0; + patch = 0; } } @@ -58,7 +58,7 @@ { if (obj is SemanticVersion other) { - return this.major == other.major && this.minor == other.minor && this.patch == other.patch; + return major == other.major && minor == other.minor && patch == other.patch; } else { @@ -68,7 +68,7 @@ public override int GetHashCode() { - return this.major.GetHashCode() ^ this.minor.GetHashCode() ^ this.patch.GetHashCode(); + return major.GetHashCode() ^ minor.GetHashCode() ^ patch.GetHashCode(); } /// @@ -77,18 +77,18 @@ /// major.minor.patch public override string ToString() { - return this.version; + return version; } public string ToVersionString(string? prefix = null) { if (prefix == null) { - return this.version; + return version; } else { - return $"{prefix}{this.version}"; + return $"{prefix}{version}"; } } @@ -108,31 +108,31 @@ private bool GreaterEquals(SemanticVersion other) { - if (this.major < other.major) + if (major < other.major) { return false; } - else if (this.major > other.major) + else if (major > other.major) { return true; } else { - if (this.minor < other.minor) + if (minor < other.minor) { return false; } - else if (this.minor > other.minor) + else if (minor > other.minor) { return true; } else { - if (this.patch < other.patch) + if (patch < other.patch) { return false; } - else if (this.patch > other.patch) + else if (patch > other.patch) { return true; } @@ -146,31 +146,31 @@ private bool LessEquals(SemanticVersion other) { - if (this.major < other.major) + if (major < other.major) { return true; } - else if (this.major > other.major) + else if (major > other.major) { return false; } else { - if (this.minor < other.minor) + if (minor < other.minor) { return true; } - else if (this.minor > other.minor) + else if (minor > other.minor) { return false; } else { - if (this.patch < other.patch) + if (patch < other.patch) { return true; } - else if (this.patch > other.patch) + else if (patch > other.patch) { return false; } @@ -184,4 +184,4 @@ #endregion Private } -} \ No newline at end of file +} diff --git a/v2rayn/v2rayN/ServiceLib/Common/SqliteHelper.cs b/v2rayn/v2rayN/ServiceLib/Common/SqliteHelper.cs index 10a7793b22..dca10c57b2 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/SqliteHelper.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/SqliteHelper.cs @@ -7,7 +7,7 @@ namespace ServiceLib.Common { private static readonly Lazy _instance = new(() => new()); public static SQLiteHelper Instance => _instance.Value; - private string _connstr; + private readonly string _connstr; private SQLiteConnection _db; private SQLiteAsyncConnection _dbAsync; private readonly string _configDB = "guiNDB.db"; diff --git a/v2rayn/v2rayN/ServiceLib/Common/StringEx.cs b/v2rayn/v2rayN/ServiceLib/Common/StringEx.cs index ab21016aba..ab5b808a0f 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/StringEx.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/StringEx.cs @@ -6,7 +6,7 @@ namespace ServiceLib.Common { public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value) { - return string.IsNullOrEmpty(value); + return string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value); } public static bool IsNullOrWhiteSpace([NotNullWhen(false)] this string? value) @@ -22,7 +22,9 @@ namespace ServiceLib.Common public static bool BeginWithAny(this string s, IEnumerable chars) { if (s.IsNullOrEmpty()) + { return false; + } return chars.Contains(s.First()); } @@ -36,7 +38,9 @@ namespace ServiceLib.Common while (reader.ReadLine() is { } line) { if (line.IsWhiteSpace()) + { continue; + } yield return line; } } @@ -70,5 +74,10 @@ namespace ServiceLib.Common { return string.IsNullOrEmpty(value) ? string.Empty : $"\"{value}\""; } + + public static int ToInt(this string? value, int defaultValue = 0) + { + return int.TryParse(value, out var result) ? result : defaultValue; + } } } diff --git a/v2rayn/v2rayN/ServiceLib/Common/Utils.cs b/v2rayn/v2rayN/ServiceLib/Common/Utils.cs index 7e345eef4e..5883d3db64 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/Utils.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/Utils.cs @@ -20,85 +20,69 @@ namespace ServiceLib.Common #region 转换函数 /// - /// 转逗号分隔的字符串 + /// Convert to comma-separated string /// /// /// /// public static string List2String(List? lst, bool wrap = false) { + if (lst == null || lst.Count == 0) + { + return string.Empty; + } + + var separator = wrap ? "," + Environment.NewLine : ","; + try { - if (lst == null) - { - return string.Empty; - } - if (wrap) - { - return string.Join("," + Environment.NewLine, lst); - } - else - { - return string.Join(",", lst); - } + return string.Join(separator, lst); } catch (Exception ex) { Logging.SaveLog(_tag, ex); + return string.Empty; } - - return string.Empty; } /// - /// 逗号分隔的字符串 + /// Comma-separated string /// /// /// public static List? String2List(string? str) { + if (string.IsNullOrWhiteSpace(str)) + { + return null; + } + try { - if (str == null) - { - return null; - } - - str = str.Replace(Environment.NewLine, ""); + str = str.Replace(Environment.NewLine, string.Empty); return new List(str.Split(',', StringSplitOptions.RemoveEmptyEntries)); } catch (Exception ex) { Logging.SaveLog(_tag, ex); + return null; } - - return null; } /// - /// 逗号分隔的字符串,先排序后转List + /// Comma-separated string, sorted and then converted to List /// /// /// public static List? String2ListSorted(string str) { - try - { - str = str.Replace(Environment.NewLine, ""); - List list = new(str.Split(',', StringSplitOptions.RemoveEmptyEntries)); - list.Sort(); - return list; - } - catch (Exception ex) - { - Logging.SaveLog(_tag, ex); - } - - return null; + var lst = String2List(str); + lst?.Sort(); + return lst; } /// - /// Base64编码 + /// Base64 Encode /// /// /// @@ -118,7 +102,7 @@ namespace ServiceLib.Common } /// - /// Base64解码 + /// Base64 Decode /// /// /// @@ -127,7 +111,10 @@ namespace ServiceLib.Common try { if (plainText.IsNullOrEmpty()) + { return ""; + } + plainText = plainText.Trim() .Replace(Environment.NewLine, "") .Replace("\n", "") @@ -152,18 +139,6 @@ namespace ServiceLib.Common return string.Empty; } - public static int ToInt(object? obj) - { - try - { - return Convert.ToInt32(obj ?? string.Empty); - } - catch - { - return 0; - } - } - public static bool ToBool(object obj) { try @@ -188,55 +163,25 @@ namespace ServiceLib.Common } } - private static void ToHumanReadable(long amount, out double result, out string unit) - { - var factor = 1024u; - //long KBs = amount / factor; - var KBs = amount; - if (KBs > 0) - { - // multi KB - var MBs = KBs / factor; - if (MBs > 0) - { - // multi MB - var GBs = MBs / factor; - if (GBs > 0) - { - // multi GB - var TBs = GBs / factor; - if (TBs > 0) - { - result = TBs + ((GBs % factor) / (factor + 0.0)); - unit = "TB"; - return; - } - - result = GBs + ((MBs % factor) / (factor + 0.0)); - unit = "GB"; - return; - } - - result = MBs + ((KBs % factor) / (factor + 0.0)); - unit = "MB"; - return; - } - - result = KBs + ((amount % factor) / (factor + 0.0)); - unit = "KB"; - return; - } - else - { - result = amount; - unit = "B"; - } - } - public static string HumanFy(long amount) { - ToHumanReadable(amount, out var result, out var unit); - return $"{result:f1} {unit}"; + if (amount <= 0) + { + return $"{amount:f1} B"; + } + + string[] units = ["KB", "MB", "GB", "TB", "PB"]; + var unitIndex = 0; + double size = amount; + + // Loop and divide by 1024 until a suitable unit is found + while (size >= 1024 && unitIndex < units.Length - 1) + { + size /= 1024; + unitIndex++; + } + + return $"{size:f1} {units[unitIndex]}"; } public static string UrlEncode(string url) @@ -252,7 +197,7 @@ namespace ServiceLib.Common public static NameValueCollection ParseQueryString(string query) { var result = new NameValueCollection(StringComparer.OrdinalIgnoreCase); - if (IsNullOrEmpty(query)) + if (query.IsNullOrEmpty()) { return result; } @@ -298,7 +243,7 @@ namespace ServiceLib.Common /// public static string GetPunycode(string url) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { return url; } @@ -331,7 +276,7 @@ namespace ServiceLib.Common public static string Convert2Comma(string text) { - if (IsNullOrEmpty(text)) + if (text.IsNullOrEmpty()) { return text; } @@ -344,7 +289,7 @@ namespace ServiceLib.Common #region 数据检查 /// - /// 判断输入的是否是数字 + /// Determine if the input is a number /// /// /// @@ -353,28 +298,13 @@ namespace ServiceLib.Common return oText.All(char.IsNumber); } - public static bool IsNullOrEmpty(string? text) - { - if (string.IsNullOrWhiteSpace(text)) - { - return true; - } - - return text == "null"; - } - - public static bool IsNotEmpty(string? text) - { - return !string.IsNullOrEmpty(text); - } - /// - /// 验证Domain地址是否合法 + /// Validate if the domain address is valid /// /// public static bool IsDomain(string? domain) { - if (IsNullOrEmpty(domain)) + if (domain.IsNullOrEmpty()) { return false; } @@ -491,7 +421,7 @@ namespace ServiceLib.Common } /// - /// 取得版本 + /// Get version /// /// public static string GetVersion(bool blFull = true) @@ -529,7 +459,7 @@ namespace ServiceLib.Common } /// - /// 取得GUID + /// GUID /// /// public static string GetGuid(bool full = true) @@ -660,7 +590,7 @@ namespace ServiceLib.Common public static string GetPath(string fileName) { var startupPath = StartupPath(); - if (IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { return startupPath; } @@ -696,7 +626,7 @@ namespace ServiceLib.Common Directory.CreateDirectory(tempPath); } - if (IsNullOrEmpty(filename)) + if (filename.IsNullOrEmpty()) { return tempPath; } @@ -725,7 +655,7 @@ namespace ServiceLib.Common Directory.CreateDirectory(tempPath); } - if (Utils.IsNullOrEmpty(filename)) + if (filename.IsNullOrEmpty()) { return tempPath; } @@ -752,7 +682,7 @@ namespace ServiceLib.Common } } - if (IsNullOrEmpty(filename)) + if (filename.IsNullOrEmpty()) { return tempPath; } @@ -770,7 +700,7 @@ namespace ServiceLib.Common Directory.CreateDirectory(tempPath); } - if (Utils.IsNullOrEmpty(filename)) + if (filename.IsNullOrEmpty()) { return tempPath; } @@ -788,7 +718,7 @@ namespace ServiceLib.Common Directory.CreateDirectory(tempPath); } - if (Utils.IsNullOrEmpty(filename)) + if (filename.IsNullOrEmpty()) { return tempPath; } @@ -806,7 +736,7 @@ namespace ServiceLib.Common Directory.CreateDirectory(tempPath); } - if (Utils.IsNullOrEmpty(filename)) + if (filename.IsNullOrEmpty()) { return tempPath; } diff --git a/v2rayn/v2rayN/ServiceLib/Common/WindowsUtils.cs b/v2rayn/v2rayN/ServiceLib/Common/WindowsUtils.cs index 77877d602d..1d4740c342 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/WindowsUtils.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/WindowsUtils.cs @@ -15,7 +15,7 @@ namespace ServiceLib.Common { regKey = Registry.CurrentUser.OpenSubKey(path, false); var value = regKey?.GetValue(name) as string; - return Utils.IsNullOrEmpty(value) ? def : value; + return value.IsNullOrEmpty() ? def : value; } catch (Exception ex) { @@ -34,7 +34,7 @@ namespace ServiceLib.Common try { regKey = Registry.CurrentUser.CreateSubKey(path); - if (Utils.IsNullOrEmpty(value.ToString())) + if (value.ToString().IsNullOrEmpty()) { regKey?.DeleteValue(name, false); } @@ -63,7 +63,7 @@ namespace ServiceLib.Common var arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """; // Try to remove the device - await Utils.GetCliWrapOutput(pnpUtilPath, arg); + _ = await Utils.GetCliWrapOutput(pnpUtilPath, arg); } catch (Exception ex) { diff --git a/v2rayn/v2rayN/ServiceLib/Common/YamlUtils.cs b/v2rayn/v2rayN/ServiceLib/Common/YamlUtils.cs index 13ad2d78ca..511e41e5fd 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/YamlUtils.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/YamlUtils.cs @@ -1,4 +1,4 @@ -using YamlDotNet.Core; +using YamlDotNet.Core; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; @@ -62,9 +62,6 @@ namespace ServiceLib.Common public static string? PreprocessYaml(string str) { - var deserializer = new DeserializerBuilder() - .WithNamingConvention(PascalCaseNamingConvention.Instance) - .Build(); try { var mergingParser = new MergingParser(new Parser(new StringReader(str))); @@ -80,4 +77,4 @@ namespace ServiceLib.Common #endregion YAML } -} \ No newline at end of file +} diff --git a/v2rayn/v2rayN/ServiceLib/Handler/AppHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/AppHandler.cs index 8a17932ffe..0ac794ac56 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/AppHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/AppHandler.cs @@ -131,7 +131,7 @@ namespace ServiceLib.Handler public async Task?> ProfileItems(string subid) { - if (Utils.IsNullOrEmpty(subid)) + if (subid.IsNullOrEmpty()) { return await SQLiteHelper.Instance.TableAsync().ToListAsync(); } @@ -153,11 +153,11 @@ namespace ServiceLib.Handler from ProfileItem a left join SubItem b on a.subid = b.id where 1=1 "; - if (Utils.IsNotEmpty(subid)) + if (subid.IsNotEmpty()) { sql += $" and a.subid = '{subid}'"; } - if (Utils.IsNotEmpty(filter)) + if (filter.IsNotEmpty()) { if (filter.Contains('\'')) { @@ -171,7 +171,7 @@ namespace ServiceLib.Handler public async Task GetProfileItem(string indexId) { - if (Utils.IsNullOrEmpty(indexId)) + if (indexId.IsNullOrEmpty()) { return null; } @@ -180,7 +180,7 @@ namespace ServiceLib.Handler public async Task GetProfileItemViaRemarks(string? remarks) { - if (Utils.IsNullOrEmpty(remarks)) + if (remarks.IsNullOrEmpty()) { return null; } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs index cb742d4c81..4ba63ba86f 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs @@ -85,7 +85,7 @@ namespace ServiceLib.Handler /// public static void AutoStartTaskService(string taskName, string fileName, string description) { - if (Utils.IsNullOrEmpty(taskName)) + if (taskName.IsNullOrEmpty()) { return; } @@ -93,7 +93,7 @@ namespace ServiceLib.Handler var logonUser = WindowsIdentity.GetCurrent().Name; using var taskService = new Microsoft.Win32.TaskScheduler.TaskService(); var tasks = taskService.RootFolder.GetTasks(new Regex(taskName)); - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { foreach (var t in tasks) { diff --git a/v2rayn/v2rayN/ServiceLib/Handler/ClashApiHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/ClashApiHandler.cs index 01134e6d10..d61709edf4 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/ClashApiHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/ClashApiHandler.cs @@ -37,7 +37,7 @@ namespace ServiceLib.Handler public void ClashProxiesDelayTest(bool blAll, List lstProxy, Action updateFunc) { - Task.Run(() => + Task.Run(async () => { if (blAll) { @@ -47,7 +47,7 @@ namespace ServiceLib.Handler { break; } - Task.Delay(5000).Wait(); + await Task.Delay(5000); } if (_proxies == null) { @@ -90,9 +90,8 @@ namespace ServiceLib.Handler updateFunc?.Invoke(it, result); })); } - Task.WaitAll(tasks.ToArray()); - - Task.Delay(1000).Wait(); + await Task.WhenAll(tasks); + await Task.Delay(1000); updateFunc?.Invoke(null, ""); }); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/ConfigHandler.cs index 0016de60e4..714e5da118 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/ConfigHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/ConfigHandler.cs @@ -22,7 +22,7 @@ namespace ServiceLib.Handler { Config? config = null; var result = EmbedUtils.LoadResource(Utils.GetConfigPath(_configRes)); - if (Utils.IsNotEmpty(result)) + if (result.IsNotEmpty()) { config = JsonUtils.Deserialize(result); } @@ -67,7 +67,7 @@ namespace ServiceLib.Handler } config.RoutingBasicItem ??= new(); - if (Utils.IsNullOrEmpty(config.RoutingBasicItem.DomainStrategy)) + if (config.RoutingBasicItem.DomainStrategy.IsNullOrEmpty()) { config.RoutingBasicItem.DomainStrategy = Global.DomainStrategies.First(); } @@ -103,7 +103,7 @@ namespace ServiceLib.Handler }; config.UiItem.MainColumnItem ??= new(); - if (Utils.IsNullOrEmpty(config.UiItem.CurrentLanguage)) + if (config.UiItem.CurrentLanguage.IsNullOrEmpty()) { config.UiItem.CurrentLanguage = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.Equals("zh", StringComparison.CurrentCultureIgnoreCase) ? Global.Languages.First() @@ -117,11 +117,11 @@ namespace ServiceLib.Handler { config.SpeedTestItem.SpeedTestTimeout = 10; } - if (Utils.IsNullOrEmpty(config.SpeedTestItem.SpeedTestUrl)) + if (config.SpeedTestItem.SpeedTestUrl.IsNullOrEmpty()) { config.SpeedTestItem.SpeedTestUrl = Global.SpeedTestUrls.First(); } - if (Utils.IsNullOrEmpty(config.SpeedTestItem.SpeedPingTestUrl)) + if (config.SpeedTestItem.SpeedPingTestUrl.IsNullOrEmpty()) { config.SpeedTestItem.SpeedPingTestUrl = Global.SpeedPingTestUrl; } @@ -354,7 +354,7 @@ namespace ServiceLib.Handler /// public static async Task SetDefaultServerIndex(Config config, string? indexId) { - if (Utils.IsNullOrEmpty(indexId)) + if (indexId.IsNullOrEmpty()) { return -1; } @@ -506,7 +506,7 @@ namespace ServiceLib.Handler profileItem.Address = newFileName; profileItem.ConfigType = EConfigType.Custom; - if (Utils.IsNullOrEmpty(profileItem.Remarks)) + if (profileItem.Remarks.IsNullOrEmpty()) { profileItem.Remarks = $"import custom@{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}"; } @@ -624,7 +624,7 @@ namespace ServiceLib.Handler profileItem.Address = profileItem.Address.TrimEx(); profileItem.Id = profileItem.Id.TrimEx(); - if (Utils.IsNullOrEmpty(profileItem.StreamSecurity)) + if (profileItem.StreamSecurity.IsNullOrEmpty()) { profileItem.StreamSecurity = Global.StreamSecurity; } @@ -654,7 +654,7 @@ namespace ServiceLib.Handler profileItem.Path = profileItem.Path.TrimEx(); profileItem.Network = string.Empty; - if (Utils.IsNullOrEmpty(profileItem.StreamSecurity)) + if (profileItem.StreamSecurity.IsNullOrEmpty()) { profileItem.StreamSecurity = Global.StreamSecurity; } @@ -689,11 +689,11 @@ namespace ServiceLib.Handler profileItem.HeaderType = Global.TuicCongestionControls.FirstOrDefault()!; } - if (Utils.IsNullOrEmpty(profileItem.StreamSecurity)) + if (profileItem.StreamSecurity.IsNullOrEmpty()) { profileItem.StreamSecurity = Global.StreamSecurity; } - if (Utils.IsNullOrEmpty(profileItem.Alpn)) + if (profileItem.Alpn.IsNullOrEmpty()) { profileItem.Alpn = "h3"; } @@ -858,7 +858,7 @@ namespace ServiceLib.Handler { return -1; } - if (Utils.IsNotEmpty(profileItem.Security) && profileItem.Security != Global.None) + if (profileItem.Security.IsNotEmpty() && profileItem.Security != Global.None) { profileItem.Security = Global.None; } @@ -897,7 +897,7 @@ namespace ServiceLib.Handler { profileItem.ConfigVersion = 2; - if (Utils.IsNotEmpty(profileItem.StreamSecurity)) + if (profileItem.StreamSecurity.IsNotEmpty()) { if (profileItem.StreamSecurity != Global.StreamSecurity && profileItem.StreamSecurity != Global.StreamSecurityReality) @@ -906,24 +906,24 @@ namespace ServiceLib.Handler } else { - if (Utils.IsNullOrEmpty(profileItem.AllowInsecure)) + if (profileItem.AllowInsecure.IsNullOrEmpty()) { profileItem.AllowInsecure = config.CoreBasicItem.DefAllowInsecure.ToString().ToLower(); } - if (Utils.IsNullOrEmpty(profileItem.Fingerprint) && profileItem.StreamSecurity == Global.StreamSecurityReality) + if (profileItem.Fingerprint.IsNullOrEmpty() && profileItem.StreamSecurity == Global.StreamSecurityReality) { profileItem.Fingerprint = config.CoreBasicItem.DefFingerprint; } } } - if (Utils.IsNotEmpty(profileItem.Network) && !Global.Networks.Contains(profileItem.Network)) + if (profileItem.Network.IsNotEmpty() && !Global.Networks.Contains(profileItem.Network)) { profileItem.Network = Global.DefaultNetwork; } var maxSort = -1; - if (Utils.IsNullOrEmpty(profileItem.IndexId)) + if (profileItem.IndexId.IsNullOrEmpty()) { profileItem.IndexId = Utils.GetGuid(false); maxSort = ProfileExHandler.Instance.GetMaxSort(); @@ -1084,14 +1084,14 @@ namespace ServiceLib.Handler /// 成功导入的数量 private static async Task AddBatchServersCommon(Config config, string strData, string subid, bool isSub) { - if (Utils.IsNullOrEmpty(strData)) + if (strData.IsNullOrEmpty()) { return -1; } var subFilter = string.Empty; //remove sub items - if (isSub && Utils.IsNotEmpty(subid)) + if (isSub && subid.IsNotEmpty()) { await RemoveServersViaSubid(config, subid, isSub); subFilter = (await AppHandler.Instance.GetSubItem(subid))?.Filter ?? ""; @@ -1122,7 +1122,7 @@ namespace ServiceLib.Handler } //exist sub items //filter - if (isSub && Utils.IsNotEmpty(subid) && Utils.IsNotEmpty(subFilter)) + if (isSub && subid.IsNotEmpty() && subFilter.IsNotEmpty()) { if (!Regex.IsMatch(profileItem.Remarks, subFilter)) { @@ -1163,7 +1163,7 @@ namespace ServiceLib.Handler private static async Task AddBatchServers4Custom(Config config, string strData, string subid, bool isSub) { - if (Utils.IsNullOrEmpty(strData)) + if (strData.IsNullOrEmpty()) { return -1; } @@ -1185,7 +1185,7 @@ namespace ServiceLib.Handler } if (lstProfiles != null && lstProfiles.Count > 0) { - if (isSub && Utils.IsNotEmpty(subid)) + if (isSub && subid.IsNotEmpty()) { await RemoveServersViaSubid(config, subid, isSub); } @@ -1236,12 +1236,12 @@ namespace ServiceLib.Handler { profileItem = NaiveproxyFmt.ResolveFull(strData, subRemarks); } - if (profileItem is null || Utils.IsNullOrEmpty(profileItem.Address)) + if (profileItem is null || profileItem.Address.IsNullOrEmpty()) { return -1; } - if (isSub && Utils.IsNotEmpty(subid)) + if (isSub && subid.IsNotEmpty()) { await RemoveServersViaSubid(config, subid, isSub); } @@ -1261,12 +1261,12 @@ namespace ServiceLib.Handler private static async Task AddBatchServers4SsSIP008(Config config, string strData, string subid, bool isSub) { - if (Utils.IsNullOrEmpty(strData)) + if (strData.IsNullOrEmpty()) { return -1; } - if (isSub && Utils.IsNotEmpty(subid)) + if (isSub && subid.IsNotEmpty()) { await RemoveServersViaSubid(config, subid, isSub); } @@ -1293,13 +1293,13 @@ namespace ServiceLib.Handler public static async Task AddBatchServers(Config config, string strData, string subid, bool isSub) { - if (Utils.IsNullOrEmpty(strData)) + if (strData.IsNullOrEmpty()) { return -1; } List? lstOriSub = null; ProfileItem? activeProfile = null; - if (isSub && Utils.IsNotEmpty(subid)) + if (isSub && subid.IsNotEmpty()) { lstOriSub = await AppHandler.Instance.ProfileItems(subid); activeProfile = lstOriSub?.FirstOrDefault(t => t.IndexId == config.IndexId); @@ -1424,7 +1424,7 @@ namespace ServiceLib.Handler item.Memo = subItem.Memo; } - if (Utils.IsNullOrEmpty(item.Id)) + if (item.Id.IsNullOrEmpty()) { item.Id = Utils.GetGuid(false); @@ -1457,7 +1457,7 @@ namespace ServiceLib.Handler /// public static async Task RemoveServersViaSubid(Config config, string subid, bool isSub) { - if (Utils.IsNullOrEmpty(subid)) + if (subid.IsNullOrEmpty()) { return -1; } @@ -1508,7 +1508,7 @@ namespace ServiceLib.Handler public static async Task SaveRoutingItem(Config config, RoutingItem item) { - if (Utils.IsNullOrEmpty(item.Id)) + if (item.Id.IsNullOrEmpty()) { item.Id = Utils.GetGuid(false); } @@ -1531,7 +1531,7 @@ namespace ServiceLib.Handler /// public static async Task AddBatchRoutingRules(RoutingItem routingItem, string strData) { - if (Utils.IsNullOrEmpty(strData)) + if (strData.IsNullOrEmpty()) { return -1; } @@ -1549,7 +1549,7 @@ namespace ServiceLib.Handler routingItem.RuleNum = lstRules.Count; routingItem.RuleSet = JsonUtils.Serialize(lstRules, false); - if (Utils.IsNullOrEmpty(routingItem.Id)) + if (routingItem.Id.IsNullOrEmpty()) { routingItem.Id = Utils.GetGuid(false); } @@ -1668,7 +1668,7 @@ namespace ServiceLib.Handler public static async Task InitRouting(Config config, bool blImportAdvancedRules = false) { - if (string.IsNullOrEmpty(config.ConstItem.RouteRulesTemplateSourceUrl)) + if (config.ConstItem.RouteRulesTemplateSourceUrl.IsNullOrEmpty()) { await InitBuiltinRouting(config, blImportAdvancedRules); } @@ -1684,7 +1684,7 @@ namespace ServiceLib.Handler { var downloadHandle = new DownloadService(); var templateContent = await downloadHandle.TryDownloadString(config.ConstItem.RouteRulesTemplateSourceUrl, true, ""); - if (string.IsNullOrEmpty(templateContent)) + if (templateContent.IsNullOrEmpty()) return await InitBuiltinRouting(config, blImportAdvancedRules); // fallback var template = JsonUtils.Deserialize(templateContent); @@ -1701,14 +1701,14 @@ namespace ServiceLib.Handler { var item = template.RoutingItems[i]; - if (string.IsNullOrEmpty(item.Url) && string.IsNullOrEmpty(item.RuleSet)) + if (item.Url.IsNullOrEmpty() && item.RuleSet.IsNullOrEmpty()) continue; - var ruleSetsString = !string.IsNullOrEmpty(item.RuleSet) + var ruleSetsString = !item.RuleSet.IsNullOrEmpty() ? item.RuleSet : await downloadHandle.TryDownloadString(item.Url, true, ""); - if (string.IsNullOrEmpty(ruleSetsString)) + if (ruleSetsString.IsNullOrEmpty()) continue; item.Remarks = $"{template.Version}-{item.Remarks}"; @@ -1820,7 +1820,7 @@ namespace ServiceLib.Handler return -1; } - if (Utils.IsNullOrEmpty(item.Id)) + if (item.Id.IsNullOrEmpty()) { item.Id = Utils.GetGuid(false); } @@ -1841,17 +1841,17 @@ namespace ServiceLib.Handler var downloadHandle = new DownloadService(); var templateContent = await downloadHandle.TryDownloadString(url, true, ""); - if (string.IsNullOrEmpty(templateContent)) + if (templateContent.IsNullOrEmpty()) return currentItem; var template = JsonUtils.Deserialize(templateContent); if (template == null) return currentItem; - if (!string.IsNullOrEmpty(template.NormalDNS)) + if (!template.NormalDNS.IsNullOrEmpty()) template.NormalDNS = await downloadHandle.TryDownloadString(template.NormalDNS, true, ""); - if (!string.IsNullOrEmpty(template.TunDNS)) + if (!template.TunDNS.IsNullOrEmpty()) template.TunDNS = await downloadHandle.TryDownloadString(template.TunDNS, true, ""); template.Id = currentItem.Id; diff --git a/v2rayn/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs index 11982882fa..0d9b2a0e80 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/CoreConfigHandler.cs @@ -33,7 +33,7 @@ namespace ServiceLib.Handler { return result; } - if (Utils.IsNotEmpty(fileName) && result.Data != null) + if (fileName.IsNotEmpty() && result.Data != null) { await File.WriteAllTextAsync(fileName, result.Data.ToString()); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/CoreHandler.cs index 8f6200b975..0c05db6436 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/CoreHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/CoreHandler.cs @@ -240,7 +240,7 @@ namespace ServiceLib.Handler private async Task RunProcess(CoreInfo? coreInfo, string configPath, bool displayLog, bool mayNeedSudo) { var fileName = CoreInfoHandler.Instance.GetCoreExecFile(coreInfo, out var msg); - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { UpdateFunc(false, msg); return null; @@ -274,13 +274,13 @@ namespace ServiceLib.Handler { proc.OutputDataReceived += (sender, e) => { - if (Utils.IsNullOrEmpty(e.Data)) + if (e.Data.IsNullOrEmpty()) return; UpdateFunc(false, e.Data + Environment.NewLine); }; proc.ErrorDataReceived += (sender, e) => { - if (Utils.IsNullOrEmpty(e.Data)) + if (e.Data.IsNullOrEmpty()) return; UpdateFunc(false, e.Data + Environment.NewLine); }; diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs index 276cd44d16..2e52130e4b 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs @@ -16,12 +16,12 @@ namespace ServiceLib.Handler.Fmt protected static int GetStdTransport(ProfileItem item, string? securityDef, ref Dictionary dicQuery) { - if (Utils.IsNotEmpty(item.Flow)) + if (item.Flow.IsNotEmpty()) { dicQuery.Add("flow", item.Flow); } - if (Utils.IsNotEmpty(item.StreamSecurity)) + if (item.StreamSecurity.IsNotEmpty()) { dicQuery.Add("security", item.StreamSecurity); } @@ -32,27 +32,27 @@ namespace ServiceLib.Handler.Fmt dicQuery.Add("security", securityDef); } } - if (Utils.IsNotEmpty(item.Sni)) + if (item.Sni.IsNotEmpty()) { dicQuery.Add("sni", item.Sni); } - if (Utils.IsNotEmpty(item.Alpn)) + if (item.Alpn.IsNotEmpty()) { dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); } - if (Utils.IsNotEmpty(item.Fingerprint)) + if (item.Fingerprint.IsNotEmpty()) { dicQuery.Add("fp", Utils.UrlEncode(item.Fingerprint)); } - if (Utils.IsNotEmpty(item.PublicKey)) + if (item.PublicKey.IsNotEmpty()) { dicQuery.Add("pbk", Utils.UrlEncode(item.PublicKey)); } - if (Utils.IsNotEmpty(item.ShortId)) + if (item.ShortId.IsNotEmpty()) { dicQuery.Add("sid", Utils.UrlEncode(item.ShortId)); } - if (Utils.IsNotEmpty(item.SpiderX)) + if (item.SpiderX.IsNotEmpty()) { dicQuery.Add("spx", Utils.UrlEncode(item.SpiderX)); } @@ -61,21 +61,21 @@ namespace ServiceLib.Handler.Fmt dicQuery.Add("allowInsecure", "1"); } - dicQuery.Add("type", Utils.IsNotEmpty(item.Network) ? item.Network : nameof(ETransport.tcp)); + dicQuery.Add("type", item.Network.IsNotEmpty() ? item.Network : nameof(ETransport.tcp)); switch (item.Network) { case nameof(ETransport.tcp): - dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None); - if (Utils.IsNotEmpty(item.RequestHost)) + dicQuery.Add("headerType", item.HeaderType.IsNotEmpty() ? item.HeaderType : Global.None); + if (item.RequestHost.IsNotEmpty()) { dicQuery.Add("host", Utils.UrlEncode(item.RequestHost)); } break; case nameof(ETransport.kcp): - dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None); - if (Utils.IsNotEmpty(item.Path)) + dicQuery.Add("headerType", item.HeaderType.IsNotEmpty() ? item.HeaderType : Global.None); + if (item.Path.IsNotEmpty()) { dicQuery.Add("seed", Utils.UrlEncode(item.Path)); } @@ -83,30 +83,30 @@ namespace ServiceLib.Handler.Fmt case nameof(ETransport.ws): case nameof(ETransport.httpupgrade): - if (Utils.IsNotEmpty(item.RequestHost)) + if (item.RequestHost.IsNotEmpty()) { dicQuery.Add("host", Utils.UrlEncode(item.RequestHost)); } - if (Utils.IsNotEmpty(item.Path)) + if (item.Path.IsNotEmpty()) { dicQuery.Add("path", Utils.UrlEncode(item.Path)); } break; case nameof(ETransport.xhttp): - if (Utils.IsNotEmpty(item.RequestHost)) + if (item.RequestHost.IsNotEmpty()) { dicQuery.Add("host", Utils.UrlEncode(item.RequestHost)); } - if (Utils.IsNotEmpty(item.Path)) + if (item.Path.IsNotEmpty()) { dicQuery.Add("path", Utils.UrlEncode(item.Path)); } - if (Utils.IsNotEmpty(item.HeaderType) && Global.XhttpMode.Contains(item.HeaderType)) + if (item.HeaderType.IsNotEmpty() && Global.XhttpMode.Contains(item.HeaderType)) { dicQuery.Add("mode", Utils.UrlEncode(item.HeaderType)); } - if (Utils.IsNotEmpty(item.Extra)) + if (item.Extra.IsNotEmpty()) { dicQuery.Add("extra", Utils.UrlEncode(item.Extra)); } @@ -115,24 +115,24 @@ namespace ServiceLib.Handler.Fmt case nameof(ETransport.http): case nameof(ETransport.h2): dicQuery["type"] = nameof(ETransport.http); - if (Utils.IsNotEmpty(item.RequestHost)) + if (item.RequestHost.IsNotEmpty()) { dicQuery.Add("host", Utils.UrlEncode(item.RequestHost)); } - if (Utils.IsNotEmpty(item.Path)) + if (item.Path.IsNotEmpty()) { dicQuery.Add("path", Utils.UrlEncode(item.Path)); } break; case nameof(ETransport.quic): - dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None); + dicQuery.Add("headerType", item.HeaderType.IsNotEmpty() ? item.HeaderType : Global.None); dicQuery.Add("quicSecurity", Utils.UrlEncode(item.RequestHost)); dicQuery.Add("key", Utils.UrlEncode(item.Path)); break; case nameof(ETransport.grpc): - if (Utils.IsNotEmpty(item.Path)) + if (item.Path.IsNotEmpty()) { dicQuery.Add("authority", Utils.UrlEncode(item.RequestHost)); dicQuery.Add("serviceName", Utils.UrlEncode(item.Path)); @@ -215,7 +215,9 @@ namespace ServiceLib.Handler.Fmt foreach (var item in s) { if (str.Contains(item, StringComparison.OrdinalIgnoreCase)) + { return true; + } } return false; } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/FmtHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/FmtHandler.cs index 1830c8afa1..b2d5ac58b6 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/FmtHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/FmtHandler.cs @@ -37,7 +37,7 @@ try { string str = config.TrimEx(); - if (Utils.IsNullOrEmpty(str)) + if (str.IsNullOrEmpty()) { msg = ResUI.FailedReadConfiguration; return null; diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs index be6630e150..46e397b3e8 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs @@ -36,26 +36,26 @@ namespace ServiceLib.Handler.Fmt string url = string.Empty; string remark = string.Empty; - if (Utils.IsNotEmpty(item.Remarks)) + if (item.Remarks.IsNotEmpty()) { remark = "#" + Utils.UrlEncode(item.Remarks); } var dicQuery = new Dictionary(); - if (Utils.IsNotEmpty(item.Sni)) + if (item.Sni.IsNotEmpty()) { dicQuery.Add("sni", item.Sni); } - if (Utils.IsNotEmpty(item.Alpn)) + if (item.Alpn.IsNotEmpty()) { dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); } - if (Utils.IsNotEmpty(item.Path)) + if (item.Path.IsNotEmpty()) { dicQuery.Add("obfs", "salamander"); dicQuery.Add("obfs-password", Utils.UrlEncode(item.Path)); } dicQuery.Add("insecure", item.AllowInsecure.ToLower() == "true" ? "1" : "0"); - if (Utils.IsNotEmpty(item.Ports)) + if (item.Ports.IsNotEmpty()) { dicQuery.Add("mport", Utils.UrlEncode(item.Ports.Replace(':', '-'))); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs index a9ebac335b..d35226e960 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/ShadowsocksFmt.cs @@ -27,11 +27,11 @@ namespace ServiceLib.Handler.Fmt public static string? ToUri(ProfileItem? item) { if (item == null) + { return null; - string url = string.Empty; - - string remark = string.Empty; - if (Utils.IsNotEmpty(item.Remarks)) + } + var remark = string.Empty; + if (item.Remarks.IsNotEmpty()) { remark = "#" + Utils.UrlEncode(item.Remarks); } @@ -53,12 +53,14 @@ namespace ServiceLib.Handler.Fmt { var match = UrlFinder.Match(result); if (!match.Success) + { return null; + } ProfileItem item = new(); var base64 = match.Groups["base64"].Value.TrimEnd('/'); var tag = match.Groups["tag"].Value; - if (Utils.IsNotEmpty(tag)) + if (tag.IsNotEmpty()) { item.Remarks = Utils.UrlDecode(tag); } @@ -72,11 +74,13 @@ namespace ServiceLib.Handler.Fmt return null; } if (!details.Success) + { return null; + } item.Security = details.Groups["method"].Value; item.Id = details.Groups["password"].Value; item.Address = details.Groups["hostname"].Value; - item.Port = Utils.ToInt(details.Groups["port"].Value); + item.Port = details.Groups["port"].Value.ToInt(); return item; } @@ -84,7 +88,9 @@ namespace ServiceLib.Handler.Fmt { var parsedUrl = Utils.TryUri(result); if (parsedUrl == null) + { return null; + } ProfileItem item = new() { @@ -96,7 +102,7 @@ namespace ServiceLib.Handler.Fmt //2022-blake3 if (rawUserInfo.Contains(':')) { - string[] userInfoParts = rawUserInfo.Split(new[] { ':' }, 2); + var userInfoParts = rawUserInfo.Split(new[] { ':' }, 2); if (userInfoParts.Length != 2) { return null; @@ -107,8 +113,8 @@ namespace ServiceLib.Handler.Fmt else { // parse base64 UserInfo - string userInfo = Utils.Base64Decode(rawUserInfo); - string[] userInfoParts = userInfo.Split(new[] { ':' }, 2); + var userInfo = Utils.Base64Decode(rawUserInfo); + var userInfoParts = userInfo.Split(new[] { ':' }, 2); if (userInfoParts.Length != 2) { return null; @@ -122,7 +128,7 @@ namespace ServiceLib.Handler.Fmt { //obfs-host exists var obfsHost = queryParameters["plugin"]?.Split(';').FirstOrDefault(t => t.Contains("obfs-host")); - if (queryParameters["plugin"].Contains("obfs=http") && Utils.IsNotEmpty(obfsHost)) + if (queryParameters["plugin"].Contains("obfs=http") && obfsHost.IsNotEmpty()) { obfsHost = obfsHost?.Replace("obfs-host=", ""); item.Network = Global.DefaultNetwork; @@ -162,7 +168,7 @@ namespace ServiceLib.Handler.Fmt Security = it.method, Id = it.password, Address = it.server, - Port = Utils.ToInt(it.server_port) + Port = it.server_port.ToInt() }; lst.Add(ssItem); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/SingboxFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/SingboxFmt.cs index e3540872c5..07098d2b47 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/SingboxFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/SingboxFmt.cs @@ -1,10 +1,10 @@ -namespace ServiceLib.Handler.Fmt +namespace ServiceLib.Handler.Fmt { public class SingboxFmt : BaseFmt { public static List? ResolveFullArray(string strData, string? subRemarks) { - var configObjects = JsonUtils.Deserialize(strData); + var configObjects = JsonUtils.Deserialize(strData); if (configObjects != null && configObjects.Length > 0) { List lstResult = []; @@ -52,4 +52,4 @@ return null; } } -} \ No newline at end of file +} diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/SocksFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/SocksFmt.cs index 3883fab83f..9527bb56f5 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/SocksFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/SocksFmt.cs @@ -24,11 +24,11 @@ namespace ServiceLib.Handler.Fmt public static string? ToUri(ProfileItem? item) { if (item == null) + { return null; - var url = string.Empty; - + } var remark = string.Empty; - if (Utils.IsNotEmpty(item.Remarks)) + if (item.Remarks.IsNotEmpty()) { remark = "#" + Utils.UrlEncode(item.Remarks); } @@ -77,7 +77,7 @@ namespace ServiceLib.Handler.Fmt return null; } item.Address = arr1[1][..indexPort]; - item.Port = Utils.ToInt(arr1[1][(indexPort + 1)..]); + item.Port = arr1[1][(indexPort + 1)..].ToInt(); item.Security = arr21.First(); item.Id = arr21[1]; @@ -88,7 +88,9 @@ namespace ServiceLib.Handler.Fmt { var parsedUrl = Utils.TryUri(result); if (parsedUrl == null) + { return null; + } ProfileItem item = new() { diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs index 1bd863792c..60f05764c2 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/TrojanFmt.cs @@ -13,7 +13,9 @@ namespace ServiceLib.Handler.Fmt var url = Utils.TryUri(str); if (url == null) + { return null; + } item.Address = url.IdnHost; item.Port = url.Port; @@ -21,7 +23,7 @@ namespace ServiceLib.Handler.Fmt item.Id = Utils.UrlDecode(url.UserInfo); var query = Utils.ParseQueryString(url.Query); - ResolveStdTransport(query, ref item); + _ = ResolveStdTransport(query, ref item); return item; } @@ -29,16 +31,16 @@ namespace ServiceLib.Handler.Fmt public static string? ToUri(ProfileItem? item) { if (item == null) + { return null; - string url = string.Empty; - - string remark = string.Empty; - if (Utils.IsNotEmpty(item.Remarks)) + } + var remark = string.Empty; + if (item.Remarks.IsNotEmpty()) { remark = "#" + Utils.UrlEncode(item.Remarks); } var dicQuery = new Dictionary(); - GetStdTransport(item, null, ref dicQuery); + _ = GetStdTransport(item, null, ref dicQuery); return ToUri(EConfigType.Trojan, item.Address, item.Port, item.Id, dicQuery, remark); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs index 4099314747..39f52d7b25 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/TuicFmt.cs @@ -13,7 +13,9 @@ namespace ServiceLib.Handler.Fmt var url = Utils.TryUri(str); if (url == null) + { return null; + } item.Address = url.IdnHost; item.Port = url.Port; @@ -36,20 +38,21 @@ namespace ServiceLib.Handler.Fmt public static string? ToUri(ProfileItem? item) { if (item == null) + { return null; - string url = string.Empty; + } - string remark = string.Empty; - if (Utils.IsNotEmpty(item.Remarks)) + var remark = string.Empty; + if (item.Remarks.IsNotEmpty()) { remark = "#" + Utils.UrlEncode(item.Remarks); } var dicQuery = new Dictionary(); - if (Utils.IsNotEmpty(item.Sni)) + if (item.Sni.IsNotEmpty()) { dicQuery.Add("sni", item.Sni); } - if (Utils.IsNotEmpty(item.Alpn)) + if (item.Alpn.IsNotEmpty()) { dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn)); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/V2rayFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/V2rayFmt.cs index cc2ec7bf57..ee5c851216 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/V2rayFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/V2rayFmt.cs @@ -1,10 +1,10 @@ -namespace ServiceLib.Handler.Fmt +namespace ServiceLib.Handler.Fmt { public class V2rayFmt : BaseFmt { public static List? ResolveFullArray(string strData, string? subRemarks) { - var configObjects = JsonUtils.Deserialize(strData); + var configObjects = JsonUtils.Deserialize(strData); if (configObjects != null && configObjects.Length > 0) { List lstResult = []; @@ -53,4 +53,4 @@ return null; } } -} \ No newline at end of file +} diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs index 4fc0976516..819c50b632 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/VLESSFmt.cs @@ -14,7 +14,9 @@ namespace ServiceLib.Handler.Fmt var url = Utils.TryUri(str); if (url == null) + { return null; + } item.Address = url.IdnHost; item.Port = url.Port; @@ -24,7 +26,7 @@ namespace ServiceLib.Handler.Fmt var query = Utils.ParseQueryString(url.Query); item.Security = query["encryption"] ?? Global.None; item.StreamSecurity = query["security"] ?? ""; - ResolveStdTransport(query, ref item); + _ = ResolveStdTransport(query, ref item); return item; } @@ -32,16 +34,17 @@ namespace ServiceLib.Handler.Fmt public static string? ToUri(ProfileItem? item) { if (item == null) + { return null; - string url = string.Empty; + } - string remark = string.Empty; - if (Utils.IsNotEmpty(item.Remarks)) + var remark = string.Empty; + if (item.Remarks.IsNotEmpty()) { remark = "#" + Utils.UrlEncode(item.Remarks); } var dicQuery = new Dictionary(); - if (Utils.IsNotEmpty(item.Security)) + if (item.Security.IsNotEmpty()) { dicQuery.Add("encryption", item.Security); } @@ -49,7 +52,7 @@ namespace ServiceLib.Handler.Fmt { dicQuery.Add("encryption", Global.None); } - GetStdTransport(item, Global.None, ref dicQuery); + _ = GetStdTransport(item, Global.None, ref dicQuery); return ToUri(EConfigType.VLESS, item.Address, item.Port, item.Id, dicQuery, remark); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs index a2058aeb08..47bf297d75 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/VmessFmt.cs @@ -20,10 +20,10 @@ namespace ServiceLib.Handler.Fmt public static string? ToUri(ProfileItem? item) { if (item == null) + { return null; - string url = string.Empty; - - VmessQRCode vmessQRCode = new() + } + var vmessQRCode = new VmessQRCode { v = item.ConfigVersion, ps = item.Remarks.TrimEx(), @@ -42,7 +42,7 @@ namespace ServiceLib.Handler.Fmt fp = item.Fingerprint }; - url = JsonUtils.Serialize(vmessQRCode); + var url = JsonUtils.Serialize(vmessQRCode); url = Utils.Base64Encode(url); url = $"{Global.ProtocolShares[EConfigType.VMess]}{url}"; @@ -60,7 +60,7 @@ namespace ServiceLib.Handler.Fmt result = result[Global.ProtocolShares[EConfigType.VMess].Length..]; result = Utils.Base64Decode(result); - VmessQRCode? vmessQRCode = JsonUtils.Deserialize(result); + var vmessQRCode = JsonUtils.Deserialize(result); if (vmessQRCode == null) { msg = ResUI.FailedConversionConfiguration; @@ -78,12 +78,12 @@ namespace ServiceLib.Handler.Fmt item.AlterId = vmessQRCode.aid; item.Security = Utils.ToString(vmessQRCode.scy); - item.Security = Utils.IsNotEmpty(vmessQRCode.scy) ? vmessQRCode.scy : Global.DefaultSecurity; - if (Utils.IsNotEmpty(vmessQRCode.net)) + item.Security = vmessQRCode.scy.IsNotEmpty() ? vmessQRCode.scy : Global.DefaultSecurity; + if (vmessQRCode.net.IsNotEmpty()) { item.Network = vmessQRCode.net; } - if (Utils.IsNotEmpty(vmessQRCode.type)) + if (vmessQRCode.type.IsNotEmpty()) { item.HeaderType = vmessQRCode.type; } @@ -100,7 +100,7 @@ namespace ServiceLib.Handler.Fmt public static ProfileItem? ResolveStdVmess(string str) { - ProfileItem item = new() + var item = new ProfileItem { ConfigType = EConfigType.VMess, Security = "auto" @@ -108,7 +108,9 @@ namespace ServiceLib.Handler.Fmt var url = Utils.TryUri(str); if (url == null) + { return null; + } item.Address = url.IdnHost; item.Port = url.Port; diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/WireguardFmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/WireguardFmt.cs index beb7d93354..d7083963db 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/WireguardFmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/WireguardFmt.cs @@ -13,7 +13,9 @@ namespace ServiceLib.Handler.Fmt var url = Utils.TryUri(str); if (url == null) + { return null; + } item.Address = url.IdnHost; item.Port = url.Port; @@ -33,29 +35,30 @@ namespace ServiceLib.Handler.Fmt public static string? ToUri(ProfileItem? item) { if (item == null) + { return null; - string url = string.Empty; + } - string remark = string.Empty; - if (Utils.IsNotEmpty(item.Remarks)) + var remark = string.Empty; + if (item.Remarks.IsNotEmpty()) { remark = "#" + Utils.UrlEncode(item.Remarks); } var dicQuery = new Dictionary(); - if (Utils.IsNotEmpty(item.PublicKey)) + if (item.PublicKey.IsNotEmpty()) { dicQuery.Add("publickey", Utils.UrlEncode(item.PublicKey)); } - if (Utils.IsNotEmpty(item.Path)) + if (item.Path.IsNotEmpty()) { dicQuery.Add("reserved", Utils.UrlEncode(item.Path)); } - if (Utils.IsNotEmpty(item.RequestHost)) + if (item.RequestHost.IsNotEmpty()) { dicQuery.Add("address", Utils.UrlEncode(item.RequestHost)); } - if (Utils.IsNotEmpty(item.ShortId)) + if (item.ShortId.IsNotEmpty()) { dicQuery.Add("mtu", Utils.UrlEncode(item.ShortId)); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/PacHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/PacHandler.cs index b6f81ca61a..f70173c5eb 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/PacHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/PacHandler.cs @@ -15,7 +15,7 @@ namespace ServiceLib.Handler public static async Task Start(string configPath, int httpPort, int pacPort) { - _needRestart = (configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning); + _needRestart = configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning; _configPath = configPath; _httpPort = httpPort; @@ -70,7 +70,7 @@ namespace ServiceLib.Handler } var client = await _tcpListener.AcceptTcpClientAsync(); - await Task.Run(() => { WriteContent(client); }); + await Task.Run(() => WriteContent(client)); } catch { @@ -90,7 +90,9 @@ namespace ServiceLib.Handler public static void Stop() { if (_tcpListener == null) + { return; + } try { _isRunning = false; diff --git a/v2rayn/v2rayN/ServiceLib/Handler/ProfileExHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/ProfileExHandler.cs index 31a6b56c34..b9bc873579 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/ProfileExHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/ProfileExHandler.cs @@ -36,7 +36,7 @@ namespace ServiceLib.Handler private void IndexIdEnqueue(string indexId) { - if (Utils.IsNotEmpty(indexId) && !_queIndexIds.Contains(indexId)) + if (indexId.IsNotEmpty() && !_queIndexIds.Contains(indexId)) { _queIndexIds.Enqueue(indexId); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/ProxySettingWindows.cs b/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/ProxySettingWindows.cs index 818ea3f377..614bd65665 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/ProxySettingWindows.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/ProxySettingWindows.cs @@ -60,7 +60,7 @@ namespace ServiceLib.Handler.SysProxy try { // set proxy for LAN - bool result = SetConnectionProxy(null, strProxy, exceptions, type); + var result = SetConnectionProxy(null, strProxy, exceptions, type); // set proxy for dial up connections var connections = EnumerateRasEntries(); foreach (var connection in connections) @@ -71,27 +71,27 @@ namespace ServiceLib.Handler.SysProxy } catch { - SetProxyFallback(strProxy, exceptions, type); + _ = SetProxyFallback(strProxy, exceptions, type); return false; } } private static bool SetConnectionProxy(string? connectionName, string? strProxy, string? exceptions, int type) { - InternetPerConnOptionList list = new(); + var list = new InternetPerConnOptionList(); - int optionCount = 1; + var optionCount = 1; if (type == 1) // No proxy { optionCount = 1; } else if (type is 2 or 4) // named proxy or autoproxy script URL { - optionCount = string.IsNullOrEmpty(exceptions) ? 2 : 3; + optionCount = exceptions.IsNullOrEmpty() ? 2 : 3; } - int m_Int = (int)PerConnFlags.PROXY_TYPE_DIRECT; - PerConnOption m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS; + var m_Int = (int)PerConnFlags.PROXY_TYPE_DIRECT; + var m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS; if (type == 2) // named proxy { m_Int = (int)(PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY); @@ -103,11 +103,9 @@ namespace ServiceLib.Handler.SysProxy m_Option = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL; } - //int optionCount = Utile.IsNullOrEmpty(strProxy) ? 1 : (Utile.IsNullOrEmpty(exceptions) ? 2 : 3); - InternetConnectionOption[] options = new InternetConnectionOption[optionCount]; + var options = new InternetConnectionOption[optionCount]; // USE a proxy server ... options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS; - //options[0].m_Value.m_Int = (int)((optionCount < 2) ? PerConnFlags.PROXY_TYPE_DIRECT : (PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY)); options[0].m_Value.m_Int = m_Int; // use THIS proxy server if (optionCount > 1) @@ -135,20 +133,20 @@ namespace ServiceLib.Handler.SysProxy list.dwOptionCount = options.Length; list.dwOptionError = 0; - int optSize = Marshal.SizeOf(typeof(InternetConnectionOption)); + var optSize = Marshal.SizeOf(typeof(InternetConnectionOption)); // make a pointer out of all that ... - nint optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length); // !! remember to deallocate memory 4 + var optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length); // !! remember to deallocate memory 4 // copy the array over into that spot in memory ... - for (int i = 0; i < options.Length; ++i) + for (var i = 0; i < options.Length; ++i) { if (Environment.Is64BitOperatingSystem) { - nint opt = new(optionsPtr.ToInt64() + (i * optSize)); + var opt = new nint(optionsPtr.ToInt64() + (i * optSize)); Marshal.StructureToPtr(options[i], opt, false); } else { - nint opt = new(optionsPtr.ToInt32() + (i * optSize)); + var opt = new nint(optionsPtr.ToInt32() + (i * optSize)); Marshal.StructureToPtr(options[i], opt, false); } } @@ -156,14 +154,14 @@ namespace ServiceLib.Handler.SysProxy list.options = optionsPtr; // and then make a pointer out of the whole list - nint ipcoListPtr = Marshal.AllocCoTaskMem(list.dwSize); // !! remember to deallocate memory 5 + var ipcoListPtr = Marshal.AllocCoTaskMem(list.dwSize); // !! remember to deallocate memory 5 Marshal.StructureToPtr(list, ipcoListPtr, false); // and finally, call the API method! - bool isSuccess = NativeMethods.InternetSetOption(nint.Zero, + var isSuccess = NativeMethods.InternetSetOption(nint.Zero, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION, ipcoListPtr, list.dwSize); - int returnvalue = 0; // ERROR_SUCCESS + var returnvalue = 0; // ERROR_SUCCESS if (!isSuccess) { // get the error codes, they might be helpful returnvalue = Marshal.GetLastPInvokeError(); @@ -171,13 +169,15 @@ namespace ServiceLib.Handler.SysProxy else { // Notify the system that the registry settings have been changed and cause them to be refreshed - NativeMethods.InternetSetOption(nint.Zero, InternetOption.INTERNET_OPTION_SETTINGS_CHANGED, nint.Zero, 0); - NativeMethods.InternetSetOption(nint.Zero, InternetOption.INTERNET_OPTION_REFRESH, nint.Zero, 0); + _ = NativeMethods.InternetSetOption(nint.Zero, InternetOption.INTERNET_OPTION_SETTINGS_CHANGED, nint.Zero, 0); + _ = NativeMethods.InternetSetOption(nint.Zero, InternetOption.INTERNET_OPTION_REFRESH, nint.Zero, 0); } // FREE the data ASAP if (list.szConnection != nint.Zero) + { Marshal.FreeHGlobal(list.szConnection); // release mem 3 + } if (optionCount > 1) { Marshal.FreeHGlobal(options[1].m_Value.m_StringPtr); // release mem 1 @@ -204,18 +204,18 @@ namespace ServiceLib.Handler.SysProxy /// Error message with win32 error code private static IEnumerable EnumerateRasEntries() { - int entries = 0; + var entries = 0; // attempt to query with 1 entry buffer - RASENTRYNAME[] rasEntryNames = new RASENTRYNAME[1]; - int bufferSize = Marshal.SizeOf(typeof(RASENTRYNAME)); + var rasEntryNames = new RASENTRYNAME[1]; + var bufferSize = Marshal.SizeOf(typeof(RASENTRYNAME)); rasEntryNames[0].dwSize = Marshal.SizeOf(typeof(RASENTRYNAME)); - uint result = NativeMethods.RasEnumEntries(null, null, rasEntryNames, ref bufferSize, ref entries); + var result = NativeMethods.RasEnumEntries(null, null, rasEntryNames, ref bufferSize, ref entries); // increase buffer if the buffer is not large enough if (result == (uint)ErrorCode.ERROR_BUFFER_TOO_SMALL) { rasEntryNames = new RASENTRYNAME[bufferSize / Marshal.SizeOf(typeof(RASENTRYNAME))]; - for (int i = 0; i < rasEntryNames.Length; i++) + for (var i = 0; i < rasEntryNames.Length; i++) { rasEntryNames[i].dwSize = Marshal.SizeOf(typeof(RASENTRYNAME)); } @@ -225,7 +225,7 @@ namespace ServiceLib.Handler.SysProxy if (result == 0) { var entryNames = new List(); - for (int i = 0; i < entries; i++) + for (var i = 0; i < entries; i++) { entryNames.Add(rasEntryNames[i].szEntryName); } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs index 99cc991abc..6d8a9b441f 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs @@ -75,7 +75,7 @@ } strProxy = string.Empty; - if (Utils.IsNullOrEmpty(config.SystemProxyItem.SystemProxyAdvancedProtocol)) + if (config.SystemProxyItem.SystemProxyAdvancedProtocol.IsNullOrEmpty()) { strProxy = $"{Global.Loopback}:{port}"; } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/WebDavHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/WebDavHandler.cs index 8e37fc4359..ac9a626f42 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/WebDavHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/WebDavHandler.cs @@ -8,7 +8,7 @@ namespace ServiceLib.Handler private static readonly Lazy _instance = new(() => new()); public static WebDavHandler Instance => _instance.Value; - private Config? _config; + private readonly Config? _config; private WebDavClient? _client; private string? _lastDescription; private string _webDir = Global.AppName + "_backup"; @@ -62,7 +62,9 @@ namespace ServiceLib.Handler private async Task TryCreateDir() { if (_client is null) + { return false; + } try { var result2 = await _client.Mkcol(_webDir); diff --git a/v2rayn/v2rayN/ServiceLib/Models/ProfileItem.cs b/v2rayn/v2rayN/ServiceLib/Models/ProfileItem.cs index 5f7081033c..db752a756a 100644 --- a/v2rayn/v2rayN/ServiceLib/Models/ProfileItem.cs +++ b/v2rayn/v2rayN/ServiceLib/Models/ProfileItem.cs @@ -48,12 +48,12 @@ namespace ServiceLib.Models public List? GetAlpn() { - return Utils.IsNullOrEmpty(Alpn) ? null : Utils.String2List(Alpn); + return Alpn.IsNullOrEmpty() ? null : Utils.String2List(Alpn); } public string GetNetwork() { - if (Utils.IsNullOrEmpty(Network) || !Global.Networks.Contains(Network)) + if (Network.IsNullOrEmpty() || !Global.Networks.Contains(Network)) { return Global.DefaultNetwork; } diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs index d64d22b7b9..4358b5a909 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs @@ -44,8 +44,8 @@ namespace ServiceLib.Services.CoreConfig File.Delete(fileName); } - string addressFileName = node.Address; - if (Utils.IsNullOrEmpty(addressFileName)) + var addressFileName = node.Address; + if (addressFileName.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -60,9 +60,9 @@ namespace ServiceLib.Services.CoreConfig return ret; } - string tagYamlStr1 = "!"; - string tagYamlStr2 = "__strn__"; - string tagYamlStr3 = "!!str"; + var tagYamlStr1 = "!"; + var tagYamlStr2 = "__strn__"; + var tagYamlStr3 = "!!str"; var txtFile = File.ReadAllText(addressFileName); txtFile = txtFile.Replace(tagYamlStr1, tagYamlStr2); @@ -117,11 +117,13 @@ namespace ServiceLib.Services.CoreConfig if (_config.TunModeItem.EnableTun) { var tun = EmbedUtils.GetEmbedText(Global.ClashTunYaml); - if (Utils.IsNotEmpty(tun)) + if (tun.IsNotEmpty()) { var tunContent = YamlUtils.FromYaml>(tun); if (tunContent != null) + { fileContent["tun"] = tunContent["tun"]; + } } } @@ -202,8 +204,8 @@ namespace ServiceLib.Services.CoreConfig private void ModifyContentMerge(Dictionary fileContent, string key, object value) { - bool blPrepend = false; - bool blRemoved = false; + var blPrepend = false; + var blRemoved = false; if (key.StartsWith("prepend-")) { blPrepend = true; @@ -244,17 +246,11 @@ namespace ServiceLib.Services.CoreConfig if (blPrepend) { lstValue.Reverse(); - foreach (var item in lstValue) - { - lstOri.Insert(0, item); - } + lstValue.ForEach(item => lstOri.Insert(0, item)); } else { - foreach (var item in lstValue) - { - lstOri.Add(item); - } + lstValue.ForEach(item => lstOri.Add(item)); } } diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs index 475eed106c..29ff8a424b 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs @@ -36,7 +36,7 @@ namespace ServiceLib.Services.CoreConfig ret.Msg = ResUI.InitialConfiguration; string result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient); - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -93,7 +93,7 @@ namespace ServiceLib.Services.CoreConfig var result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient); var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound); - if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) + if (result.IsNullOrEmpty() || txtOutbound.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -138,7 +138,7 @@ namespace ServiceLib.Services.CoreConfig var item = await AppHandler.Instance.GetProfileItem(it.IndexId); if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS) { - if (item is null || Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id)) + if (item is null || item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id)) { continue; } @@ -261,7 +261,7 @@ namespace ServiceLib.Services.CoreConfig ret.Msg = ResUI.InitialConfiguration; var result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient); - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -317,7 +317,7 @@ namespace ServiceLib.Services.CoreConfig string result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient); string txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound); - if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) + if (result.IsNullOrEmpty() || txtOutbound.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -354,7 +354,7 @@ namespace ServiceLib.Services.CoreConfig } if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS) { - if (Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id)) + if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id)) { continue; } @@ -443,7 +443,7 @@ namespace ServiceLib.Services.CoreConfig } string addressFileName = node.Address; - if (Utils.IsNullOrEmpty(addressFileName)) + if (addressFileName.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -560,10 +560,10 @@ namespace ServiceLib.Services.CoreConfig inbound.listen_port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks); inbound.sniff = _config.Inbound.First().SniffingEnabled; inbound.sniff_override_destination = _config.Inbound.First().RouteOnly ? false : _config.Inbound.First().SniffingEnabled; - inbound.domain_strategy = Utils.IsNullOrEmpty(_config.RoutingBasicItem.DomainStrategy4Singbox) ? null : _config.RoutingBasicItem.DomainStrategy4Singbox; + inbound.domain_strategy = _config.RoutingBasicItem.DomainStrategy4Singbox.IsNullOrEmpty() ? null : _config.RoutingBasicItem.DomainStrategy4Singbox; var routing = await ConfigHandler.GetDefaultRouting(_config); - if (Utils.IsNotEmpty(routing.DomainStrategy4Singbox)) + if (routing.DomainStrategy4Singbox.IsNotEmpty()) { inbound.domain_strategy = routing.DomainStrategy4Singbox; } @@ -583,7 +583,7 @@ namespace ServiceLib.Services.CoreConfig singboxConfig.inbounds.Add(inbound3); //auth - if (Utils.IsNotEmpty(_config.Inbound.First().User) && Utils.IsNotEmpty(_config.Inbound.First().Pass)) + if (_config.Inbound.First().User.IsNotEmpty() && _config.Inbound.First().Pass.IsNotEmpty()) { inbound3.users = new() { new() { username = _config.Inbound.First().User, password = _config.Inbound.First().Pass } }; } @@ -601,7 +601,7 @@ namespace ServiceLib.Services.CoreConfig { _config.TunModeItem.Mtu = Global.TunMtus.First(); } - if (Utils.IsNullOrEmpty(_config.TunModeItem.Stack)) + if (_config.TunModeItem.Stack.IsNullOrEmpty()) { _config.TunModeItem.Stack = Global.TunStacks.First(); } @@ -674,8 +674,8 @@ namespace ServiceLib.Services.CoreConfig case EConfigType.SOCKS: { outbound.version = "5"; - if (Utils.IsNotEmpty(node.Security) - && Utils.IsNotEmpty(node.Id)) + if (node.Security.IsNotEmpty() + && node.Id.IsNotEmpty()) { outbound.username = node.Security; outbound.password = node.Id; @@ -684,8 +684,8 @@ namespace ServiceLib.Services.CoreConfig } case EConfigType.HTTP: { - if (Utils.IsNotEmpty(node.Security) - && Utils.IsNotEmpty(node.Id)) + if (node.Security.IsNotEmpty() + && node.Id.IsNotEmpty()) { outbound.username = node.Security; outbound.password = node.Id; @@ -698,7 +698,7 @@ namespace ServiceLib.Services.CoreConfig outbound.packet_encoding = "xudp"; - if (Utils.IsNullOrEmpty(node.Flow)) + if (node.Flow.IsNullOrEmpty()) { await GenOutboundMux(node, outbound); } @@ -719,7 +719,7 @@ namespace ServiceLib.Services.CoreConfig { outbound.password = node.Id; - if (Utils.IsNotEmpty(node.Path)) + if (node.Path.IsNotEmpty()) { outbound.obfs = new() { @@ -755,7 +755,7 @@ namespace ServiceLib.Services.CoreConfig outbound.peer_public_key = node.PublicKey; outbound.reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList(); outbound.local_address = Utils.String2List(node.RequestHost); - outbound.mtu = Utils.ToInt(node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId); + outbound.mtu = node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId.ToInt(); break; } } @@ -775,7 +775,7 @@ namespace ServiceLib.Services.CoreConfig { try { - if (_config.CoreBasicItem.MuxEnabled && Utils.IsNotEmpty(_config.Mux4SboxItem.Protocol)) + if (_config.CoreBasicItem.MuxEnabled && _config.Mux4SboxItem.Protocol.IsNotEmpty()) { var mux = new Multiplex4Sbox() { @@ -801,11 +801,11 @@ namespace ServiceLib.Services.CoreConfig if (node.StreamSecurity == Global.StreamSecurityReality || node.StreamSecurity == Global.StreamSecurity) { var server_name = string.Empty; - if (Utils.IsNotEmpty(node.Sni)) + if (node.Sni.IsNotEmpty()) { server_name = node.Sni; } - else if (Utils.IsNotEmpty(node.RequestHost)) + else if (node.RequestHost.IsNotEmpty()) { server_name = Utils.String2List(node.RequestHost)?.First(); } @@ -816,7 +816,7 @@ namespace ServiceLib.Services.CoreConfig insecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure), alpn = node.GetAlpn(), }; - if (Utils.IsNotEmpty(node.Fingerprint)) + if (node.Fingerprint.IsNotEmpty()) { tls.utls = new Utls4Sbox() { @@ -854,8 +854,8 @@ namespace ServiceLib.Services.CoreConfig { case nameof(ETransport.h2): transport.type = nameof(ETransport.http); - transport.host = Utils.IsNullOrEmpty(node.RequestHost) ? null : Utils.String2List(node.RequestHost); - transport.path = Utils.IsNullOrEmpty(node.Path) ? null : node.Path; + transport.host = node.RequestHost.IsNullOrEmpty() ? null : Utils.String2List(node.RequestHost); + transport.path = node.Path.IsNullOrEmpty() ? null : node.Path; break; case nameof(ETransport.tcp): //http @@ -869,16 +869,16 @@ namespace ServiceLib.Services.CoreConfig else { transport.type = nameof(ETransport.http); - transport.host = Utils.IsNullOrEmpty(node.RequestHost) ? null : Utils.String2List(node.RequestHost); - transport.path = Utils.IsNullOrEmpty(node.Path) ? null : node.Path; + transport.host = node.RequestHost.IsNullOrEmpty() ? null : Utils.String2List(node.RequestHost); + transport.path = node.Path.IsNullOrEmpty() ? null : node.Path; } } break; case nameof(ETransport.ws): transport.type = nameof(ETransport.ws); - transport.path = Utils.IsNullOrEmpty(node.Path) ? null : node.Path; - if (Utils.IsNotEmpty(node.RequestHost)) + transport.path = node.Path.IsNullOrEmpty() ? null : node.Path; + if (node.RequestHost.IsNotEmpty()) { transport.headers = new() { @@ -889,8 +889,8 @@ namespace ServiceLib.Services.CoreConfig case nameof(ETransport.httpupgrade): transport.type = nameof(ETransport.httpupgrade); - transport.path = Utils.IsNullOrEmpty(node.Path) ? null : node.Path; - transport.host = Utils.IsNullOrEmpty(node.RequestHost) ? null : node.RequestHost; + transport.path = node.Path.IsNullOrEmpty() ? null : node.Path; + transport.host = node.RequestHost.IsNullOrEmpty() ? null : node.RequestHost; break; @@ -1085,7 +1085,7 @@ namespace ServiceLib.Services.CoreConfig outbound = item.OutboundTag, }; - if (Utils.IsNotEmpty(item.Port)) + if (item.Port.IsNotEmpty()) { if (item.Port.Contains("-")) { @@ -1093,10 +1093,10 @@ namespace ServiceLib.Services.CoreConfig } else { - rule.port = new List { Utils.ToInt(item.Port) }; + rule.port = new List { item.Port.ToInt() }; } } - if (Utils.IsNotEmpty(item.Network)) + if (item.Network.IsNotEmpty()) { rule.network = Utils.String2List(item.Network); } @@ -1241,11 +1241,11 @@ namespace ServiceLib.Services.CoreConfig var strDNS = string.Empty; if (_config.TunModeItem.EnableTun) { - strDNS = Utils.IsNullOrEmpty(item?.TunDNS) ? EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.TunDNS; + strDNS = string.IsNullOrEmpty(item?.TunDNS) ? EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.TunDNS; } else { - strDNS = Utils.IsNullOrEmpty(item?.NormalDNS) ? EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.NormalDNS; + strDNS = string.IsNullOrEmpty(item?.NormalDNS) ? EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.NormalDNS; } var dns4Sbox = JsonUtils.Deserialize(strDNS); @@ -1274,9 +1274,9 @@ namespace ServiceLib.Services.CoreConfig dns4Sbox.servers.Add(new() { tag = tag, - address = Utils.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress, + address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress, detour = Global.DirectTag, - strategy = Utils.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom, + strategy = string.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom, }); dns4Sbox.rules.Insert(0, new() { @@ -1290,7 +1290,7 @@ namespace ServiceLib.Services.CoreConfig }); var lstDomain = singboxConfig.outbounds - .Where(t => Utils.IsNotEmpty(t.server) && Utils.IsDomain(t.server)) + .Where(t => t.server.IsNotEmpty() && Utils.IsDomain(t.server)) .Select(t => t.server) .Distinct() .ToList(); @@ -1394,10 +1394,10 @@ namespace ServiceLib.Services.CoreConfig List customRulesets = []; var routing = await ConfigHandler.GetDefaultRouting(_config); - if (Utils.IsNotEmpty(routing.CustomRulesetPath4Singbox)) + if (routing.CustomRulesetPath4Singbox.IsNotEmpty()) { var result = EmbedUtils.LoadResource(routing.CustomRulesetPath4Singbox); - if (Utils.IsNotEmpty(result)) + if (result.IsNotEmpty()) { customRulesets = (JsonUtils.Deserialize>(result) ?? []) .Where(t => t.tag != null) @@ -1414,7 +1414,7 @@ namespace ServiceLib.Services.CoreConfig singboxConfig.route.rule_set = []; foreach (var item in new HashSet(ruleSets)) { - if (Utils.IsNullOrEmpty(item)) + if (item.IsNullOrEmpty()) { continue; } var customRuleset = customRulesets.FirstOrDefault(t => t.tag != null && t.tag.Equals(item)); if (customRuleset is null) diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs index f07a9c940b..5c23ca19cf 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigV2rayService.cs @@ -37,7 +37,7 @@ namespace ServiceLib.Services.CoreConfig ret.Msg = ResUI.InitialConfiguration; var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient); - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -93,7 +93,7 @@ namespace ServiceLib.Services.CoreConfig string result = EmbedUtils.GetEmbedText(Global.V2raySampleClient); string txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound); - if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) + if (result.IsNullOrEmpty() || txtOutbound.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -135,7 +135,7 @@ namespace ServiceLib.Services.CoreConfig } if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS) { - if (Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id)) + if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id)) { continue; } @@ -216,7 +216,7 @@ namespace ServiceLib.Services.CoreConfig var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient); var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound); - if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) + if (result.IsNullOrEmpty() || txtOutbound.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -261,7 +261,7 @@ namespace ServiceLib.Services.CoreConfig var item = await AppHandler.Instance.GetProfileItem(it.IndexId); if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS) { - if (item is null || Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id)) + if (item is null || item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id)) { continue; } @@ -371,7 +371,7 @@ namespace ServiceLib.Services.CoreConfig } var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient); - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { ret.Msg = ResUI.FailedGetDefaultConfiguration; return ret; @@ -465,7 +465,7 @@ namespace ServiceLib.Services.CoreConfig v2rayConfig.inbounds.Add(inbound3); //auth - if (Utils.IsNotEmpty(_config.Inbound.First().User) && Utils.IsNotEmpty(_config.Inbound.First().Pass)) + if (_config.Inbound.First().User.IsNotEmpty() && _config.Inbound.First().Pass.IsNotEmpty()) { inbound3.settings.auth = "password"; inbound3.settings.accounts = new List { new AccountsItem4Ray() { user = _config.Inbound.First().User, pass = _config.Inbound.First().Pass } }; @@ -487,7 +487,7 @@ namespace ServiceLib.Services.CoreConfig private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks) { string result = EmbedUtils.GetEmbedText(Global.V2raySampleInbound); - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { return new(); } @@ -515,12 +515,12 @@ namespace ServiceLib.Services.CoreConfig if (v2rayConfig.routing?.rules != null) { v2rayConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy; - v2rayConfig.routing.domainMatcher = Utils.IsNullOrEmpty(_config.RoutingBasicItem.DomainMatcher) ? null : _config.RoutingBasicItem.DomainMatcher; + v2rayConfig.routing.domainMatcher = _config.RoutingBasicItem.DomainMatcher.IsNullOrEmpty() ? null : _config.RoutingBasicItem.DomainMatcher; var routing = await ConfigHandler.GetDefaultRouting(_config); if (routing != null) { - if (Utils.IsNotEmpty(routing.DomainStrategy)) + if (routing.DomainStrategy.IsNotEmpty()) { v2rayConfig.routing.domainStrategy = routing.DomainStrategy; } @@ -551,11 +551,11 @@ namespace ServiceLib.Services.CoreConfig { return 0; } - if (Utils.IsNullOrEmpty(rule.port)) + if (rule.port.IsNullOrEmpty()) { rule.port = null; } - if (Utils.IsNullOrEmpty(rule.network)) + if (rule.network.IsNullOrEmpty()) { rule.network = null; } @@ -603,7 +603,7 @@ namespace ServiceLib.Services.CoreConfig } if (!hasDomainIp) { - if (Utils.IsNotEmpty(rule.port) + if (rule.port.IsNotEmpty() || rule.protocol?.Count > 0 || rule.inboundTag?.Count > 0 ) @@ -714,8 +714,8 @@ namespace ServiceLib.Services.CoreConfig serversItem.method = null; serversItem.password = null; - if (Utils.IsNotEmpty(node.Security) - && Utils.IsNotEmpty(node.Id)) + if (node.Security.IsNotEmpty() + && node.Id.IsNotEmpty()) { SocksUsersItem4Ray socksUsersItem = new() { @@ -868,11 +868,11 @@ namespace ServiceLib.Services.CoreConfig alpn = node.GetAlpn(), fingerprint = node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.Fingerprint }; - if (Utils.IsNotEmpty(sni)) + if (sni.IsNotEmpty()) { tlsSettings.serverName = sni; } - else if (Utils.IsNotEmpty(host)) + else if (host.IsNotEmpty()) { tlsSettings.serverName = Utils.String2List(host)?.First(); } @@ -918,7 +918,7 @@ namespace ServiceLib.Services.CoreConfig type = node.HeaderType, domain = host.IsNullOrEmpty() ? null : host }; - if (Utils.IsNotEmpty(path)) + if (path.IsNotEmpty()) { kcpSettings.seed = path; } @@ -929,16 +929,16 @@ namespace ServiceLib.Services.CoreConfig WsSettings4Ray wsSettings = new(); wsSettings.headers = new Headers4Ray(); - if (Utils.IsNotEmpty(host)) + if (host.IsNotEmpty()) { wsSettings.host = host; wsSettings.headers.Host = host; } - if (Utils.IsNotEmpty(path)) + if (path.IsNotEmpty()) { wsSettings.path = path; } - if (Utils.IsNotEmpty(useragent)) + if (useragent.IsNotEmpty()) { wsSettings.headers.UserAgent = useragent; } @@ -949,11 +949,11 @@ namespace ServiceLib.Services.CoreConfig case nameof(ETransport.httpupgrade): HttpupgradeSettings4Ray httpupgradeSettings = new(); - if (Utils.IsNotEmpty(path)) + if (path.IsNotEmpty()) { httpupgradeSettings.path = path; } - if (Utils.IsNotEmpty(host)) + if (host.IsNotEmpty()) { httpupgradeSettings.host = host; } @@ -965,19 +965,19 @@ namespace ServiceLib.Services.CoreConfig streamSettings.network = ETransport.xhttp.ToString(); XhttpSettings4Ray xhttpSettings = new(); - if (Utils.IsNotEmpty(path)) + if (path.IsNotEmpty()) { xhttpSettings.path = path; } - if (Utils.IsNotEmpty(host)) + if (host.IsNotEmpty()) { xhttpSettings.host = host; } - if (Utils.IsNotEmpty(node.HeaderType) && Global.XhttpMode.Contains(node.HeaderType)) + if (node.HeaderType.IsNotEmpty() && Global.XhttpMode.Contains(node.HeaderType)) { xhttpSettings.mode = node.HeaderType; } - if (Utils.IsNotEmpty(node.Extra)) + if (node.Extra.IsNotEmpty()) { xhttpSettings.extra = JsonUtils.ParseJson(node.Extra); } @@ -990,7 +990,7 @@ namespace ServiceLib.Services.CoreConfig case nameof(ETransport.h2): HttpSettings4Ray httpSettings = new(); - if (Utils.IsNotEmpty(host)) + if (host.IsNotEmpty()) { httpSettings.host = Utils.String2List(host); } @@ -1013,7 +1013,7 @@ namespace ServiceLib.Services.CoreConfig streamSettings.quicSettings = quicsettings; if (node.StreamSecurity == Global.StreamSecurity) { - if (Utils.IsNotEmpty(sni)) + if (sni.IsNotEmpty()) { streamSettings.tlsSettings.serverName = sni; } @@ -1027,7 +1027,7 @@ namespace ServiceLib.Services.CoreConfig case nameof(ETransport.grpc): GrpcSettings4Ray grpcSettings = new() { - authority = Utils.IsNullOrEmpty(host) ? null : host, + authority = host.IsNullOrEmpty() ? null : host, serviceName = path, multiMode = node.HeaderType == Global.GrpcMultiMode, idle_timeout = _config.GrpcItem.IdleTimeout, @@ -1058,7 +1058,7 @@ namespace ServiceLib.Services.CoreConfig request = request.Replace("$requestUserAgent$", $"{useragent.AppendQuotes()}"); //Path string pathHttp = @"/"; - if (Utils.IsNotEmpty(path)) + if (path.IsNotEmpty()) { string[] arrPath = path.Split(','); pathHttp = string.Join(",".AppendQuotes(), arrPath); @@ -1085,13 +1085,13 @@ namespace ServiceLib.Services.CoreConfig var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray); var normalDNS = item?.NormalDNS; var domainStrategy4Freedom = item?.DomainStrategy4Freedom; - if (Utils.IsNullOrEmpty(normalDNS)) + if (normalDNS.IsNullOrEmpty()) { normalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName); } //Outbound Freedom domainStrategy - if (Utils.IsNotEmpty(domainStrategy4Freedom)) + if (domainStrategy4Freedom.IsNotEmpty()) { var outbound = v2rayConfig.outbounds.FirstOrDefault(t => t is { protocol: "freedom", tag: Global.DirectTag }); if (outbound != null) @@ -1156,7 +1156,7 @@ namespace ServiceLib.Services.CoreConfig { var dnsServer = new DnsServer4Ray() { - address = Utils.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress, + address = string.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress, domains = [node.Address] }; servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer)); @@ -1216,7 +1216,7 @@ namespace ServiceLib.Services.CoreConfig { //fragment proxy if (_config.CoreBasicItem.EnableFragment - && Utils.IsNotEmpty(v2rayConfig.outbounds.First().streamSettings?.security)) + && v2rayConfig.outbounds.First().streamSettings?.security.IsNullOrEmpty() == false) { var fragmentOutbound = new Outbounds4Ray { diff --git a/v2rayn/v2rayN/ServiceLib/Services/DownloadService.cs b/v2rayn/v2rayN/ServiceLib/Services/DownloadService.cs index e94dd9c216..aab888c932 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/DownloadService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/DownloadService.cs @@ -23,14 +23,7 @@ namespace ServiceLib.Services SetSecurityProtocol(AppHandler.Instance.Config.GuiItem.EnableSecurityProtocolTls13); var progress = new Progress(); - progress.ProgressChanged += (sender, value) => - { - if (updateFunc != null) - { - string msg = $"{value}"; - updateFunc?.Invoke(false, msg); - } - }; + progress.ProgressChanged += (sender, value) => updateFunc?.Invoke(false, $"{value}"); await DownloaderHelper.Instance.DownloadDataAsync4Speed(webProxy, url, @@ -56,10 +49,7 @@ namespace ServiceLib.Services UpdateCompleted?.Invoke(this, new RetResult(false, $"{ResUI.Downloading} {url}")); var progress = new Progress(); - progress.ProgressChanged += (sender, value) => - { - UpdateCompleted?.Invoke(this, new RetResult(value > 100, $"...{value}%")); - }; + progress.ProgressChanged += (sender, value) => UpdateCompleted?.Invoke(this, new RetResult(value > 100, $"...{value}%")); var webProxy = await GetWebProxy(blProxy); await DownloaderHelper.Instance.DownloadFileAsync(webProxy, @@ -108,7 +98,7 @@ namespace ServiceLib.Services try { var result1 = await DownloadStringAsync(url, blProxy, userAgent, 15); - if (Utils.IsNotEmpty(result1)) + if (result1.IsNotEmpty()) { return result1; } @@ -126,7 +116,7 @@ namespace ServiceLib.Services try { var result2 = await DownloadStringViaDownloader(url, blProxy, userAgent, 15); - if (Utils.IsNotEmpty(result2)) + if (result2.IsNotEmpty()) { return result2; } @@ -160,7 +150,7 @@ namespace ServiceLib.Services UseProxy = webProxy != null }); - if (Utils.IsNullOrEmpty(userAgent)) + if (userAgent.IsNullOrEmpty()) { userAgent = Utils.GetVersion(false); } @@ -168,7 +158,7 @@ namespace ServiceLib.Services Uri uri = new(url); //Authorization Header - if (Utils.IsNotEmpty(uri.UserInfo)) + if (uri.UserInfo.IsNotEmpty()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Utils.Base64Encode(uri.UserInfo)); } @@ -201,7 +191,7 @@ namespace ServiceLib.Services var webProxy = await GetWebProxy(blProxy); - if (Utils.IsNullOrEmpty(userAgent)) + if (userAgent.IsNullOrEmpty()) { userAgent = Utils.GetVersion(false); } @@ -263,7 +253,7 @@ namespace ServiceLib.Services for (var i = 0; i < 2; i++) { var timer = Stopwatch.StartNew(); - await client.GetAsync(url, cts.Token); + await client.GetAsync(url, cts.Token).ConfigureAwait(false); timer.Stop(); oneTime.Add((int)timer.Elapsed.TotalMilliseconds); await Task.Delay(100); diff --git a/v2rayn/v2rayN/ServiceLib/Services/SpeedtestService.cs b/v2rayn/v2rayN/ServiceLib/Services/SpeedtestService.cs index 05de5b0264..e9ab134406 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/SpeedtestService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/SpeedtestService.cs @@ -141,8 +141,7 @@ namespace ServiceLib.Services } })); } - Task.WaitAll([.. tasks]); - await Task.CompletedTask; + await Task.WhenAll(tasks); } private async Task RunRealPingBatchAsync(List lstSelected, string exitLoopKey, int pageSize = 0) @@ -216,7 +215,7 @@ namespace ServiceLib.Services await DoRealPing(downloadHandle, it); })); } - Task.WaitAll(tasks.ToArray()); + await Task.WhenAll(tasks); } catch (Exception ex) { @@ -291,7 +290,7 @@ namespace ServiceLib.Services } })); } - Task.WaitAll(tasks.ToArray()); + await Task.WhenAll(tasks); } private async Task DoRealPing(DownloadService downloadHandle, ServerTestItem it) diff --git a/v2rayn/v2rayN/ServiceLib/Services/Statistics/StatisticsSingboxService.cs b/v2rayn/v2rayN/ServiceLib/Services/Statistics/StatisticsSingboxService.cs index 3eecee2695..b09402a00a 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/Statistics/StatisticsSingboxService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/Statistics/StatisticsSingboxService.cs @@ -5,7 +5,7 @@ namespace ServiceLib.Services.Statistics { public class StatisticsSingboxService { - private Config _config; + private readonly Config _config; private bool _exitFlag; private ClientWebSocket? webSocket; private Action? _updateFunc; @@ -18,7 +18,7 @@ namespace ServiceLib.Services.Statistics _updateFunc = updateFunc; _exitFlag = false; - Task.Run(Run); + _ = Task.Run(Run); } private async Task Init() @@ -68,8 +68,7 @@ namespace ServiceLib.Services.Statistics } if (webSocket != null) { - if (webSocket.State == WebSocketState.Aborted - || webSocket.State == WebSocketState.Closed) + if (webSocket.State is WebSocketState.Aborted or WebSocketState.Closed) { webSocket.Abort(); webSocket = null; @@ -87,9 +86,9 @@ namespace ServiceLib.Services.Statistics while (!res.CloseStatus.HasValue) { var result = Encoding.UTF8.GetString(buffer, 0, res.Count); - if (Utils.IsNotEmpty(result)) + if (result.IsNotEmpty()) { - ParseOutput(result, out ulong up, out ulong down); + ParseOutput(result, out var up, out var down); _updateFunc?.Invoke(new ServerSpeedItem() { diff --git a/v2rayn/v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs b/v2rayn/v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs index 92ced15ee9..d74a3e4883 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs @@ -4,7 +4,7 @@ namespace ServiceLib.Services.Statistics { private const long linkBase = 1024; private ServerSpeedItem _serverSpeedItem = new(); - private Config _config; + private readonly Config _config; private bool _exitFlag; private Action? _updateFunc; private string Url => $"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort}/debug/vars"; @@ -15,7 +15,7 @@ namespace ServiceLib.Services.Statistics _updateFunc = updateFunc; _exitFlag = false; - Task.Run(Run); + _ = Task.Run(Run); } public void Close() @@ -60,11 +60,13 @@ namespace ServiceLib.Services.Statistics } ServerSpeedItem server = new(); - foreach (string key in source.stats.outbound.Keys) + foreach (var key in source.stats.outbound.Keys.Cast()) { var value = source.stats.outbound[key]; if (value == null) + { continue; + } var state = JsonUtils.Deserialize(value.ToString()); if (key.StartsWith(Global.ProxyTag)) diff --git a/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs b/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs index 6be2b3bf50..0452f087f3 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs @@ -123,7 +123,7 @@ namespace ServiceLib.Services var url = item.Url.TrimEx(); var userAgent = item.UserAgent.TrimEx(); var hashCode = $"{item.Remarks}->"; - if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || (Utils.IsNotEmpty(subId) && item.Id != subId)) + if (id.IsNullOrEmpty() || url.IsNullOrEmpty() || (subId.IsNotEmpty() && item.Id != subId)) { //_updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgNoValidSubscription}"); continue; @@ -149,9 +149,9 @@ namespace ServiceLib.Services //one url url = Utils.GetPunycode(url); //convert - if (Utils.IsNotEmpty(item.ConvertTarget)) + if (item.ConvertTarget.IsNotEmpty()) { - var subConvertUrl = Utils.IsNullOrEmpty(config.ConstItem.SubConvertUrl) ? Global.SubConvertUrls.FirstOrDefault() : config.ConstItem.SubConvertUrl; + var subConvertUrl = config.ConstItem.SubConvertUrl.IsNullOrEmpty() ? Global.SubConvertUrls.FirstOrDefault() : config.ConstItem.SubConvertUrl; url = string.Format(subConvertUrl!, Utils.UrlEncode(url)); if (!url.Contains("target=")) { @@ -163,15 +163,15 @@ namespace ServiceLib.Services } } var result = await downloadHandle.TryDownloadString(url, blProxy, userAgent); - if (blProxy && Utils.IsNullOrEmpty(result)) + if (blProxy && result.IsNullOrEmpty()) { result = await downloadHandle.TryDownloadString(url, false, userAgent); } //more url - if (Utils.IsNullOrEmpty(item.ConvertTarget) && Utils.IsNotEmpty(item.MoreUrl.TrimEx())) + if (item.ConvertTarget.IsNullOrEmpty() && item.MoreUrl.TrimEx().IsNotEmpty()) { - if (Utils.IsNotEmpty(result) && Utils.IsBase64String(result)) + if (result.IsNotEmpty() && Utils.IsBase64String(result)) { result = Utils.Base64Decode(result); } @@ -180,17 +180,17 @@ namespace ServiceLib.Services foreach (var it in lstUrl) { var url2 = Utils.GetPunycode(it); - if (Utils.IsNullOrEmpty(url2)) + if (url2.IsNullOrEmpty()) { continue; } var result2 = await downloadHandle.TryDownloadString(url2, blProxy, userAgent); - if (blProxy && Utils.IsNullOrEmpty(result2)) + if (blProxy && result2.IsNullOrEmpty()) { result2 = await downloadHandle.TryDownloadString(url2, false, userAgent); } - if (Utils.IsNotEmpty(result2)) + if (result2.IsNotEmpty()) { if (Utils.IsBase64String(result2)) { @@ -204,7 +204,7 @@ namespace ServiceLib.Services } } - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { _updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}"); } @@ -287,7 +287,7 @@ namespace ServiceLib.Services { var url = coreInfo?.ReleaseApiUrl; var result = await downloadHandle.TryDownloadString(url, true, Global.AppName); - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { return new RetResult(false, ""); } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/AddServer2ViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/AddServer2ViewModel.cs index a37fa46e9b..9ea17199b3 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/AddServer2ViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/AddServer2ViewModel.cs @@ -42,14 +42,14 @@ namespace ServiceLib.ViewModels private async Task SaveServerAsync() { - string remarks = SelectedSource.Remarks; - if (Utils.IsNullOrEmpty(remarks)) + var remarks = SelectedSource.Remarks; + if (remarks.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); return; } - if (Utils.IsNullOrEmpty(SelectedSource.Address)) + if (SelectedSource.Address.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.FillServerAddressCustom); return; @@ -69,7 +69,7 @@ namespace ServiceLib.ViewModels public async Task BrowseServer(string fileName) { - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { return; } @@ -80,7 +80,7 @@ namespace ServiceLib.ViewModels if (await ConfigHandler.AddCustomServer(_config, item, false) == 0) { NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedCustomServer); - if (Utils.IsNotEmpty(item.IndexId)) + if (item.IndexId.IsNotEmpty()) { SelectedSource = JsonUtils.DeepCopy(item); } @@ -95,7 +95,7 @@ namespace ServiceLib.ViewModels private async Task EditServer() { var address = SelectedSource.Address; - if (Utils.IsNullOrEmpty(address)) + if (address.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.FillServerAddressCustom); return; diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs index bba48dd3e1..a1ff122b70 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs @@ -41,19 +41,19 @@ namespace ServiceLib.ViewModels private async Task SaveServerAsync() { - if (Utils.IsNullOrEmpty(SelectedSource.Remarks)) + if (SelectedSource.Remarks.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); return; } - if (Utils.IsNullOrEmpty(SelectedSource.Address)) + if (SelectedSource.Address.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.FillServerAddress); return; } var port = SelectedSource.Port.ToString(); - if (Utils.IsNullOrEmpty(port) || !Utils.IsNumeric(port) + if (port.IsNullOrEmpty() || !Utils.IsNumeric(port) || SelectedSource.Port <= 0 || SelectedSource.Port >= Global.MaxPort) { NoticeHandler.Instance.Enqueue(ResUI.FillCorrectServerPort); @@ -61,21 +61,20 @@ namespace ServiceLib.ViewModels } if (SelectedSource.ConfigType == EConfigType.Shadowsocks) { - if (Utils.IsNullOrEmpty(SelectedSource.Id)) + if (SelectedSource.Id.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.FillPassword); return; } - if (Utils.IsNullOrEmpty(SelectedSource.Security)) + if (SelectedSource.Security.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectEncryption); return; } } - if (SelectedSource.ConfigType != EConfigType.SOCKS - && SelectedSource.ConfigType != EConfigType.HTTP) + if (SelectedSource.ConfigType is not EConfigType.SOCKS and not EConfigType.HTTP) { - if (Utils.IsNullOrEmpty(SelectedSource.Id)) + if (SelectedSource.Id.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.FillUUID); return; diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs index fddb48d7eb..61ce834f3a 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs @@ -50,7 +50,7 @@ namespace ServiceLib.ViewModels { DisplayOperationMsg(); _config.WebDavItem = SelectedSource; - await ConfigHandler.SaveConfig(_config); + _ = await ConfigHandler.SaveConfig(_config); var result = await WebDavHandler.Instance.CheckConnection(); if (result) @@ -114,7 +114,7 @@ namespace ServiceLib.ViewModels public async Task LocalRestore(string fileName) { DisplayOperationMsg(); - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { return; } @@ -151,7 +151,7 @@ namespace ServiceLib.ViewModels { if (Utils.UpgradeAppExists(out var upgradeFileName)) { - ProcUtils.ProcessStart(upgradeFileName, Global.RebootAs, Utils.StartupPath()); + _ = ProcUtils.ProcessStart(upgradeFileName, Global.RebootAs, Utils.StartupPath()); } } service?.Shutdown(true); @@ -164,7 +164,7 @@ namespace ServiceLib.ViewModels private async Task CreateZipFileFromDirectory(string fileName) { - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { return false; } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs index 166da0ee1d..03b21524be 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs @@ -32,7 +32,7 @@ namespace ServiceLib.ViewModels var canEditRemove = this.WhenAnyValue( x => x.SelectedSource, - selectedSource => selectedSource != null && Utils.IsNotEmpty(selectedSource.Id)); + selectedSource => selectedSource != null && selectedSource.Id.IsNotEmpty()); this.WhenAnyValue( x => x.AutoRefresh, @@ -53,7 +53,78 @@ namespace ServiceLib.ViewModels private async Task Init() { - Task.Run(async () => + _ = DelayTestTask(); + } + + private async Task GetClashConnections() + { + var ret = await ClashApiHandler.Instance.GetClashConnectionsAsync(_config); + if (ret == null) + { + return; + } + + _ = _updateView?.Invoke(EViewAction.DispatcherRefreshConnections, ret?.connections); + } + + public void RefreshConnections(List? connections) + { + _connectionItems.Clear(); + + var dtNow = DateTime.Now; + var lstModel = new List(); + foreach (var item in connections ?? new()) + { + var host = $"{(item.metadata.host.IsNullOrEmpty() ? item.metadata.destinationIP : item.metadata.host)}:{item.metadata.destinationPort}"; + if (HostFilter.IsNotEmpty() && !host.Contains(HostFilter)) + { + continue; + } + + var model = new ClashConnectionModel + { + Id = item.id, + Network = item.metadata.network, + Type = item.metadata.type, + Host = host, + Time = (dtNow - item.start).TotalSeconds < 0 ? 1 : (dtNow - item.start).TotalSeconds, + Elapsed = (dtNow - item.start).ToString(@"hh\:mm\:ss"), + Chain = $"{item.rule} , {string.Join("->", item.chains ?? new())}" + }; + + lstModel.Add(model); + } + if (lstModel.Count <= 0) + { + return; + } + + _connectionItems.AddRange(lstModel); + } + + public async Task ClashConnectionClose(bool all) + { + var id = string.Empty; + if (!all) + { + var item = SelectedSource; + if (item is null) + { + return; + } + id = item.Id; + } + else + { + _connectionItems.Clear(); + } + await ClashApiHandler.Instance.ClashConnectionClose(id); + await GetClashConnections(); + } + + public async Task DelayTestTask() + { + _ = Task.Run(async () => { var numOfExecuted = 1; while (true) @@ -80,70 +151,5 @@ namespace ServiceLib.ViewModels await Task.CompletedTask; } - - private async Task GetClashConnections() - { - var ret = await ClashApiHandler.Instance.GetClashConnectionsAsync(_config); - if (ret == null) - { - return; - } - - _updateView?.Invoke(EViewAction.DispatcherRefreshConnections, ret?.connections); - } - - public void RefreshConnections(List? connections) - { - _connectionItems.Clear(); - - var dtNow = DateTime.Now; - var lstModel = new List(); - foreach (var item in connections ?? new()) - { - var host = $"{(Utils.IsNullOrEmpty(item.metadata.host) ? item.metadata.destinationIP : item.metadata.host)}:{item.metadata.destinationPort}"; - if (HostFilter.IsNotEmpty() && !host.Contains(HostFilter)) - { - continue; - } - - ClashConnectionModel model = new(); - - model.Id = item.id; - model.Network = item.metadata.network; - model.Type = item.metadata.type; - model.Host = host; - var sp = (dtNow - item.start); - model.Time = sp.TotalSeconds < 0 ? 1 : sp.TotalSeconds; - model.Elapsed = sp.ToString(@"hh\:mm\:ss"); - item.chains?.Reverse(); - model.Chain = $"{item.rule} , {string.Join("->", item.chains ?? new())}"; - - lstModel.Add(model); - } - if (lstModel.Count <= 0) - { return; } - - _connectionItems.AddRange(lstModel); - } - - public async Task ClashConnectionClose(bool all) - { - var id = string.Empty; - if (!all) - { - var item = SelectedSource; - if (item is null) - { - return; - } - id = item.Id; - } - else - { - _connectionItems.Clear(); - } - await ClashApiHandler.Instance.ClashConnectionClose(id); - await GetClashConnections(); - } } } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs index 5d8535c48f..0a5bc8ddc1 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs @@ -72,7 +72,7 @@ namespace ServiceLib.ViewModels this.WhenAnyValue( x => x.SelectedGroup, - y => y != null && Utils.IsNotEmpty(y.Name)) + y => y != null && y.Name.IsNotEmpty()) .Subscribe(c => RefreshProxyDetails(c)); this.WhenAnyValue( @@ -96,7 +96,6 @@ namespace ServiceLib.ViewModels private async Task Init() { _ = DelayTestTask(); - await ProxiesReload(); } private async Task DoRulemodeSelected(bool c) @@ -135,22 +134,12 @@ namespace ServiceLib.ViewModels RefreshProxyDetails(c); } - private void UpdateHandler(bool notify, string msg) - { - NoticeHandler.Instance.SendMessageEx(msg); - } - public async Task ProxiesReload() { await GetClashProxies(true); await ProxiesDelayTest(); } - public async Task ProxiesDelayTest() - { - await ProxiesDelayTest(true); - } - #region proxy function private async Task SetRuleMode(ERuleMode mode) @@ -193,7 +182,7 @@ namespace ServiceLib.ViewModels { foreach (var it in proxyGroups) { - if (Utils.IsNullOrEmpty(it.name) || !_proxies.ContainsKey(it.name)) + if (it.name.IsNullOrEmpty() || !_proxies.ContainsKey(it.name)) { continue; } @@ -218,8 +207,8 @@ namespace ServiceLib.ViewModels { continue; } - var item = _proxyGroups.Where(t => t.Name == kv.Key).FirstOrDefault(); - if (item != null && Utils.IsNotEmpty(item.Name)) + var item = _proxyGroups.FirstOrDefault(t => t.Name == kv.Key); + if (item != null && item.Name.IsNotEmpty()) { continue; } @@ -256,7 +245,7 @@ namespace ServiceLib.ViewModels return; } var name = SelectedGroup?.Name; - if (Utils.IsNullOrEmpty(name)) + if (name.IsNullOrEmpty()) { return; } @@ -341,21 +330,21 @@ namespace ServiceLib.ViewModels public async Task SetActiveProxy() { - if (SelectedGroup == null || Utils.IsNullOrEmpty(SelectedGroup.Name)) + if (SelectedGroup == null || SelectedGroup.Name.IsNullOrEmpty()) { return; } - if (SelectedDetail == null || Utils.IsNullOrEmpty(SelectedDetail.Name)) + if (SelectedDetail == null || SelectedDetail.Name.IsNullOrEmpty()) { return; } var name = SelectedGroup.Name; - if (Utils.IsNullOrEmpty(name)) + if (name.IsNullOrEmpty()) { return; } var nameNode = SelectedDetail.Name; - if (Utils.IsNullOrEmpty(nameNode)) + if (nameNode.IsNullOrEmpty()) { return; } @@ -369,7 +358,7 @@ namespace ServiceLib.ViewModels await ClashApiHandler.Instance.ClashSetActiveProxy(name, nameNode); selectedProxy.now = nameNode; - var group = _proxyGroups.Where(it => it.Name == SelectedGroup.Name).FirstOrDefault(); + var group = _proxyGroups.FirstOrDefault(it => it.Name == SelectedGroup.Name); if (group != null) { group.Now = nameNode; @@ -381,7 +370,7 @@ namespace ServiceLib.ViewModels NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); } - private async Task ProxiesDelayTest(bool blAll) + private async Task ProxiesDelayTest(bool blAll = true) { ClashApiHandler.Instance.ClashProxiesDelayTest(blAll, _proxyDetails.ToList(), async (item, result) => { @@ -390,7 +379,7 @@ namespace ServiceLib.ViewModels await GetClashProxies(true); return; } - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { return; } @@ -403,19 +392,19 @@ namespace ServiceLib.ViewModels public void ProxiesDelayTestResult(SpeedTestResult result) { //UpdateHandler(false, $"{item.name}={result}"); - var detail = _proxyDetails.Where(it => it.Name == result.IndexId).FirstOrDefault(); + var detail = _proxyDetails.FirstOrDefault(it => it.Name == result.IndexId); if (detail != null) { var dicResult = JsonUtils.Deserialize>(result.Delay); - if (dicResult != null && dicResult.ContainsKey("delay")) + if (dicResult != null && dicResult.TryGetValue("delay", out var value)) { - detail.Delay = Convert.ToInt32(dicResult["delay"].ToString()); + detail.Delay = Convert.ToInt32(value.ToString()); detail.DelayName = $"{detail.Delay}ms"; } - else if (dicResult != null && dicResult.ContainsKey("message")) + else if (dicResult != null && dicResult.TryGetValue("message", out var value1)) { detail.Delay = _delayTimeout; - detail.DelayName = $"{dicResult["message"]}"; + detail.DelayName = $"{value1}"; } else { @@ -432,28 +421,28 @@ namespace ServiceLib.ViewModels public async Task DelayTestTask() { - Task.Run(async () => - { - var numOfExecuted = 1; - while (true) - { - await Task.Delay(1000 * 60); - numOfExecuted++; - if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box))) - { - continue; - } - if (_config.ClashUIItem.ProxiesAutoDelayTestInterval <= 0) - { - continue; - } - if (numOfExecuted % _config.ClashUIItem.ProxiesAutoDelayTestInterval != 0) - { - continue; - } - await ProxiesDelayTest(); - } - }); + _ = Task.Run(async () => + { + var numOfExecuted = 1; + while (true) + { + await Task.Delay(1000 * 60); + numOfExecuted++; + if (!(AutoRefresh && _config.UiItem.ShowInTaskbar && _config.IsRunningCore(ECoreType.sing_box))) + { + continue; + } + if (_config.ClashUIItem.ProxiesAutoDelayTestInterval <= 0) + { + continue; + } + if (numOfExecuted % _config.ClashUIItem.ProxiesAutoDelayTestInterval != 0) + { + continue; + } + await ProxiesDelayTest(); + } + }); await Task.CompletedTask; } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs index 9dbdba4912..b4d9bb83a3 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs @@ -6,15 +6,15 @@ namespace ServiceLib.ViewModels { public class DNSSettingViewModel : MyReactiveObject { - [Reactive] public bool useSystemHosts { get; set; } - [Reactive] public string domainStrategy4Freedom { get; set; } - [Reactive] public string domainDNSAddress { get; set; } - [Reactive] public string normalDNS { get; set; } + [Reactive] public bool UseSystemHosts { get; set; } + [Reactive] public string DomainStrategy4Freedom { get; set; } + [Reactive] public string DomainDNSAddress { get; set; } + [Reactive] public string NormalDNS { get; set; } - [Reactive] public string domainStrategy4Freedom2 { get; set; } - [Reactive] public string domainDNSAddress2 { get; set; } - [Reactive] public string normalDNS2 { get; set; } - [Reactive] public string tunDNS2 { get; set; } + [Reactive] public string DomainStrategy4Freedom2 { get; set; } + [Reactive] public string DomainDNSAddress2 { get; set; } + [Reactive] public string NormalDNS2 { get; set; } + [Reactive] public string TunDNS2 { get; set; } public ReactiveCommand SaveCmd { get; } public ReactiveCommand ImportDefConfig4V2rayCmd { get; } @@ -31,14 +31,14 @@ namespace ServiceLib.ViewModels ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () => { - normalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName); + NormalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName); await Task.CompletedTask; }); ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () => { - normalDNS2 = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName); - tunDNS2 = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName); + NormalDNS2 = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName); + TunDNS2 = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName); await Task.CompletedTask; }); @@ -48,47 +48,47 @@ namespace ServiceLib.ViewModels private async Task Init() { var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray); - useSystemHosts = item.UseSystemHosts; - domainStrategy4Freedom = item?.DomainStrategy4Freedom ?? string.Empty; - domainDNSAddress = item?.DomainDNSAddress ?? string.Empty; - normalDNS = item?.NormalDNS ?? string.Empty; + UseSystemHosts = item.UseSystemHosts; + DomainStrategy4Freedom = item?.DomainStrategy4Freedom ?? string.Empty; + DomainDNSAddress = item?.DomainDNSAddress ?? string.Empty; + NormalDNS = item?.NormalDNS ?? string.Empty; var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box); - domainStrategy4Freedom2 = item2?.DomainStrategy4Freedom ?? string.Empty; - domainDNSAddress2 = item2?.DomainDNSAddress ?? string.Empty; - normalDNS2 = item2?.NormalDNS ?? string.Empty; - tunDNS2 = item2?.TunDNS ?? string.Empty; + DomainStrategy4Freedom2 = item2?.DomainStrategy4Freedom ?? string.Empty; + DomainDNSAddress2 = item2?.DomainDNSAddress ?? string.Empty; + NormalDNS2 = item2?.NormalDNS ?? string.Empty; + TunDNS2 = item2?.TunDNS ?? string.Empty; } private async Task SaveSettingAsync() { - if (Utils.IsNotEmpty(normalDNS)) + if (NormalDNS.IsNotEmpty()) { - var obj = JsonUtils.ParseJson(normalDNS); + var obj = JsonUtils.ParseJson(NormalDNS); if (obj != null && obj["servers"] != null) { } else { - if (normalDNS.Contains('{') || normalDNS.Contains('}')) + if (NormalDNS.Contains('{') || NormalDNS.Contains('}')) { NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText); return; } } } - if (Utils.IsNotEmpty(normalDNS2)) + if (NormalDNS2.IsNotEmpty()) { - var obj2 = JsonUtils.Deserialize(normalDNS2); + var obj2 = JsonUtils.Deserialize(NormalDNS2); if (obj2 == null) { NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText); return; } } - if (Utils.IsNotEmpty(tunDNS2)) + if (TunDNS2.IsNotEmpty()) { - var obj2 = JsonUtils.Deserialize(tunDNS2); + var obj2 = JsonUtils.Deserialize(TunDNS2); if (obj2 == null) { NoticeHandler.Instance.Enqueue(ResUI.FillCorrectDNSText); @@ -97,21 +97,21 @@ namespace ServiceLib.ViewModels } var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray); - item.DomainStrategy4Freedom = domainStrategy4Freedom; - item.DomainDNSAddress = domainDNSAddress; - item.UseSystemHosts = useSystemHosts; - item.NormalDNS = normalDNS; + item.DomainStrategy4Freedom = DomainStrategy4Freedom; + item.DomainDNSAddress = DomainDNSAddress; + item.UseSystemHosts = UseSystemHosts; + item.NormalDNS = NormalDNS; await ConfigHandler.SaveDNSItems(_config, item); var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box); - item2.DomainStrategy4Freedom = domainStrategy4Freedom2; - item2.DomainDNSAddress = domainDNSAddress2; - item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2)); - item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); + item2.DomainStrategy4Freedom = DomainStrategy4Freedom2; + item2.DomainDNSAddress = DomainDNSAddress2; + item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(NormalDNS2)); + item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(TunDNS2)); await ConfigHandler.SaveDNSItems(_config, item2); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); - _updateView?.Invoke(EViewAction.CloseWindow, null); + _ = _updateView?.Invoke(EViewAction.CloseWindow, null); } } } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs index 295b5364af..263f231572 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs @@ -421,7 +421,7 @@ namespace ServiceLib.ViewModels public async Task ScanImageResult(string fileName) { - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { return; } @@ -432,7 +432,7 @@ namespace ServiceLib.ViewModels private async Task AddScanResultAsync(string? result) { - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.NoValidQRcodeFound); } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index 378b374cfd..85b0114498 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -266,7 +266,7 @@ namespace ServiceLib.ViewModels private async Task SaveSettingAsync() { - if (Utils.IsNullOrEmpty(localPort.ToString()) || !Utils.IsNumeric(localPort.ToString()) + if (localPort.ToString().IsNullOrEmpty() || !Utils.IsNumeric(localPort.ToString()) || localPort <= 0 || localPort >= Global.MaxPort) { NoticeHandler.Instance.Enqueue(ResUI.FillLocalListeningPort); diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index 9405a42aaa..3f9e9cf27e 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -267,7 +267,7 @@ namespace ServiceLib.ViewModels public void SetSpeedTestResult(SpeedTestResult result) { - if (Utils.IsNullOrEmpty(result.IndexId)) + if (result.IndexId.IsNullOrEmpty()) { NoticeHandler.Instance.SendMessageEx(result.Delay); NoticeHandler.Instance.Enqueue(result.Delay); @@ -279,13 +279,13 @@ namespace ServiceLib.ViewModels return; } - if (Utils.IsNotEmpty(result.Delay)) + if (result.Delay.IsNotEmpty()) { int.TryParse(result.Delay, out var temp); item.Delay = temp; item.DelayVal = result.Delay ?? string.Empty; } - if (Utils.IsNotEmpty(result.Speed)) + if (result.Speed.IsNotEmpty()) { item.SpeedVal = result.Speed ?? string.Empty; } @@ -350,7 +350,7 @@ namespace ServiceLib.ViewModels return; } _serverFilter = ServerFilter; - if (Utils.IsNullOrEmpty(_serverFilter)) + if (_serverFilter.IsNullOrEmpty()) { RefreshServers(); } @@ -476,7 +476,7 @@ namespace ServiceLib.ViewModels public async Task EditServerAsync(EConfigType eConfigType) { - if (Utils.IsNullOrEmpty(SelectedProfile?.IndexId)) + if (string.IsNullOrEmpty(SelectedProfile?.IndexId)) { return; } @@ -557,7 +557,7 @@ namespace ServiceLib.ViewModels public async Task SetDefaultServer() { - if (Utils.IsNullOrEmpty(SelectedProfile?.IndexId)) + if (string.IsNullOrEmpty(SelectedProfile?.IndexId)) { return; } @@ -566,7 +566,7 @@ namespace ServiceLib.ViewModels public async Task SetDefaultServer(string indexId) { - if (Utils.IsNullOrEmpty(indexId)) + if (indexId.IsNullOrEmpty()) { return; } @@ -598,7 +598,7 @@ namespace ServiceLib.ViewModels { return; } - if (Utils.IsNullOrEmpty(SelectedServer.ID)) + if (SelectedServer.ID.IsNullOrEmpty()) { return; } @@ -614,7 +614,7 @@ namespace ServiceLib.ViewModels return; } var url = FmtHandler.GetShareUri(item); - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { return; } @@ -649,7 +649,7 @@ namespace ServiceLib.ViewModels public async Task SortServer(string colName) { - if (Utils.IsNullOrEmpty(colName)) + if (colName.IsNullOrEmpty()) { return; } @@ -776,7 +776,7 @@ namespace ServiceLib.ViewModels public async Task Export2ClientConfigResult(string fileName, ProfileItem item) { - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { return; } @@ -803,7 +803,7 @@ namespace ServiceLib.ViewModels foreach (var it in lstSelecteds) { var url = FmtHandler.GetShareUri(it); - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { continue; } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs index 680be44059..507336c957 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs @@ -78,8 +78,8 @@ namespace ServiceLib.ViewModels || SelectedSource.Ip?.Count > 0 || SelectedSource.Protocol?.Count > 0 || SelectedSource.Process?.Count > 0 - || Utils.IsNotEmpty(SelectedSource.Port) - || Utils.IsNotEmpty(SelectedSource.Network); + || SelectedSource.Port.IsNotEmpty() + || SelectedSource.Network.IsNotEmpty(); if (!hasRule) { diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs index 76cd301c30..9b27327f4e 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs @@ -224,7 +224,7 @@ namespace ServiceLib.ViewModels private async Task SaveRoutingAsync() { string remarks = SelectedRouting.Remarks; - if (Utils.IsNullOrEmpty(remarks)) + if (remarks.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); return; @@ -252,13 +252,13 @@ namespace ServiceLib.ViewModels public async Task ImportRulesFromFileAsync(string fileName) { - if (Utils.IsNullOrEmpty(fileName)) + if (fileName.IsNullOrEmpty()) { return; } var result = EmbedUtils.LoadResource(fileName); - if (Utils.IsNullOrEmpty(result)) + if (result.IsNullOrEmpty()) { return; } @@ -288,7 +288,7 @@ namespace ServiceLib.ViewModels private async Task ImportRulesFromUrl() { var url = SelectedRouting.Url; - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.MsgNeedUrl); return; @@ -311,7 +311,7 @@ namespace ServiceLib.ViewModels { blReplace = true; } - if (Utils.IsNullOrEmpty(clipboardData)) + if (clipboardData.IsNullOrEmpty()) { return -1; } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs index b8c7805b2c..b494b9d114 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs @@ -18,13 +18,13 @@ namespace ServiceLib.ViewModels public IList SelectedSources { get; set; } [Reactive] - public string domainStrategy { get; set; } + public string DomainStrategy { get; set; } [Reactive] - public string domainMatcher { get; set; } + public string DomainMatcher { get; set; } [Reactive] - public string domainStrategy4Singbox { get; set; } + public string DomainStrategy4Singbox { get; set; } public ReactiveCommand RoutingAdvancedAddCmd { get; } public ReactiveCommand RoutingAdvancedRemoveCmd { get; } @@ -74,9 +74,9 @@ namespace ServiceLib.ViewModels { SelectedSource = new(); - domainStrategy = _config.RoutingBasicItem.DomainStrategy; - domainMatcher = _config.RoutingBasicItem.DomainMatcher; - domainStrategy4Singbox = _config.RoutingBasicItem.DomainStrategy4Singbox; + DomainStrategy = _config.RoutingBasicItem.DomainStrategy; + DomainMatcher = _config.RoutingBasicItem.DomainMatcher; + DomainStrategy4Singbox = _config.RoutingBasicItem.DomainStrategy4Singbox; await ConfigHandler.InitBuiltinRouting(_config); await RefreshRoutingItems(); @@ -91,11 +91,7 @@ namespace ServiceLib.ViewModels var routings = await AppHandler.Instance.RoutingItems(); foreach (var item in routings) { - bool def = false; - if (item.Id == _config.RoutingBasicItem.RoutingIndexId) - { - def = true; - } + var def = item.Id == _config.RoutingBasicItem.RoutingIndexId; var it = new RoutingItemModel() { @@ -114,9 +110,9 @@ namespace ServiceLib.ViewModels private async Task SaveRoutingAsync() { - _config.RoutingBasicItem.DomainStrategy = domainStrategy; - _config.RoutingBasicItem.DomainMatcher = domainMatcher; - _config.RoutingBasicItem.DomainStrategy4Singbox = domainStrategy4Singbox; + _config.RoutingBasicItem.DomainStrategy = DomainStrategy; + _config.RoutingBasicItem.DomainMatcher = DomainMatcher; + _config.RoutingBasicItem.DomainStrategy4Singbox = DomainStrategy4Singbox; if (await ConfigHandler.SaveConfig(_config) == 0) { diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs index f0a3dcde20..2be412d469 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs @@ -301,7 +301,7 @@ namespace ServiceLib.ViewModels { return; } - if (Utils.IsNullOrEmpty(SelectedServer.ID)) + if (SelectedServer.ID.IsNullOrEmpty()) { return; } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs index 2bcffa6b51..0c1c3d7a3b 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs @@ -27,7 +27,7 @@ namespace ServiceLib.ViewModels private async Task SaveSubAsync() { var remarks = SelectedSource.Remarks; - if (Utils.IsNullOrEmpty(remarks)) + if (remarks.IsNullOrEmpty()) { NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); return; diff --git a/v2rayn/v2rayN/v2rayN.Desktop/App.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/App.axaml.cs index c3388125a6..b7cb8d7457 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/App.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/App.axaml.cs @@ -23,7 +23,7 @@ public partial class App : Application var ViewModel = new StatusBarViewModel(null); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel)); - this.DataContext = ViewModel; + DataContext = ViewModel; } public override void OnFrameworkInitializationCompleted() @@ -65,7 +65,9 @@ public partial class App : Application var clipboardData = await AvaUtils.GetClipboardData(desktop.MainWindow); var service = Locator.Current.GetService(); if (service != null) + { _ = service.AddServerViaClipboardAsync(clipboardData); + } } } } @@ -74,7 +76,9 @@ public partial class App : Application { var service = Locator.Current.GetService(); if (service != null) + { await service.MyAppExitAsync(true); + } service?.Shutdown(true); } } diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Common/UI.cs b/v2rayn/v2rayN/v2rayN.Desktop/Common/UI.cs index 0b7cf2b471..e52970e43d 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Common/UI.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Common/UI.cs @@ -19,7 +19,9 @@ namespace v2rayN.Desktop.Common { var sp = GetStorageProvider(owner); if (sp is null) + { return null; + } // Start async operation to open the dialog. var files = await sp.OpenFilePickerAsync(new FilePickerOpenOptions @@ -35,7 +37,9 @@ namespace v2rayN.Desktop.Common { var sp = GetStorageProvider(owner); if (sp is null) + { return null; + } // Start async operation to open the dialog. var files = await sp.SaveFilePickerAsync(new FilePickerSaveOptions diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Controls/AutoCompleteBox.cs b/v2rayn/v2rayN/v2rayN.Desktop/Controls/AutoCompleteBox.cs index adb760633c..82e04d4b72 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Controls/AutoCompleteBox.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Controls/AutoCompleteBox.cs @@ -27,7 +27,9 @@ public class AutoCompleteBox : Avalonia.Controls.AutoCompleteBox { base.OnGotFocus(e); if (IsDropDownOpen) + { return; + } SetCurrentValue(IsDropDownOpenProperty, true); } diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Converters/DelayColorConverter.cs b/v2rayn/v2rayN/v2rayN.Desktop/Converters/DelayColorConverter.cs index 3f1e20640e..1f3f4a2b29 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Converters/DelayColorConverter.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Converters/DelayColorConverter.cs @@ -8,14 +8,14 @@ namespace v2rayN.Desktop.Converters { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - int.TryParse(value?.ToString(), out var delay); + _ = int.TryParse(value?.ToString(), out var delay); - if (delay <= 0) - return new SolidColorBrush(Colors.Red); - if (delay <= 500) - return new SolidColorBrush(Colors.Green); - else - return new SolidColorBrush(Colors.IndianRed); + return delay switch + { + <= 0 => new SolidColorBrush(Colors.Red), + <= 500 => new SolidColorBrush(Colors.Green), + _ => new SolidColorBrush(Colors.IndianRed) + }; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Program.cs b/v2rayn/v2rayN/v2rayN.Desktop/Program.cs index acc7a3321f..15efc02303 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Program.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Program.cs @@ -25,8 +25,8 @@ internal class Program if (Utils.IsWindows()) { var exePathKey = Utils.GetMd5(Utils.GetExePath()); - var rebootas = (Args ?? Array.Empty()).Any(t => t == Global.RebootAs); - ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out bool bCreatedNew); + var rebootas = (Args ?? []).Any(t => t == Global.RebootAs); + ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, exePathKey, out var bCreatedNew); if (!rebootas && !bCreatedNew) { ProgramStarted.Set(); diff --git a/v2rayn/v2rayN/v2rayN.Desktop/ViewModels/ThemeSettingViewModel.cs b/v2rayn/v2rayN/v2rayN.Desktop/ViewModels/ThemeSettingViewModel.cs index b2f134e1b5..455414b8d3 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/ViewModels/ThemeSettingViewModel.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/ViewModels/ThemeSettingViewModel.cs @@ -69,7 +69,7 @@ namespace v2rayN.Desktop.ViewModels y => y != null && !y.IsNullOrEmpty()) .Subscribe(c => { - if (Utils.IsNotEmpty(CurrentLanguage) && _config.UiItem.CurrentLanguage != CurrentLanguage) + if (CurrentLanguage.IsNotEmpty() && _config.UiItem.CurrentLanguage != CurrentLanguage) { _config.UiItem.CurrentLanguage = CurrentLanguage; Thread.CurrentThread.CurrentUICulture = new(CurrentLanguage); diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs index 2e6c1ed292..e53c9204ee 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs @@ -272,7 +272,7 @@ namespace v2rayN.Desktop.Views cmbHeaderType.Items.Clear(); var network = cmbNetwork.SelectedItem.ToString(); - if (Utils.IsNullOrEmpty(network)) + if (network.IsNullOrEmpty()) { cmbHeaderType.Items.Add(Global.None); return; @@ -313,7 +313,7 @@ namespace v2rayN.Desktop.Views private void SetTips() { var network = cmbNetwork.SelectedItem.ToString(); - if (Utils.IsNullOrEmpty(network)) + if (network.IsNullOrEmpty()) { network = Global.DefaultNetwork; } diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml.cs index 3fd1099b09..6686389737 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml.cs @@ -36,15 +36,15 @@ namespace v2rayN.Desktop.Views this.WhenActivated(disposables => { - this.Bind(ViewModel, vm => vm.useSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.SelectedValue).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainDNSAddress, v => v.cmbdomainDNSAddress.SelectedValue).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.UseSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainDNSAddress, v => v.cmbdomainDNSAddress.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.NormalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.SelectedValue).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainDNSAddress2, v => v.cmbdomainDNSAddress2.SelectedValue).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.tunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainDNSAddress2, v => v.cmbdomainDNSAddress2.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.NormalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.TunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables); diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs index 6e4d7c1c5d..ee08d281c7 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs @@ -461,8 +461,8 @@ namespace v2rayN.Desktop.Views private void StorageUI(string? n = null) { - _config.UiItem.MainWidth = Utils.ToInt(this.Width); - _config.UiItem.MainHeight = Utils.ToInt(this.Height); + _config.UiItem.MainWidth = this.Width; + _config.UiItem.MainHeight = this.Height; if (_config.UiItem.MainGirdOrientation == EGirdOrientation.Horizontal) { diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs index dcb390ddc2..ada0b3c3f3 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs @@ -196,7 +196,7 @@ namespace v2rayN.Desktop.Views public async Task ShareServer(string url) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { return; } @@ -404,7 +404,7 @@ namespace v2rayN.Desktop.Views lvColumnItem.Add(new() { Name = (string)item2.Tag, - Width = item2.IsVisible == true ? Utils.ToInt(item2.ActualWidth) : -1, + Width = (int)(item2.IsVisible == true ? item2.ActualWidth : -1), Index = item2.DisplayIndex }); } diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml.cs index 4b89438dee..1cadca91fc 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml.cs @@ -44,9 +44,9 @@ namespace v2rayN.Desktop.Views this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.lstRoutings.ItemsSource).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRoutings.SelectedItem).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainStrategy, v => v.cmbdomainStrategy.SelectedValue).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainMatcher, v => v.cmbdomainMatcher.SelectedValue).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainStrategy, v => v.cmbdomainStrategy.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainMatcher, v => v.cmbdomainMatcher.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd2).DisposeWith(disposables); diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml.cs b/v2rayn/v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml.cs index a12c1b3318..dd5040037d 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml.cs @@ -69,7 +69,7 @@ namespace v2rayN.Desktop.Views private async Task ShareSub(string url) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { return; } diff --git a/v2rayn/v2rayN/v2rayN/Converters/MaterialDesignFonts.cs b/v2rayn/v2rayN/v2rayN/Converters/MaterialDesignFonts.cs index 20d9d5b56c..4638c3abbb 100644 --- a/v2rayn/v2rayN/v2rayN/Converters/MaterialDesignFonts.cs +++ b/v2rayn/v2rayN/v2rayN/Converters/MaterialDesignFonts.cs @@ -11,7 +11,7 @@ namespace v2rayN.Converters try { var fontFamily = AppHandler.Instance.Config.UiItem.CurrentFontFamily; - if (Utils.IsNotEmpty(fontFamily)) + if (fontFamily.IsNotEmpty()) { var fontPath = Utils.GetFontsPath(); MyFont = new FontFamily(new Uri(@$"file:///{fontPath}\"), $"./#{fontFamily}"); diff --git a/v2rayn/v2rayN/v2rayN/Handler/WindowsHandler.cs b/v2rayn/v2rayN/v2rayN/Handler/WindowsHandler.cs index 95404085fa..70c7d09d7d 100644 --- a/v2rayn/v2rayN/v2rayN/Handler/WindowsHandler.cs +++ b/v2rayn/v2rayN/v2rayN/Handler/WindowsHandler.cs @@ -56,7 +56,7 @@ namespace v2rayN.Handler try { var item = await ConfigHandler.GetDefaultRouting(config); - if (item == null || Utils.IsNullOrEmpty(item.CustomIcon) || !File.Exists(item.CustomIcon)) + if (item == null || item.CustomIcon.IsNullOrEmpty() || !File.Exists(item.CustomIcon)) { return null; } diff --git a/v2rayn/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs b/v2rayn/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs index a9ce8589b5..fd075cb026 100644 --- a/v2rayn/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs +++ b/v2rayn/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs @@ -116,7 +116,7 @@ namespace v2rayN.ViewModels y => y != null && !y.IsNullOrEmpty()) .Subscribe(c => { - if (Utils.IsNotEmpty(CurrentLanguage) && _config.UiItem.CurrentLanguage != CurrentLanguage) + if (CurrentLanguage.IsNotEmpty() && _config.UiItem.CurrentLanguage != CurrentLanguage) { _config.UiItem.CurrentLanguage = CurrentLanguage; Thread.CurrentThread.CurrentUICulture = new(CurrentLanguage); diff --git a/v2rayn/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs b/v2rayn/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs index c29b3416eb..0c6999e406 100644 --- a/v2rayn/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs +++ b/v2rayn/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs @@ -267,7 +267,7 @@ namespace v2rayN.Views cmbHeaderType.Items.Clear(); var network = cmbNetwork.SelectedItem.ToString(); - if (Utils.IsNullOrEmpty(network)) + if (network.IsNullOrEmpty()) { cmbHeaderType.Items.Add(Global.None); return; @@ -308,7 +308,7 @@ namespace v2rayN.Views private void SetTips() { var network = cmbNetwork.SelectedItem.ToString(); - if (Utils.IsNullOrEmpty(network)) + if (network.IsNullOrEmpty()) { network = Global.DefaultNetwork; } diff --git a/v2rayn/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs b/v2rayn/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs index 2fadce706b..252c56d663 100644 --- a/v2rayn/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs +++ b/v2rayn/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs @@ -36,15 +36,15 @@ namespace v2rayN.Views this.WhenActivated(disposables => { - this.Bind(ViewModel, vm => vm.useSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainDNSAddress, v => v.cmbdomainDNSAddress.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.UseSystemHosts, v => v.togUseSystemHosts.IsChecked).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainDNSAddress, v => v.cmbdomainDNSAddress.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.NormalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainDNSAddress2, v => v.cmbdomainDNSAddress2.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.tunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2, v => v.cmbdomainStrategy4Out.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainDNSAddress2, v => v.cmbdomainDNSAddress2.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.NormalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.TunDNS2, v => v.txttunDNS2.Text).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables); diff --git a/v2rayn/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayn/v2rayN/v2rayN/Views/MainWindow.xaml.cs index 4cf7233bfa..bf94a230a0 100644 --- a/v2rayn/v2rayN/v2rayN/Views/MainWindow.xaml.cs +++ b/v2rayn/v2rayN/v2rayN/Views/MainWindow.xaml.cs @@ -414,8 +414,8 @@ namespace v2rayN.Views private void StorageUI(string? n = null) { - _config.UiItem.MainWidth = Utils.ToInt(this.Width); - _config.UiItem.MainHeight = Utils.ToInt(this.Height); + _config.UiItem.MainWidth = this.Width; + _config.UiItem.MainHeight = this.Height; if (_config.UiItem.MainGirdOrientation == EGirdOrientation.Horizontal) { diff --git a/v2rayn/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs b/v2rayn/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs index e100333fa2..b332898ac8 100644 --- a/v2rayn/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs +++ b/v2rayn/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs @@ -234,10 +234,10 @@ namespace v2rayN.Views // continue; //} var fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)]; - if (Utils.IsNullOrEmpty(fontFamily)) + if (fontFamily.IsNullOrEmpty()) { fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture2)]; - if (Utils.IsNullOrEmpty(fontFamily)) + if (fontFamily.IsNullOrEmpty()) { continue; } diff --git a/v2rayn/v2rayN/v2rayN/Views/ProfilesView.xaml.cs b/v2rayn/v2rayN/v2rayN/Views/ProfilesView.xaml.cs index de4220d79a..351d44247d 100644 --- a/v2rayn/v2rayN/v2rayN/Views/ProfilesView.xaml.cs +++ b/v2rayn/v2rayN/v2rayN/Views/ProfilesView.xaml.cs @@ -375,7 +375,7 @@ namespace v2rayN.Views lvColumnItem.Add(new() { Name = item2.ExName, - Width = item2.Visibility == Visibility.Visible ? Utils.ToInt(item2.ActualWidth) : -1, + Width = (int)(item2.Visibility == Visibility.Visible ? item2.ActualWidth : -1), Index = item2.DisplayIndex }); } diff --git a/v2rayn/v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs b/v2rayn/v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs index d8ea73b98e..8eff2c05bb 100644 --- a/v2rayn/v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs +++ b/v2rayn/v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs @@ -39,9 +39,9 @@ namespace v2rayN.Views this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.lstRoutings.ItemsSource).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRoutings.SelectedItem).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainMatcher, v => v.cmbdomainMatcher.Text).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.domainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainMatcher, v => v.cmbdomainMatcher.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.Text).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd2).DisposeWith(disposables); diff --git a/v2rayn/v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs b/v2rayn/v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs index d13a189bf9..fc292db792 100644 --- a/v2rayn/v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs +++ b/v2rayn/v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs @@ -65,7 +65,7 @@ namespace v2rayN.Views private async void ShareSub(string url) { - if (Utils.IsNullOrEmpty(url)) + if (url.IsNullOrEmpty()) { return; } diff --git a/xray-core/README.md b/xray-core/README.md index 7b258cff26..fd37beb13e 100644 --- a/xray-core/README.md +++ b/xray-core/README.md @@ -85,6 +85,7 @@ - [X-flutter](https://github.com/XTLS/X-flutter) - [SaeedDev94/Xray](https://github.com/SaeedDev94/Xray) - iOS & macOS arm64 + - [Happ](https://apps.apple.com/app/happ-proxy-utility/id6504287215) - [FoXray](https://apps.apple.com/app/foxray/id6448898396) - [Streisand](https://apps.apple.com/app/streisand/id6450534064) - macOS arm64 & x64 diff --git a/xray-core/core/core.go b/xray-core/core/core.go index e36a90e20b..345f9dafd8 100644 --- a/xray-core/core/core.go +++ b/xray-core/core/core.go @@ -19,7 +19,7 @@ import ( var ( Version_x byte = 25 Version_y byte = 3 - Version_z byte = 3 + Version_z byte = 6 ) var ( diff --git a/xray-core/go.mod b/xray-core/go.mod index d7955e72c9..66c86613c6 100644 --- a/xray-core/go.mod +++ b/xray-core/go.mod @@ -22,10 +22,10 @@ require ( github.com/vishvananda/netlink v1.3.0 github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d go4.org/netipx v0.0.0-20231129151722-fdeea329fbba - golang.org/x/crypto v0.35.0 - golang.org/x/net v0.36.0 - golang.org/x/sync v0.11.0 - golang.org/x/sys v0.30.0 + golang.org/x/crypto v0.36.0 + golang.org/x/net v0.37.0 + golang.org/x/sync v0.12.0 + golang.org/x/sys v0.31.0 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 google.golang.org/grpc v1.71.0 google.golang.org/protobuf v1.36.5 @@ -51,7 +51,7 @@ require ( go.uber.org/mock v0.5.0 // indirect golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect golang.org/x/mod v0.21.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/text v0.23.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect diff --git a/xray-core/go.sum b/xray-core/go.sum index a2c07a9b67..93200ef411 100644 --- a/xray-core/go.sum +++ b/xray-core/go.sum @@ -97,8 +97,8 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg= golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= @@ -107,12 +107,12 @@ golang.org/x/mod v0.21.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.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= -golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +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/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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -121,14 +121,14 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +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/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=