diff --git a/.github/update.log b/.github/update.log index 6610056d80..42dd7f26ef 100644 --- a/.github/update.log +++ b/.github/update.log @@ -885,3 +885,4 @@ Update On Mon Jan 13 19:35:28 CET 2025 Update On Tue Jan 14 19:32:59 CET 2025 Update On Wed Jan 15 19:33:42 CET 2025 Update On Thu Jan 16 19:32:38 CET 2025 +Update On Fri Jan 17 19:33:42 CET 2025 diff --git a/clash-nyanpasu/backend/Cargo.lock b/clash-nyanpasu/backend/Cargo.lock index 6ea88b954f..4644e7905a 100644 --- a/clash-nyanpasu/backend/Cargo.lock +++ b/clash-nyanpasu/backend/Cargo.lock @@ -2664,9 +2664,9 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" dependencies = [ "enumflags2_derive", "serde", @@ -2674,9 +2674,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" dependencies = [ "proc-macro2", "quote", @@ -8617,9 +8617,9 @@ dependencies = [ [[package]] name = "tauri-plugin-notification" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46ab803095f14ac6521fdb6477210a49e86fed6623c3c97d8e4b2b35e045e922" +checksum = "0f8d3ee5207d3359ca2b714545664f24f70374d795bf91f7c1935a494003a57d" dependencies = [ "log", "notify-rust", diff --git a/clash-nyanpasu/backend/tauri/src/core/state.rs b/clash-nyanpasu/backend/tauri/src/core/state.rs index 6e0ec916a3..f0fae07bed 100644 --- a/clash-nyanpasu/backend/tauri/src/core/state.rs +++ b/clash-nyanpasu/backend/tauri/src/core/state.rs @@ -112,18 +112,18 @@ where /// whether the state is dirty, i.e. a draft is present, and not yet committed or discarded pub fn is_dirty(&self) -> bool { - self.is_dirty.load(std::sync::atomic::Ordering::Relaxed) + self.is_dirty.load(std::sync::atomic::Ordering::Acquire) } /// You can modify the draft state, and then commit it pub fn draft(&self) -> MappedRwLockWriteGuard<'_, T> { - if self.is_dirty.load(std::sync::atomic::Ordering::Relaxed) { + if self.is_dirty() { return RwLockWriteGuard::map(self.draft.write(), |guard| guard.as_mut().unwrap()); } let state = self.inner.read().clone(); self.is_dirty - .store(true, std::sync::atomic::Ordering::Relaxed); + .store(true, std::sync::atomic::Ordering::Release); RwLockWriteGuard::map(self.draft.write(), |guard| { *guard = Some(state.clone()); @@ -133,7 +133,7 @@ where /// commit the draft state, and make it the new state pub fn apply(&self) -> Option { - if !self.is_dirty.load(std::sync::atomic::Ordering::Relaxed) { + if !self.is_dirty() { return None; } @@ -142,7 +142,7 @@ where let old_value = inner.to_owned(); *inner = draft.take().unwrap(); self.is_dirty - .store(false, std::sync::atomic::Ordering::Relaxed); + .store(false, std::sync::atomic::Ordering::Release); Some(old_value) } @@ -150,7 +150,7 @@ where pub fn discard(&self) -> Option { let v = self.draft.write().take(); self.is_dirty - .store(false, std::sync::atomic::Ordering::Relaxed); + .store(false, std::sync::atomic::Ordering::Release); v } } diff --git a/clash-nyanpasu/frontend/nyanpasu/package.json b/clash-nyanpasu/frontend/nyanpasu/package.json index a9a5b711bd..1458670ea3 100644 --- a/clash-nyanpasu/frontend/nyanpasu/package.json +++ b/clash-nyanpasu/frontend/nyanpasu/package.json @@ -41,7 +41,7 @@ "react-fast-marquee": "1.6.5", "react-hook-form-mui": "7.4.1", "react-i18next": "15.4.0", - "react-markdown": "9.0.1", + "react-markdown": "9.0.3", "react-split-grid": "1.0.4", "react-use": "17.6.0", "swr": "2.3.0", @@ -52,12 +52,12 @@ "@csstools/normalize.css": "12.1.1", "@emotion/babel-plugin": "11.13.5", "@emotion/react": "11.14.0", - "@iconify/json": "2.2.295", + "@iconify/json": "2.2.296", "@monaco-editor/react": "4.6.0", "@tanstack/react-query": "5.64.1", - "@tanstack/react-router": "1.89.2", - "@tanstack/router-devtools": "1.89.2", - "@tanstack/router-plugin": "1.87.13", + "@tanstack/react-router": "1.97.1", + "@tanstack/router-devtools": "1.97.1", + "@tanstack/router-plugin": "1.97.1", "@tauri-apps/plugin-clipboard-manager": "2.2.0", "@tauri-apps/plugin-dialog": "2.2.0", "@tauri-apps/plugin-fs": "2.2.0", diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/updater/updater-dialog.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/updater/updater-dialog.tsx index 320213775d..fe93bd9d07 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/components/updater/updater-dialog.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/updater/updater-dialog.tsx @@ -115,7 +115,9 @@ export default function UpdaterDialog({ onClick={(e) => { e.preventDefault() e.stopPropagation() - openThat(node.properties.href) + if (typeof node?.properties.href === 'string') { + openThat(node.properties.href) + } }} > {children} diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/connections.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/connections.tsx index c87aaac628..ec5b74a6e9 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/connections.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/connections.tsx @@ -33,13 +33,16 @@ function Connections() { const [mountTable, setMountTable] = useState(true) const deferredMountTable = useDeferredValue(mountTable) const { proceed } = useBlocker({ - blockerFn: () => setMountTable(false), - condition: !mountTable, + shouldBlockFn: (args) => { + setMountTable(false) + return !mountTable + }, + withResolver: true, }) useEffect(() => { if (!deferredMountTable) { - proceed() + proceed?.() } }, [proceed, deferredMountTable]) diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index 874333d048..63f01b896f 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.1", - "mihomo_alpha": "alpha-c7661d7", + "mihomo_alpha": "alpha-192d769", "clash_rs": "v0.7.4", "clash_premium": "2023-09-05-gdcc8d87", "clash_rs_alpha": "0.7.4-alpha+sha.63aec82" @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-01-13T22:20:24.809Z" + "updated_at": "2025-01-16T22:20:32.490Z" } diff --git a/clash-nyanpasu/package.json b/clash-nyanpasu/package.json index 3cd164c339..00211b49a2 100644 --- a/clash-nyanpasu/package.json +++ b/clash-nyanpasu/package.json @@ -84,8 +84,8 @@ "eslint-plugin-react-compiler": "19.0.0-beta-e552027-20250112", "eslint-plugin-react-hooks": "5.1.0", "globals": "15.14.0", - "knip": "5.42.1", - "lint-staged": "15.3.0", + "knip": "5.42.2", + "lint-staged": "15.4.1", "neostandard": "0.12.0", "npm-run-all2": "7.0.2", "postcss": "8.4.49", diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index a71eae72ff..01437ac2be 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -100,11 +100,11 @@ importers: specifier: 15.14.0 version: 15.14.0 knip: - specifier: 5.42.1 - version: 5.42.1(@types/node@22.10.7)(typescript@5.7.3) + specifier: 5.42.2 + version: 5.42.2(@types/node@22.10.7)(typescript@5.7.3) lint-staged: - specifier: 15.3.0 - version: 15.3.0 + specifier: 15.4.1 + version: 15.4.1 neostandard: specifier: 0.12.0 version: 0.12.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.20.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2)))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) @@ -228,7 +228,7 @@ importers: version: link:../ui '@tanstack/router-zod-adapter': specifier: 1.81.5 - version: 1.81.5(@tanstack/react-router@1.89.2(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.1) + version: 1.81.5(@tanstack/react-router@1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.1) '@tauri-apps/api': specifier: 2.2.0 version: 2.2.0 @@ -287,8 +287,8 @@ importers: specifier: 15.4.0 version: 15.4.0(i18next@24.2.1(typescript@5.7.3))(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-markdown: - specifier: 9.0.1 - version: 9.0.1(@types/react@19.0.7)(react@19.0.0) + specifier: 9.0.3 + version: 9.0.3(@types/react@19.0.7)(react@19.0.0) react-split-grid: specifier: 1.0.4 version: 1.0.4(react@19.0.0) @@ -315,8 +315,8 @@ importers: specifier: 11.14.0 version: 11.14.0(@types/react@19.0.7)(react@19.0.0) '@iconify/json': - specifier: 2.2.295 - version: 2.2.295 + specifier: 2.2.296 + version: 2.2.296 '@monaco-editor/react': specifier: 4.6.0 version: 4.6.0(monaco-editor@0.52.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -324,14 +324,14 @@ importers: specifier: 5.64.1 version: 5.64.1(react@19.0.0) '@tanstack/react-router': - specifier: 1.89.2 - version: 1.89.2(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: 1.97.1 + version: 1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@tanstack/router-devtools': - specifier: 1.89.2 - version: 1.89.2(@tanstack/react-router@1.89.2(@tanstack/router-generator@1.87.7)(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.97.1 + version: 1.97.1(@tanstack/react-router@1.97.1(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.87.13 - version: 1.87.13(vite@6.0.7(@types/node@22.10.7)(jiti@2.4.2)(less@4.2.0)(sass-embedded@1.83.4)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) + specifier: 1.97.1 + version: 1.97.1(@tanstack/react-router@1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.0.7(@types/node@22.10.7)(jiti@2.4.2)(less@4.2.0)(sass-embedded@1.83.4)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) '@tauri-apps/plugin-clipboard-manager': specifier: 2.2.0 version: 2.2.0 @@ -551,11 +551,11 @@ importers: specifier: 1.0.0 version: 1.0.0 consola: - specifier: 3.3.3 - version: 3.3.3 + specifier: 3.4.0 + version: 3.4.0 fs-extra: - specifier: 11.2.0 - version: 11.2.0 + specifier: 11.3.0 + version: 11.3.0 https-proxy-agent: specifier: 7.0.6 version: 7.0.6 @@ -1749,8 +1749,8 @@ packages: '@vue/compiler-sfc': optional: true - '@iconify/json@2.2.295': - resolution: {integrity: sha512-VXR+Qn1G+yicPW71zxHEmNcCLVCTdqpfmwBS4Qc4ELnuXRb1a7lYLoZJKGs9MnjdWEj1VWJdKim4v9fCJin4JA==} + '@iconify/json@2.2.296': + resolution: {integrity: sha512-39NFV7HDEWBbSx6O2CrOG292+k8yf0gbH9EtbyR2nsc5PCj4OwYDYvXrkyOBM7h622HtBrV2YfSQxcgtHS76vQ==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -2725,8 +2725,8 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@tanstack/history@1.87.6': - resolution: {integrity: sha512-5OPHcc20Ye5XR+RBkFk+64TtRJ83clrpaOcC/S8t4N0k+/xPDJpkPEPnoENb3sQeRI28y1dJaUuvXt/dv/ylaQ==} + '@tanstack/history@1.97.0': + resolution: {integrity: sha512-xFdpGJqwSLUJW5TYRNjRO5T41KjGkJeHWyhANZsNJ1KDm7uCVNkfLxNXeCI1XhIFbpzJmk13vo/mY0WJDe0A5g==} engines: {node: '>=12'} '@tanstack/match-sorter-utils@8.19.4': @@ -2741,19 +2741,15 @@ packages: peerDependencies: react: ^18 || ^19 - '@tanstack/react-router@1.89.2': - resolution: {integrity: sha512-rvLyEACnDUMXseG33LsS7+uEmY1oyj2LrPpG/TUwdv/R795Gqm8JCk7B4s4nNNN29rbNN/7UpMD5YHaSabM2PQ==} + '@tanstack/react-router@1.97.1': + resolution: {integrity: sha512-loKN9SMjAiHV5FE5SQHSZMMSUgR36xSl2rsbHrbm0v0GEJgATLAI4KH2KExs4vmAyxJ0WkPx2qCBI6MtzjA0Lw==} engines: {node: '>=12'} peerDependencies: - '@tanstack/router-generator': ^1.87.7 react: '>=18' react-dom: '>=18' - peerDependenciesMeta: - '@tanstack/router-generator': - optional: true - '@tanstack/react-store@0.6.1': - resolution: {integrity: sha512-6gOopOpPp1cAXkEyTEv6tMbAywwFunvIdCKN/SpEiButUayjXU+Q5Sp5Y3hREN3VMR4OA5+RI5SPhhJoqP9e4w==} + '@tanstack/react-store@0.7.0': + resolution: {integrity: sha512-S/Rq17HaGOk+tQHV/yrePMnG1xbsKZIl/VsNWnNXt4XW+tTY8dTlvpJH2ZQ3GRALsusG5K6Q3unAGJ2pd9W/Ng==} peerDependencies: 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 @@ -2771,20 +2767,25 @@ 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-devtools@1.89.2': - resolution: {integrity: sha512-7wbS2mrE+KI26gGVIxOV/WdEkvgJ+ChDb8JDZmBKL1hCxlu06v20FbBDXuH3ltisa90721T6U8PqorqxObnipQ==} + '@tanstack/router-devtools@1.97.1': + resolution: {integrity: sha512-61g3rGVvI25xpHo7GxliqQDgFqV4FBthCasqIuGXaexKW97EK/w2xpTb4FUh5/q0Pog2FYmhCBOCQnCmVUOqbg==} engines: {node: '>=12'} peerDependencies: - '@tanstack/react-router': ^1.89.2 + '@tanstack/react-router': ^1.97.1 react: '>=18' react-dom: '>=18' - '@tanstack/router-generator@1.87.7': - resolution: {integrity: sha512-w9Px1C6DM0YNVXvu1VjUuZ5el0ykOeofEmEZBW83VUTzvCXFpcjPCHncU9FO9uXup8NFIxNfGz+xpwf93GoFnQ==} + '@tanstack/router-generator@1.97.1': + resolution: {integrity: sha512-s/G9oPV2sceDPOxds1CRVGUBoiWBw0NYn9OQKwQVw4seBVvGtmsr5dz2XlL6QuCFDJU8yYo0MY8befO9LhiFRg==} engines: {node: '>=12'} + peerDependencies: + '@tanstack/react-router': ^1.97.1 + peerDependenciesMeta: + '@tanstack/react-router': + optional: true - '@tanstack/router-plugin@1.87.13': - resolution: {integrity: sha512-h5dD0m5ixSsmIMOrNXd4NBH2Fwx+4Mb5GK0JCUVlcegjtNQ9Zx9kdWqWXi+4P595XKCmjdHVOP4vhBr9cfwozg==} + '@tanstack/router-plugin@1.97.1': + resolution: {integrity: sha512-+5USTqYXNjdluAcpGDwSKxSb0xsDnjb2tQ0xj5EH+yIFAR7cznhqTii/+1a0ZHPKtSx0S+d4ceTzSmCEn5nDTQ==} engines: {node: '>=12'} peerDependencies: '@rsbuild/core': '>=1.0.2' @@ -2805,8 +2806,8 @@ packages: '@tanstack/react-router': '>=1.43.2' zod: '>=3' - '@tanstack/store@0.6.0': - resolution: {integrity: sha512-+m2OBglsjXcLmmKOX6/9v8BDOCtyxhMmZLsRUDswOOSdIIR9mvv6i0XNKsmTh3AlYU8c1mRcodC8/Vyf+69VlQ==} + '@tanstack/store@0.7.0': + resolution: {integrity: sha512-CNIhdoUsmD2NolYuaIs8VfWM467RK6oIBAW4nPEKZhg1smZ+/CwtCdpURgp7nxSqOaV9oKkzdWD80+bC66F/Jg==} '@tanstack/table-core@8.20.5': resolution: {integrity: sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==} @@ -2815,8 +2816,8 @@ packages: '@tanstack/virtual-core@3.11.2': resolution: {integrity: sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==} - '@tanstack/virtual-file-routes@1.87.6': - resolution: {integrity: sha512-PTpeM8SHL7AJM0pJOacFvHribbUODS51qe9NsMqku4mogh6BWObY1EeVmeGnp9o3VngAEsf+rJMs2zqIVz3WFA==} + '@tanstack/virtual-file-routes@1.97.0': + resolution: {integrity: sha512-UsLBb+ALvxbRTYMlx3WJ36oq13Ps4n8tcN8biFrtiCbA8TiS0sgSAOr0lPQpzQqZuVSjscPjX43ciKf33hvkQw==} engines: {node: '>=12'} '@taplo/core@0.1.1': @@ -3052,6 +3053,9 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/diff@6.0.0': + resolution: {integrity: sha512-dhVCYGv3ZSbzmQaBSagrv1WJ6rXCdkyTcDyoNu1MD8JohI7pR7k8wdZEm+mvdxRKXyHVwckFzWU1vJc+Z29MlA==} + '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} @@ -3481,8 +3485,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - babel-dead-code-elimination@1.0.6: - resolution: {integrity: sha512-JxFi9qyRJpN0LjEbbjbN8g0ux71Qppn9R8Qe3k6QzHg2CaKsbUQtbn307LQGiDLGjV6JCtEFqfxzVig9MyDCHQ==} + babel-dead-code-elimination@1.0.8: + resolution: {integrity: sha512-og6HQERk0Cmm+nTT4Od2wbPtgABXFMPaHACjbKLulZIFMkYyXZLkUGuAxdgpMJBrxyt/XFpSz++lNzjbcMnPkQ==} babel-plugin-macros@3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} @@ -3666,10 +3670,6 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - chalk@5.4.1: resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} @@ -3822,8 +3822,8 @@ packages: consola@2.15.3: resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} - consola@3.3.3: - resolution: {integrity: sha512-Qil5KwghMzlqd51UXM0b6fyaGHtOC22scxrwrz4A2882LyUMwQjnvaedN1HAeXzphspQ6CpHkzMAWxBTUruDLg==} + consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} engines: {node: ^14.18.0 || >=16.10.0} conventional-changelog-angular@7.0.0: @@ -4237,6 +4237,10 @@ packages: didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + diff@7.0.0: + resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + engines: {node: '>=0.3.1'} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -4803,8 +4807,8 @@ packages: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} engines: {node: '>=14.14'} fs-extra@7.0.1: @@ -5624,8 +5628,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - knip@5.42.1: - resolution: {integrity: sha512-xTnwo0I5TLAEU1BNqi8EwnvxI/5yJUJmBiXJdnS0+2FDE6WQII3upoImuUbx1GxrftHmY+prqfL6XuO6JEtYBw==} + knip@5.42.2: + resolution: {integrity: sha512-hVtZ6V59COFz3Y0/BHrWMlPAx82EdX/xFHXbutIRSNfJFPMGmIpxLBWTg35F4XQJGwlu5uWiJf8rBYYkmlYWWQ==} engines: {node: '>=18.18.0'} hasBin: true peerDependencies: @@ -5662,8 +5666,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@15.3.0: - resolution: {integrity: sha512-vHFahytLoF2enJklgtOtCtIjZrKD/LoxlaUusd5nh7dWv/dkKQJY74ndFSzxCdv7g0ueGg1ORgTSt4Y9LPZn9A==} + lint-staged@15.4.1: + resolution: {integrity: sha512-P8yJuVRyLrm5KxCtFx+gjI5Bil+wO7wnTl7C3bXhvtTaAFGirzeB24++D0wGoUwxrUKecNiehemgCob9YL39NA==} engines: {node: '>=18.12.0'} hasBin: true @@ -6745,8 +6749,8 @@ packages: react-is@19.0.0: resolution: {integrity: sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==} - react-markdown@9.0.1: - resolution: {integrity: sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==} + react-markdown@9.0.3: + resolution: {integrity: sha512-Yk7Z94dbgYTOrdk41Z74GoKA7rThnsbbqBTRYuxoe08qvfQ9tJVhmAKw6BJS/ZORG7kTy/s1QvYzSuaoBA1qfw==} peerDependencies: '@types/react': '>=18' react: '>=18' @@ -7903,11 +7907,6 @@ packages: react: 16.8.0 - 18 react-dom: 16.8.0 - 18 - use-sync-external-store@1.2.2: - resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - use-sync-external-store@1.4.0: resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} peerDependencies: @@ -9056,7 +9055,7 @@ snapshots: '@commitlint/format@19.5.0': dependencies: '@commitlint/types': 19.5.0 - chalk: 5.3.0 + chalk: 5.4.1 '@commitlint/is-ignored@19.6.0': dependencies: @@ -9076,7 +9075,7 @@ snapshots: '@commitlint/execute-rule': 19.5.0 '@commitlint/resolve-extends': 19.5.0 '@commitlint/types': 19.5.0 - chalk: 5.3.0 + chalk: 5.4.1 cosmiconfig: 9.0.0(typescript@5.7.3) cosmiconfig-typescript-loader: 6.1.0(@types/node@22.10.7)(cosmiconfig@9.0.0(typescript@5.7.3))(typescript@5.7.3) lodash.isplainobject: 4.0.6 @@ -9127,7 +9126,7 @@ snapshots: '@commitlint/types@19.5.0': dependencies: '@types/conventional-commits-parser': 5.0.0 - chalk: 5.3.0 + chalk: 5.4.1 '@cryptography/aes@0.1.1': {} @@ -9517,7 +9516,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@iconify/json@2.2.295': + '@iconify/json@2.2.296': dependencies: '@iconify/types': 2.0.0 pathe: 1.1.2 @@ -10479,7 +10478,7 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tanstack/history@1.87.6': {} + '@tanstack/history@1.97.0': {} '@tanstack/match-sorter-utils@8.19.4': dependencies: @@ -10492,24 +10491,22 @@ snapshots: '@tanstack/query-core': 5.64.1 react: 19.0.0 - '@tanstack/react-router@1.89.2(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@tanstack/react-router@1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@tanstack/history': 1.87.6 - '@tanstack/react-store': 0.6.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@tanstack/history': 1.97.0 + '@tanstack/react-store': 0.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) jsesc: 3.0.2 react: 19.0.0 react-dom: 19.0.0(react@19.0.0) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - optionalDependencies: - '@tanstack/router-generator': 1.87.7 - '@tanstack/react-store@0.6.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@tanstack/react-store@0.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@tanstack/store': 0.6.0 + '@tanstack/store': 0.7.0 react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - use-sync-external-store: 1.2.2(react@19.0.0) + use-sync-external-store: 1.4.0(react@19.0.0) '@tanstack/react-table@8.20.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: @@ -10523,9 +10520,9 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - '@tanstack/router-devtools@1.89.2(@tanstack/react-router@1.89.2(@tanstack/router-generator@1.87.7)(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.97.1(@tanstack/react-router@1.97.1(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.89.2(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@tanstack/react-router': 1.97.1(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 @@ -10533,14 +10530,16 @@ snapshots: transitivePeerDependencies: - csstype - '@tanstack/router-generator@1.87.7': + '@tanstack/router-generator@1.97.1(@tanstack/react-router@1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))': dependencies: - '@tanstack/virtual-file-routes': 1.87.6 + '@tanstack/virtual-file-routes': 1.97.0 prettier: 3.4.2 tsx: 4.19.2 zod: 3.24.1 + optionalDependencies: + '@tanstack/react-router': 1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@tanstack/router-plugin@1.87.13(vite@6.0.7(@types/node@22.10.7)(jiti@2.4.2)(less@4.2.0)(sass-embedded@1.83.4)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))': + '@tanstack/router-plugin@1.97.1(@tanstack/react-router@1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.0.7(@types/node@22.10.7)(jiti@2.4.2)(less@4.2.0)(sass-embedded@1.83.4)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1))': dependencies: '@babel/core': 7.26.0 '@babel/generator': 7.26.3 @@ -10550,33 +10549,37 @@ snapshots: '@babel/template': 7.25.9 '@babel/traverse': 7.26.4 '@babel/types': 7.26.3 - '@tanstack/router-generator': 1.87.7 - '@tanstack/virtual-file-routes': 1.87.6 + '@tanstack/router-generator': 1.97.1(@tanstack/react-router@1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)) + '@tanstack/virtual-file-routes': 1.97.0 '@types/babel__core': 7.20.5 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 - babel-dead-code-elimination: 1.0.6 + '@types/diff': 6.0.0 + babel-dead-code-elimination: 1.0.8 + chalk: 5.4.1 chokidar: 3.6.0 + diff: 7.0.0 unplugin: 1.16.0 zod: 3.24.1 optionalDependencies: vite: 6.0.7(@types/node@22.10.7)(jiti@2.4.2)(less@4.2.0)(sass-embedded@1.83.4)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) transitivePeerDependencies: + - '@tanstack/react-router' - supports-color - '@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.89.2(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.1)': + '@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.1)': dependencies: - '@tanstack/react-router': 1.89.2(@tanstack/router-generator@1.87.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@tanstack/react-router': 1.97.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) zod: 3.24.1 - '@tanstack/store@0.6.0': {} + '@tanstack/store@0.7.0': {} '@tanstack/table-core@8.20.5': {} '@tanstack/virtual-core@3.11.2': {} - '@tanstack/virtual-file-routes@1.87.6': {} + '@tanstack/virtual-file-routes@1.97.0': {} '@taplo/core@0.1.1': {} @@ -10837,6 +10840,8 @@ snapshots: dependencies: '@types/ms': 0.7.34 + '@types/diff@6.0.0': {} + '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.6 @@ -11389,7 +11394,7 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - babel-dead-code-elimination@1.0.6: + babel-dead-code-elimination@1.0.8: dependencies: '@babel/core': 7.26.0 '@babel/parser': 7.26.3 @@ -11593,8 +11598,6 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.3.0: {} - chalk@5.4.1: {} change-case@5.4.4: {} @@ -11729,7 +11732,7 @@ snapshots: consola@2.15.3: {} - consola@3.3.3: {} + consola@3.4.0: {} conventional-changelog-angular@7.0.0: dependencies: @@ -12153,6 +12156,8 @@ snapshots: didyoumean@1.2.2: {} + diff@7.0.0: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -12977,7 +12982,7 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 - fs-extra@11.2.0: + fs-extra@11.3.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 @@ -13800,7 +13805,7 @@ snapshots: kind-of@6.0.3: {} - knip@5.42.1(@types/node@22.10.7)(typescript@5.7.3): + knip@5.42.2(@types/node@22.10.7)(typescript@5.7.3): dependencies: '@nodelib/fs.walk': 3.0.1 '@snyk/github-codeowners': 1.1.0 @@ -13854,7 +13859,7 @@ snapshots: lines-and-columns@1.2.4: {} - lint-staged@15.3.0: + lint-staged@15.4.1: dependencies: chalk: 5.4.1 commander: 12.1.0 @@ -15011,7 +15016,7 @@ snapshots: react-is@19.0.0: {} - react-markdown@9.0.1(@types/react@19.0.7)(react@19.0.0): + react-markdown@9.0.3(@types/react@19.0.7)(react@19.0.0): dependencies: '@types/hast': 3.0.4 '@types/react': 19.0.7 @@ -16396,10 +16401,6 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - use-sync-external-store@1.2.2(react@19.0.0): - dependencies: - react: 19.0.0 - use-sync-external-store@1.4.0(react@19.0.0): dependencies: react: 19.0.0 diff --git a/clash-nyanpasu/scripts/package.json b/clash-nyanpasu/scripts/package.json index 165f9f2da2..13bd3a7cc4 100644 --- a/clash-nyanpasu/scripts/package.json +++ b/clash-nyanpasu/scripts/package.json @@ -14,8 +14,8 @@ "@types/adm-zip": "0.5.7", "adm-zip": "0.5.16", "colorize-template": "1.0.0", - "consola": "3.3.3", - "fs-extra": "11.2.0", + "consola": "3.4.0", + "fs-extra": "11.3.0", "https-proxy-agent": "7.0.6", "node-fetch": "3.3.2", "octokit": "4.1.0", diff --git a/lede/.github/workflows/openwrt-ci.yml b/lede/.github/workflows/openwrt-ci.yml index 3a40468922..004ed5ee90 100644 --- a/lede/.github/workflows/openwrt-ci.yml +++ b/lede/.github/workflows/openwrt-ci.yml @@ -20,25 +20,27 @@ jobs: name: Build OpenWrt Firmware - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Space cleanup and Initialization environment env: DEBIAN_FRONTEND: noninteractive run: | + docker rmi `docker images -q` sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /etc/apt/sources.list.d /usr/local/lib/android sudo -E apt-mark hold grub-efi-amd64-signed sudo -E apt update + sudo -E apt -y purge azure-cli* docker* ghc* zulu* llvm* firefox google* dotnet* powershell* openjdk* mysql* php* mongodb* dotnet* snap* sudo -E apt -y full-upgrade - sudo -E apt -y install ack antlr3 aria2 asciidoc autoconf automake autopoint binutils bison build-essential bzip2 ccache cmake cpio curl device-tree-compiler fastjar flex gawk gettext gcc-multilib g++-multilib git gperf haveged help2man intltool libc6-dev-i386 libelf-dev libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libreadline-dev libssl-dev libtool lrzsz mkisofs msmtp nano ninja-build p7zip p7zip-full patch pkgconf python3 python3-pip libpython3-dev qemu-utils rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev + sudo -E apt -y install ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential bzip2 ccache clang cmake cpio curl device-tree-compiler flex gawk gcc-multilib g++-multilib gettext genisoimage git gperf haveged help2man intltool libc6-dev-i386 libelf-dev libfuse-dev libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libpython3-dev libreadline-dev libssl-dev libtool llvm lrzsz msmtp ninja-build p7zip p7zip-full patch pkgconf python3 python3-pyelftools python3-setuptools qemu-utils rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev sudo -E systemctl daemon-reload sudo -E apt -y autoremove --purge sudo -E apt clean sudo -E timedatectl set-timezone "Asia/Shanghai" - name: Checkout OpenWrt - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Update feeds run: | @@ -73,19 +75,19 @@ jobs: cp -rf $(find ./bin/targets/ -type f -name "*.buildinfo" -o -name "*.manifest") ./artifact/buildinfo/ - name: Upload buildinfo - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: OpenWrt_buildinfo path: ./artifact/buildinfo/ - name: Upload package - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: OpenWrt_package path: ./artifact/package/ - name: Upload firmware - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: OpenWrt_firmware path: ./bin/targets/ diff --git a/openwrt-passwall/.github/workflows/Auto compile with openwrt sdk.yml b/openwrt-passwall/.github/workflows/Auto compile with openwrt sdk.yml index 77dec61b0d..18bb1c2cb2 100644 --- a/openwrt-passwall/.github/workflows/Auto compile with openwrt sdk.yml +++ b/openwrt-passwall/.github/workflows/Auto compile with openwrt sdk.yml @@ -141,7 +141,7 @@ jobs: echo "CONFIG_PACKAGE_luci-app-passwall=m" >> .config make defconfig echo "make package/luci-app-passwall/{clean,compile} -j$(nproc)" - make package/luci-app-passwall/{clean,compile} -j$(nproc) + make package/luci-app-passwall/{clean,compile} -j$(nproc) V=s mv bin/packages/x86_64/passwall/ ../ make clean rm .config .config.old @@ -305,7 +305,7 @@ jobs: cd sdk for package in $(ls feeds/passwall_packages); do if [ -d "feeds/passwall_packages/$package" ]; then - make package/feeds/passwall_packages/$package/compile -j$(nproc) 2>/dev/null + make package/feeds/passwall_packages/$package/compile -j$(nproc) V=s 2>/dev/null fi done diff --git a/openwrt-passwall2/.github/workflows/Auto compile with openwrt sdk.yml b/openwrt-passwall2/.github/workflows/Auto compile with openwrt sdk.yml index c32bd83ec4..3b0ccc705e 100644 --- a/openwrt-passwall2/.github/workflows/Auto compile with openwrt sdk.yml +++ b/openwrt-passwall2/.github/workflows/Auto compile with openwrt sdk.yml @@ -141,7 +141,7 @@ jobs: echo "CONFIG_PACKAGE_luci-app-passwall2=m" >> .config make defconfig echo "make package/luci-app-passwall2/{clean,compile} -j1" - make package/luci-app-passwall2/{clean,compile} -j1 + make package/luci-app-passwall2/{clean,compile} -j1 V=s mv bin/packages/x86_64/passwall2/ ../ make clean rm .config .config.old @@ -299,20 +299,20 @@ jobs: id: compile run: | cd sdk - make package/feeds/passwall_packages/chinadns-ng/compile -j1 2>/dev/null - make package/feeds/passwall_packages/geoview/compile -j1 2>/dev/null - make package/feeds/passwall_packages/tcping/compile -j1 2>/dev/null - make package/feeds/passwall_packages/xray-core/compile -j1 2>/dev/null - make package/feeds/passwall_packages/v2ray-geodata/compile -j1 2>/dev/null + make package/feeds/passwall_packages/chinadns-ng/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/geoview/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/tcping/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/xray-core/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/v2ray-geodata/compile -j1 V=s 2>/dev/null - make package/feeds/passwall_packages/hysteria/compile -j1 2>/dev/null - make package/feeds/passwall_packages/naiveproxy/compile -j1 2>/dev/null - make package/feeds/passwall_packages/shadowsocks-rust/compile -j1 2>/dev/null - make package/feeds/passwall_packages/shadowsocksr-libev/compile -j1 2>/dev/null - make package/feeds/passwall_packages/simple-obfs/compile -j1 2>/dev/null - make package/feeds/passwall_packages/sing-box/compile -j1 2>/dev/null - make package/feeds/passwall_packages/tuic-client/compile -j1 2>/dev/null - make package/feeds/passwall_packages/v2ray-plugin/compile -j1 2>/dev/null + make package/feeds/passwall_packages/hysteria/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/naiveproxy/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/shadowsocks-rust/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/shadowsocksr-libev/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/simple-obfs/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/sing-box/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/tuic-client/compile -j1 V=s 2>/dev/null + make package/feeds/passwall_packages/v2ray-plugin/compile -j1 V=s 2>/dev/null echo "status=success" >> $GITHUB_OUTPUT diff --git a/sing-box/box.go b/sing-box/box.go index 1908f6dbfe..0cbf1b3b3d 100644 --- a/sing-box/box.go +++ b/sing-box/box.go @@ -399,7 +399,7 @@ func (s *Box) Close() error { close(s.done) } err := common.Close( - s.inbound, s.outbound, s.router, s.connection, s.network, + s.inbound, s.outbound, s.endpoint, s.router, s.connection, s.network, ) for _, lifecycleService := range s.services { err = E.Append(err, lifecycleService.Close(), func(err error) error { diff --git a/small/luci-app-fchomo/Makefile b/small/luci-app-fchomo/Makefile index e2e6d847de..ce00c01a90 100644 --- a/small/luci-app-fchomo/Makefile +++ b/small/luci-app-fchomo/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 # -# Copyright (C) 2024 Anya Lin +# Copyright (C) 2024-2025 Anya Lin include $(TOPDIR)/rules.mk 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 d8e56e2913..054d4702f3 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js @@ -7,6 +7,7 @@ 'require ui'; 'require validation'; +/* Member */ const rulesetdoc = 'data:text/html;base64,' + 'cmxzdHBsYWNlaG9sZGVy'; const sharktaikogif = function() { @@ -25,6 +26,103 @@ const monospacefonts = [ 'monospace' ]; +const dashrepos = [ + ['zephyruso/zashboard', _('zashboard')], + ['metacubex/metacubexd', _('metacubexd')], + ['metacubex/yacd-meta', _('yacd-meta')], + ['metacubex/razord-meta', _('razord-meta')] +]; + +const dashrepos_urlparams = { + 'zephyruso/zashboard': '#/setup' + '?hostname=%s&port=%s&secret=%s', + 'metacubex/metacubexd': '#/setup' + '?hostname=%s&port=%s&secret=%s', + 'metacubex/yacd-meta': '?hostname=%s&port=%s&secret=%s', + 'metacubex/razord-meta': '?host=%s&port=%s&secret=%s' +}; + +const checkurls = [ + ['https://www.baidu.com', _('Baidu')], + ['https://s1.music.126.net/style/favicon.ico', _('163Music')], + ['https://www.google.com/generate_204', _('Google')], + ['https://github.com', _('GitHub')], + ['https://www.youtube.com', _('YouTube')] +]; + +const health_checkurls = [ + ['https://cp.cloudflare.com'], + ['https://www.gstatic.com/generate_204'] +]; + +const inbound_type = [ + ['http', _('HTTP')], + ['socks', _('SOCKS')], + ['mixed', _('Mixed')], + ['shadowsocks', _('Shadowsocks')], + ['vmess', _('VMess')], + ['tuic', _('TUIC')], + ['hysteria2', _('Hysteria2')], + //['tunnel', _('Tunnel')] +]; + +const ip_version = [ + ['', _('Keep default')], + ['dual', _('Dual stack')], + ['ipv4', _('IPv4 only')], + ['ipv6', _('IPv6 only')], + ['ipv4-prefer', _('Prefer IPv4')], + ['ipv6-prefer', _('Prefer IPv6')] +]; + +const load_balance_strategy = [ + ['round-robin', _('Simple round-robin all nodes')], + ['consistent-hashing', _('Same dstaddr requests. Same node')], + ['sticky-sessions', _('Same srcaddr and dstaddr requests. Same node')] +]; + +const outbound_type = [ + ['direct', _('DIRECT')], + ['http', _('HTTP')], + ['socks5', _('SOCKS5')], + ['ss', _('Shadowsocks')], + //['ssr', _('ShadowsocksR')], // Deprecated + ['mieru', _('Mieru')], + ['snell', _('Snell')], + ['vmess', _('VMess')], + ['vless', _('VLESS')], + ['trojan', _('Trojan')], + //['hysteria', _('Hysteria')], + ['hysteria2', _('Hysteria2')], + ['tuic', _('TUIC')], + ['wireguard', _('WireGuard')], + ['ssh', _('SSH')] +]; + +const preset_outbound = { + full: [ + ['DIRECT'], + ['REJECT'], + ['REJECT-DROP'], + ['PASS'], + ['COMPATIBLE'] + ], + direct: [ + ['', _('null')], + ['DIRECT'] + ], + dns: [ + ['', 'RULES'], + ['DIRECT'] + ] +}; + +const proxy_group_type = [ + ['select', _('Select')], + ['fallback', _('Fallback')], + ['url-test', _('URL test')], + ['load-balance', _('Load balance')], + //['relay', _('Relay')], // Deprecated +]; + const routing_port_type = [ ['all', _('All ports')], ['common_tcpport', _('Common ports only (bypass P2P traffic)')], @@ -33,984 +131,1011 @@ const routing_port_type = [ ['turn_port', _('TURN ports')], ]; -return baseclass.extend({ - rulesetdoc, - sharktaikogif, - monospacefonts, +const rules_type = [ + ['DOMAIN'], + ['DOMAIN-SUFFIX'], + ['DOMAIN-KEYWORD'], + ['DOMAIN-REGEX'], + ['GEOSITE'], - dashrepos: [ - ['zephyruso/zashboard', _('zashboard')], - ['metacubex/metacubexd', _('metacubexd')], - ['metacubex/yacd-meta', _('yacd-meta')], - ['metacubex/razord-meta', _('razord-meta')] - ], + ['IP-CIDR'], + ['IP-CIDR6'], + ['IP-SUFFIX'], + ['IP-ASN'], + ['GEOIP'], - dashrepos_urlparams: { - 'zephyruso/zashboard': '#/setup' + '?hostname=%s&port=%s&secret=%s', - 'metacubex/metacubexd': '#/setup' + '?hostname=%s&port=%s&secret=%s', - 'metacubex/yacd-meta': '?hostname=%s&port=%s&secret=%s', - 'metacubex/razord-meta': '?host=%s&port=%s&secret=%s' - }, + ['SRC-GEOIP'], + ['SRC-IP-ASN'], + ['SRC-IP-CIDR'], + ['SRC-IP-SUFFIX'], - checkurls: [ - ['https://www.baidu.com', _('Baidu')], - ['https://s1.music.126.net/style/favicon.ico', _('163Music')], - ['https://www.google.com/generate_204', _('Google')], - ['https://github.com', _('GitHub')], - ['https://www.youtube.com', _('YouTube')] - ], + ['DST-PORT'], + ['SRC-PORT'], - health_checkurls: [ - ['https://cp.cloudflare.com'], - ['https://www.gstatic.com/generate_204'] - ], + //['IN-PORT'], + //['IN-TYPE'], + //['IN-USER'], + //['IN-NAME'], - inbound_type: [ - ['http', _('HTTP')], - ['socks', _('SOCKS')], - ['mixed', _('Mixed')], - ['shadowsocks', _('Shadowsocks')], - ['vmess', _('VMess')], - ['tuic', _('TUIC')], - ['hysteria2', _('Hysteria2')], - //['tunnel', _('Tunnel')] - ], + ['PROCESS-PATH'], + ['PROCESS-PATH-REGEX'], + ['PROCESS-NAME'], + ['PROCESS-NAME-REGEX'], + //['UID'], - ip_version: [ - ['', _('Keep default')], - ['dual', _('Dual stack')], - ['ipv4', _('IPv4 only')], - ['ipv6', _('IPv6 only')], - ['ipv4-prefer', _('Prefer IPv4')], - ['ipv6-prefer', _('Prefer IPv6')] - ], + ['NETWORK'], + ['DSCP'], - load_balance_strategy: [ - ['round-robin', _('Simple round-robin all nodes')], - ['consistent-hashing', _('Same dstaddr requests. Same node')], - ['sticky-sessions', _('Same srcaddr and dstaddr requests. Same node')] - ], + ['RULE-SET'], - outbound_type: [ - ['direct', _('DIRECT')], - ['http', _('HTTP')], - ['socks5', _('SOCKS5')], - ['ss', _('Shadowsocks')], - //['ssr', _('ShadowsocksR')], // Deprecated - ['mieru', _('Mieru')], - ['snell', _('Snell')], - ['vmess', _('VMess')], - ['vless', _('VLESS')], - ['trojan', _('Trojan')], - //['hysteria', _('Hysteria')], - ['hysteria2', _('Hysteria2')], - ['tuic', _('TUIC')], - ['wireguard', _('WireGuard')], - ['ssh', _('SSH')] - ], + ['MATCH'] +]; - preset_outbound: { - full: [ - ['DIRECT'], - ['REJECT'], - ['REJECT-DROP'], - ['PASS'], - ['COMPATIBLE'] - ], - direct: [ - ['', _('null')], - ['DIRECT'] - ], - dns: [ - ['', 'RULES'], - ['DIRECT'] - ] - }, +const rules_logical_type = [ + ['AND'], + ['OR'], + ['NOT'], + //['SUB-RULE'], +]; - proxy_group_type: [ - ['select', _('Select')], - ['fallback', _('Fallback')], - ['url-test', _('URL test')], - ['load-balance', _('Load balance')], - //['relay', _('Relay')], // Deprecated - ], +const rules_logical_payload_count = { + 'AND': { low: 2, high: undefined }, + 'OR': { low: 2, high: undefined }, + 'NOT': { low: 1, high: 1 }, + //'SUB-RULE': 0, +}; - routing_port_type, +const shadowsocks_cipher_methods = [ + /* Stream */ + ['none', _('none')], + /* AEAD */ + ['aes-128-gcm', _('aes-128-gcm')], + ['aes-192-gcm', _('aes-192-gcm')], + ['aes-256-gcm', _('aes-256-gcm')], + ['chacha20-ietf-poly1305', _('chacha20-ietf-poly1305')], + ['xchacha20-ietf-poly1305', _('xchacha20-ietf-poly1305')], + /* AEAD 2022 */ + ['2022-blake3-aes-128-gcm', _('2022-blake3-aes-128-gcm')], + ['2022-blake3-aes-256-gcm', _('2022-blake3-aes-256-gcm')], + ['2022-blake3-chacha20-poly1305', _('2022-blake3-chacha20-poly1305')] +]; - rules_type: [ - ['DOMAIN'], - ['DOMAIN-SUFFIX'], - ['DOMAIN-KEYWORD'], - ['DOMAIN-REGEX'], - ['GEOSITE'], +const shadowsocks_cipher_length = { + /* AEAD */ + 'aes-128-gcm': 0, + 'aes-192-gcm': 0, + 'aes-256-gcm': 0, + 'chacha20-ietf-poly1305': 0, + 'xchacha20-ietf-poly1305': 0, + /* AEAD 2022 */ + '2022-blake3-aes-128-gcm': 16, + '2022-blake3-aes-256-gcm': 32, + '2022-blake3-chacha20-poly1305': 32 +}; - ['IP-CIDR'], - ['IP-CIDR6'], - ['IP-SUFFIX'], - ['IP-ASN'], - ['GEOIP'], +const stunserver = [ + ['stun.fitauto.ru:3478'], + ['stun.hot-chilli.net:3478'], + ['stun.pure-ip.com:3478'], + ['stun.voipgate.com:3478'], + ['stun.voipia.net:3478'], + ['stunserver2024.stunprotocol.org:3478'] +]; - ['SRC-GEOIP'], - ['SRC-IP-ASN'], - ['SRC-IP-CIDR'], - ['SRC-IP-SUFFIX'], +const tls_client_fingerprints = [ + ['chrome'], + ['firefox'], + ['safari'], + ['iOS'], + ['android'], + ['edge'], + ['360'], + ['qq'], + ['random'] +]; - ['DST-PORT'], - ['SRC-PORT'], +/* Prototype */ +const CBIGenValue = form.Value.extend({ + __name__: 'CBI.GenValue', - //['IN-PORT'], - //['IN-TYPE'], - //['IN-USER'], - //['IN-NAME'], + renderWidget() { + let node = form.Value.prototype.renderWidget.apply(this, arguments); - ['PROCESS-PATH'], - ['PROCESS-PATH-REGEX'], - ['PROCESS-NAME'], - ['PROCESS-NAME-REGEX'], - //['UID'], + if (!this.password) + node.classList.add('control-group'); - ['NETWORK'], - ['DSCP'], + (node.querySelector('.control-group') || node).appendChild(E('button', { + 'class': 'cbi-button cbi-button-add', + 'title': _('Generate'), + 'click': ui.createHandlerFn(this, handleGenKey, this.option) + }, [ _('Generate') ])); - ['RULE-SET'], + return node; + } +}); - ['MATCH'] - ], +const CBIListValue = form.ListValue.extend({ + renderWidget(/* ... */) { + let frameEl = form.ListValue.prototype.renderWidget.apply(this, arguments); - rules_logical_type: [ - ['AND'], - ['OR'], - ['NOT'], - //['SUB-RULE'], - ], + frameEl.querySelector('select').style["min-width"] = '10em'; - rules_logical_payload_count: { - 'AND': { low: 2, high: undefined }, - 'OR': { low: 2, high: undefined }, - 'NOT': { low: 1, high: 1 }, - //'SUB-RULE': 0, - }, + return frameEl; + } +}); - shadowsocks_cipher_methods: [ - /* Stream */ - ['none', _('none')], - /* AEAD */ - ['aes-128-gcm', _('aes-128-gcm')], - ['aes-192-gcm', _('aes-192-gcm')], - ['aes-256-gcm', _('aes-256-gcm')], - ['chacha20-ietf-poly1305', _('chacha20-ietf-poly1305')], - ['xchacha20-ietf-poly1305', _('xchacha20-ietf-poly1305')], - /* AEAD 2022 */ - ['2022-blake3-aes-128-gcm', _('2022-blake3-aes-128-gcm')], - ['2022-blake3-aes-256-gcm', _('2022-blake3-aes-256-gcm')], - ['2022-blake3-chacha20-poly1305', _('2022-blake3-chacha20-poly1305')] - ], +const CBIStaticList = form.DynamicList.extend({ + __name__: 'CBI.StaticList', - shadowsocks_cipher_length: { - /* AEAD */ - 'aes-128-gcm': 0, - 'aes-192-gcm': 0, - 'aes-256-gcm': 0, - 'chacha20-ietf-poly1305': 0, - 'xchacha20-ietf-poly1305': 0, - /* AEAD 2022 */ - '2022-blake3-aes-128-gcm': 16, - '2022-blake3-aes-256-gcm': 32, - '2022-blake3-chacha20-poly1305': 32 - }, + renderWidget(/* ... */) { + let El = form.DynamicList.prototype.renderWidget.apply(this, arguments); - stunserver: [ - ['stun.fitauto.ru:3478'], - ['stun.hot-chilli.net:3478'], - ['stun.pure-ip.com:3478'], - ['stun.voipgate.com:3478'], - ['stun.voipia.net:3478'], - ['stunserver2024.stunprotocol.org:3478'] - ], + El.querySelector('.add-item ul > li[data-value="-"]')?.remove(); - tls_client_fingerprints: [ - ['chrome'], - ['firefox'], - ['safari'], - ['iOS'], - ['android'], - ['edge'], - ['360'], - ['qq'], - ['random'] - ], + return El; + } +}); - CBIListValue: form.ListValue.extend({ - renderWidget(/* ... */) { - let frameEl = form.ListValue.prototype.renderWidget.apply(this, arguments); +const CBITextValue = form.TextValue.extend({ + renderWidget(/* ... */) { + let frameEl = form.TextValue.prototype.renderWidget.apply(this, arguments); - frameEl.querySelector('select').style["min-width"] = '10em'; + frameEl.querySelector('textarea').style.fontFamily = monospacefonts.join(','); - return frameEl; + return frameEl; + } +}); + +/* Method */ +// thanks to homeproxy +function calcStringMD5(e) { + /* Thanks to https://stackoverflow.com/a/41602636 */ + function h(a, b) { + var c, d, e, f, g; + e = a & 2147483648; + f = b & 2147483648; + c = a & 1073741824; + d = b & 1073741824; + g = (a & 1073741823) + (b & 1073741823); + return c & d ? g ^ 2147483648 ^ e ^ f : c | d ? g & 1073741824 ? g ^ 3221225472 ^ e ^ f : g ^ 1073741824 ^ e ^ f : g ^ e ^ f; + } + function k(a, b, c, d, e, f, g) { a = h(a, h(h(b & c | ~b & d, e), g)); return h(a << f | a >>> 32 - f, b); } + function l(a, b, c, d, e, f, g) { a = h(a, h(h(b & d | c & ~d, e), g)); return h(a << f | a >>> 32 - f, b); } + function m(a, b, d, c, e, f, g) { a = h(a, h(h(b ^ d ^ c, e), g)); return h(a << f | a >>> 32 - f, b); } + function n(a, b, d, c, e, f, g) { a = h(a, h(h(d ^ (b | ~c), e), g)); return h(a << f | a >>> 32 - f, b); } + function p(a) { + var b = '', d = ''; + for (var c = 0; 3 >= c; c++) d = a >>> 8 * c & 255, d = '0' + d.toString(16), b += d.substr(d.length - 2, 2); + return b; + } + + var f = [], q, r, s, t, a, b, c, d; + e = function(a) { + a = a.replace(/\r\n/g, '\n'); + for (var b = '', d = 0; d < a.length; d++) { + var c = a.charCodeAt(d); + 128 > c ? b += String.fromCharCode(c) : (127 < c && 2048 > c ? b += String.fromCharCode(c >> 6 | 192) : + (b += String.fromCharCode(c >> 12 | 224), b += String.fromCharCode(c >> 6 & 63 | 128)), + b += String.fromCharCode(c & 63 | 128)) } - }), + return b; + }(e); + f = function(b) { + var c = b.length, a = c + 8; + for (var d = 16 * ((a - a % 64) / 64 + 1), e = Array(d - 1), f = 0, g = 0; g < c;) + a = (g - g % 4) / 4, f = g % 4 * 8, e[a] |= b.charCodeAt(g) << f, g++; + a = (g - g % 4) / 4; e[a] |= 128 << g % 4 * 8; e[d - 2] = c << 3; e[d - 1] = c >>> 29; + return e; + }(e); + a = 1732584193; + b = 4023233417; + c = 2562383102; + d = 271733878; - CBIStaticList: form.DynamicList.extend({ - __name__: 'CBI.StaticList', + for (e = 0; e < f.length; e += 16) q = a, r = b, s = c, t = d, + a = k(a, b, c, d, f[e + 0], 7, 3614090360), d = k(d, a, b, c, f[e + 1], 12, 3905402710), + c = k(c, d, a, b, f[e + 2], 17, 606105819), b = k(b, c, d, a, f[e + 3], 22, 3250441966), + a = k(a, b, c, d, f[e + 4], 7, 4118548399), d = k(d, a, b, c, f[e + 5], 12, 1200080426), + c = k(c, d, a, b, f[e + 6], 17, 2821735955), b = k(b, c, d, a, f[e + 7], 22, 4249261313), + a = k(a, b, c, d, f[e + 8], 7, 1770035416), d = k(d, a, b, c, f[e + 9], 12, 2336552879), + c = k(c, d, a, b, f[e + 10], 17, 4294925233), b = k(b, c, d, a, f[e + 11], 22, 2304563134), + a = k(a, b, c, d, f[e + 12], 7, 1804603682), d = k(d, a, b, c, f[e + 13], 12, 4254626195), + c = k(c, d, a, b, f[e + 14], 17, 2792965006), b = k(b, c, d, a, f[e + 15], 22, 1236535329), + a = l(a, b, c, d, f[e + 1], 5, 4129170786), d = l(d, a, b, c, f[e + 6], 9, 3225465664), + c = l(c, d, a, b, f[e + 11], 14, 643717713), b = l(b, c, d, a, f[e + 0], 20, 3921069994), + a = l(a, b, c, d, f[e + 5], 5, 3593408605), d = l(d, a, b, c, f[e + 10], 9, 38016083), + c = l(c, d, a, b, f[e + 15], 14, 3634488961), b = l(b, c, d, a, f[e + 4], 20, 3889429448), + a = l(a, b, c, d, f[e + 9], 5, 568446438), d = l(d, a, b, c, f[e + 14], 9, 3275163606), + c = l(c, d, a, b, f[e + 3], 14, 4107603335), b = l(b, c, d, a, f[e + 8], 20, 1163531501), + a = l(a, b, c, d, f[e + 13], 5, 2850285829), d = l(d, a, b, c, f[e + 2], 9, 4243563512), + c = l(c, d, a, b, f[e + 7], 14, 1735328473), b = l(b, c, d, a, f[e + 12], 20, 2368359562), + a = m(a, b, c, d, f[e + 5], 4, 4294588738), d = m(d, a, b, c, f[e + 8], 11, 2272392833), + c = m(c, d, a, b, f[e + 11], 16, 1839030562), b = m(b, c, d, a, f[e + 14], 23, 4259657740), + a = m(a, b, c, d, f[e + 1], 4, 2763975236), d = m(d, a, b, c, f[e + 4], 11, 1272893353), + c = m(c, d, a, b, f[e + 7], 16, 4139469664), b = m(b, c, d, a, f[e + 10], 23, 3200236656), + a = m(a, b, c, d, f[e + 13], 4, 681279174), d = m(d, a, b, c, f[e + 0], 11, 3936430074), + c = m(c, d, a, b, f[e + 3], 16, 3572445317), b = m(b, c, d, a, f[e + 6], 23, 76029189), + a = m(a, b, c, d, f[e + 9], 4, 3654602809), d = m(d, a, b, c, f[e + 12], 11, 3873151461), + c = m(c, d, a, b, f[e + 15], 16, 530742520), b = m(b, c, d, a, f[e + 2], 23, 3299628645), + a = n(a, b, c, d, f[e + 0], 6, 4096336452), d = n(d, a, b, c, f[e + 7], 10, 1126891415), + c = n(c, d, a, b, f[e + 14], 15, 2878612391), b = n(b, c, d, a, f[e + 5], 21, 4237533241), + a = n(a, b, c, d, f[e + 12], 6, 1700485571), d = n(d, a, b, c, f[e + 3], 10, 2399980690), + c = n(c, d, a, b, f[e + 10], 15, 4293915773), b = n(b, c, d, a, f[e + 1], 21, 2240044497), + a = n(a, b, c, d, f[e + 8], 6, 1873313359), d = n(d, a, b, c, f[e + 15], 10, 4264355552), + c = n(c, d, a, b, f[e + 6], 15, 2734768916), b = n(b, c, d, a, f[e + 13], 21, 1309151649), + a = n(a, b, c, d, f[e + 4], 6, 4149444226), d = n(d, a, b, c, f[e + 11], 10, 3174756917), + c = n(c, d, a, b, f[e + 2], 15, 718787259), b = n(b, c, d, a, f[e + 9], 21, 3951481745), + a = h(a, q), b = h(b, r), c = h(c, s), d = h(d, t); + return (p(a) + p(b) + p(c) + p(d)).toLowerCase(); +} - renderWidget(/* ... */) { - let El = form.DynamicList.prototype.renderWidget.apply(this, arguments); +// thanks to homeproxy +function decodeBase64Str(str) { + if (!str) + return null; - El.querySelector('.add-item ul > li[data-value="-"]')?.remove(); + /* Thanks to luci-app-ssr-plus */ + str = str.replace(/-/g, '+').replace(/_/g, '/'); + let padding = (4 - (str.length % 4)) % 4; + if (padding) + str = str + Array(padding + 1).join('='); - return El; - } - }), + return decodeURIComponent(Array.prototype.map.call(atob(str), (c) => + '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) + ).join('')); +} - CBITextValue: form.TextValue.extend({ - renderWidget(/* ... */) { - let frameEl = form.TextValue.prototype.renderWidget.apply(this, arguments); - - frameEl.querySelector('textarea').style.fontFamily = monospacefonts.join(','); - - return frameEl; - } - }), - - // thanks to homeproxy - calcStringMD5(e) { - /* Thanks to https://stackoverflow.com/a/41602636 */ - function h(a, b) { - var c, d, e, f, g; - e = a & 2147483648; - f = b & 2147483648; - c = a & 1073741824; - d = b & 1073741824; - g = (a & 1073741823) + (b & 1073741823); - return c & d ? g ^ 2147483648 ^ e ^ f : c | d ? g & 1073741824 ? g ^ 3221225472 ^ e ^ f : g ^ 1073741824 ^ e ^ f : g ^ e ^ f; - } - function k(a, b, c, d, e, f, g) { a = h(a, h(h(b & c | ~b & d, e), g)); return h(a << f | a >>> 32 - f, b); } - function l(a, b, c, d, e, f, g) { a = h(a, h(h(b & d | c & ~d, e), g)); return h(a << f | a >>> 32 - f, b); } - function m(a, b, d, c, e, f, g) { a = h(a, h(h(b ^ d ^ c, e), g)); return h(a << f | a >>> 32 - f, b); } - function n(a, b, d, c, e, f, g) { a = h(a, h(h(d ^ (b | ~c), e), g)); return h(a << f | a >>> 32 - f, b); } - function p(a) { - var b = '', d = ''; - for (var c = 0; 3 >= c; c++) d = a >>> 8 * c & 255, d = '0' + d.toString(16), b += d.substr(d.length - 2, 2); - return b; - } - - var f = [], q, r, s, t, a, b, c, d; - e = function(a) { - a = a.replace(/\r\n/g, '\n'); - for (var b = '', d = 0; d < a.length; d++) { - var c = a.charCodeAt(d); - 128 > c ? b += String.fromCharCode(c) : (127 < c && 2048 > c ? b += String.fromCharCode(c >> 6 | 192) : - (b += String.fromCharCode(c >> 12 | 224), b += String.fromCharCode(c >> 6 & 63 | 128)), - b += String.fromCharCode(c & 63 | 128)) - } - return b; - }(e); - f = function(b) { - var c = b.length, a = c + 8; - for (var d = 16 * ((a - a % 64) / 64 + 1), e = Array(d - 1), f = 0, g = 0; g < c;) - a = (g - g % 4) / 4, f = g % 4 * 8, e[a] |= b.charCodeAt(g) << f, g++; - a = (g - g % 4) / 4; e[a] |= 128 << g % 4 * 8; e[d - 2] = c << 3; e[d - 1] = c >>> 29; - return e; - }(e); - a = 1732584193; - b = 4023233417; - c = 2562383102; - d = 271733878; - - for (e = 0; e < f.length; e += 16) q = a, r = b, s = c, t = d, - a = k(a, b, c, d, f[e + 0], 7, 3614090360), d = k(d, a, b, c, f[e + 1], 12, 3905402710), - c = k(c, d, a, b, f[e + 2], 17, 606105819), b = k(b, c, d, a, f[e + 3], 22, 3250441966), - a = k(a, b, c, d, f[e + 4], 7, 4118548399), d = k(d, a, b, c, f[e + 5], 12, 1200080426), - c = k(c, d, a, b, f[e + 6], 17, 2821735955), b = k(b, c, d, a, f[e + 7], 22, 4249261313), - a = k(a, b, c, d, f[e + 8], 7, 1770035416), d = k(d, a, b, c, f[e + 9], 12, 2336552879), - c = k(c, d, a, b, f[e + 10], 17, 4294925233), b = k(b, c, d, a, f[e + 11], 22, 2304563134), - a = k(a, b, c, d, f[e + 12], 7, 1804603682), d = k(d, a, b, c, f[e + 13], 12, 4254626195), - c = k(c, d, a, b, f[e + 14], 17, 2792965006), b = k(b, c, d, a, f[e + 15], 22, 1236535329), - a = l(a, b, c, d, f[e + 1], 5, 4129170786), d = l(d, a, b, c, f[e + 6], 9, 3225465664), - c = l(c, d, a, b, f[e + 11], 14, 643717713), b = l(b, c, d, a, f[e + 0], 20, 3921069994), - a = l(a, b, c, d, f[e + 5], 5, 3593408605), d = l(d, a, b, c, f[e + 10], 9, 38016083), - c = l(c, d, a, b, f[e + 15], 14, 3634488961), b = l(b, c, d, a, f[e + 4], 20, 3889429448), - a = l(a, b, c, d, f[e + 9], 5, 568446438), d = l(d, a, b, c, f[e + 14], 9, 3275163606), - c = l(c, d, a, b, f[e + 3], 14, 4107603335), b = l(b, c, d, a, f[e + 8], 20, 1163531501), - a = l(a, b, c, d, f[e + 13], 5, 2850285829), d = l(d, a, b, c, f[e + 2], 9, 4243563512), - c = l(c, d, a, b, f[e + 7], 14, 1735328473), b = l(b, c, d, a, f[e + 12], 20, 2368359562), - a = m(a, b, c, d, f[e + 5], 4, 4294588738), d = m(d, a, b, c, f[e + 8], 11, 2272392833), - c = m(c, d, a, b, f[e + 11], 16, 1839030562), b = m(b, c, d, a, f[e + 14], 23, 4259657740), - a = m(a, b, c, d, f[e + 1], 4, 2763975236), d = m(d, a, b, c, f[e + 4], 11, 1272893353), - c = m(c, d, a, b, f[e + 7], 16, 4139469664), b = m(b, c, d, a, f[e + 10], 23, 3200236656), - a = m(a, b, c, d, f[e + 13], 4, 681279174), d = m(d, a, b, c, f[e + 0], 11, 3936430074), - c = m(c, d, a, b, f[e + 3], 16, 3572445317), b = m(b, c, d, a, f[e + 6], 23, 76029189), - a = m(a, b, c, d, f[e + 9], 4, 3654602809), d = m(d, a, b, c, f[e + 12], 11, 3873151461), - c = m(c, d, a, b, f[e + 15], 16, 530742520), b = m(b, c, d, a, f[e + 2], 23, 3299628645), - a = n(a, b, c, d, f[e + 0], 6, 4096336452), d = n(d, a, b, c, f[e + 7], 10, 1126891415), - c = n(c, d, a, b, f[e + 14], 15, 2878612391), b = n(b, c, d, a, f[e + 5], 21, 4237533241), - a = n(a, b, c, d, f[e + 12], 6, 1700485571), d = n(d, a, b, c, f[e + 3], 10, 2399980690), - c = n(c, d, a, b, f[e + 10], 15, 4293915773), b = n(b, c, d, a, f[e + 1], 21, 2240044497), - a = n(a, b, c, d, f[e + 8], 6, 1873313359), d = n(d, a, b, c, f[e + 15], 10, 4264355552), - c = n(c, d, a, b, f[e + 6], 15, 2734768916), b = n(b, c, d, a, f[e + 13], 21, 1309151649), - a = n(a, b, c, d, f[e + 4], 6, 4149444226), d = n(d, a, b, c, f[e + 11], 10, 3174756917), - c = n(c, d, a, b, f[e + 2], 15, 718787259), b = n(b, c, d, a, f[e + 9], 21, 3951481745), - a = h(a, q), b = h(b, r), c = h(c, s), d = h(d, t); - return (p(a) + p(b) + p(c) + p(d)).toLowerCase(); - }, - - // thanks to homeproxy - decodeBase64Str(str) { - if (!str) +function generateRand(type, length) { + let byteArr; + if (['base64', 'hex'].includes(type)) + byteArr = crypto.getRandomValues(new Uint8Array(length)); + switch (type) { + case 'base64': + /* Thanks to https://stackoverflow.com/questions/9267899 */ + return btoa(String.fromCharCode.apply(null, byteArr)); + case 'hex': + return Array.from(byteArr, (byte) => + (byte & 255).toString(16).padStart(2, '0') + ).join(''); + case 'uuid': + /* Thanks to https://stackoverflow.com/a/2117523 */ + return (location.protocol === 'https:') ? crypto.randomUUID() : + ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c) => + (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) + ); + default: return null; + }; +} - /* Thanks to luci-app-ssr-plus */ - str = str.replace(/-/g, '+').replace(/_/g, '/'); - let padding = (4 - (str.length % 4)) % 4; - if (padding) - str = str + Array(padding + 1).join('='); +function isEmpty(res) { + if (res == null) return true; // null, undefined + if (typeof res === 'string' || Array.isArray(res)) return res.length === 0; // empty String/Array + if (typeof res === 'object') { + if (res instanceof Map || res instanceof Set) return res.size === 0; // empty Map/Set + return Object.keys(res).length === 0; // empty Object + } + return false; +} - return decodeURIComponent(Array.prototype.map.call(atob(str), (c) => - '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) - ).join('')); - }, - - generateRand(type, length) { - let byteArr; - if (['base64', 'hex'].includes(type)) - byteArr = crypto.getRandomValues(new Uint8Array(length)); - switch (type) { - case 'base64': - /* Thanks to https://stackoverflow.com/questions/9267899 */ - return btoa(String.fromCharCode.apply(null, byteArr)); - case 'hex': - return Array.from(byteArr, (byte) => - (byte & 255).toString(16).padStart(2, '0') - ).join(''); - case 'uuid': - /* Thanks to https://stackoverflow.com/a/2117523 */ - return (location.protocol === 'https:') ? crypto.randomUUID() : - ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c) => - (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16) - ); - default: - return null; - }; - }, - - isEmpty(res) { - if (res == null) return true; // null, undefined - if (typeof res === 'string' || Array.isArray(res)) return res.length === 0; // empty String/Array - if (typeof res === 'object') { - if (res instanceof Map || res instanceof Set) return res.size === 0; // empty Map/Set - return Object.keys(res).length === 0; // empty Object +function removeBlankAttrs(res) { + if (Array.isArray(res)) { + return res + .filter(item => !isEmpty(item)) + .map(item => removeBlankAttrs(item)); + } + if (res !== null && typeof res === 'object') { + const obj = {}; + for (const key in res) { + const val = removeBlankAttrs(res[key]); + if (!isEmpty(val)) + obj[key] = val; } - return false; - }, + return obj; + } + return res; +} - removeBlankAttrs(self, res) { - if (Array.isArray(res)) { - return res - .filter(item => !self.isEmpty(item)) - .map(item => self.removeBlankAttrs(self, item)); - } - if (res !== null && typeof res === 'object') { - const obj = {}; - for (const key in res) { - const val = self.removeBlankAttrs(self, res[key]); - if (!self.isEmpty(val)) - obj[key] = val; - } - return obj; - } - return res; - }, +function getFeatures() { + const callGetFeatures = rpc.declare({ + object: 'luci.fchomo', + method: 'get_features', + expect: { '': {} } + }); - getFeatures() { - const callGetFeatures = rpc.declare({ - object: 'luci.fchomo', - method: 'get_features', - expect: { '': {} } + return L.resolveDefault(callGetFeatures(), {}); +} + +function getServiceStatus(instance) { + var conf = 'fchomo'; + const callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: ['name'], + expect: { '': {} } + }); + + return L.resolveDefault(callServiceList(conf), {}) + .then((res) => { + let isRunning = false; + try { + isRunning = res[conf]['instances'][instance].running; + } catch (e) {} + return isRunning; }); +} - return L.resolveDefault(callGetFeatures(), {}); - }, +function getClashAPI(instance) { + const callGetClashAPI = rpc.declare({ + object: 'luci.fchomo', + method: 'get_clash_api', + params: ['instance'], + expect: { '': {} } + }); - getServiceStatus(instance) { - var conf = 'fchomo'; - const callServiceList = rpc.declare({ - object: 'service', - method: 'list', - params: ['name'], - expect: { '': {} } - }); + return L.resolveDefault(callGetClashAPI(instance), {}); +} - return L.resolveDefault(callServiceList(conf), {}) - .then((res) => { - let isRunning = false; - try { - isRunning = res[conf]['instances'][instance].running; - } catch (e) {} - return isRunning; +// thanks to homeproxy +function loadDefaultLabel(section_id) { + const label = uci.get(this.config, section_id, 'label'); + if (label) { + return label; + } else { + uci.set(this.config, section_id, 'label', section_id); + return section_id; + } +} + +// thanks to homeproxy +function loadModalTitle(title, addtitle, section_id) { + const label = uci.get(this.config, section_id, 'label'); + return label ? title + ' » ' + label : addtitle; +} + +function loadProxyGroupLabel(preadds, section_id) { + delete this.keylist; + delete this.vallist; + + preadds?.forEach((arr) => { + this.value.apply(this, arr); + }); + uci.sections(this.config, 'proxy_group', (res) => { + if (res.enabled !== '0') + this.value(res['.name'], res.label); + }); + + return this.super('load', section_id); +} + +function loadNodeLabel(preadds, section_id) { + delete this.keylist; + delete this.vallist; + + preadds?.forEach((arr) => { + this.value.apply(this, arr); + }); + uci.sections(this.config, 'node', (res) => { + if (res.enabled !== '0') + this.value(res['.name'], res.label); + }); + + return this.super('load', section_id); +} + +function loadProviderLabel(preadds, section_id) { + delete this.keylist; + delete this.vallist; + + preadds?.forEach((arr) => { + this.value.apply(this, arr); + }); + uci.sections(this.config, 'provider', (res) => { + if (res.enabled !== '0') + this.value(res['.name'], res.label); + }); + + return this.super('load', section_id); +} + +function loadRulesetLabel(preadds, behaviors, section_id) { + delete this.keylist; + delete this.vallist; + + preadds?.forEach((arr) => { + this.value.apply(this, arr); + }); + uci.sections(this.config, 'ruleset', (res) => { + if (res.enabled !== '0') + if (behaviors ? behaviors.includes(res.behavior) : true) + this.value(res['.name'], res.label); + }); + + return this.super('load', section_id); +} + +function loadSubRuleGroup(preadds, section_id) { + delete this.keylist; + delete this.vallist; + + preadds?.forEach((arr) => { + this.value.apply(this, arr); + }); + let groups = {}; + uci.sections(this.config, 'subrules', (res) => { + if (res.enabled !== '0') + groups[res.group] = res.group; + }); + Object.keys(groups).forEach((group) => { + this.value(group, group); + }); + + return this.super('load', section_id); +} + +function renderStatus(ElId, isRunning, instance, noGlobal) { + const visible = isRunning && (isRunning.http || isRunning.https); + + return E([ + E('button', { + 'class': 'cbi-button cbi-button-apply' + (noGlobal ? ' hidden' : ''), + 'click': ui.createHandlerFn(this, handleReload, instance) + }, [ _('Reload') ]), + updateStatus(E('span', { id: ElId, style: 'border: unset; font-style: italic; font-weight: bold' }), isRunning ? true : false), + E('a', { + 'class': 'cbi-button cbi-button-apply %s'.format(visible ? '' : 'hidden'), + 'href': visible ? getDashURL(isRunning) : '', + 'target': '_blank', + 'rel': 'noreferrer noopener' + }, [ _('Open Dashboard') ]) + ]); +} +function updateStatus(El, isRunning, instance, noGlobal) { + if (El) { + El.style.color = isRunning ? 'green' : 'red'; + El.innerHTML = ' %s%s '.format(noGlobal ? instance + ' ' : '', isRunning ? _('Running') : _('Not Running')); + /* Dashboard button */ + if (El.nextSibling?.localName === 'a') + getClashAPI(instance).then((res) => { + let visible = isRunning && (res.http || res.https); + if (visible) { + El.nextSibling.classList.remove('hidden'); + } else + El.nextSibling.classList.add('hidden'); + + El.nextSibling.href = visible ? getDashURL(Object.assign(res, isRunning)) : ''; }); - }, + } - getClashAPI(instance) { - const callGetClashAPI = rpc.declare({ - object: 'luci.fchomo', - method: 'get_clash_api', - params: ['instance'], - expect: { '': {} } - }); + return El; +} +function getDashURL(isRunning) { + const tls = isRunning.https ? 's' : ''; + const host = window.location.hostname; + const port = isRunning.https ? isRunning.https.split(':').pop() : isRunning.http.split(':').pop(); + const secret = isRunning.secret; + const repo = isRunning.dashboard_repo; - return L.resolveDefault(callGetClashAPI(instance), {}); - }, + return 'http%s://%s:%s/ui/'.format(tls, host, port) + + String.format(dashrepos_urlparams[repo] || '', host, port, secret) +} - // thanks to homeproxy - loadDefaultLabel(section_id) { - const label = uci.get(this.config, section_id, 'label'); - if (label) { - return label; - } else { - uci.set(this.config, section_id, 'label', section_id); - return section_id; - } - }, +function renderResDownload(section_id) { + const section_type = this.section.sectiontype; + const type = uci.get(this.config, section_id, 'type'); + const url = uci.get(this.config, section_id, 'url'); + const header = uci.get(this.config, section_id, 'header'); - // thanks to homeproxy - loadModalTitle(title, addtitle, section_id) { - const label = uci.get(this.config, section_id, 'label'); - return label ? title + ' » ' + label : addtitle; - }, + let El = E([ + E('button', { + class: 'cbi-button cbi-button-add', + disabled: (type !== 'http') || null, + click: ui.createHandlerFn(this, function(section_type, section_id, type, url, header) { + if (type === 'http') { + return downloadFile(section_type, section_id, url, header).then((res) => { + ui.addNotification(null, E('p', _('Download successful.'))); + }).catch((e) => { + ui.addNotification(null, E('p', _('Download failed: %s').format(e))); + }); + } else + return ui.addNotification(null, E('p', _('Unable to download unsupported type: %s').format(type))); + }, section_type, section_id, type, url, header) + }, [ _('🡇') ]) //🗘 + ]); - loadProxyGroupLabel(preadds, section_id) { - delete this.keylist; - delete this.vallist; + return El; +} - preadds?.forEach((arr) => { - this.value.apply(this, arr); - }); - uci.sections(this.config, 'proxy_group', (res) => { - if (res.enabled !== '0') - this.value(res['.name'], res.label); - }); - - return this.super('load', section_id); - }, - - loadNodeLabel(preadds, section_id) { - delete this.keylist; - delete this.vallist; - - preadds?.forEach((arr) => { - this.value.apply(this, arr); - }); - uci.sections(this.config, 'node', (res) => { - if (res.enabled !== '0') - this.value(res['.name'], res.label); - }); - - return this.super('load', section_id); - }, - - loadProviderLabel(preadds, section_id) { - delete this.keylist; - delete this.vallist; - - preadds?.forEach((arr) => { - this.value.apply(this, arr); - }); - uci.sections(this.config, 'provider', (res) => { - if (res.enabled !== '0') - this.value(res['.name'], res.label); - }); - - return this.super('load', section_id); - }, - - loadRulesetLabel(preadds, behaviors, section_id) { - delete this.keylist; - delete this.vallist; - - preadds?.forEach((arr) => { - this.value.apply(this, arr); - }); - uci.sections(this.config, 'ruleset', (res) => { - if (res.enabled !== '0') - if (behaviors ? behaviors.includes(res.behavior) : true) - this.value(res['.name'], res.label); - }); - - return this.super('load', section_id); - }, - - loadSubRuleGroup(preadds, section_id) { - delete this.keylist; - delete this.vallist; - - preadds?.forEach((arr) => { - this.value.apply(this, arr); - }); - let groups = {}; - uci.sections(this.config, 'subrules', (res) => { - if (res.enabled !== '0') - groups[res.group] = res.group; - }); - Object.keys(groups).forEach((group) => { - this.value(group, group); - }); - - return this.super('load', section_id); - }, - - renderStatus(self, ElId, isRunning, instance, noGlobal) { - const visible = isRunning && (isRunning.http || isRunning.https); - - return E([ - E('button', { - 'class': 'cbi-button cbi-button-apply' + (noGlobal ? ' hidden' : ''), - 'click': ui.createHandlerFn(this, self.handleReload, instance) - }, [ _('Reload') ]), - self.updateStatus(self, E('span', { id: ElId, style: 'border: unset; font-style: italic; font-weight: bold' }), isRunning ? true : false), - E('a', { - 'class': 'cbi-button cbi-button-apply %s'.format(visible ? '' : 'hidden'), - 'href': visible ? self.getDashURL(self, isRunning) : '', - 'target': '_blank', - 'rel': 'noreferrer noopener' - }, [ _('Open Dashboard') ]) - ]); - }, - updateStatus(self, El, isRunning, instance, noGlobal) { - if (El) { - El.style.color = isRunning ? 'green' : 'red'; - El.innerHTML = ' %s%s '.format(noGlobal ? instance + ' ' : '', isRunning ? _('Running') : _('Not Running')); - /* Dashboard button */ - if (El.nextSibling?.localName === 'a') - self.getClashAPI(instance).then((res) => { - let visible = isRunning && (res.http || res.https); - if (visible) { - El.nextSibling.classList.remove('hidden'); - } else - El.nextSibling.classList.add('hidden'); - - El.nextSibling.href = visible ? self.getDashURL(self, Object.assign(res, isRunning)) : ''; - }); - } - - return El; - }, - getDashURL(self, isRunning) { - const tls = isRunning.https ? 's' : ''; - const host = window.location.hostname; - const port = isRunning.https ? isRunning.https.split(':').pop() : isRunning.http.split(':').pop(); - const secret = isRunning.secret; - const repo = isRunning.dashboard_repo; - - return 'http%s://%s:%s/ui/'.format(tls, host, port) + - String.format(self.dashrepos_urlparams[repo] || '', host, port, secret) - }, - - renderResDownload(self, section_id) { - const section_type = this.section.sectiontype; - const type = uci.get(this.config, section_id, 'type'); - const url = uci.get(this.config, section_id, 'url'); - const header = uci.get(this.config, section_id, 'header'); - - let El = E([ - E('button', { - class: 'cbi-button cbi-button-add', - disabled: (type !== 'http') || null, - click: ui.createHandlerFn(this, function(section_type, section_id, type, url, header) { - if (type === 'http') { - return self.downloadFile(section_type, section_id, url, header).then((res) => { - ui.addNotification(null, E('p', _('Download successful.'))); - }).catch((e) => { - ui.addNotification(null, E('p', _('Download failed: %s').format(e))); - }); - } else - return ui.addNotification(null, E('p', _('Unable to download unsupported type: %s').format(type))); - }, section_type, section_id, type, url, header) - }, [ _('🡇') ]) //🗘 - ]); - - return El; - }, - - renderSectionAdd(prefmt, LC, extra_class) { - let el = form.GridSection.prototype.renderSectionAdd.apply(this, [ extra_class ]), - nameEl = el.querySelector('.cbi-section-create-name'); - ui.addValidator(nameEl, 'uciname', true, (v) => { - let button = el.querySelector('.cbi-section-create > .cbi-button-add'); - const prefix = prefmt?.prefix ? prefmt.prefix : ''; - const suffix = prefmt?.suffix ? prefmt.suffix : ''; - - if (!v) { - button.disabled = true; - return true; - } else if (LC && (v !== v.toLowerCase())) { - button.disabled = true; - return _('Expecting: %s').format(_('Lowercase only')); - } else if (uci.get(this.config, v)) { - button.disabled = true; - return _('Expecting: %s').format(_('unique UCI identifier')); - } else if (uci.get(this.config, prefix + v + suffix)) { - button.disabled = true; - return _('Expecting: %s').format(_('unique identifier')); - } else { - button.disabled = null; - return true; - } - }, 'blur', 'keyup'); - - return el; - }, - - handleAdd(prefmt, ev, name) { +function renderSectionAdd(prefmt, LC, extra_class) { + let el = form.GridSection.prototype.renderSectionAdd.apply(this, [ extra_class ]), + nameEl = el.querySelector('.cbi-section-create-name'); + ui.addValidator(nameEl, 'uciname', true, (v) => { + let button = el.querySelector('.cbi-section-create > .cbi-button-add'); const prefix = prefmt?.prefix ? prefmt.prefix : ''; const suffix = prefmt?.suffix ? prefmt.suffix : ''; - return form.GridSection.prototype.handleAdd.apply(this, [ ev, prefix + name + suffix ]); - }, - - handleReload(instance, ev, section_id) { - instance = instance || ''; - return fs.exec('/etc/init.d/fchomo', ['reload', instance]) - .then((res) => { /* return window.location = window.location.href.split('#')[0] */ }) - .catch((e) => { - ui.addNotification(null, E('p', _('Failed to execute "/etc/init.d/fchomo %s %s" reason: %s').format('reload', instance, e))) - }) - }, - - handleRemoveIdles(self) { - const section_type = this.sectiontype; - - let loaded = []; - uci.sections(this.config, section_type, (section, sid) => loaded.push(sid)); - - return self.lsDir(section_type).then((res) => { - let sectionEl = E('div', { class: 'cbi-section' }, []); - - res.filter(e => !loaded.includes(e)).forEach((filename) => { - sectionEl.appendChild(E('div', { class: 'cbi-value' }, [ - E('label', { - class: 'cbi-value-title', - id: 'rmidles.' + filename + '.label' - }, [ filename ]), - E('div', { class: 'cbi-value-field' }, [ - E('button', { - class: 'cbi-button cbi-button-negative important', - id: 'rmidles.' + filename + '.button', - click: ui.createHandlerFn(this, function(filename) { - return self.removeFile(section_type, filename).then((res) => { - let node = document.getElementById('rmidles.' + filename + '.label'); - node.innerHTML = '%s'.format(node.innerHTML); - node = document.getElementById('rmidles.' + filename + '.button'); - node.classList.add('hidden'); - }); - }, filename) - }, [ _('Remove') ]) - ]) - ])); - }); - - ui.showModal(_('Remove idles'), [ - sectionEl, - E('div', { class: 'right' }, [ - E('button', { - class: 'btn cbi-button-action', - click: ui.hideModal - }, [ _('Complete') ]) - ]) - ]); - }); - }, - - textvalue2Value(section_id) { - let cval = this.cfgvalue(section_id); - let i = this.keylist.indexOf(cval); - - return this.vallist[i]; - }, - - validateAuth(section_id, value) { - if (!value) + if (!v) { + button.disabled = true; return true; - if (!value.match(/^[\w-]{3,}:[^:]+$/)) - return _('Expecting: %s').format('[A-Za-z0-9_-]{3,}:[^:]+'); - - return true; - }, - validateAuthUsername(section_id, value) { - if (!value) + } else if (LC && (v !== v.toLowerCase())) { + button.disabled = true; + return _('Expecting: %s').format(_('Lowercase only')); + } else if (uci.get(this.config, v)) { + button.disabled = true; + return _('Expecting: %s').format(_('unique UCI identifier')); + } else if (uci.get(this.config, prefix + v + suffix)) { + button.disabled = true; + return _('Expecting: %s').format(_('unique identifier')); + } else { + button.disabled = null; return true; - if (!value.match(/^[\w-]{3,}$/)) - return _('Expecting: %s').format('[A-Za-z0-9_-]{3,}'); - - return true; - }, - validateAuthPassword(section_id, value) { - if (!value) - return true; - if (!value.match(/^[^:]+$/)) - return _('Expecting: %s').format('[^:]+'); - - return true; - }, - - validateCommonPort(section_id, value) { - // thanks to homeproxy - let stubValidator = { - factory: validation, - apply(type, value, args) { - if (value != null) - this.value = value; - - return validation.types[type].apply(this, args); - }, - assert(condition) { - return !!condition; - } - }; - - const arr = value.trim().split(' '); - - if (arr.length === 0 || arr.includes('')) - return _('Expecting: %s').format(_('non-empty value')); - - if (arr.length > 1 && arr.includes('all')) - return _('Expecting: %s').format(_('If All ports is selected, uncheck others')); - - for (let custom of arr) { - if (!routing_port_type.map(e => e[0]).includes(custom)) { - let ports = []; - for (let i of custom.split(',')) { - if (!stubValidator.apply('port', i) && !stubValidator.apply('portrange', i)) - return _('Expecting: %s').format(_('valid port value')); - if (ports.includes(i)) - return _('Port %s alrealy exists!').format(i); - ports = ports.concat(i); - } - } } + }, 'blur', 'keyup'); - return true; - }, + return el; +} - validateJson(section_id, value) { - if (!value) - return true; +function handleAdd(prefmt, ev, name) { + const prefix = prefmt?.prefix ? prefmt.prefix : ''; + const suffix = prefmt?.suffix ? prefmt.suffix : ''; - try { - let obj = JSON.parse(value.trim()); - if (!obj) - return _('Expecting: %s').format(_('valid JSON format')); - } - catch(e) { - return _('Expecting: %s').format(_('valid JSON format')); - } + return form.GridSection.prototype.handleAdd.apply(this, [ ev, prefix + name + suffix ]); +} - return true; - }, +function handleGenKey(option) { + const section_id = this.section.section; + const type = this.section.getOption('type').formvalue(section_id); + let widget = this.map.findElement('id', 'widget.cbid.fchomo.%s.%s'.format(section_id, option)); + let password, required_method; - validateBase64Key(length, section_id, value) { - /* Thanks to luci-proto-wireguard */ - if (value) - if (value.length !== length || !value.match(/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/) || value[length-1] !== '=') - return _('Expecting: %s').format(_('valid base64 key with %d characters').format(length)); + if (option === 'uuid' || option.match(/_uuid/)) + required_method = 'uuid'; + else if (type === 'shadowsocks') + required_method = this.section.getOption('shadowsocks_chipher')?.formvalue(section_id); - return true; - }, - - validateShadowsocksPassword(self, encmode, section_id, value) { - let length = self.shadowsocks_cipher_length[encmode]; - if (typeof length !== 'undefined') { - length = Math.ceil(length/3)*4; - if (encmode.match(/^2022-/)) { - return self.validateBase64Key(length, section_id, value); - } else { - if (length === 0 && !value) - return _('Expecting: %s').format(_('non-empty value')); - if (length !== 0 && value.length !== length) - return _('Expecting: %s').format(_('valid key length with %d characters').format(length)); - } - } else - return true; - - return true; - }, - - validateBytesize(section_id, value) { - if (!value) - return true; - - if (!value.match(/^(\d+)(k|m|g)?b?$/)) - return _('Expecting: %s').format('^(\\d+)(k|m|g)?b?$'); - - return true; - }, - validateTimeDuration(section_id, value) { - if (!value) - return true; - - if (!value.match(/^(\d+)(s|m|h|d)?$/)) - return _('Expecting: %s').format('^(\\d+)(s|m|h|d)?$'); - - return true; - }, - - validateUniqueValue(section_id, value) { - if (!value) - return _('Expecting: %s').format(_('non-empty value')); - - let duplicate = false; - uci.sections(this.config, this.section.sectiontype, (res) => { - if (res['.name'] !== section_id) - if (res[this.option] === value) - duplicate = true; - }); - if (duplicate) - return _('Expecting: %s').format(_('unique value')); - - return true; - }, - - validateUrl(section_id, value) { - if (!value) - return true; - - try { - let url = new URL(value); - if (!url.hostname) - return _('Expecting: %s').format(_('valid URL')); - } - catch(e) { - return _('Expecting: %s').format(_('valid URL')); - } - - return true; - }, - - validateUUID(section_id, value) { - if (!value) - return true; - else if (value.match('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') === null) - return _('Expecting: %s').format(_('valid uuid')); - - return true; - }, - - lsDir(type) { - const callLsDir = rpc.declare({ - object: 'luci.fchomo', - method: 'dir_ls', - params: ['type'], - expect: { '': {} } - }); - - return L.resolveDefault(callLsDir(type), {}).then((res) => { - if (res.result) { - return res.result; - } else - throw res.error || 'unknown error'; - }); - }, - - readFile(type, filename) { - const callReadFile = rpc.declare({ - object: 'luci.fchomo', - method: 'file_read', - params: ['type', 'filename'], - expect: { '': {} } - }); - - return L.resolveDefault(callReadFile(type, filename), {}).then((res) => { - if (res.content ?? true) { - return res.content; - } else - throw res.error || 'unknown error'; - }); - }, - - writeFile(type, filename, content) { - const callWriteFile = rpc.declare({ - object: 'luci.fchomo', - method: 'file_write', - params: ['type', 'filename', 'content'], - expect: { '': {} } - }); - - return L.resolveDefault(callWriteFile(type, filename, content), {}).then((res) => { - if (res.result) { - return res.result; - } else - throw res.error || 'unknown error'; - }); - }, - - downloadFile(type, filename, url, header) { - const callDownloadFile = rpc.declare({ - object: 'luci.fchomo', - method: 'file_download', - params: ['type', 'filename', 'url', 'header'], - expect: { '': {} } - }); - - return L.resolveDefault(callDownloadFile(type, filename, url, header), {}).then((res) => { - if (res.result) { - return res.result; - } else - throw res.error || 'unknown error'; - }); - }, - - removeFile(type, filename) { - const callRemoveFile = rpc.declare({ - object: 'luci.fchomo', - method: 'file_remove', - params: ['type', 'filename'], - expect: { '': {} } - }); - - return L.resolveDefault(callRemoveFile(type, filename), {}).then((res) => { - if (res.result) { - return res.result; - } else - throw res.error || 'unknown error'; - }); - }, - - // thanks to homeproxy - uploadCertificate(type, filename, ev) { - const callWriteCertificate = rpc.declare({ - object: 'luci.fchomo', - method: 'certificate_write', - params: ['filename'], - expect: { '': {} } - }); - - return ui.uploadFile('/tmp/fchomo_certificate.tmp', ev.target) - .then(L.bind((btn, res) => { - return L.resolveDefault(callWriteCertificate(filename), {}).then((ret) => { - if (ret.result === true) - ui.addNotification(null, E('p', _('Your %s was successfully uploaded. Size: %sB.').format(type, res.size))); - else - ui.addNotification(null, E('p', _('Failed to upload %s, error: %s.').format(type, ret.error))); - }); - }, this, ev.target)) - .catch((e) => { ui.addNotification(null, E('p', e.message)) }); - }, - uploadInitialPack(ev, section_id) { - const callWriteInitialPack = rpc.declare({ - object: 'luci.fchomo', - method: 'initialpack_write', - expect: { '': {} } - }); - - return ui.uploadFile('/tmp/fchomo_initialpack.tmp', ev.target) - .then(L.bind((btn, res) => { - return L.resolveDefault(callWriteInitialPack(), {}).then((ret) => { - if (ret.result === true) { - ui.addNotification(null, E('p', _('Successfully uploaded.'))); - return window.location = window.location.href.split('#')[0]; - } else - ui.addNotification(null, E('p', _('Failed to upload, error: %s.').format(ret.error))); - }); - }, this, ev.target)) - .catch((e) => { ui.addNotification(null, E('p', e.message)) }); + switch (required_method) { + /* NONE */ + case 'none': + password = ''; + break; + /* UUID */ + case 'uuid': + password = generateRand('uuid'); + break; + /* DEFAULT */ + default: + password = generateRand('hex', 16); + break; } + /* AEAD */ + (function(length) { + if (length && length > 0) + password = generateRand('base64', length); + }(shadowsocks_cipher_length[required_method])); + + return widget.value = password; +} + +function handleReload(instance, ev, section_id) { + instance = instance || ''; + return fs.exec('/etc/init.d/fchomo', ['reload', instance]) + .then((res) => { /* return window.location = window.location.href.split('#')[0] */ }) + .catch((e) => { + ui.addNotification(null, E('p', _('Failed to execute "/etc/init.d/fchomo %s %s" reason: %s').format('reload', instance, e))) + }) +} + +function handleRemoveIdles() { + const section_type = this.sectiontype; + + let loaded = []; + uci.sections(this.config, section_type, (section, sid) => loaded.push(sid)); + + return lsDir(section_type).then((res) => { + let sectionEl = E('div', { class: 'cbi-section' }, []); + + res.filter(e => !loaded.includes(e)).forEach((filename) => { + sectionEl.appendChild(E('div', { class: 'cbi-value' }, [ + E('label', { + class: 'cbi-value-title', + id: 'rmidles.' + filename + '.label' + }, [ filename ]), + E('div', { class: 'cbi-value-field' }, [ + E('button', { + class: 'cbi-button cbi-button-negative important', + id: 'rmidles.' + filename + '.button', + click: ui.createHandlerFn(this, function(filename) { + return removeFile(section_type, filename).then((res) => { + let node = document.getElementById('rmidles.' + filename + '.label'); + node.innerHTML = '%s'.format(node.innerHTML); + node = document.getElementById('rmidles.' + filename + '.button'); + node.classList.add('hidden'); + }); + }, filename) + }, [ _('Remove') ]) + ]) + ])); + }); + + ui.showModal(_('Remove idles'), [ + sectionEl, + E('div', { class: 'right' }, [ + E('button', { + class: 'btn cbi-button-action', + click: ui.hideModal + }, [ _('Complete') ]) + ]) + ]); + }); +} + +function textvalue2Value(section_id) { + let cval = this.cfgvalue(section_id); + let i = this.keylist.indexOf(cval); + + return this.vallist[i]; +} + +function validateAuth(section_id, value) { + if (!value) + return true; + if (!value.match(/^[\w-]{3,}:[^:]+$/)) + return _('Expecting: %s').format('[A-Za-z0-9_-]{3,}:[^:]+'); + + return true; +} +function validateAuthUsername(section_id, value) { + if (!value) + return true; + if (!value.match(/^[\w-]{3,}$/)) + return _('Expecting: %s').format('[A-Za-z0-9_-]{3,}'); + + return true; +} +function validateAuthPassword(section_id, value) { + if (!value) + return true; + if (!value.match(/^[^:]+$/)) + return _('Expecting: %s').format('[^:]+'); + + return true; +} + +function validateCommonPort(section_id, value) { + // thanks to homeproxy + let stubValidator = { + factory: validation, + apply(type, value, args) { + if (value != null) + this.value = value; + + return validation.types[type].apply(this, args); + }, + assert(condition) { + return !!condition; + } + }; + + const arr = value.trim().split(' '); + + if (arr.length === 0 || arr.includes('')) + return _('Expecting: %s').format(_('non-empty value')); + + if (arr.length > 1 && arr.includes('all')) + return _('Expecting: %s').format(_('If All ports is selected, uncheck others')); + + for (let custom of arr) { + if (!routing_port_type.map(e => e[0]).includes(custom)) { + let ports = []; + for (let i of custom.split(',')) { + if (!stubValidator.apply('port', i) && !stubValidator.apply('portrange', i)) + return _('Expecting: %s').format(_('valid port value')); + if (ports.includes(i)) + return _('Port %s alrealy exists!').format(i); + ports = ports.concat(i); + } + } + } + + return true; +} + +function validateJson(section_id, value) { + if (!value) + return true; + + try { + let obj = JSON.parse(value.trim()); + if (!obj) + return _('Expecting: %s').format(_('valid JSON format')); + } + catch(e) { + return _('Expecting: %s').format(_('valid JSON format')); + } + + return true; +} + +function validateBase64Key(length, section_id, value) { + /* Thanks to luci-proto-wireguard */ + if (value) + if (value.length !== length || !value.match(/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/) || value[length-1] !== '=') + return _('Expecting: %s').format(_('valid base64 key with %d characters').format(length)); + + return true; +} + +function validateShadowsocksPassword(encmode, section_id, value) { + let length = shadowsocks_cipher_length[encmode]; + if (typeof length !== 'undefined') { + length = Math.ceil(length/3)*4; + if (encmode.match(/^2022-/)) { + return validateBase64Key(length, section_id, value); + } else { + if (length === 0 && !value) + return _('Expecting: %s').format(_('non-empty value')); + if (length !== 0 && value.length !== length) + return _('Expecting: %s').format(_('valid key length with %d characters').format(length)); + } + } else + return true; + + return true; +} + +function validateBytesize(section_id, value) { + if (!value) + return true; + + if (!value.match(/^(\d+)(k|m|g)?b?$/)) + return _('Expecting: %s').format('^(\\d+)(k|m|g)?b?$'); + + return true; +} +function validateTimeDuration(section_id, value) { + if (!value) + return true; + + if (!value.match(/^(\d+)(s|m|h|d)?$/)) + return _('Expecting: %s').format('^(\\d+)(s|m|h|d)?$'); + + return true; +} + +function validateUniqueValue(section_id, value) { + if (!value) + return _('Expecting: %s').format(_('non-empty value')); + + let duplicate = false; + uci.sections(this.config, this.section.sectiontype, (res) => { + if (res['.name'] !== section_id) + if (res[this.option] === value) + duplicate = true; + }); + if (duplicate) + return _('Expecting: %s').format(_('unique value')); + + return true; +} + +function validateUrl(section_id, value) { + if (!value) + return true; + + try { + let url = new URL(value); + if (!url.hostname) + return _('Expecting: %s').format(_('valid URL')); + } + catch(e) { + return _('Expecting: %s').format(_('valid URL')); + } + + return true; +} + +function validateUUID(section_id, value) { + if (!value) + return true; + else if (value.match('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') === null) + return _('Expecting: %s').format(_('valid uuid')); + + return true; +} + +function lsDir(type) { + const callLsDir = rpc.declare({ + object: 'luci.fchomo', + method: 'dir_ls', + params: ['type'], + expect: { '': {} } + }); + + return L.resolveDefault(callLsDir(type), {}).then((res) => { + if (res.result) { + return res.result; + } else + throw res.error || 'unknown error'; + }); +} + +function readFile(type, filename) { + const callReadFile = rpc.declare({ + object: 'luci.fchomo', + method: 'file_read', + params: ['type', 'filename'], + expect: { '': {} } + }); + + return L.resolveDefault(callReadFile(type, filename), {}).then((res) => { + if (res.content ?? true) { + return res.content; + } else + throw res.error || 'unknown error'; + }); +} + +function writeFile(type, filename, content) { + const callWriteFile = rpc.declare({ + object: 'luci.fchomo', + method: 'file_write', + params: ['type', 'filename', 'content'], + expect: { '': {} } + }); + + return L.resolveDefault(callWriteFile(type, filename, content), {}).then((res) => { + if (res.result) { + return res.result; + } else + throw res.error || 'unknown error'; + }); +} + +function downloadFile(type, filename, url, header) { + const callDownloadFile = rpc.declare({ + object: 'luci.fchomo', + method: 'file_download', + params: ['type', 'filename', 'url', 'header'], + expect: { '': {} } + }); + + return L.resolveDefault(callDownloadFile(type, filename, url, header), {}).then((res) => { + if (res.result) { + return res.result; + } else + throw res.error || 'unknown error'; + }); +} + +function removeFile(type, filename) { + const callRemoveFile = rpc.declare({ + object: 'luci.fchomo', + method: 'file_remove', + params: ['type', 'filename'], + expect: { '': {} } + }); + + return L.resolveDefault(callRemoveFile(type, filename), {}).then((res) => { + if (res.result) { + return res.result; + } else + throw res.error || 'unknown error'; + }); +} + +// thanks to homeproxy +function uploadCertificate(type, filename, ev) { + const callWriteCertificate = rpc.declare({ + object: 'luci.fchomo', + method: 'certificate_write', + params: ['filename'], + expect: { '': {} } + }); + + return ui.uploadFile('/tmp/fchomo_certificate.tmp', ev.target) + .then(L.bind((btn, res) => { + return L.resolveDefault(callWriteCertificate(filename), {}).then((ret) => { + if (ret.result === true) + ui.addNotification(null, E('p', _('Your %s was successfully uploaded. Size: %sB.').format(type, res.size))); + else + ui.addNotification(null, E('p', _('Failed to upload %s, error: %s.').format(type, ret.error))); + }); + }, this, ev.target)) + .catch((e) => { ui.addNotification(null, E('p', e.message)) }); +} +function uploadInitialPack(ev, section_id) { + const callWriteInitialPack = rpc.declare({ + object: 'luci.fchomo', + method: 'initialpack_write', + expect: { '': {} } + }); + + return ui.uploadFile('/tmp/fchomo_initialpack.tmp', ev.target) + .then(L.bind((btn, res) => { + return L.resolveDefault(callWriteInitialPack(), {}).then((ret) => { + if (ret.result === true) { + ui.addNotification(null, E('p', _('Successfully uploaded.'))); + return window.location = window.location.href.split('#')[0]; + } else + ui.addNotification(null, E('p', _('Failed to upload, error: %s.').format(ret.error))); + }); + }, this, ev.target)) + .catch((e) => { ui.addNotification(null, E('p', e.message)) }); +} + +return baseclass.extend({ + /* Member */ + rulesetdoc, + sharktaikogif, + monospacefonts, + dashrepos, + dashrepos_urlparams, + checkurls, + health_checkurls, + inbound_type, + ip_version, + load_balance_strategy, + outbound_type, + preset_outbound, + proxy_group_type, + routing_port_type, + rules_type, + rules_logical_type, + rules_logical_payload_count, + shadowsocks_cipher_methods, + shadowsocks_cipher_length, + stunserver, + tls_client_fingerprints, + + /* Prototype */ + GenValue: CBIGenValue, + ListValue: CBIListValue, + StaticList: CBIStaticList, + TextValue: CBITextValue, + + /* Method */ + calcStringMD5, + decodeBase64Str, + generateRand, + isEmpty, + removeBlankAttrs, + getFeatures, + getServiceStatus, + getClashAPI, + loadDefaultLabel, + loadModalTitle, + loadProxyGroupLabel, + loadNodeLabel, + loadProviderLabel, + loadRulesetLabel, + loadSubRuleGroup, + renderStatus, + updateStatus, + getDashURL, + renderResDownload, + renderSectionAdd, + handleAdd, + handleGenKey, + handleReload, + handleRemoveIdles, + textvalue2Value, + validateAuth, + validateAuthUsername, + validateAuthPassword, + validateCommonPort, + validateJson, + validateBase64Key, + validateShadowsocksPassword, + validateBytesize, + validateTimeDuration, + validateUniqueValue, + validateUrl, + validateUUID, + lsDir, + readFile, + writeFile, + downloadFile, + removeFile, + uploadCertificate, + uploadInitialPack, }); 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 2f18ada714..5086644dcb 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 @@ -165,7 +165,7 @@ class RulesEntry { factor = [{type: 'MATCH'}]; } - rule = hm.removeBlankAttrs(hm, { + rule = hm.removeBlankAttrs({ type: this.type, payload: factor, detour: detour || null, @@ -366,7 +366,7 @@ function renderPayload(s, total, uciconfig) { Object.keys(extenbox).forEach((n) => { prefix = `payload${n}_`; - o = s.option(hm.CBIStaticList, prefix + 'type', _('Type') + ' ++'); + o = s.option(hm.StaticList, prefix + 'type', _('Type') + ' ++'); o.default = hm.rules_type[0][0]; hm.rules_type.forEach((res) => { o.value.apply(o, res); @@ -411,7 +411,7 @@ function renderPayload(s, total, uciconfig) { return new RulesEntry(uci.get(uciconfig, section_id, 'entry')).getPayloads().slice(n).map(e => e[key] ?? ''); }, o, n, 'factor', uciconfig) - o = s.option(hm.CBIStaticList, prefix + 'NOTs', _('NOT') + ' ++', + o = s.option(hm.StaticList, prefix + 'NOTs', _('NOT') + ' ++', _('0 or 1 only.')); o.value('0'); o.value('1'); @@ -508,7 +508,7 @@ function renderRules(s, uciconfig) { renderPayload(s, Math.max(...Object.values(hm.rules_logical_payload_count).map(e => e.low)), uciconfig); - o = s.option(hm.CBIListValue, 'detour', _('Proxy group')); + o = s.option(hm.ListValue, 'detour', _('Proxy group')); o.load = function(section_id) { hm.loadProxyGroupLabel.call(this, hm.preset_outbound.full, section_id); @@ -577,15 +577,15 @@ return view.extend({ s = m.section(form.TypedSection); s.render = function () { - poll.add(function () { + poll.add(function() { return hm.getServiceStatus('mihomo-c').then((isRunning) => { - hm.updateStatus(hm, document.getElementById('_client_bar'), isRunning ? { dashboard_repo: dashboard_repo } : false, 'mihomo-c', true); + hm.updateStatus(document.getElementById('_client_bar'), isRunning ? { dashboard_repo: dashboard_repo } : false, 'mihomo-c', true); }); }); return E('div', { class: 'cbi-section' }, [ E('p', [ - hm.renderStatus(hm, '_client_bar', false, 'mihomo-c', true) + hm.renderStatus('_client_bar', false, 'mihomo-c', true) ]) ]); } @@ -1010,7 +1010,7 @@ return view.extend({ so.rmempty = false; so.modalonly = true; - so = ss.option(hm.CBIListValue, 'detour', _('Proxy group')); + so = ss.option(hm.ListValue, 'detour', _('Proxy group')); so.load = function(section_id) { hm.loadProxyGroupLabel.call(this, hm.preset_outbound.dns, section_id); @@ -1142,7 +1142,7 @@ return view.extend({ so.rmempty = false; so.editable = true; - so = ss.option(hm.CBIListValue, 'proxy', _('Proxy group override'), + so = ss.option(hm.ListValue, 'proxy', _('Proxy group override'), _('Override the Proxy group of DNS server.')); so.default = hm.preset_outbound.direct[0][0]; hm.preset_outbound.direct.forEach((res) => { 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 675e94a7dd..a6b1aabb2e 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 @@ -195,18 +195,18 @@ return view.extend({ } so = ss.option(form.DummyValue, '_client_status', _('Client status')); - so.cfgvalue = function() { return hm.renderStatus(hm, '_client_bar', CisRunning ? { ...CclashAPI, dashboard_repo: dashboard_repo } : false, 'mihomo-c') } + so.cfgvalue = function() { return hm.renderStatus('_client_bar', CisRunning ? { ...CclashAPI, dashboard_repo: dashboard_repo } : false, 'mihomo-c') } poll.add(function() { return hm.getServiceStatus('mihomo-c').then((isRunning) => { - hm.updateStatus(hm, document.getElementById('_client_bar'), isRunning ? { dashboard_repo: dashboard_repo } : false, 'mihomo-c'); + hm.updateStatus(document.getElementById('_client_bar'), isRunning ? { dashboard_repo: dashboard_repo } : false, 'mihomo-c'); }); }) so = ss.option(form.DummyValue, '_server_status', _('Server status')); - so.cfgvalue = function() { return hm.renderStatus(hm, '_server_bar', SisRunning ? { ...SclashAPI, dashboard_repo: dashboard_repo } : false, 'mihomo-s') } + so.cfgvalue = function() { return hm.renderStatus('_server_bar', SisRunning ? { ...SclashAPI, dashboard_repo: dashboard_repo } : false, 'mihomo-s') } poll.add(function() { return hm.getServiceStatus('mihomo-s').then((isRunning) => { - hm.updateStatus(hm, document.getElementById('_server_bar'), isRunning ? { dashboard_repo: dashboard_repo } : false, 'mihomo-s'); + hm.updateStatus(document.getElementById('_server_bar'), isRunning ? { dashboard_repo: dashboard_repo } : false, 'mihomo-s'); }); }) @@ -774,7 +774,7 @@ return view.extend({ /* Custom Direct list */ ss.tab('direct_list', _('Custom Direct List')); - so = ss.taboption('direct_list', hm.CBITextValue, 'direct_list.yaml', null); + so = ss.taboption('direct_list', hm.TextValue, 'direct_list.yaml', null); so.rows = 20; so.default = 'FQDN:\nIPCIDR:\nIPCIDR6:\n'; so.placeholder = "FQDN:\n- mask.icloud.com\n- mask-h2.icloud.com\n- mask.apple-dns.net\nIPCIDR:\n- '223.0.0.0/12'\nIPCIDR6:\n- '2400:3200::/32'\n"; @@ -792,7 +792,7 @@ return view.extend({ /* Custom Proxy list */ ss.tab('proxy_list', _('Custom Proxy List')); - so = ss.taboption('proxy_list', hm.CBITextValue, 'proxy_list.yaml', null); + so = ss.taboption('proxy_list', hm.TextValue, 'proxy_list.yaml', null); so.rows = 20; so.default = 'FQDN:\nIPCIDR:\nIPCIDR6:\n'; so.placeholder = "FQDN:\n- www.google.com\nIPCIDR:\n- '91.105.192.0/23'\nIPCIDR6:\n- '2001:67c:4e8::/48'\n"; diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/hosts.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/hosts.js index 5a5f322d9f..9bbd6eb981 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/hosts.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/hosts.js @@ -14,10 +14,10 @@ return view.extend({ handleSave(ev) { let value = (document.querySelector('textarea').value || '').trim().replace(/\r\n/g, '\n') + '\n'; - return hm.writeFile('templates', 'hosts.yaml', value).then(function(rc) { + return hm.writeFile('templates', 'hosts.yaml', value).then((rc) => { document.querySelector('textarea').value = value; ui.addNotification(null, E('p', _('Contents have been saved.')), 'info'); - }).catch(function(e) { + }).catch((e) => { ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e))); }); }, diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/log.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/log.js index bceb08e871..b6a31cf697 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/log.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/log.js @@ -42,13 +42,13 @@ function getRuntimeLog(name, filename) { let log; poll.add(L.bind(function() { return fs.read_direct(String.format('%s/%s.log', hm_dir, filename), 'text') - .then(function(res) { + .then((res) => { log = E('pre', { 'wrap': 'pre' }, [ res.trim() || _('Log is empty.') ]); dom.content(log_textarea, log); - }).catch(function(err) { + }).catch((err) => { if (err.toString().includes('NotFoundError')) log = E('pre', { 'wrap': 'pre' }, [ _('Log file does not exist.') diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js index 19bd17ca0d..33c7dccdc4 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/node.js @@ -81,7 +81,7 @@ return view.extend({ so.depends({type: /^(http|socks5|mieru|trojan|hysteria2|tuic|ssh)$/}); so.modalonly = true; - so = ss.taboption('field_general', hm.CBITextValue, 'headers', _('HTTP header')); + so = ss.taboption('field_general', hm.TextValue, 'headers', _('HTTP header')); so.placeholder = '{\n "User-Agent": [\n "Clash/v1.18.0",\n "mihomo/1.18.3"\n ],\n "Authorization": [\n //"token 1231231"\n ]\n}'; so.validate = L.bind(hm.validateJson, so); so.depends('type', 'http'); @@ -152,7 +152,7 @@ return view.extend({ so.password = true; so.validate = function(section_id, value) { const encmode = this.section.getOption('shadowsocks_chipher').formvalue(section_id); - return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value); + return hm.validateShadowsocksPassword.call(this, encmode, section_id, value); } so.depends({type: 'ss', shadowsocks_chipher: /.+/}); so.modalonly = true; @@ -279,7 +279,7 @@ return view.extend({ so.password = true; so.validate = function(section_id, value) { const encmode = this.section.getOption('trojan_ss_chipher').formvalue(section_id); - return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value); + return hm.validateShadowsocksPassword.call(this, encmode, section_id, value); } so.depends({type: 'trojan', trojan_ss_enabled: '1'}); so.modalonly = true; @@ -639,7 +639,7 @@ return view.extend({ so.depends({transport_enabled: '1', transport_type: /^(h2|ws)$/}); so.modalonly = true; - so = ss.taboption('field_transport', hm.CBITextValue, 'transport_http_headers', _('HTTP header')); + so = ss.taboption('field_transport', hm.TextValue, 'transport_http_headers', _('HTTP header')); so.placeholder = '{\n "Host": "example.com",\n "Connection": [\n "keep-alive"\n ]\n}'; so.validate = L.bind(hm.validateJson, so); so.depends({transport_enabled: '1', transport_type: /^(http|ws)$/}); @@ -798,7 +798,7 @@ return view.extend({ el.appendChild(E('button', { 'class': 'cbi-button cbi-button-add', 'title': _('Remove idles'), - 'click': ui.createHandlerFn(this, hm.handleRemoveIdles, hm) + 'click': ui.createHandlerFn(this, hm.handleRemoveIdles) }, [ _('Remove idles') ])); return el; @@ -843,7 +843,7 @@ return view.extend({ } so.modalonly = false; - so = ss.taboption('field_general', hm.CBITextValue, '_editer', _('Editer'), + so = ss.taboption('field_general', hm.TextValue, '_editer', _('Editer'), _('Please type %s.') .format('https://wiki.metacubex.one/config/proxy-providers/content/', _('Contents'))); so.placeholder = _('Content will not be verified, Please make sure you enter it correctly.'); @@ -857,7 +857,7 @@ return view.extend({ so.depends('type', 'file'); so.modalonly = true; - so = ss.taboption('field_general', hm.CBITextValue, 'payload', 'payload:', + so = ss.taboption('field_general', hm.TextValue, 'payload', 'payload:', _('Please type %s.') .format('https://wiki.metacubex.one/config/proxy-providers/content/', _('Payload'))); so.placeholder = '- name: "ss1"\n type: ss\n server: server\n port: 443\n cipher: chacha20-ietf-poly1305\n password: "password"\n# ' + _('Content will not be verified, Please make sure you enter it correctly.'); @@ -894,7 +894,7 @@ return view.extend({ //so.editable = true; so.depends('type', 'http'); - so = ss.taboption('field_general', hm.CBITextValue, 'header', _('HTTP header'), + so = ss.taboption('field_general', hm.TextValue, 'header', _('HTTP header'), _('Custom HTTP header.')); so.placeholder = '{\n "User-Agent": [\n "Clash/v1.18.0",\n "mihomo/1.18.3"\n ],\n "Accept": [\n //"application/vnd.github.v3.raw"\n ],\n "Authorization": [\n //"token 1231231"\n ]\n}'; so.validate = L.bind(hm.validateJson, so); @@ -1041,7 +1041,7 @@ return view.extend({ so.modalonly = true; so = ss.option(form.DummyValue, '_update'); - so.cfgvalue = L.bind(hm.renderResDownload, so, hm); + so.cfgvalue = L.bind(hm.renderResDownload, so); so.editable = true; so.modalonly = false; /* Provider END */ diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/ruleset.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/ruleset.js index f71d23588c..6c89cdca41 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/ruleset.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/ruleset.js @@ -162,7 +162,7 @@ return view.extend({ .then(L.bind(this.map.load, this.map)) .then(L.bind(this.map.reset, this.map)) .then(L.ui.hideModal) - .catch(function() {}); + .catch(() => {}); } else { return ui.hideModal(); } @@ -183,7 +183,7 @@ return view.extend({ el.appendChild(E('button', { 'class': 'cbi-button cbi-button-add', 'title': _('Remove idles'), - 'click': ui.createHandlerFn(this, hm.handleRemoveIdles, hm) + 'click': ui.createHandlerFn(this, hm.handleRemoveIdles) }, [ _('Remove idles') ])); return el; @@ -260,7 +260,7 @@ return view.extend({ } o.modalonly = false; - o = s.option(hm.CBITextValue, '_editer', _('Editer'), + o = s.option(hm.TextValue, '_editer', _('Editer'), _('Please type %s.') .format('https://wiki.metacubex.one/config/rule-providers/content/', _('Contents'))); o.placeholder = _('Content will not be verified, Please make sure you enter it correctly.'); @@ -274,7 +274,7 @@ return view.extend({ o.depends({'type': 'file', 'format': /^(text|yaml)$/}); o.modalonly = true; - o = s.option(hm.CBITextValue, 'payload', 'payload:', + o = s.option(hm.TextValue, 'payload', 'payload:', _('Please type %s.') .format('https://wiki.metacubex.one/config/rule-providers/content/', _('Payload'))); o.placeholder = '- DOMAIN-SUFFIX,google.com\n# ' + _('Content will not be verified, Please make sure you enter it correctly.'); @@ -312,7 +312,7 @@ return view.extend({ o.depends('type', 'http'); o = s.option(form.DummyValue, '_update'); - o.cfgvalue = L.bind(hm.renderResDownload, o, hm); + o.cfgvalue = L.bind(hm.renderResDownload, o); o.editable = true; o.modalonly = false; /* Rule set END */ diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/server.js b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/server.js index ff0d5f45ce..a3da3ede0b 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/server.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/view/fchomo/server.js @@ -7,56 +7,6 @@ 'require fchomo as hm'; -function handleGenKey(option) { - const section_id = this.section.section; - const type = this.section.getOption('type').formvalue(section_id); - let widget = this.map.findElement('id', 'widget.cbid.fchomo.%s.%s'.format(section_id, option)); - let password, required_method; - - if (option === 'uuid' || option.match(/_uuid/)) - required_method = 'uuid'; - else if (type === 'shadowsocks') - required_method = this.section.getOption('shadowsocks_chipher')?.formvalue(section_id); - - switch (required_method) { - /* NONE */ - case 'none': - password = ''; - break; - /* UUID */ - case 'uuid': - password = hm.generateRand('uuid'); - break; - /* DEFAULT */ - default: - password = hm.generateRand('hex', 16); - break; - } - /* AEAD */ - (function(length) { - if (length && length > 0) - password = hm.generateRand('base64', length); - }(hm.shadowsocks_cipher_length[required_method])); - - return widget.value = password; -} - -const CBIPWGenValue = form.Value.extend({ - __name__: 'CBI.PWGenValue', - - renderWidget() { - let node = form.Value.prototype.renderWidget.apply(this, arguments); - - (node.querySelector('.control-group') || node).appendChild(E('button', { - 'class': 'cbi-button cbi-button-add', - 'title': _('Generate'), - 'click': ui.createHandlerFn(this, handleGenKey, this.option) - }, [ _('Generate') ])); - - return node; - } -}); - return view.extend({ load() { return Promise.all([ @@ -76,15 +26,15 @@ return view.extend({ s = m.section(form.TypedSection); s.render = function () { - poll.add(function () { + poll.add(function() { return hm.getServiceStatus('mihomo-s').then((isRunning) => { - hm.updateStatus(hm, document.getElementById('_server_bar'), isRunning ? { dashboard_repo: dashboard_repo } : false, 'mihomo-s', true); + hm.updateStatus(document.getElementById('_server_bar'), isRunning ? { dashboard_repo: dashboard_repo } : false, 'mihomo-s', true); }); }); return E('div', { class: 'cbi-section' }, [ E('p', [ - hm.renderStatus(hm, '_server_bar', false, 'mihomo-s', true) + hm.renderStatus('_server_bar', false, 'mihomo-s', true) ]) ]); } @@ -151,7 +101,7 @@ return view.extend({ o.depends({type: /^(http|socks|mixed|hysteria2)$/}); o.modalonly = true; - o = s.option(CBIPWGenValue, 'password', _('Password')); + o = s.option(hm.GenValue, 'password', _('Password')); o.password = true; o.validate = L.bind(hm.validateAuthPassword, o); o.rmempty = false; @@ -184,7 +134,7 @@ return view.extend({ o.depends('type', 'hysteria2'); o.modalonly = true; - o = s.option(CBIPWGenValue, 'hysteria_obfs_password', _('Obfuscate password'), + o = s.option(hm.GenValue, 'hysteria_obfs_password', _('Obfuscate password'), _('Enabling obfuscation will make the server incompatible with standard QUIC connections, losing the ability to masquerade with HTTP/3.')); o.password = true; o.rmempty = false; @@ -207,17 +157,17 @@ return view.extend({ o.depends('type', 'shadowsocks'); o.modalonly = true; - o = s.option(CBIPWGenValue, 'shadowsocks_password', _('Password')); + o = s.option(hm.GenValue, 'shadowsocks_password', _('Password')); o.password = true; o.validate = function(section_id, value) { const encmode = this.section.getOption('shadowsocks_chipher').formvalue(section_id); - return hm.validateShadowsocksPassword.call(this, hm, encmode, section_id, value); + return hm.validateShadowsocksPassword.call(this, encmode, section_id, value); } o.depends({type: 'shadowsocks', shadowsocks_chipher: /.+/}); o.modalonly = true; /* Tuic fields */ - o = s.option(CBIPWGenValue, 'uuid', _('UUID')); + o = s.option(hm.GenValue, 'uuid', _('UUID')); o.rmempty = false; o.validate = L.bind(hm.validateUUID, o); o.depends('type', 'tuic'); @@ -253,7 +203,7 @@ return view.extend({ o.modalonly = true; /* VMess fields */ - o = s.option(CBIPWGenValue, 'vmess_uuid', _('UUID')); + o = s.option(hm.GenValue, 'vmess_uuid', _('UUID')); o.rmempty = false; o.validate = L.bind(hm.validateUUID, o); o.depends('type', 'vmess'); diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/scripts/generate_client.uc b/small/luci-app-homeproxy/root/etc/homeproxy/scripts/generate_client.uc index 38c8177d34..c56998afcc 100755 --- a/small/luci-app-homeproxy/root/etc/homeproxy/scripts/generate_client.uc +++ b/small/luci-app-homeproxy/root/etc/homeproxy/scripts/generate_client.uc @@ -392,8 +392,7 @@ if (!isEmpty(main_node)) { if (length(direct_domain_list)) push(config.dns.rules, { rule_set: 'direct-domain', - server: (routing_mode === 'bypass_mainland_china' ) ? 'china-dns' : 'default-dns', - address_resolver: 'default-dns' + server: (routing_mode === 'bypass_mainland_china' ) ? 'china-dns' : 'default-dns' }); /* Filter out SVCB/HTTPS queries for "exquisite" Apple devices */ @@ -408,6 +407,7 @@ if (!isEmpty(main_node)) { push(config.dns.servers, { tag: 'china-dns', address: china_dns_server, + address_resolver: 'default-dns', detour: 'direct-out' }); diff --git a/v2ray-core/app/commander/commander.go b/v2ray-core/app/commander/commander.go index 8b1ca61aa1..76163c292e 100644 --- a/v2ray-core/app/commander/commander.go +++ b/v2ray-core/app/commander/commander.go @@ -4,6 +4,7 @@ package commander import ( "context" + "github.com/v2fly/v2ray-core/v5/features" "net" "sync" @@ -17,6 +18,12 @@ import ( "github.com/v2fly/v2ray-core/v5/infra/conf/v5cfg" ) +type CommanderIfce interface { + features.Feature + + ExtractGrpcServer() *grpc.Server +} + // Commander is a V2Ray feature that provides gRPC methods to external clients. type Commander struct { sync.Mutex @@ -57,7 +64,7 @@ func NewCommander(ctx context.Context, config *Config) (*Commander, error) { // Type implements common.HasType. func (c *Commander) Type() interface{} { - return (*Commander)(nil) + return (*CommanderIfce)(nil) } // Start implements common.Runnable. @@ -103,6 +110,14 @@ func (c *Commander) Close() error { return nil } +// ExtractGrpcServer extracts the gRPC server from Commander. +// Private function for core code base. +func (c *Commander) ExtractGrpcServer() *grpc.Server { + c.Lock() + defer c.Unlock() + return c.server +} + func init() { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) { return NewCommander(ctx, cfg.(*Config)) diff --git a/v2ray-core/app/commander/config.pb.go b/v2ray-core/app/commander/config.pb.go index bac9fa6bf2..bd420502c8 100644 --- a/v2ray-core/app/commander/config.pb.go +++ b/v2ray-core/app/commander/config.pb.go @@ -18,24 +18,21 @@ const ( // Config is the settings for Commander. type Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Tag of the outbound handler that handles grpc connections. Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` // Services that supported by this server. All services must implement Service // interface. - Service []*anypb.Any `protobuf:"bytes,2,rep,name=service,proto3" json:"service,omitempty"` + Service []*anypb.Any `protobuf:"bytes,2,rep,name=service,proto3" json:"service,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Config) Reset() { *x = Config{} - if protoimpl.UnsafeEnabled { - mi := &file_app_commander_config_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_app_commander_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Config) String() string { @@ -46,7 +43,7 @@ func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { mi := &file_app_commander_config_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -77,18 +74,16 @@ func (x *Config) GetService() []*anypb.Any { // ReflectionConfig is the placeholder config for ReflectionService. type ReflectionConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ReflectionConfig) Reset() { *x = ReflectionConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_app_commander_config_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_app_commander_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ReflectionConfig) String() string { @@ -99,7 +94,7 @@ func (*ReflectionConfig) ProtoMessage() {} func (x *ReflectionConfig) ProtoReflect() protoreflect.Message { mi := &file_app_commander_config_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -115,21 +110,18 @@ func (*ReflectionConfig) Descriptor() ([]byte, []int) { } type SimplifiedConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + Name []string `protobuf:"bytes,2,rep,name=name,proto3" json:"name,omitempty"` unknownFields protoimpl.UnknownFields - - Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` - Name []string `protobuf:"bytes,2,rep,name=name,proto3" json:"name,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SimplifiedConfig) Reset() { *x = SimplifiedConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_app_commander_config_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_app_commander_config_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SimplifiedConfig) String() string { @@ -140,7 +132,7 @@ func (*SimplifiedConfig) ProtoMessage() {} func (x *SimplifiedConfig) ProtoReflect() protoreflect.Message { mi := &file_app_commander_config_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -215,7 +207,7 @@ func file_app_commander_config_proto_rawDescGZIP() []byte { } var file_app_commander_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_app_commander_config_proto_goTypes = []interface{}{ +var file_app_commander_config_proto_goTypes = []any{ (*Config)(nil), // 0: v2ray.core.app.commander.Config (*ReflectionConfig)(nil), // 1: v2ray.core.app.commander.ReflectionConfig (*SimplifiedConfig)(nil), // 2: v2ray.core.app.commander.SimplifiedConfig @@ -235,44 +227,6 @@ func file_app_commander_config_proto_init() { if File_app_commander_config_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_app_commander_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Config); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_app_commander_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReflectionConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_app_commander_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SimplifiedConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/v2ray-core/app/commander/outbound.go b/v2ray-core/app/commander/outbound.go index c7dde67e68..253a36d21c 100644 --- a/v2ray-core/app/commander/outbound.go +++ b/v2ray-core/app/commander/outbound.go @@ -10,6 +10,13 @@ import ( "github.com/v2fly/v2ray-core/v5/transport" ) +func NewOutboundListener() *OutboundListener { + return &OutboundListener{ + buffer: make(chan net.Conn, 4), + done: done.New(), + } +} + // OutboundListener is a net.Listener for listening gRPC connections. type OutboundListener struct { buffer chan net.Conn @@ -59,6 +66,13 @@ func (l *OutboundListener) Addr() net.Addr { } } +func NewOutbound(tag string, listener *OutboundListener) *Outbound { + return &Outbound{ + tag: tag, + listener: listener, + } +} + // Outbound is a outbound.Handler that handles gRPC connections. type Outbound struct { tag string diff --git a/v2ray-core/app/commander/webcommander/config.pb.go b/v2ray-core/app/commander/webcommander/config.pb.go new file mode 100644 index 0000000000..857e206747 --- /dev/null +++ b/v2ray-core/app/commander/webcommander/config.pb.go @@ -0,0 +1,166 @@ +package webcommander + +import ( + _ "github.com/v2fly/v2ray-core/v5/common/protoext" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Config struct { + state protoimpl.MessageState `protogen:"open.v1"` + Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` + WebRoot []byte `protobuf:"bytes,2,opt,name=web_root,json=webRoot,proto3" json:"web_root,omitempty"` + WebRootFile string `protobuf:"bytes,96002,opt,name=web_root_file,json=webRootFile,proto3" json:"web_root_file,omitempty"` + ApiMountpoint string `protobuf:"bytes,3,opt,name=api_mountpoint,json=apiMountpoint,proto3" json:"api_mountpoint,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Config) Reset() { + *x = Config{} + mi := &file_app_commander_webcommander_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Config) ProtoMessage() {} + +func (x *Config) ProtoReflect() protoreflect.Message { + mi := &file_app_commander_webcommander_config_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Config.ProtoReflect.Descriptor instead. +func (*Config) Descriptor() ([]byte, []int) { + return file_app_commander_webcommander_config_proto_rawDescGZIP(), []int{0} +} + +func (x *Config) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +func (x *Config) GetWebRoot() []byte { + if x != nil { + return x.WebRoot + } + return nil +} + +func (x *Config) GetWebRootFile() string { + if x != nil { + return x.WebRootFile + } + return "" +} + +func (x *Config) GetApiMountpoint() string { + if x != nil { + return x.ApiMountpoint + } + return "" +} + +var File_app_commander_webcommander_config_proto protoreflect.FileDescriptor + +var file_app_commander_webcommander_config_proto_rawDesc = []byte{ + 0x0a, 0x27, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2f, + 0x77, 0x65, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x65, 0x72, 0x2e, 0x77, 0x65, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, + 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65, 0x78, + 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0xaf, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, + 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, + 0x19, 0x0a, 0x08, 0x77, 0x65, 0x62, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x77, 0x65, 0x62, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x34, 0x0a, 0x0d, 0x77, 0x65, + 0x62, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x82, 0xee, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x0e, 0x82, 0xb5, 0x18, 0x0a, 0x22, 0x08, 0x77, 0x65, 0x62, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x52, 0x0b, 0x77, 0x65, 0x62, 0x52, 0x6f, 0x6f, 0x74, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x70, 0x69, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x70, 0x69, 0x4d, 0x6f, 0x75, + 0x6e, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x1b, 0x82, 0xb5, 0x18, 0x17, 0x0a, 0x07, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x0c, 0x77, 0x65, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x65, 0x72, 0x42, 0x90, 0x01, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, + 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x77, 0x65, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x65, 0x72, 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, + 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x65, 0x72, 0x2f, 0x77, 0x65, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0xaa, + 0x02, 0x25, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x2e, 0x57, 0x65, 0x62, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_app_commander_webcommander_config_proto_rawDescOnce sync.Once + file_app_commander_webcommander_config_proto_rawDescData = file_app_commander_webcommander_config_proto_rawDesc +) + +func file_app_commander_webcommander_config_proto_rawDescGZIP() []byte { + file_app_commander_webcommander_config_proto_rawDescOnce.Do(func() { + file_app_commander_webcommander_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_commander_webcommander_config_proto_rawDescData) + }) + return file_app_commander_webcommander_config_proto_rawDescData +} + +var file_app_commander_webcommander_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_app_commander_webcommander_config_proto_goTypes = []any{ + (*Config)(nil), // 0: v2ray.core.app.commander.webcommander.Config +} +var file_app_commander_webcommander_config_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_app_commander_webcommander_config_proto_init() } +func file_app_commander_webcommander_config_proto_init() { + if File_app_commander_webcommander_config_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_app_commander_webcommander_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_app_commander_webcommander_config_proto_goTypes, + DependencyIndexes: file_app_commander_webcommander_config_proto_depIdxs, + MessageInfos: file_app_commander_webcommander_config_proto_msgTypes, + }.Build() + File_app_commander_webcommander_config_proto = out.File + file_app_commander_webcommander_config_proto_rawDesc = nil + file_app_commander_webcommander_config_proto_goTypes = nil + file_app_commander_webcommander_config_proto_depIdxs = nil +} diff --git a/v2ray-core/app/commander/webcommander/config.proto b/v2ray-core/app/commander/webcommander/config.proto new file mode 100644 index 0000000000..6118867bf4 --- /dev/null +++ b/v2ray-core/app/commander/webcommander/config.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package v2ray.core.app.commander.webcommander; +option csharp_namespace = "V2Ray.Core.App.Commander.WebCommander"; +option go_package = "github.com/v2fly/v2ray-core/v5/app/commander/webcommander"; +option java_package = "com.v2ray.core.app.commander.webcommander"; +option java_multiple_files = true; + +import "common/protoext/extensions.proto"; + +message Config { + option (v2ray.core.common.protoext.message_opt).type = "service"; + option (v2ray.core.common.protoext.message_opt).short_name = "webcommander"; + + string tag = 1; + + bytes web_root = 2; + string web_root_file = 96002 [(v2ray.core.common.protoext.field_opt).convert_time_read_file_into = "web_root"]; + + string api_mountpoint = 3; +} \ No newline at end of file diff --git a/v2ray-core/app/commander/webcommander/errors.generated.go b/v2ray-core/app/commander/webcommander/errors.generated.go new file mode 100644 index 0000000000..53c265c87d --- /dev/null +++ b/v2ray-core/app/commander/webcommander/errors.generated.go @@ -0,0 +1,9 @@ +package webcommander + +import "github.com/v2fly/v2ray-core/v5/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/v2ray-core/app/commander/webcommander/webcommander.go b/v2ray-core/app/commander/webcommander/webcommander.go new file mode 100644 index 0000000000..251b518d89 --- /dev/null +++ b/v2ray-core/app/commander/webcommander/webcommander.go @@ -0,0 +1,148 @@ +package webcommander + +import ( + "archive/zip" + "bytes" + "context" + "io/fs" + "net/http" + "strings" + "sync" + "time" + + "github.com/improbable-eng/grpc-web/go/grpcweb" + "google.golang.org/grpc" + + core "github.com/v2fly/v2ray-core/v5" + "github.com/v2fly/v2ray-core/v5/app/commander" + "github.com/v2fly/v2ray-core/v5/common" + "github.com/v2fly/v2ray-core/v5/features/outbound" +) + +//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen + +func newWebCommander(ctx context.Context, config *Config) (*WebCommander, error) { + if config == nil { + return nil, newError("config is nil") + } + if config.Tag == "" { + return nil, newError("config.Tag is empty") + } + var webRootfs fs.FS + if config.WebRoot != nil { + zipReader, err := zip.NewReader(bytes.NewReader(config.WebRoot), int64(len(config.WebRoot))) + if err != nil { + return nil, newError("failed to create zip reader").Base(err) + } + webRootfs = zipReader + } + + return &WebCommander{ctx: ctx, config: config, webRootfs: webRootfs}, nil + +} + +type WebCommander struct { + sync.Mutex + + ctx context.Context + ohm outbound.Manager + cm commander.CommanderIfce + + server *http.Server + wrappedGrpc *grpcweb.WrappedGrpcServer + webRootfs fs.FS + + config *Config +} + +func (w *WebCommander) ServeHTTP(writer http.ResponseWriter, request *http.Request) { + api_path := w.config.ApiMountpoint + if strings.HasPrefix(request.URL.Path, api_path) { + request.URL.Path = strings.TrimPrefix(request.URL.Path, api_path) + if w.wrappedGrpc.IsGrpcWebRequest(request) { + w.wrappedGrpc.ServeHTTP(writer, request) + return + } + } + if w.webRootfs != nil { + http.ServeFileFS(writer, request, w.webRootfs, request.URL.Path) + return + } + writer.WriteHeader(http.StatusNotFound) +} + +func (w *WebCommander) asyncStart() { + var grpcServer *grpc.Server + for { + grpcServer = w.cm.ExtractGrpcServer() + if grpcServer != nil { + break + } + time.Sleep(time.Second) + } + + listener := commander.NewOutboundListener() + + wrappedGrpc := grpcweb.WrapServer(grpcServer) + w.server = &http.Server{} + w.wrappedGrpc = wrappedGrpc + w.server.Handler = w + + go func() { + err := w.server.Serve(listener) + if err != nil { + newError("failed to serve HTTP").Base(err).WriteToLog() + } + }() + + if err := w.ohm.RemoveHandler(context.Background(), w.config.Tag); err != nil { + newError("failed to remove existing handler").WriteToLog() + } + + if err := w.ohm.AddHandler(context.Background(), commander.NewOutbound(w.config.Tag, listener)); err != nil { + newError("failed to add handler").Base(err).WriteToLog() + } +} + +func (w *WebCommander) Type() interface{} { + return (*WebCommander)(nil) +} + +func (w *WebCommander) Start() error { + + if err := core.RequireFeatures(w.ctx, func(cm commander.CommanderIfce, om outbound.Manager) { + w.Lock() + defer w.Unlock() + + w.cm = cm + w.ohm = om + + go w.asyncStart() + + }); err != nil { + return err + } + + return nil +} + +func (w *WebCommander) Close() error { + w.Lock() + defer w.Unlock() + + if w.server != nil { + if err := w.server.Close(); err != nil { + return newError("failed to close http server").Base(err) + } + + w.server = nil + } + + return nil +} + +func init() { + common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { + return newWebCommander(ctx, config.(*Config)) + })) +} diff --git a/v2ray-core/app/observatory/command/command.go b/v2ray-core/app/observatory/command/command.go index 9d7e97a3e3..72331ea70c 100644 --- a/v2ray-core/app/observatory/command/command.go +++ b/v2ray-core/app/observatory/command/command.go @@ -34,6 +34,9 @@ func (s *service) GetOutboundStatus(ctx context.Context, request *GetOutboundSta } result = observeResult } else { + if _, ok := s.observatory.(features.TaggedFeatures); !ok { + return nil, newError("observatory does not support tagged features") + } fet, err := s.observatory.(features.TaggedFeatures).GetFeaturesByTag(request.Tag) if err != nil { return nil, newError("cannot get tagged observatory").Base(err) diff --git a/v2ray-core/app/router/strategy_leastping.go b/v2ray-core/app/router/strategy_leastping.go index 184335c47c..ea93370524 100644 --- a/v2ray-core/app/router/strategy_leastping.go +++ b/v2ray-core/app/router/strategy_leastping.go @@ -40,6 +40,11 @@ func (l *LeastPingStrategy) PickOutbound(strings []string) string { })) } + if l.observatory == nil { + newError("cannot find observatory").WriteToLog() + return "" + } + observeReport, err := l.observatory.GetObservation(l.ctx) if err != nil { newError("cannot get observe report").Base(err).WriteToLog() diff --git a/v2ray-core/app/subscription/config.pb.go b/v2ray-core/app/subscription/config.pb.go index 14e66cb752..717a4e3a4f 100644 --- a/v2ray-core/app/subscription/config.pb.go +++ b/v2ray-core/app/subscription/config.pb.go @@ -16,24 +16,21 @@ const ( ) type ImportSource struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` - TagPrefix string `protobuf:"bytes,3,opt,name=tag_prefix,json=tagPrefix,proto3" json:"tag_prefix,omitempty"` - ImportUsingTag string `protobuf:"bytes,4,opt,name=import_using_tag,json=importUsingTag,proto3" json:"import_using_tag,omitempty"` - DefaultExpireSeconds uint64 `protobuf:"varint,5,opt,name=default_expire_seconds,json=defaultExpireSeconds,proto3" json:"default_expire_seconds,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` + TagPrefix string `protobuf:"bytes,3,opt,name=tag_prefix,json=tagPrefix,proto3" json:"tag_prefix,omitempty"` + ImportUsingTag string `protobuf:"bytes,4,opt,name=import_using_tag,json=importUsingTag,proto3" json:"import_using_tag,omitempty"` + DefaultExpireSeconds uint64 `protobuf:"varint,5,opt,name=default_expire_seconds,json=defaultExpireSeconds,proto3" json:"default_expire_seconds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ImportSource) Reset() { *x = ImportSource{} - if protoimpl.UnsafeEnabled { - mi := &file_app_subscription_config_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_app_subscription_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ImportSource) String() string { @@ -44,7 +41,7 @@ func (*ImportSource) ProtoMessage() {} func (x *ImportSource) ProtoReflect() protoreflect.Message { mi := &file_app_subscription_config_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -96,22 +93,19 @@ func (x *ImportSource) GetDefaultExpireSeconds() uint64 { // Config is the settings for Subscription Manager. type Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Imports []*ImportSource `protobuf:"bytes,1,rep,name=imports,proto3" json:"imports,omitempty"` - NonnativeConverterOverlay []byte `protobuf:"bytes,2,opt,name=nonnative_converter_overlay,json=nonnativeConverterOverlay,proto3" json:"nonnative_converter_overlay,omitempty"` - NonnativeConverterOverlayFile string `protobuf:"bytes,96002,opt,name=nonnative_converter_overlay_file,json=nonnativeConverterOverlayFile,proto3" json:"nonnative_converter_overlay_file,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Imports []*ImportSource `protobuf:"bytes,1,rep,name=imports,proto3" json:"imports,omitempty"` + NonnativeConverterOverlay []byte `protobuf:"bytes,2,opt,name=nonnative_converter_overlay,json=nonnativeConverterOverlay,proto3" json:"nonnative_converter_overlay,omitempty"` + NonnativeConverterOverlayFile string `protobuf:"bytes,96002,opt,name=nonnative_converter_overlay_file,json=nonnativeConverterOverlayFile,proto3" json:"nonnative_converter_overlay_file,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Config) Reset() { *x = Config{} - if protoimpl.UnsafeEnabled { - mi := &file_app_subscription_config_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_app_subscription_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Config) String() string { @@ -122,7 +116,7 @@ func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { mi := &file_app_subscription_config_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -219,7 +213,7 @@ func file_app_subscription_config_proto_rawDescGZIP() []byte { } var file_app_subscription_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_app_subscription_config_proto_goTypes = []interface{}{ +var file_app_subscription_config_proto_goTypes = []any{ (*ImportSource)(nil), // 0: v2ray.core.app.subscription.ImportSource (*Config)(nil), // 1: v2ray.core.app.subscription.Config } @@ -237,32 +231,6 @@ func file_app_subscription_config_proto_init() { if File_app_subscription_config_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_app_subscription_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ImportSource); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_app_subscription_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Config); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/v2ray-core/app/subscription/containers/urlline/errors.generated.go b/v2ray-core/app/subscription/containers/urlline/errors.generated.go new file mode 100644 index 0000000000..118d6efeaa --- /dev/null +++ b/v2ray-core/app/subscription/containers/urlline/errors.generated.go @@ -0,0 +1,9 @@ +package urlline + +import "github.com/v2fly/v2ray-core/v5/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/v2ray-core/app/subscription/containers/urlline/parser.go b/v2ray-core/app/subscription/containers/urlline/parser.go new file mode 100644 index 0000000000..0750cf5b91 --- /dev/null +++ b/v2ray-core/app/subscription/containers/urlline/parser.go @@ -0,0 +1,63 @@ +package urlline + +import ( + "bufio" + "bytes" + "github.com/v2fly/v2ray-core/v5/app/subscription/containers" + "github.com/v2fly/v2ray-core/v5/common" + "net/url" + "strings" +) + +func newURLLineParser() containers.SubscriptionContainerDocumentParser { + return &parser{} +} + +type parser struct{} + +func (p parser) ParseSubscriptionContainerDocument(rawConfig []byte) (*containers.Container, error) { + result := &containers.Container{} + result.Kind = "URLLine" + result.Metadata = make(map[string]string) + + scanner := bufio.NewScanner(bytes.NewReader(rawConfig)) + + const maxCapacity int = 1024 * 256 + buf := make([]byte, maxCapacity) + scanner.Buffer(buf, maxCapacity) + + parsedLine := 0 + failedLine := 0 + + for scanner.Scan() { + content := scanner.Text() + content = strings.TrimSpace(content) + if strings.HasPrefix(content, "#") { + continue + } + if strings.HasPrefix(content, "//") { + continue + } + _, err := url.Parse(content) + if err != nil { + failedLine++ + continue + } else { + parsedLine++ + } + result.ServerSpecs = append(result.ServerSpecs, containers.UnparsedServerConf{ + KindHint: "URL", + Content: scanner.Bytes(), + }) + } + + if failedLine > parsedLine || parsedLine == 0 { + return nil, newError("failed to parse as URLLine").Base(newError("too many failed lines")) + } + + return result, nil +} + +func init() { + common.Must(containers.RegisterParser("URLLine", newURLLineParser())) +} diff --git a/v2ray-core/app/subscription/containers/urlline/urlline.go b/v2ray-core/app/subscription/containers/urlline/urlline.go new file mode 100644 index 0000000000..3d0c24b5b0 --- /dev/null +++ b/v2ray-core/app/subscription/containers/urlline/urlline.go @@ -0,0 +1,3 @@ +package urlline + +//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen diff --git a/v2ray-core/app/subscription/entries/nonnative/definitions/shadowsocks.jsont b/v2ray-core/app/subscription/entries/nonnative/definitions/shadowsocks.jsont index 05303f8a15..47955a9286 100644 --- a/v2ray-core/app/subscription/entries/nonnative/definitions/shadowsocks.jsont +++ b/v2ray-core/app/subscription/entries/nonnative/definitions/shadowsocks.jsont @@ -37,7 +37,7 @@ }, "metadata":{ - "TagName": {{print $name_annotation "_" $server_address | jsonEncode}} - + "TagName": {{print $name_annotation "_" $server_address | jsonEncode}}, + "DisplayName": {{print $name_annotation | jsonEncode}} } } \ No newline at end of file diff --git a/v2ray-core/app/subscription/entries/nonnative/definitions/shadowsocks2022.jsont b/v2ray-core/app/subscription/entries/nonnative/definitions/shadowsocks2022.jsont index 585008867e..dd0ee8b2cc 100644 --- a/v2ray-core/app/subscription/entries/nonnative/definitions/shadowsocks2022.jsont +++ b/v2ray-core/app/subscription/entries/nonnative/definitions/shadowsocks2022.jsont @@ -44,8 +44,8 @@ "metadata":{ - "TagName": {{print $name_annotation "_" $server_address | jsonEncode}} - + "TagName": {{print $name_annotation "_" $server_address | jsonEncode}}, + "DisplayName": {{print $name_annotation | jsonEncode}} } } \ No newline at end of file diff --git a/v2ray-core/app/subscription/entries/nonnative/definitions/vmess.jsont b/v2ray-core/app/subscription/entries/nonnative/definitions/vmess.jsont index 327a465e81..afbb035bb2 100644 --- a/v2ray-core/app/subscription/entries/nonnative/definitions/vmess.jsont +++ b/v2ray-core/app/subscription/entries/nonnative/definitions/vmess.jsont @@ -59,8 +59,7 @@ } }, "metadata":{ - - "TagName": {{print $name_annotation "_" $server_address | jsonEncode}} - + "TagName": {{print $name_annotation "_" $server_address | jsonEncode}}, + "DisplayName": {{print $name_annotation | jsonEncode}} } } diff --git a/v2ray-core/app/subscription/subscription.go b/v2ray-core/app/subscription/subscription.go index f4cd634fea..3ec7678327 100644 --- a/v2ray-core/app/subscription/subscription.go +++ b/v2ray-core/app/subscription/subscription.go @@ -1,3 +1,17 @@ package subscription +import "github.com/v2fly/v2ray-core/v5/features" + //go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen + +type SubscriptionManager interface { + features.Feature + AddTrackedSubscriptionFromImportSource(importSource *ImportSource) error + RemoveTrackedSubscription(name string) error + ListTrackedSubscriptions() []string + GetTrackedSubscriptionStatus(name string) (*TrackedSubscriptionStatus, error) +} + +func SubscriptionManagerType() interface{} { + return (*SubscriptionManager)(nil) +} diff --git a/v2ray-core/app/subscription/subscription_rpc.pb.go b/v2ray-core/app/subscription/subscription_rpc.pb.go new file mode 100644 index 0000000000..8646a818f9 --- /dev/null +++ b/v2ray-core/app/subscription/subscription_rpc.pb.go @@ -0,0 +1,252 @@ +package subscription + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SubscriptionServer struct { + state protoimpl.MessageState `protogen:"open.v1"` + ServerMetadata map[string]string `protobuf:"bytes,2,rep,name=serverMetadata,proto3" json:"serverMetadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Tag string `protobuf:"bytes,3,opt,name=tag,proto3" json:"tag,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SubscriptionServer) Reset() { + *x = SubscriptionServer{} + mi := &file_app_subscription_subscription_rpc_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SubscriptionServer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscriptionServer) ProtoMessage() {} + +func (x *SubscriptionServer) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscription_rpc_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscriptionServer.ProtoReflect.Descriptor instead. +func (*SubscriptionServer) Descriptor() ([]byte, []int) { + return file_app_subscription_subscription_rpc_proto_rawDescGZIP(), []int{0} +} + +func (x *SubscriptionServer) GetServerMetadata() map[string]string { + if x != nil { + return x.ServerMetadata + } + return nil +} + +func (x *SubscriptionServer) GetTag() string { + if x != nil { + return x.Tag + } + return "" +} + +type TrackedSubscriptionStatus struct { + state protoimpl.MessageState `protogen:"open.v1"` + Servers map[string]*SubscriptionServer `protobuf:"bytes,1,rep,name=servers,proto3" json:"servers,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + DocumentMetadata map[string]string `protobuf:"bytes,2,rep,name=documentMetadata,proto3" json:"documentMetadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + ImportSource *ImportSource `protobuf:"bytes,3,opt,name=importSource,proto3" json:"importSource,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TrackedSubscriptionStatus) Reset() { + *x = TrackedSubscriptionStatus{} + mi := &file_app_subscription_subscription_rpc_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TrackedSubscriptionStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrackedSubscriptionStatus) ProtoMessage() {} + +func (x *TrackedSubscriptionStatus) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscription_rpc_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TrackedSubscriptionStatus.ProtoReflect.Descriptor instead. +func (*TrackedSubscriptionStatus) Descriptor() ([]byte, []int) { + return file_app_subscription_subscription_rpc_proto_rawDescGZIP(), []int{1} +} + +func (x *TrackedSubscriptionStatus) GetServers() map[string]*SubscriptionServer { + if x != nil { + return x.Servers + } + return nil +} + +func (x *TrackedSubscriptionStatus) GetDocumentMetadata() map[string]string { + if x != nil { + return x.DocumentMetadata + } + return nil +} + +func (x *TrackedSubscriptionStatus) GetImportSource() *ImportSource { + if x != nil { + return x.ImportSource + } + return nil +} + +var File_app_subscription_subscription_rpc_proto protoreflect.FileDescriptor + +var file_app_subscription_subscription_rpc_proto_rawDesc = []byte{ + 0x0a, 0x27, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1d, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd6, 0x01, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x6b, 0x0a, 0x0e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x1a, 0x41, 0x0a, 0x13, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf5, + 0x03, 0x0a, 0x19, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x5d, 0x0a, 0x07, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x63, + 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x78, 0x0a, 0x10, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x44, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x10, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4d, 0x0a, 0x0c, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x1a, 0x6b, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0x43, 0x0a, 0x15, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x72, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, + 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0xaa, 0x02, 0x1b, 0x56, + 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_app_subscription_subscription_rpc_proto_rawDescOnce sync.Once + file_app_subscription_subscription_rpc_proto_rawDescData = file_app_subscription_subscription_rpc_proto_rawDesc +) + +func file_app_subscription_subscription_rpc_proto_rawDescGZIP() []byte { + file_app_subscription_subscription_rpc_proto_rawDescOnce.Do(func() { + file_app_subscription_subscription_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_subscription_subscription_rpc_proto_rawDescData) + }) + return file_app_subscription_subscription_rpc_proto_rawDescData +} + +var file_app_subscription_subscription_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_app_subscription_subscription_rpc_proto_goTypes = []any{ + (*SubscriptionServer)(nil), // 0: v2ray.core.app.subscription.SubscriptionServer + (*TrackedSubscriptionStatus)(nil), // 1: v2ray.core.app.subscription.TrackedSubscriptionStatus + nil, // 2: v2ray.core.app.subscription.SubscriptionServer.ServerMetadataEntry + nil, // 3: v2ray.core.app.subscription.TrackedSubscriptionStatus.ServersEntry + nil, // 4: v2ray.core.app.subscription.TrackedSubscriptionStatus.DocumentMetadataEntry + (*ImportSource)(nil), // 5: v2ray.core.app.subscription.ImportSource +} +var file_app_subscription_subscription_rpc_proto_depIdxs = []int32{ + 2, // 0: v2ray.core.app.subscription.SubscriptionServer.serverMetadata:type_name -> v2ray.core.app.subscription.SubscriptionServer.ServerMetadataEntry + 3, // 1: v2ray.core.app.subscription.TrackedSubscriptionStatus.servers:type_name -> v2ray.core.app.subscription.TrackedSubscriptionStatus.ServersEntry + 4, // 2: v2ray.core.app.subscription.TrackedSubscriptionStatus.documentMetadata:type_name -> v2ray.core.app.subscription.TrackedSubscriptionStatus.DocumentMetadataEntry + 5, // 3: v2ray.core.app.subscription.TrackedSubscriptionStatus.importSource:type_name -> v2ray.core.app.subscription.ImportSource + 0, // 4: v2ray.core.app.subscription.TrackedSubscriptionStatus.ServersEntry.value:type_name -> v2ray.core.app.subscription.SubscriptionServer + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_app_subscription_subscription_rpc_proto_init() } +func file_app_subscription_subscription_rpc_proto_init() { + if File_app_subscription_subscription_rpc_proto != nil { + return + } + file_app_subscription_config_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_app_subscription_subscription_rpc_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_app_subscription_subscription_rpc_proto_goTypes, + DependencyIndexes: file_app_subscription_subscription_rpc_proto_depIdxs, + MessageInfos: file_app_subscription_subscription_rpc_proto_msgTypes, + }.Build() + File_app_subscription_subscription_rpc_proto = out.File + file_app_subscription_subscription_rpc_proto_rawDesc = nil + file_app_subscription_subscription_rpc_proto_goTypes = nil + file_app_subscription_subscription_rpc_proto_depIdxs = nil +} diff --git a/v2ray-core/app/subscription/subscription_rpc.proto b/v2ray-core/app/subscription/subscription_rpc.proto new file mode 100644 index 0000000000..14a86f27ff --- /dev/null +++ b/v2ray-core/app/subscription/subscription_rpc.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package v2ray.core.app.subscription; + +option csharp_namespace = "V2Ray.Core.App.Subscription"; +option go_package = "github.com/v2fly/v2ray-core/v5/app/subscription"; +option java_package = "com.v2ray.core.app.subscription"; +option java_multiple_files = true; + +import "app/subscription/config.proto"; + +message SubscriptionServer { + map serverMetadata = 2; + string tag = 3; +} + +message TrackedSubscriptionStatus { + map servers = 1; + map documentMetadata = 2; + v2ray.core.app.subscription.ImportSource importSource = 3; +} \ No newline at end of file diff --git a/v2ray-core/app/subscription/subscriptionmanager/command/command.go b/v2ray-core/app/subscription/subscriptionmanager/command/command.go new file mode 100644 index 0000000000..738530f289 --- /dev/null +++ b/v2ray-core/app/subscription/subscriptionmanager/command/command.go @@ -0,0 +1,78 @@ +package command + +import ( + "context" + + core "github.com/v2fly/v2ray-core/v5" + "github.com/v2fly/v2ray-core/v5/app/subscription" + "github.com/v2fly/v2ray-core/v5/common" + + "google.golang.org/grpc" +) + +//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen + +type SubscriptionManagerService struct { + UnimplementedSubscriptionManagerServiceServer + manager subscription.SubscriptionManager +} + +func NewSubscriptionManagerService(manager subscription.SubscriptionManager) *SubscriptionManagerService { + return &SubscriptionManagerService{manager: manager} +} + +func (s *SubscriptionManagerService) ListTrackedSubscription(ctx context.Context, req *ListTrackedSubscriptionRequest) (*ListTrackedSubscriptionResponse, error) { + if s.manager == nil { + return nil, newError("subscription manager is not available") + } + names := s.manager.ListTrackedSubscriptions() + return &ListTrackedSubscriptionResponse{Names: names}, nil +} + +func (s *SubscriptionManagerService) AddTrackedSubscription(ctx context.Context, req *AddTrackedSubscriptionRequest) (*AddTrackedSubscriptionResponse, error) { + if s.manager == nil { + return nil, newError("subscription manager is not available") + } + err := s.manager.AddTrackedSubscriptionFromImportSource(req.Source) + if err != nil { + return nil, err + } + return &AddTrackedSubscriptionResponse{}, nil +} + +func (s *SubscriptionManagerService) RemoveTrackedSubscription(ctx context.Context, req *RemoveTrackedSubscriptionRequest) (*RemoveTrackedSubscriptionResponse, error) { + if s.manager == nil { + return nil, newError("subscription manager is not available") + } + err := s.manager.RemoveTrackedSubscription(req.Name) + if err != nil { + return nil, err + } + return &RemoveTrackedSubscriptionResponse{}, nil +} + +func (s *SubscriptionManagerService) GetTrackedSubscriptionStatus(ctx context.Context, req *GetTrackedSubscriptionStatusRequest) (*GetTrackedSubscriptionStatusResponse, error) { + if s.manager == nil { + return nil, newError("subscription manager is not available") + } + status, err := s.manager.GetTrackedSubscriptionStatus(req.Name) + if err != nil { + return nil, err + } + return &GetTrackedSubscriptionStatusResponse{Status: status}, nil +} + +func (s *SubscriptionManagerService) Register(server *grpc.Server) { + RegisterSubscriptionManagerServiceServer(server, s) +} + +func init() { + common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) { + var manager subscription.SubscriptionManager + common.Must(core.RequireFeatures(ctx, func(m subscription.SubscriptionManager) { + manager = m + })) + service := NewSubscriptionManagerService(manager) + return service, nil + })) +} diff --git a/v2ray-core/app/subscription/subscriptionmanager/command/command.pb.go b/v2ray-core/app/subscription/subscriptionmanager/command/command.pb.go new file mode 100644 index 0000000000..6626676a1c --- /dev/null +++ b/v2ray-core/app/subscription/subscriptionmanager/command/command.pb.go @@ -0,0 +1,572 @@ +package command + +import ( + subscription "github.com/v2fly/v2ray-core/v5/app/subscription" + _ "github.com/v2fly/v2ray-core/v5/common/protoext" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ListTrackedSubscriptionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListTrackedSubscriptionRequest) Reset() { + *x = ListTrackedSubscriptionRequest{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListTrackedSubscriptionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTrackedSubscriptionRequest) ProtoMessage() {} + +func (x *ListTrackedSubscriptionRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListTrackedSubscriptionRequest.ProtoReflect.Descriptor instead. +func (*ListTrackedSubscriptionRequest) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{0} +} + +type ListTrackedSubscriptionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Names []string `protobuf:"bytes,1,rep,name=names,proto3" json:"names,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListTrackedSubscriptionResponse) Reset() { + *x = ListTrackedSubscriptionResponse{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListTrackedSubscriptionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTrackedSubscriptionResponse) ProtoMessage() {} + +func (x *ListTrackedSubscriptionResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListTrackedSubscriptionResponse.ProtoReflect.Descriptor instead. +func (*ListTrackedSubscriptionResponse) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{1} +} + +func (x *ListTrackedSubscriptionResponse) GetNames() []string { + if x != nil { + return x.Names + } + return nil +} + +type AddTrackedSubscriptionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Source *subscription.ImportSource `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddTrackedSubscriptionRequest) Reset() { + *x = AddTrackedSubscriptionRequest{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddTrackedSubscriptionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddTrackedSubscriptionRequest) ProtoMessage() {} + +func (x *AddTrackedSubscriptionRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddTrackedSubscriptionRequest.ProtoReflect.Descriptor instead. +func (*AddTrackedSubscriptionRequest) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{2} +} + +func (x *AddTrackedSubscriptionRequest) GetSource() *subscription.ImportSource { + if x != nil { + return x.Source + } + return nil +} + +type AddTrackedSubscriptionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddTrackedSubscriptionResponse) Reset() { + *x = AddTrackedSubscriptionResponse{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddTrackedSubscriptionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddTrackedSubscriptionResponse) ProtoMessage() {} + +func (x *AddTrackedSubscriptionResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddTrackedSubscriptionResponse.ProtoReflect.Descriptor instead. +func (*AddTrackedSubscriptionResponse) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{3} +} + +type RemoveTrackedSubscriptionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RemoveTrackedSubscriptionRequest) Reset() { + *x = RemoveTrackedSubscriptionRequest{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RemoveTrackedSubscriptionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveTrackedSubscriptionRequest) ProtoMessage() {} + +func (x *RemoveTrackedSubscriptionRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveTrackedSubscriptionRequest.ProtoReflect.Descriptor instead. +func (*RemoveTrackedSubscriptionRequest) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{4} +} + +func (x *RemoveTrackedSubscriptionRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type RemoveTrackedSubscriptionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RemoveTrackedSubscriptionResponse) Reset() { + *x = RemoveTrackedSubscriptionResponse{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RemoveTrackedSubscriptionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveTrackedSubscriptionResponse) ProtoMessage() {} + +func (x *RemoveTrackedSubscriptionResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveTrackedSubscriptionResponse.ProtoReflect.Descriptor instead. +func (*RemoveTrackedSubscriptionResponse) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{5} +} + +type GetTrackedSubscriptionStatusRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetTrackedSubscriptionStatusRequest) Reset() { + *x = GetTrackedSubscriptionStatusRequest{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTrackedSubscriptionStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTrackedSubscriptionStatusRequest) ProtoMessage() {} + +func (x *GetTrackedSubscriptionStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTrackedSubscriptionStatusRequest.ProtoReflect.Descriptor instead. +func (*GetTrackedSubscriptionStatusRequest) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{6} +} + +func (x *GetTrackedSubscriptionStatusRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GetTrackedSubscriptionStatusResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Status *subscription.TrackedSubscriptionStatus `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetTrackedSubscriptionStatusResponse) Reset() { + *x = GetTrackedSubscriptionStatusResponse{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTrackedSubscriptionStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTrackedSubscriptionStatusResponse) ProtoMessage() {} + +func (x *GetTrackedSubscriptionStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTrackedSubscriptionStatusResponse.ProtoReflect.Descriptor instead. +func (*GetTrackedSubscriptionStatusResponse) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{7} +} + +func (x *GetTrackedSubscriptionStatusResponse) GetStatus() *subscription.TrackedSubscriptionStatus { + if x != nil { + return x.Status + } + return nil +} + +type Config struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Config) Reset() { + *x = Config{} + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Config) ProtoMessage() {} + +func (x *Config) ProtoReflect() protoreflect.Message { + mi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Config.ProtoReflect.Descriptor instead. +func (*Config) Descriptor() ([]byte, []int) { + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{8} +} + +var File_app_subscription_subscriptionmanager_command_command_proto protoreflect.FileDescriptor + +var file_app_subscription_subscriptionmanager_command_command_proto_rawDesc = []byte{ + 0x0a, 0x3a, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x37, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x20, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x37, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x62, 0x0a, 0x1d, 0x41, 0x64, + 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x76, 0x32, + 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x20, + 0x0a, 0x1e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x36, 0x0a, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x23, 0x0a, 0x21, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, + 0x23, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x76, 0x0a, 0x24, 0x47, 0x65, 0x74, 0x54, + 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x4e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x36, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, + 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x30, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x26, 0x82, 0xb5, 0x18, 0x22, + 0x0a, 0x0b, 0x67, 0x72, 0x70, 0x63, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x13, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x32, 0xf2, 0x06, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0xce, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x57, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, + 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x58, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0xcb, 0x01, 0x0a, 0x16, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, + 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x57, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, + 0x41, 0x64, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0xd4, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, + 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x59, + 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, + 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x5a, 0x2e, 0x76, 0x32, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xdd, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x54, + 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x5c, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x5d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xc2, 0x01, 0x0a, 0x37, 0x63, 0x6f, 0x6d, 0x2e, + 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, + 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0xaa, 0x02, 0x37, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, + 0x41, 0x70, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_app_subscription_subscriptionmanager_command_command_proto_rawDescOnce sync.Once + file_app_subscription_subscriptionmanager_command_command_proto_rawDescData = file_app_subscription_subscriptionmanager_command_command_proto_rawDesc +) + +func file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP() []byte { + file_app_subscription_subscriptionmanager_command_command_proto_rawDescOnce.Do(func() { + file_app_subscription_subscriptionmanager_command_command_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_subscription_subscriptionmanager_command_command_proto_rawDescData) + }) + return file_app_subscription_subscriptionmanager_command_command_proto_rawDescData +} + +var file_app_subscription_subscriptionmanager_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_app_subscription_subscriptionmanager_command_command_proto_goTypes = []any{ + (*ListTrackedSubscriptionRequest)(nil), // 0: v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionRequest + (*ListTrackedSubscriptionResponse)(nil), // 1: v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionResponse + (*AddTrackedSubscriptionRequest)(nil), // 2: v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionRequest + (*AddTrackedSubscriptionResponse)(nil), // 3: v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionResponse + (*RemoveTrackedSubscriptionRequest)(nil), // 4: v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionRequest + (*RemoveTrackedSubscriptionResponse)(nil), // 5: v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionResponse + (*GetTrackedSubscriptionStatusRequest)(nil), // 6: v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusRequest + (*GetTrackedSubscriptionStatusResponse)(nil), // 7: v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusResponse + (*Config)(nil), // 8: v2ray.core.app.subscription.subscriptionmanager.command.Config + (*subscription.ImportSource)(nil), // 9: v2ray.core.app.subscription.ImportSource + (*subscription.TrackedSubscriptionStatus)(nil), // 10: v2ray.core.app.subscription.TrackedSubscriptionStatus +} +var file_app_subscription_subscriptionmanager_command_command_proto_depIdxs = []int32{ + 9, // 0: v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionRequest.source:type_name -> v2ray.core.app.subscription.ImportSource + 10, // 1: v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusResponse.status:type_name -> v2ray.core.app.subscription.TrackedSubscriptionStatus + 0, // 2: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.ListTrackedSubscription:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionRequest + 2, // 3: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.AddTrackedSubscription:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionRequest + 4, // 4: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.RemoveTrackedSubscription:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionRequest + 6, // 5: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.GetTrackedSubscriptionStatus:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusRequest + 1, // 6: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.ListTrackedSubscription:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionResponse + 3, // 7: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.AddTrackedSubscription:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionResponse + 5, // 8: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.RemoveTrackedSubscription:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionResponse + 7, // 9: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.GetTrackedSubscriptionStatus:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusResponse + 6, // [6:10] is the sub-list for method output_type + 2, // [2:6] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_app_subscription_subscriptionmanager_command_command_proto_init() } +func file_app_subscription_subscriptionmanager_command_command_proto_init() { + if File_app_subscription_subscriptionmanager_command_command_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_app_subscription_subscriptionmanager_command_command_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_app_subscription_subscriptionmanager_command_command_proto_goTypes, + DependencyIndexes: file_app_subscription_subscriptionmanager_command_command_proto_depIdxs, + MessageInfos: file_app_subscription_subscriptionmanager_command_command_proto_msgTypes, + }.Build() + File_app_subscription_subscriptionmanager_command_command_proto = out.File + file_app_subscription_subscriptionmanager_command_command_proto_rawDesc = nil + file_app_subscription_subscriptionmanager_command_command_proto_goTypes = nil + file_app_subscription_subscriptionmanager_command_command_proto_depIdxs = nil +} diff --git a/v2ray-core/app/subscription/subscriptionmanager/command/command.proto b/v2ray-core/app/subscription/subscriptionmanager/command/command.proto new file mode 100644 index 0000000000..cc3b83f210 --- /dev/null +++ b/v2ray-core/app/subscription/subscriptionmanager/command/command.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; + +package v2ray.core.app.subscription.subscriptionmanager.command; +option csharp_namespace = "V2Ray.Core.App.Subscription.Subscriptionmanager.Command"; +option go_package = "github.com/v2fly/v2ray-core/v5/app/subscription/subscriptionmanager/command"; +option java_package = "com.v2ray.core.subscription.subscriptionmanager.command"; +option java_multiple_files = true; + +import "common/protoext/extensions.proto"; +import "app/subscription/config.proto"; +import "app/subscription/subscription_rpc.proto"; + +message ListTrackedSubscriptionRequest { +} + +message ListTrackedSubscriptionResponse { + repeated string names = 1; +} + +message AddTrackedSubscriptionRequest{ + v2ray.core.app.subscription.ImportSource source = 1; +} +message AddTrackedSubscriptionResponse{ + +} +message RemoveTrackedSubscriptionRequest{ + string name = 1; +} +message RemoveTrackedSubscriptionResponse{ + +} + +message GetTrackedSubscriptionStatusRequest { + string name = 1; +} + +message GetTrackedSubscriptionStatusResponse { + v2ray.core.app.subscription.TrackedSubscriptionStatus status = 1; +} + + +service SubscriptionManagerService { + rpc ListTrackedSubscription(ListTrackedSubscriptionRequest) + returns (ListTrackedSubscriptionResponse) {} + rpc AddTrackedSubscription(AddTrackedSubscriptionRequest) + returns (AddTrackedSubscriptionResponse) {} + rpc RemoveTrackedSubscription(RemoveTrackedSubscriptionRequest) + returns (RemoveTrackedSubscriptionResponse) {} + rpc GetTrackedSubscriptionStatus(GetTrackedSubscriptionStatusRequest) + returns (GetTrackedSubscriptionStatusResponse) {} +} + + +message Config { + option (v2ray.core.common.protoext.message_opt).type = "grpcservice"; + option (v2ray.core.common.protoext.message_opt).short_name = "subscriptionmanager"; +} \ No newline at end of file diff --git a/v2ray-core/app/subscription/subscriptionmanager/command/command_grpc.pb.go b/v2ray-core/app/subscription/subscriptionmanager/command/command_grpc.pb.go new file mode 100644 index 0000000000..0d4cdb584d --- /dev/null +++ b/v2ray-core/app/subscription/subscriptionmanager/command/command_grpc.pb.go @@ -0,0 +1,230 @@ +package command + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + SubscriptionManagerService_ListTrackedSubscription_FullMethodName = "/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/ListTrackedSubscription" + SubscriptionManagerService_AddTrackedSubscription_FullMethodName = "/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/AddTrackedSubscription" + SubscriptionManagerService_RemoveTrackedSubscription_FullMethodName = "/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/RemoveTrackedSubscription" + SubscriptionManagerService_GetTrackedSubscriptionStatus_FullMethodName = "/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/GetTrackedSubscriptionStatus" +) + +// SubscriptionManagerServiceClient is the client API for SubscriptionManagerService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type SubscriptionManagerServiceClient interface { + ListTrackedSubscription(ctx context.Context, in *ListTrackedSubscriptionRequest, opts ...grpc.CallOption) (*ListTrackedSubscriptionResponse, error) + AddTrackedSubscription(ctx context.Context, in *AddTrackedSubscriptionRequest, opts ...grpc.CallOption) (*AddTrackedSubscriptionResponse, error) + RemoveTrackedSubscription(ctx context.Context, in *RemoveTrackedSubscriptionRequest, opts ...grpc.CallOption) (*RemoveTrackedSubscriptionResponse, error) + GetTrackedSubscriptionStatus(ctx context.Context, in *GetTrackedSubscriptionStatusRequest, opts ...grpc.CallOption) (*GetTrackedSubscriptionStatusResponse, error) +} + +type subscriptionManagerServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSubscriptionManagerServiceClient(cc grpc.ClientConnInterface) SubscriptionManagerServiceClient { + return &subscriptionManagerServiceClient{cc} +} + +func (c *subscriptionManagerServiceClient) ListTrackedSubscription(ctx context.Context, in *ListTrackedSubscriptionRequest, opts ...grpc.CallOption) (*ListTrackedSubscriptionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListTrackedSubscriptionResponse) + err := c.cc.Invoke(ctx, SubscriptionManagerService_ListTrackedSubscription_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *subscriptionManagerServiceClient) AddTrackedSubscription(ctx context.Context, in *AddTrackedSubscriptionRequest, opts ...grpc.CallOption) (*AddTrackedSubscriptionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AddTrackedSubscriptionResponse) + err := c.cc.Invoke(ctx, SubscriptionManagerService_AddTrackedSubscription_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *subscriptionManagerServiceClient) RemoveTrackedSubscription(ctx context.Context, in *RemoveTrackedSubscriptionRequest, opts ...grpc.CallOption) (*RemoveTrackedSubscriptionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RemoveTrackedSubscriptionResponse) + err := c.cc.Invoke(ctx, SubscriptionManagerService_RemoveTrackedSubscription_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *subscriptionManagerServiceClient) GetTrackedSubscriptionStatus(ctx context.Context, in *GetTrackedSubscriptionStatusRequest, opts ...grpc.CallOption) (*GetTrackedSubscriptionStatusResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetTrackedSubscriptionStatusResponse) + err := c.cc.Invoke(ctx, SubscriptionManagerService_GetTrackedSubscriptionStatus_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SubscriptionManagerServiceServer is the server API for SubscriptionManagerService service. +// All implementations must embed UnimplementedSubscriptionManagerServiceServer +// for forward compatibility. +type SubscriptionManagerServiceServer interface { + ListTrackedSubscription(context.Context, *ListTrackedSubscriptionRequest) (*ListTrackedSubscriptionResponse, error) + AddTrackedSubscription(context.Context, *AddTrackedSubscriptionRequest) (*AddTrackedSubscriptionResponse, error) + RemoveTrackedSubscription(context.Context, *RemoveTrackedSubscriptionRequest) (*RemoveTrackedSubscriptionResponse, error) + GetTrackedSubscriptionStatus(context.Context, *GetTrackedSubscriptionStatusRequest) (*GetTrackedSubscriptionStatusResponse, error) + mustEmbedUnimplementedSubscriptionManagerServiceServer() +} + +// UnimplementedSubscriptionManagerServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedSubscriptionManagerServiceServer struct{} + +func (UnimplementedSubscriptionManagerServiceServer) ListTrackedSubscription(context.Context, *ListTrackedSubscriptionRequest) (*ListTrackedSubscriptionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListTrackedSubscription not implemented") +} +func (UnimplementedSubscriptionManagerServiceServer) AddTrackedSubscription(context.Context, *AddTrackedSubscriptionRequest) (*AddTrackedSubscriptionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddTrackedSubscription not implemented") +} +func (UnimplementedSubscriptionManagerServiceServer) RemoveTrackedSubscription(context.Context, *RemoveTrackedSubscriptionRequest) (*RemoveTrackedSubscriptionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveTrackedSubscription not implemented") +} +func (UnimplementedSubscriptionManagerServiceServer) GetTrackedSubscriptionStatus(context.Context, *GetTrackedSubscriptionStatusRequest) (*GetTrackedSubscriptionStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTrackedSubscriptionStatus not implemented") +} +func (UnimplementedSubscriptionManagerServiceServer) mustEmbedUnimplementedSubscriptionManagerServiceServer() { +} +func (UnimplementedSubscriptionManagerServiceServer) testEmbeddedByValue() {} + +// UnsafeSubscriptionManagerServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SubscriptionManagerServiceServer will +// result in compilation errors. +type UnsafeSubscriptionManagerServiceServer interface { + mustEmbedUnimplementedSubscriptionManagerServiceServer() +} + +func RegisterSubscriptionManagerServiceServer(s grpc.ServiceRegistrar, srv SubscriptionManagerServiceServer) { + // If the following call pancis, it indicates UnimplementedSubscriptionManagerServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&SubscriptionManagerService_ServiceDesc, srv) +} + +func _SubscriptionManagerService_ListTrackedSubscription_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListTrackedSubscriptionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubscriptionManagerServiceServer).ListTrackedSubscription(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SubscriptionManagerService_ListTrackedSubscription_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubscriptionManagerServiceServer).ListTrackedSubscription(ctx, req.(*ListTrackedSubscriptionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SubscriptionManagerService_AddTrackedSubscription_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddTrackedSubscriptionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubscriptionManagerServiceServer).AddTrackedSubscription(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SubscriptionManagerService_AddTrackedSubscription_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubscriptionManagerServiceServer).AddTrackedSubscription(ctx, req.(*AddTrackedSubscriptionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SubscriptionManagerService_RemoveTrackedSubscription_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveTrackedSubscriptionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubscriptionManagerServiceServer).RemoveTrackedSubscription(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SubscriptionManagerService_RemoveTrackedSubscription_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubscriptionManagerServiceServer).RemoveTrackedSubscription(ctx, req.(*RemoveTrackedSubscriptionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SubscriptionManagerService_GetTrackedSubscriptionStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTrackedSubscriptionStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubscriptionManagerServiceServer).GetTrackedSubscriptionStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SubscriptionManagerService_GetTrackedSubscriptionStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubscriptionManagerServiceServer).GetTrackedSubscriptionStatus(ctx, req.(*GetTrackedSubscriptionStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// SubscriptionManagerService_ServiceDesc is the grpc.ServiceDesc for SubscriptionManagerService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SubscriptionManagerService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService", + HandlerType: (*SubscriptionManagerServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListTrackedSubscription", + Handler: _SubscriptionManagerService_ListTrackedSubscription_Handler, + }, + { + MethodName: "AddTrackedSubscription", + Handler: _SubscriptionManagerService_AddTrackedSubscription_Handler, + }, + { + MethodName: "RemoveTrackedSubscription", + Handler: _SubscriptionManagerService_RemoveTrackedSubscription_Handler, + }, + { + MethodName: "GetTrackedSubscriptionStatus", + Handler: _SubscriptionManagerService_GetTrackedSubscriptionStatus_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "app/subscription/subscriptionmanager/command/command.proto", +} diff --git a/v2ray-core/app/subscription/subscriptionmanager/command/errors.generated.go b/v2ray-core/app/subscription/subscriptionmanager/command/errors.generated.go new file mode 100644 index 0000000000..668365807e --- /dev/null +++ b/v2ray-core/app/subscription/subscriptionmanager/command/errors.generated.go @@ -0,0 +1,9 @@ +package command + +import "github.com/v2fly/v2ray-core/v5/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/v2ray-core/app/subscription/subscriptionmanager/manager.go b/v2ray-core/app/subscription/subscriptionmanager/manager.go index 5f10fcb95b..17e9cb4b42 100644 --- a/v2ray-core/app/subscription/subscriptionmanager/manager.go +++ b/v2ray-core/app/subscription/subscriptionmanager/manager.go @@ -4,20 +4,22 @@ import ( "archive/zip" "bytes" "context" + "sync" "time" core "github.com/v2fly/v2ray-core/v5" "github.com/v2fly/v2ray-core/v5/app/subscription" "github.com/v2fly/v2ray-core/v5/app/subscription/entries" "github.com/v2fly/v2ray-core/v5/app/subscription/entries/nonnative/nonnativeifce" + "github.com/v2fly/v2ray-core/v5/app/subscription/specs" "github.com/v2fly/v2ray-core/v5/common" "github.com/v2fly/v2ray-core/v5/common/task" - "github.com/v2fly/v2ray-core/v5/features/extension" ) //go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen type SubscriptionManagerImpl struct { + sync.Mutex config *subscription.Config ctx context.Context @@ -30,22 +32,26 @@ type SubscriptionManagerImpl struct { } func (s *SubscriptionManagerImpl) Type() interface{} { - return extension.SubscriptionManagerType() + return subscription.SubscriptionManagerType() } func (s *SubscriptionManagerImpl) housekeeping() error { for subscriptionName := range s.trackedSubscriptions { + s.Lock() if err := s.checkupSubscription(subscriptionName); err != nil { newError("failed to checkup subscription: ", err).AtWarning().WriteToLog() } + s.Unlock() } return nil } func (s *SubscriptionManagerImpl) Start() error { - if err := s.refreshTask.Start(); err != nil { - return err - } + go func() { + if err := s.refreshTask.Start(); err != nil { + return + } + }() return nil } @@ -56,6 +62,26 @@ func (s *SubscriptionManagerImpl) Close() error { return nil } +func (s *SubscriptionManagerImpl) addTrackedSubscriptionFromImportSource(importSource *subscription.ImportSource) error { + tracked, err := newTrackedSubscription(importSource) + if err != nil { + return newError("failed to init subscription ", importSource.Name, ": ", err) + } + s.trackedSubscriptions[importSource.Name] = tracked + return nil +} + +func (s *SubscriptionManagerImpl) removeTrackedSubscription(subscriptionName string) error { + if _, ok := s.trackedSubscriptions[subscriptionName]; ok { + err := s.applySubscriptionTo(subscriptionName, &specs.SubscriptionDocument{Server: make([]*specs.SubscriptionServerConfig, 0)}) + if err != nil { + return newError("failed to apply empty subscription: ", err) + } + delete(s.trackedSubscriptions, subscriptionName) + } + return nil +} + func (s *SubscriptionManagerImpl) init() error { s.refreshTask = &task.Periodic{ Interval: time.Duration(60) * time.Second, @@ -78,11 +104,9 @@ func (s *SubscriptionManagerImpl) init() error { } for _, v := range s.config.Imports { - tracked, err := newTrackedSubscription(v) - if err != nil { - return newError("failed to init subscription ", v.Name, ": ", err) + if err := s.addTrackedSubscriptionFromImportSource(v); err != nil { + return newError("failed to add tracked subscription: ", err) } - s.trackedSubscriptions[v.Name] = tracked } return nil } diff --git a/v2ray-core/app/subscription/subscriptionmanager/manager_rpc.go b/v2ray-core/app/subscription/subscriptionmanager/manager_rpc.go new file mode 100644 index 0000000000..4bbe755cc3 --- /dev/null +++ b/v2ray-core/app/subscription/subscriptionmanager/manager_rpc.go @@ -0,0 +1,41 @@ +package subscriptionmanager + +import "github.com/v2fly/v2ray-core/v5/app/subscription" + +func (s *SubscriptionManagerImpl) AddTrackedSubscriptionFromImportSource(importSource *subscription.ImportSource) error { + s.Lock() + defer s.Unlock() + return s.addTrackedSubscriptionFromImportSource(importSource) +} + +func (s *SubscriptionManagerImpl) RemoveTrackedSubscription(name string) error { + s.Lock() + defer s.Unlock() + return s.removeTrackedSubscription(name) +} + +func (s *SubscriptionManagerImpl) ListTrackedSubscriptions() []string { + s.Lock() + defer s.Unlock() + + var names []string + for name := range s.trackedSubscriptions { + names = append(names, name) + } + return names +} + +func (s *SubscriptionManagerImpl) GetTrackedSubscriptionStatus(name string) (*subscription.TrackedSubscriptionStatus, error) { + s.Lock() + defer s.Unlock() + if trackedSubscriptionItem, ok := s.trackedSubscriptions[name]; ok { + result := &subscription.TrackedSubscriptionStatus{} + if err := trackedSubscriptionItem.fillStatus(result); err != nil { + return nil, newError("failed to fill status").Base(err) + } + result.ImportSource = trackedSubscriptionItem.importSource + return result, nil + } else { + return nil, newError("unable to locate") + } +} diff --git a/v2ray-core/app/subscription/subscriptionmanager/tracked_subscription.go b/v2ray-core/app/subscription/subscriptionmanager/tracked_subscription.go index b473d8ec6a..ee7809ae49 100644 --- a/v2ray-core/app/subscription/subscriptionmanager/tracked_subscription.go +++ b/v2ray-core/app/subscription/subscriptionmanager/tracked_subscription.go @@ -76,3 +76,21 @@ type materializedServer struct { serverConfig *specs.SubscriptionServerConfig } + +func (s *trackedSubscription) fillStatus(status *subscription.TrackedSubscriptionStatus) error { + status.ImportSource = s.importSource + if s.currentDocument == nil { + return nil + } + status.DocumentMetadata = s.currentDocument.Metadata + status.Servers = make(map[string]*subscription.SubscriptionServer) + for _, v := range s.currentDocument.Server { + status.Servers[v.Id] = &subscription.SubscriptionServer{ + ServerMetadata: v.Metadata, + } + if materializedInstance, ok := s.materialized[v.Id]; ok { + status.Servers[v.Id].Tag = materializedInstance.tagPostfix + } + } + return nil +} diff --git a/v2ray-core/features/extension/subscription.go b/v2ray-core/features/extension/subscription.go deleted file mode 100644 index cbc51061a0..0000000000 --- a/v2ray-core/features/extension/subscription.go +++ /dev/null @@ -1,11 +0,0 @@ -package extension - -import "github.com/v2fly/v2ray-core/v5/features" - -type SubscriptionManager interface { - features.Feature -} - -func SubscriptionManagerType() interface{} { - return (*SubscriptionManager)(nil) -} diff --git a/v2ray-core/go.mod b/v2ray-core/go.mod index d6cdad0605..4900d6e5ea 100644 --- a/v2ray-core/go.mod +++ b/v2ray-core/go.mod @@ -16,6 +16,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/gopacket v1.1.19 github.com/gorilla/websocket v1.5.3 + github.com/improbable-eng/grpc-web v0.15.0 github.com/jhump/protoreflect v1.17.0 github.com/miekg/dns v1.1.62 github.com/mustafaturan/bus v1.0.2 @@ -40,8 +41,8 @@ require ( golang.org/x/net v0.32.0 golang.org/x/sync v0.10.0 golang.org/x/sys v0.28.0 - google.golang.org/grpc v1.68.1 - google.golang.org/protobuf v1.35.2 + google.golang.org/grpc v1.69.4 + google.golang.org/protobuf v1.36.3 gopkg.in/yaml.v3 v3.0.1 gvisor.dev/gvisor v0.0.0-20231020174304-b8a429915ff1 h12.io/socks v1.0.3 @@ -54,8 +55,10 @@ require ( github.com/andybalholm/brotli v1.0.6 // indirect github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d // indirect github.com/bufbuild/protocompile v0.14.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect @@ -79,6 +82,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/quic-go/qpack v0.5.1 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect + github.com/rs/cors v1.7.0 // indirect github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/xtaci/smux v1.5.24 // indirect @@ -88,5 +92,6 @@ require ( golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect + nhooyr.io/websocket v1.8.6 // indirect ) diff --git a/v2ray-core/go.sum b/v2ray-core/go.sum index 1ecf464e82..dd7d6e11ea 100644 --- a/v2ray-core/go.sum +++ b/v2ray-core/go.sum @@ -14,90 +14,159 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 h1:+JkXLHME8vLJafGhOH4aoV2Iu8bR55nU6iKMVfYVLjY= github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1/go.mod h1:nuudZmJhzWtx2212z+pkuy7B6nkBqa+xwNXZHL1j8cg= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apernet/quic-go v0.48.2-0.20241104191913-cb103fcecfe7 h1:zO38yBOvQ1dLHbSuaU5BFZ8zalnSDQslj+i/9AGOk9s= github.com/apernet/quic-go v0.48.2-0.20241104191913-cb103fcecfe7/go.mod h1:LoSUY2chVqNQCDyi4IZGqPpXLy1FuCkE37PKwtJvNGg= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d h1:zsO4lp+bjv5XvPTF58Vq+qgmZEYZttJK+CWtSZhKenI= github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d/go.mod h1:f1iKL6ZhUWvbk7PdWVmOaak10o86cqMUYEmn1CZNGEI= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a h1:YtdtTUN1iH97s+6PUjLnaiKSQj4oG1/EZ3N9bx6g4kU= github.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a/go.mod h1:/CZpbhAusDOobpcb9yubw46kdYjq0zRC0Wpg9a9zFQM= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= +github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259 h1:ZHJ7+IGpuOXtVf6Zk/a3WuHQgkC+vXwaqfUBDFwahtI= github.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259/go.mod h1:9Qcha0gTWLw//0VNka1Cbnjvg3pNKGFdAm7E9sBabxE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -106,14 +175,19 @@ github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+Licev github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -127,6 +201,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= @@ -136,21 +211,34 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07 h1:57oOH2Mu5Nw16KnZAVLdlUjmPH/TSYCKTJgG0OVfX0Y= github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20210420193930-a4630ec28c79/go.mod h1:Opf9rtYVq0eTyX+aRVmRO9hE8ERAozcdrBxWG9Q6mkQ= github.com/gopherjs/websocket v0.0.0-20191103002815-9a42957e2b3a/go.mod h1:jd+zY81Fx2lC4bfw58+Rflg1srqmedQjbBUejKOjYNY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364 h1:5XxdakFhqd9dnXoAZy1Mb2R/DZ6D1e+0bGC/JhucGYI= github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364/go.mod h1:eDJQioIyy4Yn3MVivT7rv/39gAJTrA7lgmYr8EW950c= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -161,6 +249,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -169,16 +258,32 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -188,6 +293,7 @@ github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ github.com/klauspost/reedsolomon v1.11.7 h1:9uaHU0slncktTEEg4+7Vl7q7XUNMBUOK4R9gnKhMjAU= github.com/klauspost/reedsolomon v1.11.7/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -195,14 +301,22 @@ github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3x github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lunixbochs/struc v0.0.0-20190916212049-a5c72983bc42/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc= github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= @@ -215,29 +329,64 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mustafaturan/bus v1.0.2 h1:2x3ErwZ0uUPwwZ5ZZoknEQprdaxr68Yl3mY8jDye1Ws= github.com/mustafaturan/bus v1.0.2/go.mod h1:h7gfehm8TThv4Dcaa+wDQG7r7j6p74v+7ftr0Rq9i1Q= github.com/mustafaturan/monoton v0.3.1/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV0Lz8p1dc+vy8= github.com/mustafaturan/monoton v1.0.0 h1:8SCej+JiNn0lyps7V+Jzc1CRAkDR4EZPWrTupQ61YCQ= github.com/mustafaturan/monoton v1.0.0/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV0Lz8p1dc+vy8= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI= github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pion/dtls/v2 v2.0.0-rc.7/go.mod h1:U199DvHpRBN0muE9+tVN4TMy1jvEhZIZ63lk4xkvVSk= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= @@ -260,23 +409,42 @@ github.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM= github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= @@ -285,8 +453,11 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 h1:zOjq+1/uLzn/Xo40stbvjIY/yehG0+mfmlsiEmc0xmQ= github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4/go.mod h1:aI+8yClBW+1uovkHw6HM01YXnYB8vohtB9C83wzx34E= @@ -297,18 +468,27 @@ github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxr github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -320,6 +500,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -327,10 +508,17 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/txthinking/runnergroup v0.0.0-20200327135940-540a793bb997/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM= github.com/txthinking/socks5 v0.0.0-20200327133705-caf148ab5e9d/go.mod h1:d3n8NJ6QMRb6I/WAlp4z5ZPAoaeqDmX5NgVZA0mhe+I= github.com/txthinking/x v0.0.0-20200330144832-5ad2416896a9/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08 h1:4Yh46CVE3k/lPq6hUbEdbB1u1anRBXLewm3k+L0iOMc= github.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08/go.mod h1:KAuQNm+LWQCOFqdBcUgihPzRpVXRKzGbTNhfEfRZ4wY= github.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848 h1:p1UzXK6VAutXFFQMnre66h7g1BjRKUnLv0HfmmRoz7w= @@ -355,17 +543,37 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.starlark.net v0.0.0-20230612165344-9532f5667272 h1:2/wtqS591wZyD2OsClsVBKRPEvBsQt/Js+fsCiYhwu8= go.starlark.net v0.0.0-20230612165344-9532f5667272/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 h1:nJAwRlGWZZDOD+6wni9KVUNHMpHko/OnRwsrCYeAzPo= go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35/go.mod h1:TQvodOM+hJTioNQJilmLXu08JNb8i+ccq418+KWu1/Y= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -373,6 +581,7 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -388,6 +597,7 @@ golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -405,6 +615,7 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -413,22 +624,29 @@ golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= @@ -445,6 +663,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -458,23 +677,37 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -498,6 +731,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= @@ -506,11 +740,14 @@ golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -527,9 +764,13 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -540,12 +781,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -554,52 +797,77 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= -google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= +google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gvisor.dev/gvisor v0.0.0-20231020174304-b8a429915ff1 h1:qDCwdCWECGnwQSQC01Dpnp09fRHxJs9PbktotUqG+hs= gvisor.dev/gvisor v0.0.0-20231020174304-b8a429915ff1/go.mod h1:8hmigyCdYtw5xJGfQDJzSH5Ju8XEIDBnpyi8+O6GRt8= h12.io/socks v1.0.3 h1:Ka3qaQewws4j4/eDQnOdpr4wXsC//dXtWvftlIcCQUo= h12.io/socks v1.0.3/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -607,4 +875,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/v2ray-core/main/distro/all/all.go b/v2ray-core/main/distro/all/all.go index ba86a4920d..ead900ced4 100644 --- a/v2ray-core/main/distro/all/all.go +++ b/v2ray-core/main/distro/all/all.go @@ -31,6 +31,7 @@ import ( _ "github.com/v2fly/v2ray-core/v5/transport/internet/tagged/taggedimpl" // Developer preview features + _ "github.com/v2fly/v2ray-core/v5/app/commander/webcommander" _ "github.com/v2fly/v2ray-core/v5/app/instman" _ "github.com/v2fly/v2ray-core/v5/app/observatory" _ "github.com/v2fly/v2ray-core/v5/app/tun" @@ -123,11 +124,14 @@ import ( // Subscription Supports _ "github.com/v2fly/v2ray-core/v5/app/subscription/subscriptionmanager" + _ "github.com/v2fly/v2ray-core/v5/app/subscription/subscriptionmanager/command" + // Subscription Containers: general purpose _ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/base64urlline" _ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/dataurlsingle" _ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/jsonfieldarray" _ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/jsonfieldarray/jsonified" + _ "github.com/v2fly/v2ray-core/v5/app/subscription/containers/urlline" // Subscription Fetchers _ "github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher/dataurlfetcher" diff --git a/v2rayn/v2rayN/AmazTool/UpgradeApp.cs b/v2rayn/v2rayN/AmazTool/UpgradeApp.cs index b1ef7bfda9..03e234a0b0 100644 --- a/v2rayn/v2rayN/AmazTool/UpgradeApp.cs +++ b/v2rayn/v2rayN/AmazTool/UpgradeApp.cs @@ -10,7 +10,7 @@ namespace AmazTool { Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}"); - Waiting(5); + Utils.Waiting(5); if (!File.Exists(fileName)) { @@ -42,12 +42,12 @@ namespace AmazTool StringBuilder sb = new(); try { - string thisAppOldFile = $"{Utils.GetExePath()}.tmp"; + var thisAppOldFile = $"{Utils.GetExePath()}.tmp"; File.Delete(thisAppOldFile); - string splitKey = "/"; + var splitKey = "/"; - using ZipArchive archive = ZipFile.OpenRead(fileName); - foreach (ZipArchiveEntry entry in archive.Entries) + using var archive = ZipFile.OpenRead(fileName); + foreach (var entry in archive.Entries) { try { @@ -60,15 +60,20 @@ namespace AmazTool var lst = entry.FullName.Split(splitKey); if (lst.Length == 1) continue; - string fullName = string.Join(splitKey, lst[1..lst.Length]); + var fullName = string.Join(splitKey, lst[1..lst.Length]); if (string.Equals(Utils.GetExePath(), Utils.GetPath(fullName), StringComparison.OrdinalIgnoreCase)) { File.Move(Utils.GetExePath(), thisAppOldFile); } - string entryOutputPath = Utils.GetPath(fullName); + var entryOutputPath = Utils.GetPath(fullName); Directory.CreateDirectory(Path.GetDirectoryName(entryOutputPath)!); + //In the bin folder, if the file already exists, it will be skipped + if (fullName.StartsWith("bin") && File.Exists(entryOutputPath)) + { + continue; + } entry.ExtractToFile(entryOutputPath, true); Console.WriteLine(entryOutputPath); @@ -91,18 +96,9 @@ namespace AmazTool } Console.WriteLine(Resx.Resource.Restartv2rayN); - Waiting(2); + Utils.Waiting(2); Utils.StartV2RayN(); } - - public static void Waiting(int second) - { - for (var i = second; i > 0; i--) - { - Console.WriteLine(i); - Thread.Sleep(1000); - } - } } } \ No newline at end of file diff --git a/v2rayn/v2rayN/AmazTool/Utils.cs b/v2rayn/v2rayN/AmazTool/Utils.cs index 9152679f90..d418964437 100644 --- a/v2rayn/v2rayN/AmazTool/Utils.cs +++ b/v2rayn/v2rayN/AmazTool/Utils.cs @@ -39,5 +39,14 @@ namespace AmazTool }; process.Start(); } + + public static void Waiting(int second) + { + for (var i = second; i > 0; i--) + { + Console.WriteLine(i); + Thread.Sleep(1000); + } + } } } \ No newline at end of file diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatActivity.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatActivity.kt index eb13c53888..b275c348ee 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatActivity.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/LogcatActivity.kt @@ -59,7 +59,7 @@ class LogcatActivity : BaseActivity(), SwipeRefreshLayout.OnRefreshListener { Runtime.getRuntime().exec(lst.toTypedArray()) } - val allText = process.inputStream.bufferedReader().use { it.readLines() } + val allText = process.inputStream.bufferedReader().use { it.readLines() }.reversed() launch(Dispatchers.Main) { logsetsAll = allText.toMutableList() logsets = allText.toMutableList() diff --git a/xray-core/common/reflect/marshal.go b/xray-core/common/reflect/marshal.go index 2b224b457b..127dc8e0b4 100644 --- a/xray-core/common/reflect/marshal.go +++ b/xray-core/common/reflect/marshal.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "reflect" - "slices" "strings" cnet "github.com/xtls/xray-core/common/net" @@ -32,6 +31,9 @@ func JSONMarshalWithoutEscape(t interface{}) ([]byte, error) { } func marshalTypedMessage(v *cserial.TypedMessage, ignoreNullValue bool, insertTypeInfo bool) interface{} { + if v == nil { + return nil + } tmsg, err := v.GetInstance() if err != nil { return nil @@ -56,7 +58,9 @@ func marshalSlice(v reflect.Value, ignoreNullValue bool, insertTypeInfo bool) in } func isNullValue(f reflect.StructField, rv reflect.Value) bool { - if rv.Kind() == reflect.String && rv.Len() == 0 { + if rv.Kind() == reflect.Struct { + return false + } else if rv.Kind() == reflect.String && rv.Len() == 0 { return true } else if !isValueKind(rv.Kind()) && rv.IsNil() { return true @@ -182,6 +186,12 @@ func marshalKnownType(v interface{}, ignoreNullValue bool, insertTypeInfo bool) case *conf.PortList: cpl := v.(*conf.PortList) return serializePortList(cpl.Build()) + case conf.Int32Range: + i32rng := v.(conf.Int32Range) + if i32rng.Left == i32rng.Right { + return i32rng.Left, true + } + return i32rng.String(), true case cnet.Address: if addr := v.(cnet.Address); addr != nil { return addr.String(), true @@ -192,28 +202,29 @@ func marshalKnownType(v interface{}, ignoreNullValue bool, insertTypeInfo bool) } } -var valueKinds = []reflect.Kind{ - reflect.Bool, - reflect.Int, - reflect.Int8, - reflect.Int16, - reflect.Int32, - reflect.Int64, - reflect.Uint, - reflect.Uint8, - reflect.Uint16, - reflect.Uint32, - reflect.Uint64, - reflect.Uintptr, - reflect.Float32, - reflect.Float64, - reflect.Complex64, - reflect.Complex128, - reflect.String, -} - func isValueKind(kind reflect.Kind) bool { - return slices.Contains(valueKinds, kind) + switch kind { + case reflect.Bool, + reflect.Int, + reflect.Int8, + reflect.Int16, + reflect.Int32, + reflect.Int64, + reflect.Uint, + reflect.Uint8, + reflect.Uint16, + reflect.Uint32, + reflect.Uint64, + reflect.Uintptr, + reflect.Float32, + reflect.Float64, + reflect.Complex64, + reflect.Complex128, + reflect.String: + return true + default: + return false + } } func marshalInterface(v interface{}, ignoreNullValue bool, insertTypeInfo bool) interface{} { diff --git a/xray-core/common/reflect/marshal_test.go b/xray-core/common/reflect/marshal_test.go index 82194279b5..80df23f1e8 100644 --- a/xray-core/common/reflect/marshal_test.go +++ b/xray-core/common/reflect/marshal_test.go @@ -116,98 +116,129 @@ func TestMarshalConfigJson(t *testing.T) { "system", "inboundDownlink", "outboundUplink", + "XHTTP_IN", + "\"host\": \"bing.com\"", + "scMaxEachPostBytes", + "\"from\": 100", + "\"to\": 1000", + "\"from\": 1000000", + "\"to\": 1000000", } for _, kw := range keywords { if !strings.Contains(tc, kw) { - t.Error("marshaled config error") + t.Log("config.json:", tc) + t.Error("keyword not found:", kw) + break } } } func getConfig() string { return `{ - "log": { - "loglevel": "debug" - }, - "stats": {}, - "policy": { - "levels": { - "0": { - "statsUserUplink": true, - "statsUserDownlink": true - } - }, - "system": { - "statsInboundUplink": true, - "statsInboundDownlink": true, - "statsOutboundUplink": true, - "statsOutboundDownlink": true - } - }, - "inbounds": [ - { - "tag": "agentin", - "protocol": "http", - "port": 8080, - "listen": "127.0.0.1", - "settings": {} - }, - { - "listen": "127.0.0.1", - "port": 10085, - "protocol": "dokodemo-door", - "settings": { - "address": "127.0.0.1" - }, - "tag": "api-in" - } - ], - "api": { - "tag": "api", - "services": [ - "HandlerService", - "StatsService" - ] - }, - "routing": { - "rules": [ - { - "inboundTag": [ - "api-in" - ], - "outboundTag": "api", - "type": "field" - } - ], - "domainStrategy": "AsIs" - }, - "outbounds": [ - { - "protocol": "vless", - "settings": { - "vnext": [ - { - "address": "1.2.3.4", - "port": 1234, - "users": [ - { - "id": "4784f9b8-a879-4fec-9718-ebddefa47750", - "encryption": "none" - } - ] - } - ] - }, - "tag": "agentout", - "streamSettings": { - "network": "ws", - "security": "none", - "wsSettings": { - "path": "/?ed=2048", - "host": "bing.com" - } - } - } - ] - }` + "log": { + "loglevel": "debug" + }, + "stats": {}, + "policy": { + "levels": { + "0": { + "statsUserUplink": true, + "statsUserDownlink": true + } + }, + "system": { + "statsInboundUplink": true, + "statsInboundDownlink": true, + "statsOutboundUplink": true, + "statsOutboundDownlink": true + } + }, + "inbounds": [ + { + "tag": "agentin", + "protocol": "http", + "port": 18080, + "listen": "127.0.0.1", + "settings": {} + }, + { + "listen": "127.0.0.1", + "port": 10085, + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1" + }, + "tag": "api-in" + } + ], + "api": { + "tag": "api", + "services": [ + "HandlerService", + "StatsService" + ] + }, + "routing": { + "rules": [ + { + "inboundTag": [ + "api-in" + ], + "outboundTag": "api", + "type": "field" + } + ], + "domainStrategy": "AsIs" + }, + "outbounds": [ + { + "protocol": "vless", + "settings": { + "vnext": [ + { + "address": "1.2.3.4", + "port": 1234, + "users": [ + { + "id": "4784f9b8-a879-4fec-9718-ebddefa47750", + "encryption": "none" + } + ] + } + ] + }, + "tag": "XHTTP_IN", + "streamSettings": { + "network": "xhttp", + "xhttpSettings": { + "host": "bing.com", + "path": "/xhttp_client_upload", + "mode": "auto", + "extra": { + "noSSEHeader": false, + "scMaxEachPostBytes": 1000000, + "scMaxBufferedPosts": 30, + "xPaddingBytes": "100-1000" + } + }, + "sockopt": { + "tcpFastOpen": true, + "acceptProxyProtocol": false, + "tcpcongestion": "bbr", + "tcpMptcp": true + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls", + "quic" + ], + "metadataOnly": false, + "routeOnly": true + } + } + ] +}` } diff --git a/xray-core/proxy/socks/server.go b/xray-core/proxy/socks/server.go index 34c42ae994..472b23a066 100644 --- a/xray-core/proxy/socks/server.go +++ b/xray-core/proxy/socks/server.go @@ -2,6 +2,7 @@ package socks import ( "context" + goerrors "errors" "io" "time" @@ -78,7 +79,13 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con switch network { case net.Network_TCP: firstbyte := make([]byte, 1) - conn.Read(firstbyte) + if n, err := conn.Read(firstbyte); n == 0 { + if goerrors.Is(err, io.EOF) { + errors.LogInfo(ctx, "Connection closed immediately, likely health check connection") + return nil + } + return errors.New("failed to read from connection").Base(err) + } if firstbyte[0] != 5 && firstbyte[0] != 4 { // Check if it is Socks5/4/4a errors.LogDebug(ctx, "Not Socks request, try to parse as HTTP request") return s.httpServer.ProcessWithFirstbyte(ctx, network, conn, dispatcher, firstbyte...)