Update On Mon Oct 21 20:36:26 CEST 2024

This commit is contained in:
github-action[bot]
2024-10-21 20:36:27 +02:00
parent a2e7d7f51b
commit db0940aedb
355 changed files with 12956 additions and 6642 deletions

1
.github/update.log vendored
View File

@@ -800,3 +800,4 @@ Update On Thu Oct 17 20:34:12 CEST 2024
Update On Fri Oct 18 20:36:34 CEST 2024
Update On Sat Oct 19 20:34:29 CEST 2024
Update On Sun Oct 20 20:32:12 CEST 2024
Update On Mon Oct 21 20:36:16 CEST 2024

View File

@@ -20,12 +20,12 @@ require (
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399
github.com/metacubex/chacha v0.1.0
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
github.com/metacubex/quic-go v0.47.1-0.20240909010619-6b38f24bfcc4
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4
github.com/metacubex/sing-shadowsocks v0.2.8
github.com/metacubex/sing-shadowsocks2 v0.2.2
github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa
@@ -39,7 +39,7 @@ require (
github.com/sagernet/cors v1.2.1
github.com/sagernet/fswatch v0.1.1
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
github.com/sagernet/sing v0.5.0-alpha.13
github.com/sagernet/sing v0.5.0-rc.4
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
github.com/sagernet/sing-shadowtls v0.1.4
github.com/samber/lo v1.47.0
@@ -116,4 +116,4 @@ require (
golang.org/x/tools v0.24.0 // indirect
)
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a

View File

@@ -104,20 +104,20 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw=
github.com/metacubex/quic-go v0.47.1-0.20240909010619-6b38f24bfcc4 h1:CgdUBRxmNlxEGkp35HwvgQ10jwOOUJKWdOxpi8yWi8o=
github.com/metacubex/quic-go v0.47.1-0.20240909010619-6b38f24bfcc4/go.mod h1:Y7yRGqFE6UQL/3aKPYmiYdjfVkeujJaStP4+jiZMcN8=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174 h1:GvigRPEU+cbnzdLWne47cxLrc28Abohl3ECtVdnrbq0=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174/go.mod h1:AiZ+UPgrkO1DTnmiAX4b+kRoV1Vfc65UkYD7RbFlIZA=
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297 h1:YG/JkwGPbca5rUtEMHIu8ZuqzR7BSVm1iqY8hNoMeMA=
github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a h1:JuR0/7RDxQtlZp/GOzrdqNq04HplTxavPRHrek8ouJk=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4 h1:HobpULaPK6OoxrHMmgcwLkwwIduXVmwdcznwUfH1GQM=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8=
github.com/metacubex/sing-shadowsocks v0.2.8 h1:wIhlaigswzjPw4hej75sEvWte3QR0+AJRafgwBHO5B4=
github.com/metacubex/sing-shadowsocks v0.2.8/go.mod h1:X3x88XtJpBxG0W0/ECOJL6Ib0SJ3xdniAkU/6/RMWU0=
github.com/metacubex/sing-shadowsocks2 v0.2.2 h1:eaf42uVx4Lr21S6MDYs0ZdTvGA0GEhDpb9no4+gdXPo=
github.com/metacubex/sing-shadowsocks2 v0.2.2/go.mod h1:BhOug03a/RbI7y6hp6q+6ITM1dXjnLTmeWBHSTwvv2Q=
github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1 h1:ypfofGDZbP8p3Y4P/m74JYu7sQViesi3c8nbmT6cS0Y=
github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1/go.mod h1:olbEx9yVcaw5tHTNlRamRoxmMKcvDvcVS1YLnQGzvWE=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c h1:qfUZ8xBrViOCZamvcC8CyV7Ii8sAUrn7RqZxFGn56tQ=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c/go.mod h1:lCrP0AW7ieKnXG1JEeZLW+9h99QzjuOX0MfCQfz6TgE=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns=

View File

@@ -279,7 +279,7 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
return
}
defaultInterfaceMonitor, err = tun.NewDefaultInterfaceMonitor(networkUpdateMonitor, log.SingLogger, tun.DefaultInterfaceMonitorOptions{OverrideAndroidVPN: true})
defaultInterfaceMonitor, err = tun.NewDefaultInterfaceMonitor(networkUpdateMonitor, log.SingLogger, tun.DefaultInterfaceMonitorOptions{InterfaceFinder: interfaceFinder, OverrideAndroidVPN: true})
if err != nil {
err = E.Cause(err, "create DefaultInterfaceMonitor")
return

View File

@@ -358,7 +358,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -548,7 +548,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -583,7 +583,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -623,7 +623,7 @@ checksum = "99e1aca718ea7b89985790c94aad72d77533063fe00bc497bb79a7c2dae6a661"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -848,7 +848,7 @@ dependencies = [
"bitflags 2.6.0",
"cexpr",
"clang-sys",
"itertools 0.12.1",
"itertools 0.10.5",
"lazy_static",
"lazycell",
"log",
@@ -858,7 +858,7 @@ dependencies = [
"regex",
"rustc-hash 1.1.0",
"shlex",
"syn 2.0.81",
"syn 2.0.82",
"which 4.4.2",
]
@@ -1046,7 +1046,7 @@ checksum = "240f4126219a83519bad05c9a40bfc0303921eeb571fc2d7e44c17ffac99d3f1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"synstructure",
]
@@ -1167,7 +1167,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -1461,7 +1461,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -1729,7 +1729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f76990911f2267d837d9d0ad060aa63aaad170af40904b29461734c339030d4d"
dependencies = [
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -1984,7 +1984,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
dependencies = [
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -1994,7 +1994,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
dependencies = [
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2065,7 +2065,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2076,7 +2076,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2180,7 +2180,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2201,7 +2201,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2211,7 +2211,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
dependencies = [
"derive_builder_core",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2224,7 +2224,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2356,7 +2356,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2388,7 +2388,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2659,7 +2659,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2680,7 +2680,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -2982,7 +2982,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -3106,7 +3106,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -3394,7 +3394,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -3668,7 +3668,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -4122,7 +4122,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -4306,7 +4306,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -5013,7 +5013,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -5389,7 +5389,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -5449,7 +5449,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -5506,7 +5506,7 @@ version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -5835,7 +5835,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -5986,7 +5986,7 @@ checksum = "0a4b29106d9f2bbcca4f5ee7a9325c99844ff9721d10103625cd5278795507fe"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -6226,7 +6226,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -6364,7 +6364,7 @@ dependencies = [
"phf_shared 0.11.2",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -6417,7 +6417,7 @@ checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -6568,7 +6568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
dependencies = [
"proc-macro2",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -6654,7 +6654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd"
dependencies = [
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -6989,7 +6989,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -7237,7 +7237,7 @@ dependencies = [
"serde",
"serde_json",
"serde_yml",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -7422,7 +7422,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -7564,7 +7564,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -7575,7 +7575,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -7608,7 +7608,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -7659,7 +7659,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -8162,7 +8162,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -8215,9 +8215,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.81"
version = "2.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "198514704ca887dd5a1e408c6c6cdcba43672f9b4062e1b24aa34e74e6d7faae"
checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021"
dependencies = [
"proc-macro2",
"quote",
@@ -8247,7 +8247,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -8368,7 +8368,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -8485,7 +8485,7 @@ dependencies = [
"serde",
"serde_json",
"sha2 0.10.8",
"syn 2.0.81",
"syn 2.0.82",
"tauri-utils",
"thiserror",
"time",
@@ -8503,7 +8503,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"tauri-codegen",
"tauri-utils",
]
@@ -8558,9 +8558,9 @@ dependencies = [
[[package]]
name = "tauri-plugin-dialog"
version = "2.0.1"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddb2fe88b602461c118722c574e2775ab26a4e68886680583874b2f6520608b7"
checksum = "4307310e1d2c09ab110235834722e7c2b85099b683e1eb7342ab351b0be5ada3"
dependencies = [
"log",
"raw-window-handle",
@@ -8576,9 +8576,9 @@ dependencies = [
[[package]]
name = "tauri-plugin-fs"
version = "2.0.1"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab300488ebec3487ca5f56289692e7e45feb07eea8d5e1dba497f7dc9dd9c407"
checksum = "96ba7d46e86db8c830d143ef90ab5a453328365b0cc834c24edea4267b16aba0"
dependencies = [
"anyhow",
"dunce",
@@ -8659,9 +8659,9 @@ dependencies = [
[[package]]
name = "tauri-plugin-shell"
version = "2.0.1"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "371fb9aca2823990a2d0db7970573be5fdf07881fcaa2b835b29631feb84aec1"
checksum = "0ad7880c5586b6b2104be451e3d7fc0f3800c84bda69e9ba81c828f87cb34267"
dependencies = [
"encoding_rs",
"log",
@@ -8916,7 +8916,7 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -8959,7 +8959,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -9115,7 +9115,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -9295,7 +9295,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -9936,7 +9936,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"wasm-bindgen-shared",
]
@@ -9970,7 +9970,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -10241,7 +10241,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -10548,7 +10548,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -10559,7 +10559,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -10570,7 +10570,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -10581,7 +10581,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -10592,7 +10592,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -10603,7 +10603,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -11170,7 +11170,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"synstructure",
]
@@ -11231,7 +11231,7 @@ checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"zbus-lockstep",
"zbus_xml",
"zvariant",
@@ -11246,7 +11246,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"zvariant_utils",
]
@@ -11292,7 +11292,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -11312,7 +11312,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"synstructure",
]
@@ -11333,7 +11333,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -11355,7 +11355,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]
[[package]]
@@ -11485,7 +11485,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
"zvariant_utils",
]
@@ -11497,5 +11497,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.81",
"syn 2.0.82",
]

View File

@@ -21,7 +21,7 @@
"@mui/material": "6.1.4",
"@nyanpasu/interface": "workspace:^",
"@nyanpasu/ui": "workspace:^",
"@tanstack/router-zod-adapter": "1.74.0",
"@tanstack/router-zod-adapter": "1.74.4",
"@tauri-apps/api": "2.0.2",
"@types/json-schema": "7.0.15",
"ahooks": "3.8.1",
@@ -29,7 +29,7 @@
"country-code-emoji": "2.3.0",
"dayjs": "1.11.13",
"framer-motion": "12.0.0-alpha.1",
"i18next": "23.16.1",
"i18next": "23.16.2",
"jotai": "2.10.1",
"json-schema": "0.4.0",
"material-react-table": "3.0.1",
@@ -52,18 +52,18 @@
"@csstools/normalize.css": "12.1.1",
"@emotion/babel-plugin": "11.12.0",
"@emotion/react": "11.13.3",
"@iconify/json": "2.2.261",
"@iconify/json": "2.2.262",
"@monaco-editor/react": "4.6.0",
"@tanstack/react-router": "1.74.0",
"@tanstack/router-devtools": "1.74.0",
"@tanstack/router-plugin": "1.73.1",
"@tanstack/react-router": "1.74.4",
"@tanstack/router-devtools": "1.74.4",
"@tanstack/router-plugin": "1.74.2",
"@tauri-apps/plugin-clipboard-manager": "2.0.0",
"@tauri-apps/plugin-dialog": "2.0.1",
"@tauri-apps/plugin-fs": "2.0.0",
"@tauri-apps/plugin-fs": "2.0.1",
"@tauri-apps/plugin-notification": "2.0.0",
"@tauri-apps/plugin-os": "2.0.0",
"@tauri-apps/plugin-process": "2.0.0",
"@tauri-apps/plugin-shell": "2.0.0",
"@tauri-apps/plugin-shell": "2.0.1",
"@tauri-apps/plugin-updater": "2.0.0",
"@types/react": "18.3.11",
"@types/react-dom": "18.3.1",

View File

@@ -217,8 +217,8 @@ importers:
specifier: workspace:^
version: link:../ui
'@tanstack/router-zod-adapter':
specifier: 1.74.0
version: 1.74.0(@tanstack/react-router@1.74.0(@tanstack/router-generator@1.73.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020))(zod@3.23.8)
specifier: 1.74.4
version: 1.74.4(@tanstack/react-router@1.74.4(@tanstack/router-generator@1.74.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020))(zod@3.23.8)
'@tauri-apps/api':
specifier: 2.0.2
version: 2.0.2
@@ -241,8 +241,8 @@ importers:
specifier: 12.0.0-alpha.1
version: 12.0.0-alpha.1(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
i18next:
specifier: 23.16.1
version: 23.16.1
specifier: 23.16.2
version: 23.16.2
jotai:
specifier: 2.10.1
version: 2.10.1(react@19.0.0-rc-65a56d0e-20241020)(types-react@19.0.0-rc.1)
@@ -275,7 +275,7 @@ importers:
version: 7.4.0(xjqvl6gudwt62pepgh7ow64mzi)
react-i18next:
specifier: 15.0.3
version: 15.0.3(i18next@23.16.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
version: 15.0.3(i18next@23.16.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
react-markdown:
specifier: 9.0.1
version: 9.0.1(react@19.0.0-rc-65a56d0e-20241020)(types-react@19.0.0-rc.1)
@@ -305,20 +305,20 @@ importers:
specifier: 11.13.3
version: 11.13.3(react@19.0.0-rc-65a56d0e-20241020)(types-react@19.0.0-rc.1)
'@iconify/json':
specifier: 2.2.261
version: 2.2.261
specifier: 2.2.262
version: 2.2.262
'@monaco-editor/react':
specifier: 4.6.0
version: 4.6.0(monaco-editor@0.52.0)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
'@tanstack/react-router':
specifier: 1.74.0
version: 1.74.0(@tanstack/router-generator@1.73.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
specifier: 1.74.4
version: 1.74.4(@tanstack/router-generator@1.74.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
'@tanstack/router-devtools':
specifier: 1.74.0
version: 1.74.0(@tanstack/react-router@1.74.0(@tanstack/router-generator@1.73.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020))(csstype@3.1.3)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
specifier: 1.74.4
version: 1.74.4(@tanstack/react-router@1.74.4(@tanstack/router-generator@1.74.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020))(csstype@3.1.3)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
'@tanstack/router-plugin':
specifier: 1.73.1
version: 1.73.1(vite@5.4.9(@types/node@22.7.7)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.80.3)(stylus@0.62.0))(webpack-sources@3.2.3)
specifier: 1.74.2
version: 1.74.2(vite@5.4.9(@types/node@22.7.7)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.80.3)(stylus@0.62.0))(webpack-sources@3.2.3)
'@tauri-apps/plugin-clipboard-manager':
specifier: 2.0.0
version: 2.0.0
@@ -326,8 +326,8 @@ importers:
specifier: 2.0.1
version: 2.0.1
'@tauri-apps/plugin-fs':
specifier: 2.0.0
version: 2.0.0
specifier: 2.0.1
version: 2.0.1
'@tauri-apps/plugin-notification':
specifier: 2.0.0
version: 2.0.0
@@ -338,8 +338,8 @@ importers:
specifier: 2.0.0
version: 2.0.0
'@tauri-apps/plugin-shell':
specifier: 2.0.0
version: 2.0.0
specifier: 2.0.1
version: 2.0.1
'@tauri-apps/plugin-updater':
specifier: 2.0.0
version: 2.0.0
@@ -462,7 +462,7 @@ importers:
version: 4.1.2(react@19.0.0-rc-65a56d0e-20241020)
react-i18next:
specifier: 15.0.3
version: 15.0.3(i18next@23.16.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
version: 15.0.3(i18next@23.16.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
react-use:
specifier: 17.5.1
version: 17.5.1(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
@@ -801,10 +801,6 @@ packages:
resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==}
engines: {node: '>=6.9.0'}
'@babel/template@7.25.0':
resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==}
engines: {node: '>=6.9.0'}
'@babel/template@7.25.7':
resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==}
engines: {node: '>=6.9.0'}
@@ -1377,8 +1373,8 @@ packages:
'@vue/compiler-sfc':
optional: true
'@iconify/json@2.2.261':
resolution: {integrity: sha512-uUm8Svulz5aRRF0X+r2/UG5P0xcUCGOGVmAFJ/ZANx29wqE79PvGCYXHuznNC0h8+UW1fnvprj7FmgJELvMYZw==}
'@iconify/json@2.2.262':
resolution: {integrity: sha512-h7zMbLxsKohKXvf2Lpq6Xob7dxkqXxrUVR58ZvZBgCSrHcE69QJmcFG/KaAwM1eGuKToWvgPWeb1xE6zy7juqg==}
'@iconify/types@2.0.0':
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
@@ -2307,11 +2303,11 @@ packages:
resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==}
engines: {node: '>=12'}
'@tanstack/react-router@1.74.0':
resolution: {integrity: sha512-dthfscAM25bi1AjA38t9jPsU2jqNk0f6a6ziorEi845ss6Uwrbw4FSFQ1oI1UmUfaJR73S5SO8TGXKZAIxhlWQ==}
'@tanstack/react-router@1.74.4':
resolution: {integrity: sha512-dVI8L1Nc4d/njlFFm2O5NPLcqOd6/D10LaODIYNsbWts4UjQpQFBZcY5PGDBp9yPJxYMZ1wVctcWSGHrAUL4HQ==}
engines: {node: '>=12'}
peerDependencies:
'@tanstack/router-generator': 1.73.1
'@tanstack/router-generator': 1.74.2
react: '>=18'
react-dom: '>=18'
peerDependenciesMeta:
@@ -2337,20 +2333,20 @@ packages:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
'@tanstack/router-devtools@1.74.0':
resolution: {integrity: sha512-lr7e5PU43tDD//7mN+bBfSgQphchzHk5NbhzlwgEuEW74lYc6CCRUUeORR+pPAUFdf8+7yQ6iv5Ow7iaXb17ng==}
'@tanstack/router-devtools@1.74.4':
resolution: {integrity: sha512-g0ZNtee60k4sGSVSIqqeOgXgIG18e7QJysJhrPqotlRKCLBKjScqivoNejM3pYWjyJVmzdZEiclwsOOJ6CezOA==}
engines: {node: '>=12'}
peerDependencies:
'@tanstack/react-router': ^1.74.0
'@tanstack/react-router': ^1.74.4
react: '>=18'
react-dom: '>=18'
'@tanstack/router-generator@1.73.1':
resolution: {integrity: sha512-+oHYnspeS3f4bpbnUymH9dEGJbxhfV0rSwHl0cTq4pXSPXuLYcqYZmSGCqBfiq6CGtgOXZ2wEUMgezt3R2PvZg==}
'@tanstack/router-generator@1.74.2':
resolution: {integrity: sha512-S69fXvYcL+tQsO5Fe9ju/XVa/hZvk4pCaWbtoR2MNjIgR2RmjiFKOgXYeLRMNom/IpP/HAQmQ3m1DwU9jjSUKA==}
engines: {node: '>=12'}
'@tanstack/router-plugin@1.73.1':
resolution: {integrity: sha512-pJMTWVFEIvTXLL6kzYZlPRlQ7WwfsBNZGIJck+dX0NQVjw6CEj1a4w9hlJFSqIOBbRdjtY6hS3Y00DDFGf9Inw==}
'@tanstack/router-plugin@1.74.2':
resolution: {integrity: sha512-HcG0FwSZ77g0QH9Ev2I1QYeXS+WWjdThO5Whgm/9abkyJq5GfsiLm2Ey2cw2Va+iHgD2nQdkraP9xL/z9/s6BQ==}
engines: {node: '>=12'}
peerDependencies:
'@rsbuild/core': '>=1.0.2'
@@ -2364,8 +2360,8 @@ packages:
webpack:
optional: true
'@tanstack/router-zod-adapter@1.74.0':
resolution: {integrity: sha512-YBYVNyRJ/XIVJ/QUt27s+2oaEO1YcANwlRLfvfIPDk+V3DHTz33z4+oNJ/I/YlJUOTNcoqv7mlqmWnk8Zn4Cmw==}
'@tanstack/router-zod-adapter@1.74.4':
resolution: {integrity: sha512-931F+4poa6dnKN/ecHRRBPuhYUysAsd60uNWfr0Yj9XYo0OuNa8R3J2T7NBV7gVtWTg5ywxm360KXoHCJ6gSWQ==}
engines: {node: '>=12'}
peerDependencies:
'@tanstack/react-router': '>=1.43.2'
@@ -2465,8 +2461,8 @@ packages:
'@tauri-apps/plugin-dialog@2.0.1':
resolution: {integrity: sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==}
'@tauri-apps/plugin-fs@2.0.0':
resolution: {integrity: sha512-BNEeQQ5aH8J5SwYuWgRszVyItsmquRuzK2QRkVj8Z0sCsLnSvJFYI3JHRzzr3ltZGq1nMPtblrlZzuKqVzRawA==}
'@tauri-apps/plugin-fs@2.0.1':
resolution: {integrity: sha512-PkeZG2WAob9Xpmr66aPvj+McDVgFjV2a7YBzYVZjiCvbGeMs6Yk09tlXhCe3EyZdT/pwWMSi8lXUace+hlsjsw==}
'@tauri-apps/plugin-notification@2.0.0':
resolution: {integrity: sha512-6qEDYJS7mgXZWLXA0EFL+DVCJh8sJlzSoyw6B50pxhLPVFjc5Vr5DVzl5W3mUHaYhod5wsC984eQnlCCGqxYDA==}
@@ -2477,8 +2473,8 @@ packages:
'@tauri-apps/plugin-process@2.0.0':
resolution: {integrity: sha512-OYzi0GnkrF4NAnsHZU7U3tjSoP0PbeAlO7T1Z+vJoBUH9sFQ1NSLqWYWQyf8hcb3gVWe7P1JggjiskO+LST1ug==}
'@tauri-apps/plugin-shell@2.0.0':
resolution: {integrity: sha512-OpW2+ycgJLrEoZityWeWYk+6ZWP9VyiAfbO+N/O8VfLkqyOym8kXh7odKDfINx9RAotkSGBtQM4abyKfJDkcUg==}
'@tauri-apps/plugin-shell@2.0.1':
resolution: {integrity: sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==}
'@tauri-apps/plugin-updater@2.0.0':
resolution: {integrity: sha512-N0cl71g7RPr7zK2Fe5aoIwzw14NcdLcz7XMGFWZVjprsqgDRWoxbnUkknyCQMZthjhGkppCd/wN2MIsUz+eAhQ==}
@@ -4422,8 +4418,8 @@ packages:
hyphenate-style-name@1.1.0:
resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
i18next@23.16.1:
resolution: {integrity: sha512-H73h/H7BN7PI38Sq9XsOXzWFBH6mtyCYFiUMVtd9BxiYNDWPPIzKcBmDrqhjKbw3IXP5j6JoSW4ugJlaZuOvKw==}
i18next@23.16.2:
resolution: {integrity: sha512-dFyxwLXxEQK32f6tITBMaRht25mZPJhQ0WbC0p3bO2mWBal9lABTMqSka5k+GLSRWLzeJBKDpH7BeIA9TZI7Jg==}
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
@@ -7333,14 +7329,14 @@ snapshots:
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.24.7
'@babel/generator': 7.25.6
'@babel/generator': 7.25.7
'@babel/helper-compilation-targets': 7.25.2
'@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2)
'@babel/helpers': 7.25.6
'@babel/parser': 7.25.6
'@babel/template': 7.25.0
'@babel/traverse': 7.25.6
'@babel/types': 7.25.6
'@babel/parser': 7.25.8
'@babel/template': 7.25.7
'@babel/traverse': 7.25.7
'@babel/types': 7.25.8
convert-source-map: 2.0.0
debug: 4.3.7
gensync: 1.0.0-beta.2
@@ -7469,7 +7465,7 @@ snapshots:
'@babel/core': 7.25.2
'@babel/helper-module-imports': 7.24.7
'@babel/helper-simple-access': 7.24.7
'@babel/helper-validator-identifier': 7.24.7
'@babel/helper-validator-identifier': 7.25.7
'@babel/traverse': 7.25.7
transitivePeerDependencies:
- supports-color
@@ -7609,12 +7605,6 @@ snapshots:
dependencies:
regenerator-runtime: 0.14.1
'@babel/template@7.25.0':
dependencies:
'@babel/code-frame': 7.24.7
'@babel/parser': 7.25.8
'@babel/types': 7.25.8
'@babel/template@7.25.7':
dependencies:
'@babel/code-frame': 7.25.7
@@ -8162,7 +8152,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@iconify/json@2.2.261':
'@iconify/json@2.2.262':
dependencies:
'@iconify/types': 2.0.0
pathe: 1.1.2
@@ -9066,7 +9056,7 @@ snapshots:
dependencies:
remove-accents: 0.5.0
'@tanstack/react-router@1.74.0(@tanstack/router-generator@1.73.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)':
'@tanstack/react-router@1.74.4(@tanstack/router-generator@1.74.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)':
dependencies:
'@tanstack/history': 1.61.1
'@tanstack/react-store': 0.5.5(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
@@ -9075,7 +9065,7 @@ snapshots:
tiny-invariant: 1.3.3
tiny-warning: 1.0.3
optionalDependencies:
'@tanstack/router-generator': 1.73.1
'@tanstack/router-generator': 1.74.2
'@tanstack/react-store@0.5.5(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)':
dependencies:
@@ -9096,9 +9086,9 @@ snapshots:
react: 19.0.0-rc-65a56d0e-20241020
react-dom: 19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020)
'@tanstack/router-devtools@1.74.0(@tanstack/react-router@1.74.0(@tanstack/router-generator@1.73.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020))(csstype@3.1.3)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)':
'@tanstack/router-devtools@1.74.4(@tanstack/react-router@1.74.4(@tanstack/router-generator@1.74.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020))(csstype@3.1.3)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)':
dependencies:
'@tanstack/react-router': 1.74.0(@tanstack/router-generator@1.73.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
'@tanstack/react-router': 1.74.4(@tanstack/router-generator@1.74.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
clsx: 2.1.1
goober: 2.1.16(csstype@3.1.3)
react: 19.0.0-rc-65a56d0e-20241020
@@ -9106,14 +9096,14 @@ snapshots:
transitivePeerDependencies:
- csstype
'@tanstack/router-generator@1.73.1':
'@tanstack/router-generator@1.74.2':
dependencies:
'@tanstack/virtual-file-routes': 1.64.0
prettier: 3.3.3
tsx: 4.19.1
zod: 3.23.8
'@tanstack/router-plugin@1.73.1(vite@5.4.9(@types/node@22.7.7)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.80.3)(stylus@0.62.0))(webpack-sources@3.2.3)':
'@tanstack/router-plugin@1.74.2(vite@5.4.9(@types/node@22.7.7)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.80.3)(stylus@0.62.0))(webpack-sources@3.2.3)':
dependencies:
'@babel/core': 7.25.8
'@babel/generator': 7.25.7
@@ -9123,7 +9113,7 @@ snapshots:
'@babel/template': 7.25.7
'@babel/traverse': 7.25.7
'@babel/types': 7.25.8
'@tanstack/router-generator': 1.73.1
'@tanstack/router-generator': 1.74.2
'@tanstack/virtual-file-routes': 1.64.0
'@types/babel__core': 7.20.5
'@types/babel__generator': 7.6.8
@@ -9139,9 +9129,9 @@ snapshots:
- supports-color
- webpack-sources
'@tanstack/router-zod-adapter@1.74.0(@tanstack/react-router@1.74.0(@tanstack/router-generator@1.73.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020))(zod@3.23.8)':
'@tanstack/router-zod-adapter@1.74.4(@tanstack/react-router@1.74.4(@tanstack/router-generator@1.74.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020))(zod@3.23.8)':
dependencies:
'@tanstack/react-router': 1.74.0(@tanstack/router-generator@1.73.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
'@tanstack/react-router': 1.74.4(@tanstack/router-generator@1.74.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020)
zod: 3.23.8
'@tanstack/store@0.5.5': {}
@@ -9211,7 +9201,7 @@ snapshots:
dependencies:
'@tauri-apps/api': 2.0.2
'@tauri-apps/plugin-fs@2.0.0':
'@tauri-apps/plugin-fs@2.0.1':
dependencies:
'@tauri-apps/api': 2.0.2
@@ -9227,7 +9217,7 @@ snapshots:
dependencies:
'@tauri-apps/api': 2.0.2
'@tauri-apps/plugin-shell@2.0.0':
'@tauri-apps/plugin-shell@2.0.1':
dependencies:
'@tauri-apps/api': 2.0.2
@@ -11549,7 +11539,7 @@ snapshots:
hyphenate-style-name@1.1.0: {}
i18next@23.16.1:
i18next@23.16.2:
dependencies:
'@babel/runtime': 7.25.7
@@ -13035,11 +13025,11 @@ snapshots:
dependencies:
react: 19.0.0-rc-65a56d0e-20241020
react-i18next@15.0.3(i18next@23.16.1)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020):
react-i18next@15.0.3(i18next@23.16.2)(react-dom@19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020))(react@19.0.0-rc-65a56d0e-20241020):
dependencies:
'@babel/runtime': 7.25.6
html-parse-stringify: 3.0.1
i18next: 23.16.1
i18next: 23.16.2
react: 19.0.0-rc-65a56d0e-20241020
optionalDependencies:
react-dom: 19.0.0-rc-65a56d0e-20241020(react@19.0.0-rc-65a56d0e-20241020)

View File

@@ -24,7 +24,13 @@ body:
id: description
attributes:
label: 问题描述 / Describe the bug
description: 详细清晰地描述你遇到的问题 / A clear and concise description of what the bug is
description: 详细清晰地描述你遇到的问题,并配合截图 / Describe the problem you encountered in detail and clearly, and provide screenshots
validations:
required: true
- type: textarea
attributes:
label: 软件版本 / Verge Version
description: 请提供Verge的具体版本如果是alpha版本请注明下载时间(精确到小时分钟) / Please provide the specific version of Verge. If it is an alpha version, please indicate the download time (accurate to hours and minutes)
validations:
required: true
- type: textarea
@@ -51,6 +57,6 @@ body:
- type: textarea
attributes:
label: 日志 / Log
description: 请提供完整或相关部分的Debug日志 / Please provide the complete or relevant part of the Debug log
description: 请提供完整或相关部分的Debug日志(请在“软件左侧菜单”->“设置”->“日志等级”调整到debugVerge错误请把“杂项设置”->“app日志等级”调整到trace并重启Verge生效。日志文件在“软件左侧菜单”->“设置”->“日志目录”下) / Please provide a complete or relevant part of the Debug log (please adjust the "Log level" to debug in "Software left menu" -> "Settings" -> "Log level". If there is a Verge error, please adjust "Miscellaneous settings" -> "app log level" to trace, and restart Verge to take effect. The log file is under "Software left menu" -> "Settings" -> "Log directory")
validations:
required: true

View File

@@ -22,8 +22,6 @@ jobs:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: windows-latest
target: i686-pc-windows-msvc
- os: windows-latest
target: aarch64-pc-windows-msvc
- os: macos-latest
@@ -37,7 +35,7 @@ jobs:
uses: actions/checkout@v4
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@1.77.0
uses: dtolnay/rust-toolchain@stable
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
@@ -140,9 +138,6 @@ jobs:
- os: windows-latest
target: x86_64-pc-windows-msvc
arch: x64
- os: windows-latest
target: i686-pc-windows-msvc
arch: x86
- os: windows-latest
target: aarch64-pc-windows-msvc
arch: arm64
@@ -240,7 +235,7 @@ jobs:
cat > release.txt << 'EOF'
## 我应该下载哪个版本?
### MacOS (提示文件损坏或开发者无法验证请查看下面FAQ)
### MacOS
- MacOS intel芯片: x64.dmg
- MacOS apple M芯片: aarch64.dmg
@@ -250,20 +245,18 @@ jobs:
### Windows (Win7 用户请查看下面FAQ中的解决方案)
#### 正常版本(推荐)
- 64位: x64-setup.exe
- 32位: x86-setup.exe
- arm64架构: arm64-setup.exe
#### 便携版(不推荐使用,无法自动更新)
- 64位: x64_portable.zip
- 32位: x86_portable.zip
- arm64架构: arm64_portable.zip
#### 内置Webview2版(体积较大仅在企业版系统或Win7无法安装webview2时使用)
#### 便携版问题很多不再提供
#### 内置Webview2版(体积较大仅在企业版系统或无法安装webview2时使用)
- 64位: x64_fixed_webview2-setup.exe
- 32位: x86_fixed_webview2-setup.exe
- arm64架构: arm64_fixed_webview2-setup.exe
### FAQ
- [FAQ](https://clash-verge-rev.github.io/faq/windows.html)
- [常见问题](https://clash-verge-rev.github.io/faq/windows.html)
### 稳定机场VPN推荐
- [狗狗加速](https://verge.dginv.click/#/register?code=oaxsAGo6)
Created at ${{ env.BUILDTIME }}.
EOF

View File

@@ -33,7 +33,7 @@ jobs:
uses: actions/checkout@v4
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@1.77.0
uses: dtolnay/rust-toolchain@stable
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
@@ -65,6 +65,14 @@ jobs:
env:
NODE_OPTIONS: "--max_old_space_size=4096"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
with:
tauriScript: pnpm
args: --target ${{ matrix.target }} -b ${{ matrix.bundle }}

View File

@@ -15,8 +15,6 @@ jobs:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: windows-latest
target: i686-pc-windows-msvc
- os: windows-latest
target: aarch64-pc-windows-msvc
- os: macos-latest
@@ -30,7 +28,7 @@ jobs:
uses: actions/checkout@v4
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@1.77.0
uses: dtolnay/rust-toolchain@stable
- name: Add Rust Target
run: rustup target add ${{ matrix.target }}
@@ -89,12 +87,6 @@ jobs:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: ubuntu-latest
target: i686-unknown-linux-gnu
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
- os: ubuntu-latest
target: armv7-unknown-linux-gnueabihf
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository

View File

@@ -1,10 +1,44 @@
## v2.0.0
### Notice
- 由于更改了服务安装逻辑Mac/Linux 首次安装需要输入 2 遍系统密码卸载和安装服务,以后可以丝滑使用 tun(虚拟网卡)模式
### Breaking changes
- 重大框架升级:使用 Tauri 2.0(巨量改进与性能提升)
- 强烈建议完全删除 1.x 老版本再安装此版本
- 敬请测试,出现 bug 到 issues 中提出
### Features
- Meta(mihomo)内核升级 1.18.9
- Win 下的系统代理替换为 Shadowsocks/CFW/v2rayN 等成熟的 sysproxy.exe 方案,解决拨号/VPN 环境下无法设置系统代理的问题
- 服务模式改进为启动软件时自动安装TUN 模式可自由开启不再限制于服务模式
- Mac 下可用 URL Scheme 导入订阅
- 可使用 Ctrl(cmd)+Q 快捷键退出程序
- 成功导入订阅的提示消息
- 能自动选中新导入的订阅
- 日志加入颜色区分
- 改进多处文本表述
- 加入图标 svg 格式检测
- 增加更多 app 调试日志
### Performance
- 优化及重构内核启动管理逻辑
- 优化 TUN 启动逻辑
- 重构和优化 app_handle
- 重构系统代理绕过逻辑
- 移除无用的 PID 创建逻辑
### Bugs Fixes
- 修复已有多个订阅导入新订阅会跳选订阅的问题
- 修复多个 Linux 下的 bug, Tun 模式在 Linux 下目前工作正常
- 修复 Linux wayland 下任务栏图标缺失的问题
- 移除多余退出变量和钩子
---
## v1.7.7

View File

@@ -1,11 +1,11 @@
{
"name": "clash-verge",
"version": "2.0.0",
"version": "2.0.0-rc.2",
"license": "GPL-3.0-only",
"scripts": {
"dev": "tauri dev",
"dev:diff": "tauri dev -f verge-dev",
"build": "tauri build",
"dev": "cross-env RUST_BACKTRACE=1 tauri dev",
"dev:diff": "cross-env RUST_BACKTRACE=1 tauri dev -f verge-dev",
"build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build",
"tauri": "tauri",
"web:dev": "vite",
"web:build": "tsc && vite build",
@@ -40,8 +40,10 @@
"@types/json-schema": "^7.0.15",
"ahooks": "^3.8.0",
"axios": "^1.7.2",
"cli-color": "^2.0.4",
"dayjs": "1.11.5",
"foxact": "^0.2.35",
"glob": "^11.0.0",
"i18next": "^23.11.5",
"js-base64": "^3.7.7",
"js-yaml": "^4.1.0",
@@ -68,8 +70,7 @@
},
"devDependencies": {
"@actions/github": "^5.1.1",
"@tauri-apps/cli": "2.0.0-rc.8",
"@types/fs-extra": "^9.0.13",
"@tauri-apps/cli": "2.0.3",
"@types/js-cookie": "^3.0.6",
"@types/js-yaml": "^4.0.9",
"@types/lodash-es": "^4.17.12",
@@ -80,7 +81,6 @@
"@vitejs/plugin-react": "^4.3.1",
"adm-zip": "^0.5.14",
"cross-env": "^7.0.3",
"fs-extra": "^11.2.0",
"https-proxy-agent": "^5.0.1",
"husky": "^7.0.4",
"node-fetch": "^3.3.2",

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
import fs from "fs-extra";
import fs from "fs";
import fsp from "fs/promises";
import zlib from "zlib";
import tar from "tar";
import path from "path";
@@ -6,6 +7,8 @@ import AdmZip from "adm-zip";
import fetch from "node-fetch";
import proxyAgent from "https-proxy-agent";
import { execSync } from "child_process";
import { log_info, log_debug, log_error, log_success } from "./utils.mjs";
import { glob } from "glob";
const cwd = process.cwd();
const TEMP_DIR = path.join(cwd, "node_modules/.verge");
@@ -91,9 +94,9 @@ async function getLatestAlphaVersion() {
});
let v = await response.text();
META_ALPHA_VERSION = v.trim(); // Trim to remove extra whitespaces
console.log(`Latest alpha version: ${META_ALPHA_VERSION}`);
log_info(`Latest alpha version: ${META_ALPHA_VERSION}`);
} catch (error) {
console.error("Error fetching latest alpha version:", error.message);
log_error("Error fetching latest alpha version:", error.message);
process.exit(1);
}
}
@@ -138,9 +141,9 @@ async function getLatestReleaseVersion() {
});
let v = await response.text();
META_VERSION = v.trim(); // Trim to remove extra whitespaces
console.log(`Latest release version: ${META_VERSION}`);
log_info(`Latest release version: ${META_VERSION}`);
} catch (error) {
console.error("Error fetching latest release version:", error.message);
log_error("Error fetching latest release version:", error.message);
process.exit(1);
}
}
@@ -205,44 +208,44 @@ async function resolveSidecar(binInfo) {
const sidecarDir = path.join(cwd, "src-tauri", "sidecar");
const sidecarPath = path.join(sidecarDir, targetFile);
await fs.mkdirp(sidecarDir);
if (!FORCE && (await fs.pathExists(sidecarPath))) return;
await fsp.mkdir(sidecarDir, { recursive: true });
if (!FORCE && fs.existsSync(sidecarPath)) return;
const tempDir = path.join(TEMP_DIR, name);
const tempZip = path.join(tempDir, zipFile);
const tempExe = path.join(tempDir, exeFile);
await fs.mkdirp(tempDir);
await fsp.mkdir(tempDir, { recursive: true });
try {
if (!(await fs.pathExists(tempZip))) {
if (!fs.existsSync(tempZip)) {
await downloadFile(downloadURL, tempZip);
}
if (zipFile.endsWith(".zip")) {
const zip = new AdmZip(tempZip);
zip.getEntries().forEach((entry) => {
console.log(`[DEBUG]: "${name}" entry name`, entry.entryName);
log_debug(`"${name}" entry name`, entry.entryName);
});
zip.extractAllTo(tempDir, true);
await fs.rename(tempExe, sidecarPath);
console.log(`[INFO]: "${name}" unzip finished`);
await fsp.rename(tempExe, sidecarPath);
log_success(`unzip finished: "${name}"`);
} else if (zipFile.endsWith(".tgz")) {
// tgz
await fs.mkdirp(tempDir);
await fsp.mkdir(tempDir, { recursive: true });
await tar.extract({
cwd: tempDir,
file: tempZip,
//strip: 1, // 可能需要根据实际的 .tgz 文件结构调整
});
const files = await fs.readdir(tempDir);
console.log(`[DEBUG]: "${name}" files in tempDir:`, files);
const files = await fsp.readdir(tempDir);
log_debug(`"${name}" files in tempDir:`, files);
const extractedFile = files.find((file) => file.startsWith("虚空终端-"));
if (extractedFile) {
const extractedFilePath = path.join(tempDir, extractedFile);
await fs.rename(extractedFilePath, sidecarPath);
console.log(`[INFO]: "${name}" file renamed to "${sidecarPath}"`);
await fsp.rename(extractedFilePath, sidecarPath);
log_success(`"${name}" file renamed to "${sidecarPath}"`);
execSync(`chmod 755 ${sidecarPath}`);
console.log(`[INFO]: "${name}" chmod binary finished`);
log_success(`chmod binary finished: "${name}"`);
} else {
throw new Error(`Expected file not found in ${tempDir}`);
}
@@ -252,16 +255,15 @@ async function resolveSidecar(binInfo) {
const writeStream = fs.createWriteStream(sidecarPath);
await new Promise((resolve, reject) => {
const onError = (error) => {
console.error(`[ERROR]: "${name}" gz failed:`, error.message);
log_error(`"${name}" gz failed:`, error.message);
reject(error);
};
readStream
.pipe(zlib.createGunzip().on("error", onError))
.pipe(writeStream)
.on("finish", () => {
console.log(`[INFO]: "${name}" gunzip finished`);
execSync(`chmod 755 ${sidecarPath}`);
console.log(`[INFO]: "${name}" chmod binary finished`);
log_success(`chmod binary finished: "${name}"`);
resolve();
})
.on("error", onError);
@@ -269,11 +271,11 @@ async function resolveSidecar(binInfo) {
}
} catch (err) {
// 需要删除文件
await fs.remove(sidecarPath);
await fsp.rm(sidecarPath, { recursive: true, force: true });
throw err;
} finally {
// delete temp dir
await fs.remove(tempDir);
await fsp.rm(tempDir, { recursive: true, force: true });
}
}
@@ -286,12 +288,12 @@ async function resolveResource(binInfo) {
const resDir = path.join(cwd, "src-tauri/resources");
const targetPath = path.join(resDir, file);
if (!FORCE && (await fs.pathExists(targetPath))) return;
if (!FORCE && fs.existsSync(targetPath)) return;
await fs.mkdirp(resDir);
await fsp.mkdir(resDir, { recursive: true });
await downloadFile(downloadURL, targetPath);
console.log(`[INFO]: ${file} finished`);
log_success(`${file} finished`);
}
/**
@@ -316,9 +318,9 @@ async function downloadFile(url, path) {
headers: { "Content-Type": "application/octet-stream" },
});
const buffer = await response.arrayBuffer();
await fs.writeFile(path, new Uint8Array(buffer));
await fsp.writeFile(path, new Uint8Array(buffer));
console.log(`[INFO]: download finished "${url}"`);
log_success(`download finished: ${url}`);
}
// SimpleSC.dll
@@ -334,38 +336,41 @@ const resolvePlugin = async () => {
const tempDll = path.join(tempDir, "SimpleSC.dll");
const pluginDir = path.join(process.env.APPDATA, "Local/NSIS");
const pluginPath = path.join(pluginDir, "SimpleSC.dll");
await fs.mkdirp(pluginDir);
await fs.mkdirp(tempDir);
if (!FORCE && (await fs.pathExists(pluginPath))) return;
await fsp.mkdir(pluginDir, { recursive: true });
await fsp.mkdir(tempDir, { recursive: true });
if (!FORCE && fs.existsSync(pluginPath)) return;
try {
if (!(await fs.pathExists(tempZip))) {
if (!fs.existsSync(tempZip)) {
await downloadFile(url, tempZip);
}
const zip = new AdmZip(tempZip);
zip.getEntries().forEach((entry) => {
console.log(`[DEBUG]: "SimpleSC" entry name`, entry.entryName);
log_debug(`"SimpleSC" entry name`, entry.entryName);
});
zip.extractAllTo(tempDir, true);
await fs.copyFile(tempDll, pluginPath);
console.log(`[INFO]: "SimpleSC" unzip finished`);
await fsp.cp(tempDll, pluginPath, { recursive: true, force: true });
log_success(`unzip finished: "SimpleSC"`);
} finally {
await fs.remove(tempDir);
await fsp.rm(tempDir, { recursive: true, force: true });
}
};
// service chmod
const resolveServicePermission = async () => {
const serviceExecutables = [
"clash-verge-service",
"install-service",
"uninstall-service",
"clash-verge-service*",
"install-service*",
"uninstall-service*",
];
const resDir = path.join(cwd, "src-tauri/resources");
for (let f of serviceExecutables) {
const targetPath = path.join(resDir, f);
if (await fs.pathExists(targetPath)) {
execSync(`chmod 755 ${targetPath}`);
console.log(`[INFO]: "${targetPath}" chmod finished`);
// 使用glob模块来处理通配符
const files = glob.sync(path.join(resDir, f));
for (let filePath of files) {
if (fs.existsSync(filePath)) {
execSync(`chmod 755 ${filePath}`);
log_success(`chmod finished: "${filePath}"`);
}
}
}
};
@@ -373,29 +378,32 @@ const resolveServicePermission = async () => {
/**
* main
*/
const SERVICE_URL = `https://github.com/clash-verge-rev/clash-verge-service/releases/download/${SIDECAR_HOST}`;
const resolveService = () => {
let ext = platform === "win32" ? ".exe" : "";
let suffix = platform === "linux" ? "-" + SIDECAR_HOST : "";
resolveResource({
file: "clash-verge-service" + ext,
file: "clash-verge-service" + suffix + ext,
downloadURL: `${SERVICE_URL}/clash-verge-service${ext}`,
});
};
const resolveInstall = () => {
let ext = platform === "win32" ? ".exe" : "";
let suffix = platform === "linux" ? "-" + SIDECAR_HOST : "";
resolveResource({
file: "install-service" + ext,
file: "install-service" + suffix + ext,
downloadURL: `${SERVICE_URL}/install-service${ext}`,
});
};
const resolveUninstall = () => {
let ext = platform === "win32" ? ".exe" : "";
let suffix = platform === "linux" ? "-" + SIDECAR_HOST : "";
resolveResource({
file: "uninstall-service" + ext,
file: "uninstall-service" + suffix + ext,
downloadURL: `${SERVICE_URL}/uninstall-service${ext}`,
});
};
@@ -421,6 +429,12 @@ const resolveEnableLoopback = () =>
downloadURL: `https://github.com/Kuingsmile/uwp-tool/releases/download/latest/enableLoopback.exe`,
});
const resolveWinSysproxy = () =>
resolveResource({
file: "sysproxy.exe",
downloadURL: `https://github.com/clash-verge-rev/sysproxy/releases/download/${arch}/sysproxy.exe`,
});
const tasks = [
// { name: "clash", func: resolveClash, retry: 5 },
{
@@ -454,6 +468,12 @@ const tasks = [
retry: 1,
unixOnly: true,
},
{
name: "windows-sysproxy",
func: resolveWinSysproxy,
retry: 5,
winOnly: true,
},
];
async function runTask() {
@@ -468,7 +488,7 @@ async function runTask() {
await task.func();
break;
} catch (err) {
console.error(`[ERROR]: task::${task.name} try ${i} ==`, err.message);
log_error(`task::${task.name} try ${i} ==`, err.message);
if (i === task.retry - 1) throw err;
}
}

View File

@@ -1,4 +1,5 @@
import fs from "fs-extra";
import fs from "fs";
import fsp from "fs/promises";
import path from "path";
import AdmZip from "adm-zip";
import { createRequire } from "module";
@@ -30,12 +31,14 @@ async function resolvePortable() {
const configDir = path.join(releaseDir, ".config");
if (!(await fs.pathExists(releaseDir))) {
if (!fs.existsSync(releaseDir)) {
throw new Error("could not found the release dir");
}
await fs.mkdir(configDir);
await fs.createFile(path.join(configDir, "PORTABLE"));
await fsp.mkdir(configDir, { recursive: true });
if (!fs.existsSync(path.join(configDir, "PORTABLE"))) {
await fsp.writeFile(path.join(configDir, "PORTABLE"), "");
}
const zip = new AdmZip();

View File

@@ -1,4 +1,4 @@
import fs from "fs-extra";
import fs from "fs";
import path from "path";
import AdmZip from "adm-zip";
import { createRequire } from "module";
@@ -29,12 +29,14 @@ async function resolvePortable() {
: `./src-tauri/target/release`;
const configDir = path.join(releaseDir, ".config");
if (!(await fs.pathExists(releaseDir))) {
if (!fs.existsSync(releaseDir)) {
throw new Error("could not found the release dir");
}
await fs.mkdir(configDir);
await fs.createFile(path.join(configDir, "PORTABLE"));
await fsp.mkdir(configDir, { recursive: true });
if (!fs.existsSync(path.join(configDir, "PORTABLE"))) {
await fsp.writeFile(path.join(configDir, "PORTABLE"), "");
}
const zip = new AdmZip();

View File

@@ -1,4 +1,5 @@
import fs from "fs-extra";
import fs from "fs";
import fsp from "fs/promises";
import path from "path";
const UPDATE_LOG = "UPDATELOG.md";
@@ -12,11 +13,11 @@ export async function resolveUpdateLog(tag) {
const file = path.join(cwd, UPDATE_LOG);
if (!(await fs.pathExists(file))) {
if (!fs.existsSync(file)) {
throw new Error("could not found UPDATELOG.md");
}
const data = await fs.readFile(file).then((d) => d.toString("utf8"));
const data = await fsp.readFile(file, "utf-8");
const map = {};
let p = "";

View File

@@ -0,0 +1,11 @@
import clc from "cli-color";
export const log_success = (msg, ...optionalParams) =>
console.log(clc.green(msg), ...optionalParams);
export const log_error = (msg, ...optionalParams) =>
console.log(clc.red(msg), ...optionalParams);
export const log_info = (msg, ...optionalParams) =>
console.log(clc.bgBlue(msg), ...optionalParams);
var debugMsg = clc.xterm(245);
export const log_debug = (msg, ...optionalParams) =>
console.log(debugMsg(msg), ...optionalParams);

File diff suppressed because it is too large Load Diff

26
clash-verge-rev/src-tauri/Cargo.toml Normal file → Executable file
View File

@@ -22,8 +22,8 @@ dunce = "1.0"
log4rs = "1"
nanoid = "0.4"
chrono = "0.4"
sysinfo = "0.30"
boa_engine = "0.18"
sysinfo = "0.31.4"
boa_engine = "0.19.1"
serde_json = "1.0"
serde_yaml = "0.9"
once_cell = "1.19"
@@ -36,7 +36,7 @@ window-shadows = { version = "0.2.2" }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
sysproxy = { git = "https://github.com/zzzgydi/sysproxy-rs", branch = "main" }
sysproxy = { git = "https://github.com/clash-verge-rev/sysproxy-rs", branch = "main" }
tauri = { version = "2.0.0-rc", features = [
"protocol-asset",
"devtools",
@@ -45,17 +45,21 @@ tauri = { version = "2.0.0-rc", features = [
"image-png",
] }
network-interface = { version = "2.0.0", features = ["serde"] }
tauri-plugin-shell = "2.0.0-rc"
tauri-plugin-dialog = "2.0.0-rc"
tauri-plugin-fs = "2.0.0-rc"
tauri-plugin-notification = "2.0.0-rc"
tauri-plugin-process = "2.0.0-rc"
tauri-plugin-clipboard-manager = "2.1.0-beta.7"
tauri-plugin-shell = "2.0.2"
tauri-plugin-dialog = "2.0.2"
tauri-plugin-fs = "2.0.2"
tauri-plugin-notification = "2.0.1"
tauri-plugin-process = "2.0.1"
tauri-plugin-clipboard-manager = "2.0.1"
tauri-plugin-deep-link = "2.0.1"
tauri-plugin-devtools = "2.0.0-rc"
url = "2.5.2"
[target.'cfg(windows)'.dependencies]
runas = "=1.2.0"
deelevate = "0.2.0"
winreg = "0.52.0"
url = "2.5.2"
[target.'cfg(target_os = "linux")'.dependencies]
users = "0.11.0"
@@ -79,3 +83,7 @@ strip = true
[profile.dev]
incremental = true
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Clash Verge</string>
<key>CFBundleURLSchemes</key>
<array>
<string>clash</string>
</array>
</dict>
</array>
</dict>
</plist>

6
clash-verge-rev/src-tauri/capabilities/desktop.json Normal file → Executable file
View File

@@ -3,5 +3,9 @@
"platforms": ["macOS", "windows", "linux"],
"webviews": ["main"],
"windows": ["main"],
"permissions": ["global-shortcut:default", "updater:default"]
"permissions": [
"global-shortcut:default",
"updater:default",
"deep-link:default"
]
}

View File

@@ -11,6 +11,11 @@
"identifier": "fs:scope",
"allow": ["$APPDATA/**", "$RESOURCE/../**", "**"]
},
"fs:allow-write-file",
{
"identifier": "fs:scope",
"allow": ["$APPDATA/**", "$RESOURCE/../**", "**"]
},
"core:window:allow-create",
"core:window:allow-center",
"core:window:allow-request-user-attention",
@@ -43,6 +48,13 @@
"core:window:allow-set-cursor-position",
"core:window:allow-set-ignore-cursor-events",
"core:window:allow-start-dragging",
"core:window:allow-maximize",
"core:window:allow-toggle-maximize",
"core:window:allow-unmaximize",
"core:window:allow-minimize",
"core:window:allow-unminimize",
"core:window:allow-set-maximizable",
"core:window:allow-set-minimizable",
"core:webview:allow-print",
"shell:allow-execute",
"shell:allow-open",

View File

@@ -2,7 +2,7 @@ use crate::{
config::*,
core::*,
feat,
utils::{dirs, help, resolve},
utils::{dirs, help},
};
use crate::{ret_err, wrap_err};
use anyhow::{Context, Result};
@@ -14,8 +14,8 @@ type CmdResult<T = ()> = Result<T, String>;
use tauri::Manager;
#[tauri::command]
pub fn copy_clash_env(app_handle: tauri::AppHandle) -> CmdResult {
feat::copy_clash_env(&app_handle);
pub fn copy_clash_env() -> CmdResult {
feat::copy_clash_env();
Ok(())
}
@@ -185,7 +185,7 @@ pub async fn change_clash_core(clash_core: Option<String>) -> CmdResult {
/// restart the sidecar
#[tauri::command]
pub async fn restart_sidecar() -> CmdResult {
wrap_err!(CoreManager::global().run_core().await)
wrap_err!(CoreManager::global().restart_core().await)
}
/// get the system proxy
@@ -337,7 +337,7 @@ pub fn get_network_interfaces() -> Vec<String> {
for (interface_name, _) in &networks {
result.push(interface_name.clone());
}
return result;
result
}
#[tauri::command]
@@ -371,11 +371,8 @@ pub fn open_devtools(app_handle: tauri::AppHandle) {
}
#[tauri::command]
pub fn exit_app(app_handle: tauri::AppHandle) {
let _ = resolve::save_window_size_position(&app_handle, true);
resolve::resolve_reset();
app_handle.exit(0);
std::process::exit(0);
pub fn exit_app() {
feat::quit(Some(0));
}
pub mod service {
@@ -386,16 +383,6 @@ pub mod service {
pub async fn check_service() -> CmdResult<service::JsonResponse> {
wrap_err!(service::check_service().await)
}
#[tauri::command]
pub async fn install_service(passwd: String) -> CmdResult {
wrap_err!(service::install_service(passwd).await)
}
#[tauri::command]
pub async fn uninstall_service(passwd: String) -> CmdResult {
wrap_err!(service::uninstall_service(passwd).await)
}
}
#[cfg(not(windows))]

View File

@@ -32,13 +32,12 @@ impl IClashTemp {
pub fn template() -> Self {
let mut map = Mapping::new();
let mut tun = Mapping::new();
tun.insert("enable".into(), false.into());
tun.insert("stack".into(), "gvisor".into());
tun.insert("device".into(), "Mihomo".into());
tun.insert("auto-route".into(), true.into());
tun.insert("strict-route".into(), false.into());
tun.insert("auto-detect-interface".into(), true.into());
tun.insert("dns-hijack".into(), vec!["any:53"].into());
tun.insert("mtu".into(), 1500.into());
#[cfg(not(target_os = "windows"))]
map.insert("redir-port".into(), 7895.into());
#[cfg(target_os = "linux")]
@@ -50,9 +49,12 @@ impl IClashTemp {
map.insert("allow-lan".into(), false.into());
map.insert("mode".into(), "rule".into());
map.insert("external-controller".into(), "127.0.0.1:9097".into());
let mut cors_map = Mapping::new();
cors_map.insert("allow-private-network".into(), true.into());
cors_map.insert("allow-origins".into(), vec!["*"].into());
map.insert("secret".into(), "".into());
map.insert("tun".into(), tun.into());
map.insert("external-controller-cors".into(), cors_map.into());
Self(map)
}

View File

@@ -7,9 +7,6 @@ use serde::{Deserialize, Serialize};
/// ### `verge.yaml` schema
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct IVerge {
/// app listening port for app singleton
pub app_singleton_port: Option<u16>,
/// app log level
/// silent | error | warn | info | debug | trace
pub app_log_level: Option<String>,
@@ -59,10 +56,6 @@ pub struct IVerge {
/// clash tun mode
pub enable_tun_mode: Option<bool>,
/// windows service mode
#[serde(skip_serializing_if = "Option::is_none")]
pub enable_service_mode: Option<bool>,
/// can the app auto startup
pub enable_auto_launch: Option<bool>,
@@ -282,7 +275,6 @@ impl IVerge {
patch!(tun_tray_icon);
patch!(enable_tun_mode);
patch!(enable_service_mode);
patch!(enable_auto_launch);
patch!(enable_silent_start);
patch!(enable_random_port);
@@ -330,11 +322,7 @@ impl IVerge {
const SERVER_PORT: u16 = 33331;
#[cfg(feature = "verge-dev")]
const SERVER_PORT: u16 = 11233;
match dirs::verge_path().and_then(|path| help::read_yaml::<IVerge>(&path)) {
Ok(config) => config.app_singleton_port.unwrap_or(SERVER_PORT),
Err(_) => SERVER_PORT, // 这里就不log错误了
}
SERVER_PORT
}
/// 获取日志等级

View File

@@ -127,7 +127,7 @@ pub fn parse_check_output(log: String) -> String {
#[test]
fn test_parse_check_output() {
let str1 = r#"xxxx\n time="2022-11-18T20:42:58+08:00" level=error msg="proxy 0: 'alpn' expected type 'string', got unconvertible type '[]interface {}'""#;
let str2 = r#"20:43:49 ERR [Config] configuration file test failed error=proxy 0: unsupport proxy type: hysteria path=xxx"#;
//let str2 = r#"20:43:49 ERR [Config] configuration file test failed error=proxy 0: unsupport proxy type: hysteria path=xxx"#;
let str3 = r#"
"time="2022-11-18T21:38:01+08:00" level=info msg="Start initial configuration in progress"
time="2022-11-18T21:38:01+08:00" level=error msg="proxy 0: 'alpn' expected type 'string', got unconvertible type '[]interface {}'"
@@ -135,12 +135,8 @@ fn test_parse_check_output() {
"#;
let res1 = parse_check_output(str1.into());
let res2 = parse_check_output(str2.into());
// let res2 = parse_check_output(str2.into());
let res3 = parse_check_output(str3.into());
println!("res1: {res1}");
println!("res2: {res2}");
println!("res3: {res3}");
assert_eq!(res1, res3);
}

View File

@@ -2,46 +2,32 @@ use crate::config::*;
use crate::core::{clash_api, handle, logger::Logger, service};
use crate::log_err;
use crate::utils::dirs;
use anyhow::{bail, Context, Result};
use anyhow::{bail, Result};
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use serde_yaml::Mapping;
use std::{fs, io::Write, sync::Arc, time::Duration};
use sysinfo::{ProcessRefreshKind, RefreshKind, System};
use tauri::AppHandle;
use tauri_plugin_shell::process::{CommandChild, CommandEvent};
use std::{sync::Arc, time::Duration};
use tauri_plugin_shell::ShellExt;
use tokio::sync::Mutex;
use tokio::time::sleep;
#[derive(Debug)]
pub struct CoreManager {
app_handle: Arc<Mutex<Option<AppHandle>>>,
sidecar: Arc<Mutex<Option<CommandChild>>>,
#[allow(unused)]
use_service_mode: Arc<Mutex<bool>>,
running: Arc<Mutex<bool>>,
}
impl CoreManager {
pub fn global() -> &'static CoreManager {
static CORE_MANAGER: OnceCell<CoreManager> = OnceCell::new();
CORE_MANAGER.get_or_init(|| CoreManager {
app_handle: Arc::new(Mutex::new(None)),
sidecar: Arc::new(Mutex::new(None)),
use_service_mode: Arc::new(Mutex::new(false)),
running: Arc::new(Mutex::new(false)),
})
}
pub fn init(&self, app_handle: &AppHandle) -> Result<()> {
*self.app_handle.lock() = Some(app_handle.clone());
tauri::async_runtime::spawn(async {
log::trace!("run core start");
// 启动clash
log_err!(Self::global().run_core().await);
log::trace!("run core end");
});
pub async fn init(&self) -> Result<()> {
log::trace!("run core start");
// 启动clash
log_err!(Self::global().start_core().await);
log::trace!("run core end");
Ok(())
}
@@ -51,241 +37,86 @@ impl CoreManager {
let config_path = dirs::path_to_str(&config_path)?;
let clash_core = { Config::verge().latest().clash_core.clone() };
let mut clash_core = clash_core.unwrap_or("verge-mihomo".into());
// compatibility
if clash_core.contains("clash") {
clash_core = "verge-mihomo".to_string();
Config::verge().draft().patch_config(IVerge {
clash_core: Some("verge-mihomo".to_string()),
..IVerge::default()
});
Config::verge().apply();
match Config::verge().data().save_file() {
Ok(_) => handle::Handle::refresh_verge(),
Err(err) => log::error!(target: "app", "{err}"),
}
}
let clash_core = clash_core.unwrap_or("verge-mihomo".into());
let test_dir = dirs::app_home_dir()?.join("test");
let test_dir = dirs::path_to_str(&test_dir)?;
let app_handle_option = {
let lock = self.app_handle.lock();
lock.as_ref().cloned()
};
let app_handle = handle::Handle::global().app_handle().unwrap();
if let Some(app_handle) = app_handle_option {
let output = app_handle
.shell()
.sidecar(clash_core)?
.args(["-t", "-d", test_dir, "-f", config_path])
.output()
.await?;
let output = app_handle
.shell()
.sidecar(clash_core)?
.args(["-t", "-d", test_dir, "-f", config_path])
.output()
.await?;
if !output.status.success() {
let stdout = String::from_utf8(output.stdout).unwrap_or_default();
let error = clash_api::parse_check_output(stdout.clone());
let error = match !error.is_empty() {
true => error,
false => stdout.clone(),
};
Logger::global().set_log(stdout.clone());
bail!("{error}");
}
if !output.status.success() {
let stdout = String::from_utf8(output.stdout).unwrap_or_default();
let error = clash_api::parse_check_output(stdout.clone());
let error = match !error.is_empty() {
true => error,
false => stdout.clone(),
};
Logger::global().set_log(stdout.clone());
bail!("{error}");
}
Ok(())
}
/// 启动核心
pub async fn run_core(&self) -> Result<()> {
let config_path = Config::generate_file(ConfigType::Run)?;
// 关闭tun模式
let mut disable = Mapping::new();
let mut tun = Mapping::new();
tun.insert("enable".into(), false.into());
disable.insert("tun".into(), tun.into());
log::debug!(target: "app", "disable tun mode");
let _ = clash_api::patch_configs(&disable).await;
if *self.use_service_mode.lock() {
log::debug!(target: "app", "stop the core by service");
log_err!(service::stop_core_by_service().await);
} else {
let system = System::new_with_specifics(
RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
);
let procs = system.processes_by_name("verge-mihomo");
for proc in procs {
log::debug!(target: "app", "kill all clash process");
proc.kill();
}
}
// 服务模式
let enable = { Config::verge().latest().enable_service_mode };
let enable = enable.unwrap_or(false);
*self.use_service_mode.lock() = enable;
if enable {
// 服务模式启动失败就直接运行sidecar
log::debug!(target: "app", "try to run core in service mode");
let res = async {
service::check_service().await?;
service::run_core_by_service(&config_path).await
}
.await;
match res {
Ok(_) => return Ok(()),
Err(err) => {
// 修改这个值免得stop出错
*self.use_service_mode.lock() = false;
log::error!(target: "app", "{err}");
}
}
}
let app_dir = dirs::app_home_dir()?;
let app_dir = dirs::path_to_str(&app_dir)?;
let clash_core = { Config::verge().latest().clash_core.clone() };
let mut clash_core = clash_core.unwrap_or("verge-mihomo".into());
// compatibility
if clash_core.contains("clash") {
clash_core = "verge-mihomo".to_string();
Config::verge().draft().patch_config(IVerge {
clash_core: Some("verge-mihomo".to_string()),
..IVerge::default()
});
Config::verge().apply();
match Config::verge().data().save_file() {
Ok(_) => handle::Handle::refresh_verge(),
Err(err) => log::error!(target: "app", "{err}"),
}
}
let config_path = dirs::path_to_str(&config_path)?;
let args = vec!["-d", app_dir, "-f", config_path];
let app_handle = self.app_handle.lock();
if let Some(app_handle) = app_handle.as_ref() {
let cmd = app_handle.shell().sidecar(clash_core)?;
let (mut rx, cmd_child) = cmd.args(args).spawn()?;
// 将pid写入文件中
crate::log_err!((|| {
let pid = cmd_child.pid();
let path = dirs::clash_pid_path()?;
fs::File::create(path)
.context("failed to create the pid file")?
.write(format!("{pid}").as_bytes())
.context("failed to write pid to the file")?;
<Result<()>>::Ok(())
})());
let mut sidecar = self.sidecar.lock();
*sidecar = Some(cmd_child);
drop(sidecar);
tauri::async_runtime::spawn(async move {
while let Some(event) = rx.recv().await {
match event {
CommandEvent::Stdout(line) => {
let line = String::from_utf8(line).unwrap_or_default();
log::info!(target: "app", "[mihomo]: {line}");
Logger::global().set_log(line);
}
CommandEvent::Stderr(err) => {
let err = String::from_utf8(err).unwrap_or_default();
log::error!(target: "app", "[mihomo]: {err}");
Logger::global().set_log(err);
}
CommandEvent::Error(err) => {
log::error!(target: "app", "[mihomo]: {err}");
Logger::global().set_log(err);
}
CommandEvent::Terminated(_) => {
log::info!(target: "app", "mihomo core terminated");
let _ = CoreManager::global().recover_core();
break;
}
_ => {}
}
}
});
}
Ok(())
}
/// 重启内核
pub fn recover_core(&'static self) -> Result<()> {
// 服务模式不管
if *self.use_service_mode.lock() {
return Ok(());
}
// 清空原来的sidecar值
let _ = self.sidecar.lock().take();
tauri::async_runtime::spawn(async move {
// 6秒之后再查看服务是否正常 (时间随便搞的)
// terminated 可能是切换内核 (切换内核已经有500ms的延迟)
sleep(Duration::from_millis(6666)).await;
if self.sidecar.lock().is_none() {
log::info!(target: "app", "recover clash core");
// 重新启动app
if let Err(err) = self.run_core().await {
log::error!(target: "app", "failed to recover clash core");
log::error!(target: "app", "{err}");
let _ = self.recover_core();
}
}
});
Ok(())
}
/// 停止核心运行
pub async fn stop_core(&self) -> Result<()> {
let mut running = self.running.lock().await;
if !*running {
log::debug!("core is not running");
return Ok(());
}
// 关闭tun模式
let mut disable = Mapping::new();
let mut tun = Mapping::new();
tun.insert("enable".into(), false.into());
disable.insert("tun".into(), tun.into());
log::debug!(target: "app", "disable tun mode");
let _ = clash_api::patch_configs(&disable).await;
log_err!(clash_api::patch_configs(&disable).await);
if *self.use_service_mode.lock() {
log::debug!(target: "app", "stop the core by service");
log_err!(service::stop_core_by_service().await);
// 服务模式
if service::check_service().await.is_ok() {
log::info!(target: "app", "stop the core by service");
service::stop_core_by_service().await?;
}
*running = false;
Ok(())
}
/// 启动核心
pub async fn start_core(&self) -> Result<()> {
let mut running = self.running.lock().await;
if *running {
log::info!("core is running");
return Ok(());
}
let mut sidecar = self.sidecar.lock();
let _ = sidecar.take();
let config_path = Config::generate_file(ConfigType::Run)?;
let system = System::new_with_specifics(
RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
);
let procs = system.processes_by_name("verge-mihomo");
for proc in procs {
log::debug!(target: "app", "kill all clash process");
proc.kill();
// 服务模式
if service::check_service().await.is_ok() {
log::info!(target: "app", "try to run core in service mode");
service::run_core_by_service(&config_path).await?;
*running = true;
}
Ok(())
}
/// 重启内核
pub async fn restart_core(&self) -> Result<()> {
// 重新启动app
self.stop_core().await?;
self.start_core().await?;
Ok(())
}
/// 切换核心
pub async fn change_core(&self, clash_core: Option<String>) -> Result<()> {
let clash_core = clash_core.ok_or(anyhow::anyhow!("clash core is null"))?;
@@ -295,7 +126,7 @@ impl CoreManager {
bail!("invalid clash core name \"{clash_core}\"");
}
log::debug!(target: "app", "change core to `{clash_core}`");
log::info!(target: "app", "change core to `{clash_core}`");
Config::verge().draft().clash_core = Some(clash_core);
@@ -307,7 +138,7 @@ impl CoreManager {
// 清掉旧日志
Logger::global().clear_log();
match self.run_core().await {
match self.restart_core().await {
Ok(_) => {
Config::verge().apply();
Config::runtime().apply();

View File

@@ -1,14 +1,14 @@
use super::tray::Tray;
use crate::log_err;
use anyhow::{bail, Result};
use anyhow::Result;
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use parking_lot::RwLock;
use std::sync::Arc;
use tauri::{AppHandle, WebviewWindow, Manager, Emitter};
use tauri::{AppHandle, Emitter, Manager, WebviewWindow};
#[derive(Debug, Default, Clone)]
pub struct Handle {
pub app_handle: Arc<Mutex<Option<AppHandle>>>,
pub app_handle: Arc<RwLock<Option<AppHandle>>>,
}
impl Handle {
@@ -16,17 +16,21 @@ impl Handle {
static HANDLE: OnceCell<Handle> = OnceCell::new();
HANDLE.get_or_init(|| Handle {
app_handle: Arc::new(Mutex::new(None)),
app_handle: Arc::new(RwLock::new(None)),
})
}
pub fn init(&self, app_handle: &AppHandle) {
*self.app_handle.lock() = Some(app_handle.clone());
let mut handle = self.app_handle.write();
*handle = Some(app_handle.clone());
}
pub fn app_handle(&self) -> Option<AppHandle> {
self.app_handle.read().clone()
}
pub fn get_window(&self) -> Option<WebviewWindow> {
self.app_handle
.lock()
self.app_handle()
.as_ref()
.and_then(|a| a.get_webview_window("main"))
}
@@ -56,22 +60,9 @@ impl Handle {
}
}
pub fn update_systray() -> Result<()> {
let app_handle = Self::global().app_handle.lock();
if app_handle.is_none() {
bail!("update_systray unhandled error");
}
Tray::update_systray(app_handle.as_ref().unwrap())?;
Ok(())
}
/// update the system tray state
pub fn update_systray_part() -> Result<()> {
let app_handle = Self::global().app_handle.lock();
if app_handle.is_none() {
bail!("update_systray unhandled error");
}
Tray::update_part(app_handle.as_ref().unwrap())?;
Tray::update_part()?;
Ok(())
}
}

55
clash-verge-rev/src-tauri/src/core/hotkey.rs Normal file → Executable file
View File

@@ -1,14 +1,13 @@
use crate::core::handle;
use crate::{config::Config, feat, log_err};
use anyhow::{bail, Result};
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use std::{collections::HashMap, sync::Arc};
use tauri::AppHandle;
use tauri_plugin_global_shortcut::GlobalShortcutExt;
use tauri::Manager;
use tauri_plugin_global_shortcut::{Code, GlobalShortcutExt, ShortcutState};
pub struct Hotkey {
current: Arc<Mutex<Vec<String>>>, // 保存当前的热键设置
app_handle: Arc<Mutex<Option<AppHandle>>>,
}
impl Hotkey {
@@ -17,12 +16,10 @@ impl Hotkey {
HOTKEY.get_or_init(|| Hotkey {
current: Arc::new(Mutex::new(Vec::new())),
app_handle: Arc::new(Mutex::new(None)),
})
}
pub fn init(&self, app_handle: &AppHandle) -> Result<()> {
*self.app_handle.lock() = Some(app_handle.clone());
pub fn init(&self) -> Result<()> {
let verge = Config::verge();
if let Some(hotkeys) = verge.latest().hotkeys.as_ref() {
@@ -48,12 +45,9 @@ impl Hotkey {
Ok(())
}
fn register(&self, hotkey: &str, func: &str) -> Result<()> {
let app_handle = self.app_handle.lock();
if app_handle.is_none() {
bail!("failed to get the hotkey manager");
}
let manager = app_handle.as_ref().unwrap().global_shortcut();
pub fn register(&self, hotkey: &str, func: &str) -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let manager = app_handle.global_shortcut();
if manager.is_registered(hotkey) {
manager.unregister(hotkey)?;
@@ -66,20 +60,32 @@ impl Hotkey {
"clash_mode_direct" => || feat::change_clash_mode("direct".into()),
"toggle_system_proxy" => feat::toggle_system_proxy,
"toggle_tun_mode" => feat::toggle_tun_mode,
"quit" => || feat::quit(Some(0)),
_ => bail!("invalid function \"{func}\""),
};
let _ = manager.on_shortcut(hotkey, move |_, _, _| f());
let _ = manager.on_shortcut(hotkey, move |app_handle, hotkey, event| {
if event.state == ShortcutState::Pressed {
if hotkey.key == Code::KeyQ {
if let Some(window) = app_handle.get_webview_window("main") {
if window.is_focused().unwrap_or(false) {
f();
}
}
} else {
f();
}
}
});
log::info!(target: "app", "register hotkey {hotkey} {func}");
Ok(())
}
fn unregister(&self, hotkey: &str) -> Result<()> {
let app_handle = self.app_handle.lock();
if app_handle.is_none() {
bail!("failed to get the hotkey manager");
}
let manager = app_handle.as_ref().unwrap().global_shortcut();
pub fn unregister(&self, hotkey: &str) -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let manager = app_handle.global_shortcut();
manager.unregister(hotkey)?;
log::info!(target: "app", "unregister hotkey {hotkey}");
@@ -105,7 +111,7 @@ impl Hotkey {
Ok(())
}
fn get_map_from_vec(hotkeys: &Vec<String>) -> HashMap<&str, &str> {
fn get_map_from_vec(hotkeys: &[String]) -> HashMap<&str, &str> {
let mut map = HashMap::new();
hotkeys.iter().for_each(|hotkey| {
@@ -153,10 +159,9 @@ impl Hotkey {
impl Drop for Hotkey {
fn drop(&mut self) {
if let Some(app_handle) = self.app_handle.lock().as_ref() {
if let Err(e) = app_handle.global_shortcut().unregister_all() {
log::error!("Error unregistering all hotkeys: {:?}", e);
}
let app_handle = handle::Handle::global().app_handle().unwrap();
if let Err(e) = app_handle.global_shortcut().unregister_all() {
log::error!(target:"app", "Error unregistering all hotkeys: {:?}", e);
}
}
}

View File

@@ -1,13 +1,11 @@
use crate::config::{Config, IVerge};
use crate::core::handle;
use crate::config::Config;
use crate::utils::dirs;
use anyhow::{bail, Context, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;
use std::{env::current_exe, process::Command as StdCommand};
use tokio::time::sleep;
use tokio::time::Duration;
// Windows only
@@ -28,32 +26,34 @@ pub struct JsonResponse {
pub data: Option<ResponseBody>,
}
#[cfg(not(target_os = "windows"))]
pub fn sudo(passwd: &String, cmd: String) -> StdCommand {
let shell = format!("echo \"{}\" | sudo -S {}", passwd, cmd);
let mut command = StdCommand::new("bash");
command.arg("-c").arg(shell);
command
}
/// Install the Clash Verge Service
/// 该函数应该在协程或者线程中执行避免UAC弹窗阻塞主线程
///
#[cfg(target_os = "windows")]
pub async fn install_service(_passwd: String) -> Result<()> {
pub async fn reinstall_service() -> Result<()> {
log::info!(target:"app", "reinstall service");
use deelevate::{PrivilegeLevel, Token};
use runas::Command as RunasCommand;
use std::os::windows::process::CommandExt;
let binary_path = dirs::service_path()?;
let install_path = binary_path.with_file_name("install-service.exe");
let uninstall_path = binary_path.with_file_name("uninstall-service.exe");
if !install_path.exists() {
bail!("installer exe not found");
bail!(format!("installer not found: {install_path:?}"));
}
if !uninstall_path.exists() {
bail!(format!("uninstaller not found: {uninstall_path:?}"));
}
let token = Token::with_current_process()?;
let level = token.privilege_level()?;
let _ = match level {
PrivilegeLevel::NotPrivileged => RunasCommand::new(uninstall_path).show(false).status()?,
_ => StdCommand::new(uninstall_path)
.creation_flags(0x08000000)
.status()?,
};
let status = match level {
PrivilegeLevel::NotPrivileged => RunasCommand::new(install_path).show(false).status()?,
@@ -73,111 +73,48 @@ pub async fn install_service(_passwd: String) -> Result<()> {
}
#[cfg(target_os = "linux")]
pub async fn install_service(passwd: String) -> Result<()> {
pub async fn reinstall_service() -> Result<()> {
log::info!(target:"app", "reinstall service");
use users::get_effective_uid;
let binary_path = dirs::service_path()?;
let installer_path = binary_path.with_file_name("install-service");
if !installer_path.exists() {
bail!("installer not found");
let install_path = tauri::utils::platform::current_exe()?.with_file_name("install-service");
let uninstall_path = tauri::utils::platform::current_exe()?.with_file_name("uninstall-service");
if !install_path.exists() {
bail!(format!("installer not found: {install_path:?}"));
}
let output = match get_effective_uid() {
0 => {
StdCommand::new("chmod")
.arg("+x")
.arg(installer_path.clone())
.output()?;
StdCommand::new("chmod")
.arg("+x")
.arg(binary_path)
.output()?;
StdCommand::new(installer_path.clone()).output()?
}
_ => {
sudo(
&passwd,
format!("chmod +x {}", installer_path.to_string_lossy()),
)
.output()?;
sudo(
&passwd,
format!("chmod +x {}", binary_path.to_string_lossy()),
)
.output()?;
sudo(&passwd, format!("{}", installer_path.to_string_lossy())).output()?
}
};
if !output.status.success() {
bail!(
"failed to install service with error: {}",
String::from_utf8_lossy(&output.stderr)
);
}
Ok(())
}
#[cfg(target_os = "macos")]
pub async fn install_service(passwd: String) -> Result<()> {
let binary_path = dirs::service_path()?;
let installer_path = binary_path.with_file_name("install-service");
if !installer_path.exists() {
bail!("installer not found");
}
sudo(
&passwd,
format!(
"chmod +x {}",
installer_path.to_string_lossy().replace(" ", "\\ ")
),
)
.output()?;
let output = sudo(
&passwd,
format!("{}", installer_path.to_string_lossy().replace(" ", "\\ ")),
)
.output()?;
if !output.status.success() {
bail!(
"failed to install service with error: {}",
String::from_utf8_lossy(&output.stderr)
);
}
Ok(())
}
/// Uninstall the Clash Verge Service
/// 该函数应该在协程或者线程中执行避免UAC弹窗阻塞主线程
#[cfg(target_os = "windows")]
pub async fn uninstall_service(_passwd: String) -> Result<()> {
use deelevate::{PrivilegeLevel, Token};
use runas::Command as RunasCommand;
use std::os::windows::process::CommandExt;
let binary_path = dirs::service_path()?;
let uninstall_path = binary_path.with_file_name("uninstall-service.exe");
if !uninstall_path.exists() {
bail!("uninstaller exe not found");
bail!(format!("uninstaller not found: {uninstall_path:?}"));
}
let token = Token::with_current_process()?;
let level = token.privilege_level()?;
let install_shell: String = install_path.to_string_lossy().replace(" ", "\\ ");
let uninstall_shell: String = uninstall_path.to_string_lossy().replace(" ", "\\ ");
let status = match level {
PrivilegeLevel::NotPrivileged => RunasCommand::new(uninstall_path).show(false).status()?,
_ => StdCommand::new(uninstall_path)
.creation_flags(0x08000000)
let elevator = crate::utils::help::linux_elevator();
let status = match get_effective_uid() {
0 => StdCommand::new(uninstall_shell).status()?,
_ => StdCommand::new(elevator.clone())
.arg("sh")
.arg("-c")
.arg(uninstall_shell)
.status()?,
};
log::info!(target:"app", "status code:{}", status.code().unwrap());
let status = match get_effective_uid() {
0 => StdCommand::new(install_shell).status()?,
_ => StdCommand::new(elevator.clone())
.arg("sh")
.arg("-c")
.arg(install_shell)
.status()?,
};
if !status.success() {
bail!(
"failed to uninstall service with status {}",
"failed to install service with status {}",
status.code().unwrap()
);
}
@@ -185,76 +122,38 @@ pub async fn uninstall_service(_passwd: String) -> Result<()> {
Ok(())
}
#[cfg(target_os = "linux")]
pub async fn uninstall_service(passwd: String) -> Result<()> {
use users::get_effective_uid;
let binary_path = dirs::service_path()?;
let uninstaller_path = binary_path.with_file_name("uninstall-service");
if !uninstaller_path.exists() {
bail!("uninstaller not found");
}
let output = match get_effective_uid() {
0 => {
StdCommand::new("chmod")
.arg("+x")
.arg(uninstaller_path.clone())
.output()?;
StdCommand::new(uninstaller_path.clone()).output()?
}
_ => {
sudo(
&passwd,
format!("chmod +x {}", uninstaller_path.to_string_lossy()),
)
.output()?;
sudo(&passwd, format!("{}", uninstaller_path.to_string_lossy())).output()?
}
};
if !output.status.success() {
bail!(
"failed to install service with error: {}",
String::from_utf8_lossy(&output.stderr)
);
}
Ok(())
}
#[cfg(target_os = "macos")]
pub async fn uninstall_service(passwd: String) -> Result<()> {
let binary_path = dirs::service_path()?;
let uninstaller_path = binary_path.with_file_name("uninstall-service");
pub async fn reinstall_service() -> Result<()> {
log::info!(target:"app", "reinstall service");
if !uninstaller_path.exists() {
bail!("uninstaller not found");
let binary_path = dirs::service_path()?;
let install_path = binary_path.with_file_name("install-service");
let uninstall_path = binary_path.with_file_name("uninstall-service");
if !install_path.exists() {
bail!(format!("installer not found: {install_path:?}"));
}
sudo(
&passwd,
format!(
"chmod +x {}",
uninstaller_path.to_string_lossy().replace(" ", "\\ ")
),
)
.output()?;
let output = sudo(
&passwd,
format!("{}", uninstaller_path.to_string_lossy().replace(" ", "\\ ")),
)
.output()?;
if !uninstall_path.exists() {
bail!(format!("uninstaller not found: {uninstall_path:?}"));
}
if !output.status.success() {
let install_shell: String = install_path.to_string_lossy().replace(" ", "\\ ");
let uninstall_shell: String = uninstall_path.to_string_lossy().replace(" ", "\\ ");
let command = format!(
r#"do shell script "sudo {uninstall_shell} && sudo {install_shell}" with administrator privileges"#
);
let status = StdCommand::new("osascript")
.args(vec!["-e", &command])
.status()?;
if !status.success() {
bail!(
"failed to uninstall service with error: {}",
String::from_utf8_lossy(&output.stderr)
"failed to install service with status {}",
status.code().unwrap()
);
}
Ok(())
}
@@ -263,6 +162,7 @@ pub async fn check_service() -> Result<JsonResponse> {
let url = format!("{SERVICE_URL}/get_clash");
let response = reqwest::ClientBuilder::new()
.no_proxy()
.timeout(Duration::from_secs(3))
.build()?
.get(url)
.send()
@@ -277,29 +177,8 @@ pub async fn check_service() -> Result<JsonResponse> {
/// start the clash by service
pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
let status = check_service().await?;
if status.code == 0 {
stop_core_by_service().await?;
sleep(Duration::from_secs(1)).await;
}
let clash_core = { Config::verge().latest().clash_core.clone() };
let mut clash_core = clash_core.unwrap_or("verge-mihomo".into());
// compatibility
if clash_core.contains("clash") {
clash_core = "verge-mihomo".to_string();
Config::verge().draft().patch_config(IVerge {
clash_core: Some("verge-mihomo".to_string()),
..IVerge::default()
});
Config::verge().apply();
match Config::verge().data().save_file() {
Ok(_) => handle::Handle::refresh_verge(),
Err(err) => log::error!(target: "app", "{err}"),
}
}
let clash_core = clash_core.unwrap_or("verge-mihomo".into());
let bin_ext = if cfg!(windows) { ".exe" } else { "" };
let clash_bin = format!("{clash_core}{bin_ext}");
@@ -321,81 +200,31 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
map.insert("config_file", config_file);
map.insert("log_file", log_path);
log::info!(target:"app", "start service: {:?}", map.clone());
let url = format!("{SERVICE_URL}/start_clash");
let res = reqwest::ClientBuilder::new()
let _ = reqwest::ClientBuilder::new()
.no_proxy()
.build()?
.post(url)
.json(&map)
.send()
.await?
.json::<JsonResponse>()
.await
.context("failed to connect to the Clash Verge Service")?;
if res.code != 0 {
bail!(res.msg);
}
Ok(())
}
/// stop the clash by service
pub(super) async fn stop_core_by_service() -> Result<()> {
let url = format!("{SERVICE_URL}/stop_clash");
let res = reqwest::ClientBuilder::new()
let _ = reqwest::ClientBuilder::new()
.no_proxy()
.build()?
.post(url)
.send()
.await?
.json::<JsonResponse>()
.await
.context("failed to connect to the Clash Verge Service")?;
if res.code != 0 {
bail!(res.msg);
}
Ok(())
}
/// set dns by service
pub async fn set_dns_by_service() -> Result<()> {
let url = format!("{SERVICE_URL}/set_dns");
let res = reqwest::ClientBuilder::new()
.no_proxy()
.build()?
.post(url)
.send()
.await?
.json::<JsonResponse>()
.await
.context("failed to connect to the Clash Verge Service")?;
if res.code != 0 {
bail!(res.msg);
}
Ok(())
}
/// unset dns by service
pub async fn unset_dns_by_service() -> Result<()> {
let url = format!("{SERVICE_URL}/unset_dns");
let res = reqwest::ClientBuilder::new()
.no_proxy()
.build()?
.post(url)
.send()
.await?
.json::<JsonResponse>()
.await
.context("failed to connect to the Clash Verge Service")?;
if res.code != 0 {
bail!(res.msg);
}
Ok(())
}

View File

@@ -10,27 +10,15 @@ use std::env::current_exe;
use std::sync::Arc;
use sysproxy::{Autoproxy, Sysproxy};
use tauri::async_runtime::Mutex as TokioMutex;
use tokio::time::{sleep, Duration};
pub struct Sysopt {
/// current system proxy setting
cur_sysproxy: Arc<Mutex<Option<Sysproxy>>>,
/// record the original system proxy
/// recover it when exit
old_sysproxy: Arc<Mutex<Option<Sysproxy>>>,
/// current auto proxy setting
cur_autoproxy: Arc<Mutex<Option<Autoproxy>>>,
/// record the original auto proxy
/// recover it when exit
old_autoproxy: Arc<Mutex<Option<Autoproxy>>>,
update_sysproxy: Arc<TokioMutex<bool>>,
reset_sysproxy: Arc<TokioMutex<bool>>,
/// helps to auto launch the app
auto_launch: Arc<Mutex<Option<AutoLaunch>>>,
/// record whether the guard async is running or not
guard_state: Arc<TokioMutex<bool>>,
guard_state: Arc<Mutex<bool>>,
}
#[cfg(target_os = "windows")]
@@ -42,7 +30,6 @@ static DEFAULT_BYPASS: &str =
"127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,localhost,*.local,*.crashlytics.com,<local>";
fn get_bypass() -> String {
// let bypass = DEFAULT_BYPASS.to_string();
let use_default = Config::verge().latest().use_default_bypass.unwrap_or(true);
let res = {
let verge = Config::verge();
@@ -53,125 +40,35 @@ fn get_bypass() -> String {
Some(bypass) => bypass,
None => "".to_string(),
};
#[cfg(target_os = "windows")]
let bypass = if custom_bypass.is_empty() {
DEFAULT_BYPASS.to_string()
} else {
if use_default {
format!("{};{}", DEFAULT_BYPASS, custom_bypass)
} else {
custom_bypass
}
};
#[cfg(not(target_os = "windows"))]
let bypass = if custom_bypass.is_empty() {
DEFAULT_BYPASS.to_string()
} else {
if use_default {
format!("{},{}", DEFAULT_BYPASS, custom_bypass)
} else {
custom_bypass
}
};
bypass
if custom_bypass.is_empty() {
DEFAULT_BYPASS.to_string()
} else if use_default {
format!("{},{}", DEFAULT_BYPASS, custom_bypass)
} else {
custom_bypass
}
}
impl Sysopt {
pub fn global() -> &'static Sysopt {
static SYSOPT: OnceCell<Sysopt> = OnceCell::new();
SYSOPT.get_or_init(|| Sysopt {
cur_sysproxy: Arc::new(Mutex::new(None)),
old_sysproxy: Arc::new(Mutex::new(None)),
cur_autoproxy: Arc::new(Mutex::new(None)),
old_autoproxy: Arc::new(Mutex::new(None)),
update_sysproxy: Arc::new(TokioMutex::new(false)),
reset_sysproxy: Arc::new(TokioMutex::new(false)),
auto_launch: Arc::new(Mutex::new(None)),
guard_state: Arc::new(TokioMutex::new(false)),
guard_state: Arc::new(false.into()),
})
}
/// init the sysproxy
pub fn init_sysproxy(&self) -> Result<()> {
let port = Config::verge()
.latest()
.verge_mixed_port
.unwrap_or(Config::clash().data().get_mixed_port());
let pac_port = IVerge::get_singleton_port();
let (enable, pac) = {
let verge = Config::verge();
let verge = verge.latest();
(
verge.enable_system_proxy.unwrap_or(false),
verge.proxy_auto_config.unwrap_or(false),
)
};
let mut sys = Sysproxy {
enable,
host: String::from("127.0.0.1"),
port,
bypass: get_bypass(),
};
let mut auto = Autoproxy {
enable,
url: format!("http://127.0.0.1:{pac_port}/commands/pac"),
};
if pac {
sys.enable = false;
let old = Sysproxy::get_system_proxy().ok();
sys.set_system_proxy()?;
*self.old_sysproxy.lock() = old;
*self.cur_sysproxy.lock() = Some(sys);
let old = Autoproxy::get_auto_proxy().ok();
auto.set_auto_proxy()?;
*self.old_autoproxy.lock() = old;
*self.cur_autoproxy.lock() = Some(auto);
} else {
auto.enable = false;
let old = Autoproxy::get_auto_proxy().ok();
auto.set_auto_proxy()?;
*self.old_autoproxy.lock() = old;
*self.cur_autoproxy.lock() = Some(auto);
let old = Sysproxy::get_system_proxy().ok();
sys.set_system_proxy()?;
*self.old_sysproxy.lock() = old;
*self.cur_sysproxy.lock() = Some(sys);
}
// run the system proxy guard
pub fn init_guard_sysproxy(&self) -> Result<()> {
self.guard_proxy();
Ok(())
}
/// update the system proxy
pub fn update_sysproxy(&self) -> Result<()> {
let mut cur_sysproxy = self.cur_sysproxy.lock();
let old_sysproxy = self.old_sysproxy.lock();
let mut cur_autoproxy = self.cur_autoproxy.lock();
let old_autoproxy = self.old_autoproxy.lock();
let (enable, pac) = {
let verge = Config::verge();
let verge = verge.latest();
(
verge.enable_system_proxy.unwrap_or(false),
verge.proxy_auto_config.unwrap_or(false),
)
};
if pac && (cur_autoproxy.is_none() || old_autoproxy.is_none()) {
drop(cur_autoproxy);
drop(old_autoproxy);
return self.init_sysproxy();
}
if !pac && (cur_sysproxy.is_none() || old_sysproxy.is_none()) {
drop(cur_sysproxy);
drop(old_sysproxy);
return self.init_sysproxy();
}
/// init the sysproxy
pub async fn update_sysproxy(&self) -> Result<()> {
let _lock = self.update_sysproxy.lock().await;
let port = Config::verge()
.latest()
@@ -179,84 +76,139 @@ impl Sysopt {
.unwrap_or(Config::clash().data().get_mixed_port());
let pac_port = IVerge::get_singleton_port();
let mut sysproxy = cur_sysproxy.take().unwrap();
sysproxy.bypass = get_bypass();
sysproxy.port = port;
let (sys_enable, pac_enable) = {
let verge = Config::verge();
let verge = verge.latest();
(
verge.enable_system_proxy.unwrap_or(false),
verge.proxy_auto_config.unwrap_or(false),
)
};
let mut autoproxy = cur_autoproxy.take().unwrap();
autoproxy.url = format!("http://127.0.0.1:{pac_port}/commands/pac");
#[cfg(not(target_os = "windows"))]
{
let mut sys = Sysproxy {
enable: false,
host: String::from("127.0.0.1"),
port,
bypass: get_bypass(),
};
let mut auto = Autoproxy {
enable: false,
url: format!("http://127.0.0.1:{pac_port}/commands/pac"),
};
if pac {
sysproxy.enable = false;
sysproxy.set_system_proxy()?;
*cur_sysproxy = Some(sysproxy);
autoproxy.enable = enable;
autoproxy.set_auto_proxy()?;
*cur_autoproxy = Some(autoproxy);
} else {
autoproxy.enable = false;
autoproxy.set_auto_proxy()?;
*cur_autoproxy = Some(autoproxy);
sysproxy.enable = enable;
sysproxy.set_system_proxy()?;
*cur_sysproxy = Some(sysproxy);
if !sys_enable {
sys.set_system_proxy()?;
auto.set_auto_proxy()?;
return Ok(());
}
if pac_enable {
sys.enable = false;
auto.enable = true;
sys.set_system_proxy()?;
auto.set_auto_proxy()?;
return Ok(());
}
if sys_enable {
auto.enable = false;
sys.enable = true;
auto.set_auto_proxy()?;
sys.set_system_proxy()?;
return Ok(());
}
}
#[cfg(target_os = "windows")]
{
if !sys_enable {
return self.reset_sysproxy().await;
}
use crate::core::handle::Handle;
use crate::utils::dirs;
use anyhow::bail;
use tauri_plugin_shell::ShellExt;
let app_handle = Handle::global().app_handle().unwrap();
let binary_path = dirs::service_path()?;
let sysproxy_exe = binary_path.with_file_name("sysproxy.exe");
if !sysproxy_exe.exists() {
bail!("sysproxy.exe not found");
}
let shell = app_handle.shell();
let output = if pac_enable {
let address = format!("http://{}:{}/commands/pac", "127.0.0.1", pac_port);
let output = shell
.command(sysproxy_exe.as_path().to_str().unwrap())
.args(["pac", address.as_str()])
.output()
.await
.unwrap();
output
} else {
let address = format!("{}:{}", "127.0.0.1", port);
let bypass = get_bypass();
let output = shell
.command(sysproxy_exe.as_path().to_str().unwrap())
.args(["global", address.as_str(), bypass.as_ref()])
.output()
.await
.unwrap();
output
};
if !output.status.success() {
bail!("sysproxy exe run failed");
}
}
Ok(())
}
/// reset the sysproxy
pub fn reset_sysproxy(&self) -> Result<()> {
let mut cur_sysproxy = self.cur_sysproxy.lock();
let mut old_sysproxy = self.old_sysproxy.lock();
let mut cur_autoproxy = self.cur_autoproxy.lock();
let mut old_autoproxy = self.old_autoproxy.lock();
let cur_sysproxy = cur_sysproxy.take();
let cur_autoproxy = cur_autoproxy.take();
if let Some(mut old) = old_sysproxy.take() {
// 如果原代理和当前代理 端口一致就disable关闭否则就恢复原代理设置
// 当前没有设置代理的时候,不确定旧设置是否和当前一致,全关了
let port_same = cur_sysproxy.map_or(true, |cur| old.port == cur.port);
if old.enable && port_same {
old.enable = false;
log::info!(target: "app", "reset proxy by disabling the original proxy");
} else {
log::info!(target: "app", "reset proxy to the original proxy");
}
old.set_system_proxy()?;
} else if let Some(mut cur @ Sysproxy { enable: true, .. }) = cur_sysproxy {
// 没有原代理就按现在的代理设置disable即可
log::info!(target: "app", "reset proxy by disabling the current proxy");
cur.enable = false;
cur.set_system_proxy()?;
} else {
log::info!(target: "app", "reset proxy with no action");
pub async fn reset_sysproxy(&self) -> Result<()> {
let _lock = self.reset_sysproxy.lock().await;
//直接关闭所有代理
#[cfg(not(target_os = "windows"))]
{
let mut sysproxy: Sysproxy = Sysproxy::get_system_proxy()?;
let mut autoproxy = Autoproxy::get_auto_proxy()?;
sysproxy.enable = false;
autoproxy.enable = false;
autoproxy.set_auto_proxy()?;
sysproxy.set_system_proxy()?;
}
if let Some(mut old) = old_autoproxy.take() {
// 如果原代理和当前代理 URL一致就disable关闭否则就恢复原代理设置
// 当前没有设置代理的时候,不确定旧设置是否和当前一致,全关了
let url_same = cur_autoproxy.map_or(true, |cur| old.url == cur.url);
#[cfg(target_os = "windows")]
{
use crate::core::handle::Handle;
use crate::utils::dirs;
use anyhow::bail;
use tauri_plugin_shell::ShellExt;
if old.enable && url_same {
old.enable = false;
log::info!(target: "app", "reset proxy by disabling the original proxy");
} else {
log::info!(target: "app", "reset proxy to the original proxy");
let app_handle = Handle::global().app_handle().unwrap();
let binary_path = dirs::service_path()?;
let sysproxy_exe = binary_path.with_file_name("sysproxy.exe");
if !sysproxy_exe.exists() {
bail!("sysproxy.exe not found");
}
old.set_auto_proxy()?;
} else if let Some(mut cur @ Autoproxy { enable: true, .. }) = cur_autoproxy {
// 没有原代理就按现在的代理设置disable即可
log::info!(target: "app", "reset proxy by disabling the current proxy");
cur.enable = false;
cur.set_auto_proxy()?;
} else {
log::info!(target: "app", "reset proxy with no action");
let shell = app_handle.shell();
let output = shell
.command(sysproxy_exe.as_path().to_str().unwrap())
.args(["set", "1"])
.output()
.await
.unwrap();
if !output.status.success() {
bail!("sysproxy exe run failed");
}
}
Ok(())
@@ -294,14 +246,13 @@ impl Sysopt {
})()
.unwrap_or(app_path);
// fix #403
#[cfg(target_os = "linux")]
let app_path = {
use crate::core::handle::Handle;
use tauri::Manager;
let handle = Handle::global();
match handle.app_handle.lock().as_ref() {
let app_handle = Handle::global().app_handle();
match app_handle {
Some(app_handle) => {
let appimage = app_handle.env().appimage;
appimage
@@ -326,10 +277,6 @@ impl Sysopt {
pub fn update_launch(&self) -> Result<()> {
let auto_launch = self.auto_launch.lock();
if auto_launch.is_none() {
drop(auto_launch);
return self.init_launch();
}
let enable = { Config::verge().latest().enable_auto_launch };
let enable = enable.unwrap_or(false);
let auto_launch = auto_launch.as_ref().unwrap();
@@ -342,22 +289,10 @@ impl Sysopt {
Ok(())
}
/// launch a system proxy guard
/// read config from file directly
pub fn guard_proxy(&self) {
use tokio::time::{sleep, Duration};
let guard_state = self.guard_state.clone();
fn guard_proxy(&self) {
let _lock = self.guard_state.lock();
tauri::async_runtime::spawn(async move {
// if it is running, exit
let mut state = guard_state.lock().await;
if *state {
return;
}
*state = true;
drop(state);
// default duration is 10s
let mut wait_secs = 10u64;
@@ -377,7 +312,7 @@ impl Sysopt {
// stop loop
if !enable || !guard {
break;
continue;
}
// update duration
@@ -385,6 +320,20 @@ impl Sysopt {
log::debug!(target: "app", "try to guard the system proxy");
let sysproxy = Sysproxy::get_system_proxy();
let autoproxy = Autoproxy::get_auto_proxy();
if sysproxy.is_err() || autoproxy.is_err() {
log::error!(target: "app", "failed to get the system proxy");
continue;
}
let sysproxy_enable = sysproxy.ok().map(|s| s.enable).unwrap_or(false);
let autoproxy_enable = autoproxy.ok().map(|s| s.enable).unwrap_or(false);
if sysproxy_enable || autoproxy_enable {
continue;
}
let port = {
Config::verge()
.latest()
@@ -392,27 +341,66 @@ impl Sysopt {
.unwrap_or(Config::clash().data().get_mixed_port())
};
let pac_port = IVerge::get_singleton_port();
if pac {
let autoproxy = Autoproxy {
enable: true,
url: format!("http://127.0.0.1:{pac_port}/commands/pac"),
};
log_err!(autoproxy.set_auto_proxy());
} else {
let sysproxy = Sysproxy {
enable: true,
host: "127.0.0.1".into(),
port,
bypass: get_bypass(),
};
#[cfg(not(target_os = "windows"))]
{
if pac {
let autoproxy = Autoproxy {
enable: true,
url: format!("http://127.0.0.1:{pac_port}/commands/pac"),
};
log_err!(autoproxy.set_auto_proxy());
} else {
let sysproxy = Sysproxy {
enable: true,
host: "127.0.0.1".into(),
port,
bypass: get_bypass(),
};
log_err!(sysproxy.set_system_proxy());
log_err!(sysproxy.set_system_proxy());
}
}
}
let mut state = guard_state.lock().await;
*state = false;
drop(state);
#[cfg(target_os = "windows")]
{
use crate::core::handle::Handle;
use crate::utils::dirs;
use tauri_plugin_shell::ShellExt;
let app_handle = Handle::global().app_handle().unwrap();
let binary_path = dirs::service_path().unwrap();
let sysproxy_exe = binary_path.with_file_name("sysproxy.exe");
if !sysproxy_exe.exists() {
break;
}
let shell = app_handle.shell();
let output = if pac {
let address = format!("http://{}:{}/commands/pac", "127.0.0.1", pac_port);
shell
.command(sysproxy_exe.as_path().to_str().unwrap())
.args(["pac", address.as_str()])
.output()
.await
.unwrap()
} else {
let address = format!("{}:{}", "127.0.0.1", port);
let bypass = get_bypass();
shell
.command(sysproxy_exe.as_path().to_str().unwrap())
.args(["global", address.as_str(), bypass.as_ref()])
.output()
.await
.unwrap()
};
if !output.status.success() {
break;
}
};
}
});
}
}

View File

@@ -8,41 +8,65 @@ use crate::{
},
};
use anyhow::Result;
use tauri::tray::{MouseButton, MouseButtonState, TrayIconEvent};
use tauri::{
menu::CheckMenuItem,
tray::{MouseButton, MouseButtonState, TrayIconEvent, TrayIconId},
};
use tauri::{
menu::{MenuEvent, MenuItem, PredefinedMenuItem, Submenu},
Wry,
};
use tauri::{AppHandle, Manager};
use super::handle;
pub struct Tray {}
impl Tray {
pub fn update_systray(app_handle: &AppHandle) -> Result<()> {
let tray = app_handle.tray_by_id("main").unwrap();
tray.on_tray_icon_event(|tray, event| {
pub fn create_systray() -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let tray_incon_id = TrayIconId::new("main");
let tray = app_handle.tray_by_id(&tray_incon_id).unwrap();
tray.on_tray_icon_event(|_, event| {
let tray_event = { Config::verge().latest().tray_event.clone() };
let tray_event: String = tray_event.unwrap_or("main_window".into());
#[cfg(target_os = "macos")]
if let TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Up,
button: MouseButton::Right,
button_state: MouseButtonState::Down,
..
} = event
{
let app = tray.app_handle();
match tray_event.as_str() {
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(),
"main_window" => resolve::create_window(app),
"main_window" => resolve::create_window(),
_ => {}
}
}
#[cfg(not(target_os = "macos"))]
if let TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Down,
..
} = event
{
match tray_event.as_str() {
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(),
"main_window" => resolve::create_window(),
_ => {}
}
}
});
tray.on_menu_event(on_menu_event);
Ok(())
}
pub fn update_part(app_handle: &AppHandle) -> Result<()> {
pub fn update_part() -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let use_zh = { Config::verge().latest().language == Some("zh".into()) };
let version = VERSION.get().unwrap();
let mode = {
@@ -66,7 +90,7 @@ impl Tray {
let tray = app_handle.tray_by_id("main").unwrap();
let _ = tray.set_menu(Some(create_tray_menu(
app_handle,
&app_handle,
Some(mode.as_str()),
*system_proxy,
*tun_mode,
@@ -191,40 +215,113 @@ fn create_tray_menu(
let use_zh = { Config::verge().latest().language == Some("zh".into()) };
let version = VERSION.get().unwrap();
let rule_mode_text = if mode == "rule" {
"✓ 规则模式"
} else {
"规则模式"
};
let open_window = &MenuItem::with_id(
app_handle,
"open_window",
t!("Dashboard", "打开面板", use_zh),
true,
None::<&str>,
)
.unwrap();
let global_mode_text = if mode == "global" {
"✓ 全局模式"
} else {
"全局模式"
};
let rule_mode = &CheckMenuItem::with_id(
app_handle,
"rule_mode",
t!("Rule Mode", "规则模式", use_zh),
true,
mode == "rule",
None::<&str>,
)
.unwrap();
let direct_mode_text = if mode == "direct" {
"✓ 直连模式"
} else {
"直连模式"
};
let global_mode = &CheckMenuItem::with_id(
app_handle,
"global_mode",
t!("Global Mode", "全局模式", use_zh),
true,
mode == "global",
None::<&str>,
)
.unwrap();
let system_proxy_text = if system_proxy_enabled {
"✓ 系统代理"
} else {
"系统代理"
};
let direct_mode = &CheckMenuItem::with_id(
app_handle,
"direct_mode",
t!("Direct Mode", "直连模式", use_zh),
true,
mode == "direct",
None::<&str>,
)
.unwrap();
let tun_mode_text = if tun_mode_enabled {
"✓ Tun 模式"
} else {
"Tun 模式"
};
let system_proxy = &CheckMenuItem::with_id(
app_handle,
"system_proxy",
t!("System Proxy", "系统代理", use_zh),
true,
system_proxy_enabled,
None::<&str>,
)
.unwrap();
let tun_mode = &CheckMenuItem::with_id(
app_handle,
"tun_mode",
t!("TUN Mode", "Tun模式", use_zh),
true,
tun_mode_enabled,
None::<&str>,
)
.unwrap();
let copy_env = &MenuItem::with_id(
app_handle,
"copy_env",
t!("Copy Env", "复制环境变量", use_zh),
true,
None::<&str>,
)
.unwrap();
let open_app_dir = &MenuItem::with_id(
app_handle,
"open_app_dir",
t!("Conf Dir", "配置目录", use_zh),
true,
None::<&str>,
)
.unwrap();
let open_core_dir = &MenuItem::with_id(
app_handle,
"open_core_dir",
t!("Core Dir", "内核目录", use_zh),
true,
None::<&str>,
)
.unwrap();
let open_logs_dir = &MenuItem::with_id(
app_handle,
"open_logs_dir",
t!("Logs Dir", "日志目录", use_zh),
true,
None::<&str>,
)
.unwrap();
let open_dir = &Submenu::with_id_and_items(
app_handle,
"open_dir",
t!("Open Dir", "打开目录", use_zh),
true,
&[open_app_dir, open_core_dir, open_logs_dir],
)
.unwrap();
let restart_clash = &MenuItem::with_id(
app_handle,
"restart_clash",
t!("Restart App", "重启 Clash", use_zh),
t!("Restart Clash Core", "重启Clash内核", use_zh),
true,
None::<&str>,
)
@@ -233,7 +330,7 @@ fn create_tray_menu(
let restart_app = &MenuItem::with_id(
app_handle,
"restart_app",
t!("Restart App", "重启应用", use_zh),
t!("Restart App", "重启Verge", use_zh),
true,
None::<&str>,
)
@@ -248,113 +345,44 @@ fn create_tray_menu(
)
.unwrap();
let more = &Submenu::with_id_and_items(
app_handle,
"more",
t!("More", "更多", use_zh),
true,
&[restart_clash, restart_app, app_version],
)
.unwrap();
let quit = &MenuItem::with_id(
app_handle,
"quit",
t!("Quit", "退出", use_zh),
true,
Some("CmdOrControl+Q"),
)
.unwrap();
let separator = &PredefinedMenuItem::separator(app_handle).unwrap();
let menu = tauri::menu::MenuBuilder::new(app_handle)
.item(
&MenuItem::with_id(
app_handle,
"open_window",
t!("Dashboard", "打开面板", use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(&PredefinedMenuItem::separator(app_handle).unwrap())
.item(
&MenuItem::with_id(
app_handle,
"rule_mode",
t!("Rule Mode", rule_mode_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"global_mode",
t!("Global Mode", global_mode_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"direct_mode",
t!("Direct Mode", direct_mode_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(&PredefinedMenuItem::separator(app_handle).unwrap())
.item(
&MenuItem::with_id(
app_handle,
"system_proxy",
t!("System Proxy", system_proxy_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"tun_mode",
t!("TUN Mode", tun_mode_text, use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"copy_env",
t!("Copy Env", "复制环境变量", use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&MenuItem::with_id(
app_handle,
"open_dir",
t!("Open Dir", "打开目录", use_zh),
true,
None::<&str>,
)
.unwrap(),
)
.item(
&Submenu::with_id_and_items(
app_handle,
"more",
t!("More", "更多", use_zh),
true,
&[restart_clash, restart_app, app_version],
)
.unwrap(),
)
.item(&PredefinedMenuItem::separator(app_handle).unwrap())
.item(
&MenuItem::with_id(
app_handle,
"quit",
t!("Quit", "退出", use_zh),
true,
Some("CmdOrControl+Q"),
)
.unwrap(),
)
.items(&[
open_window,
separator,
rule_mode,
global_mode,
direct_mode,
separator,
system_proxy,
tun_mode,
copy_env,
open_dir,
more,
separator,
quit,
])
.build()
.unwrap();
Ok(menu)
}
@@ -365,14 +393,19 @@ fn on_menu_event(app_handle: &AppHandle, event: MenuEvent) {
println!("change mode to: {}", mode);
feat::change_clash_mode(mode.into());
}
"open_window" => resolve::create_window(app_handle),
"open_window" => resolve::create_window(),
"system_proxy" => feat::toggle_system_proxy(),
"tun_mode" => feat::toggle_tun_mode(),
"copy_env" => feat::copy_clash_env(app_handle),
"open_dir" => crate::log_err!(cmds::open_app_dir()),
"copy_env" => feat::copy_clash_env(),
"open_app_dir" => crate::log_err!(cmds::open_app_dir()),
"open_core_dir" => crate::log_err!(cmds::open_core_dir()),
"open_logs_dir" => crate::log_err!(cmds::open_logs_dir()),
"restart_clash" => feat::restart_clash_core(),
"restart_app" => tauri::process::restart(&app_handle.env()),
"quit" => cmds::exit_app(app_handle.clone()),
"quit" => {
println!("quit");
feat::quit(Some(0));
}
_ => {}
}
}

View File

@@ -54,9 +54,7 @@ fn test_merge() -> anyhow::Result<()> {
let merge = serde_yaml::from_str::<Mapping>(merge)?;
let config = serde_yaml::from_str::<Mapping>(config)?;
let result = serde_yaml::to_string(&use_merge(merge, config))?;
println!("{result}");
let _ = serde_yaml::to_string(&use_merge(merge, config))?;
Ok(())
}

View File

@@ -259,7 +259,9 @@ pub async fn enhance() -> (Mapping, Vec<String>, HashMap<String, ResultLog>) {
});
}
config = use_tun(config, enable_tun).await;
if enable_tun {
config = use_tun(config).await;
}
config = use_sort(config);
let mut exists_set = HashSet::new();

View File

@@ -103,9 +103,7 @@ fn test_script() {
let config = serde_yaml::from_str(config).unwrap();
let (config, results) = use_script(script.into(), config, "".to_string()).unwrap();
let config_str = serde_yaml::to_string(&config).unwrap();
println!("{config_str}");
let _ = serde_yaml::to_string(&config).unwrap();
dbg!(results);
}

View File

@@ -12,7 +12,7 @@ pub fn use_seq(seq_map: SeqMap, config: Mapping, name: &str) -> Mapping {
let append = seq_map.append;
let delete = seq_map.delete;
let origin_seq = config.get(&name).map_or(Sequence::default(), |val| {
let origin_seq = config.get(name).map_or(Sequence::default(), |val| {
val.as_sequence().unwrap_or(&Sequence::default()).clone()
});
let mut seq = origin_seq.clone();
@@ -23,7 +23,7 @@ pub fn use_seq(seq_map: SeqMap, config: Mapping, name: &str) -> Mapping {
if let Some(name) = if item.is_string() {
Some(item)
} else {
item.get("name").map(|y| y.clone())
item.get("name").cloned()
} {
delete_names.push(name.clone());
}
@@ -34,7 +34,7 @@ pub fn use_seq(seq_map: SeqMap, config: Mapping, name: &str) -> Mapping {
} else {
x.get("name")
} {
!delete_names.contains(&x_name)
!delete_names.contains(x_name)
} else {
true
}
@@ -51,5 +51,5 @@ pub fn use_seq(seq_map: SeqMap, config: Mapping, name: &str) -> Mapping {
let mut config = config.clone();
config.insert(Value::from(name), Value::from(seq));
return config;
config
}

View File

@@ -1,4 +1,3 @@
use crate::{core::service, log_err};
use serde_yaml::{Mapping, Value};
macro_rules! revise {
@@ -9,6 +8,7 @@ macro_rules! revise {
}
// if key not exists then append value
#[allow(unused_macros)]
macro_rules! append {
($map: expr, $key: expr, $val: expr) => {
let ret_key = Value::String($key.into());
@@ -18,61 +18,13 @@ macro_rules! append {
};
}
pub async fn use_tun(mut config: Mapping, enable: bool) -> Mapping {
pub async fn use_tun(mut config: Mapping) -> Mapping {
let tun_key = Value::from("tun");
let tun_val = config.get(&tun_key);
if !enable && tun_val.is_none() {
return config;
}
let mut tun_val = tun_val.map_or(Mapping::new(), |val| {
val.as_mapping().cloned().unwrap_or(Mapping::new())
});
revise!(tun_val, "enable", enable);
revise!(tun_val, "enable", true);
revise!(config, "tun", tun_val);
if enable {
log_err!(service::set_dns_by_service().await);
use_dns_for_tun(config)
} else {
log_err!(service::unset_dns_by_service().await);
config
}
}
fn use_dns_for_tun(mut config: Mapping) -> Mapping {
let dns_key = Value::from("dns");
let dns_val = config.get(&dns_key);
let mut dns_val = dns_val.map_or(Mapping::new(), |val| {
val.as_mapping().cloned().unwrap_or(Mapping::new())
});
// 开启tun将同时开启dns
revise!(dns_val, "enable", true);
append!(dns_val, "enhanced-mode", "fake-ip");
append!(dns_val, "fake-ip-range", "198.18.0.1/16");
append!(
dns_val,
"nameserver",
vec!["114.114.114.114", "223.5.5.5", "8.8.8.8"]
);
append!(dns_val, "fallback", vec![] as Vec<&str>);
#[cfg(target_os = "windows")]
append!(
dns_val,
"fake-ip-filter",
vec![
"dns.msftncsi.com",
"www.msftncsi.com",
"www.msftconnecttest.com"
]
);
revise!(config, "dns", dns_val);
config
}

View File

@@ -10,28 +10,23 @@ use crate::log_err;
use crate::utils::resolve;
use anyhow::{bail, Result};
use serde_yaml::{Mapping, Value};
use tauri::{AppHandle, Manager};
use tauri_plugin_clipboard_manager::ClipboardExt;
// 打开面板
pub fn open_or_close_dashboard() {
let handle = handle::Handle::global();
let app_handle = handle.app_handle.lock();
if let Some(app_handle) = app_handle.as_ref() {
if let Some(window) = app_handle.get_webview_window("main") {
if let Ok(true) = window.is_focused() {
let _ = window.close();
return;
}
if let Some(window) = handle::Handle::global().get_window() {
if let Ok(true) = window.is_focused() {
let _ = window.minimize();
return;
}
resolve::create_window(app_handle);
}
resolve::create_window();
}
// 重启clash
pub fn restart_clash_core() {
tauri::async_runtime::spawn(async {
match CoreManager::global().run_core().await {
match CoreManager::global().restart_core().await {
Ok(_) => {
handle::Handle::refresh_clash();
handle::Handle::notice_message("set_config::ok", "ok");
@@ -103,6 +98,12 @@ pub fn toggle_tun_mode() {
});
}
pub fn quit(code: Option<i32>) {
let app_handle = handle::Handle::global().app_handle().unwrap();
resolve::resolve_reset();
app_handle.exit(code.unwrap_or(0));
}
/// 修改clash的订阅
pub async fn patch_clash(patch: Mapping) -> Result<()> {
Config::clash().draft().patch_config(patch.clone());
@@ -111,7 +112,7 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
// 激活订阅
if patch.get("secret").is_some() || patch.get("external-controller").is_some() {
Config::generate().await?;
CoreManager::global().run_core().await?;
CoreManager::global().restart_core().await?;
handle::Handle::refresh_clash();
}
@@ -140,6 +141,7 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
/// 一般都是一个个的修改
pub async fn patch_verge(patch: IVerge) -> Result<()> {
Config::verge().draft().patch_config(patch.clone());
let tun_mode = patch.enable_tun_mode;
let auto_launch = patch.enable_auto_launch;
let system_proxy = patch.enable_system_proxy;
@@ -150,6 +152,8 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
let mixed_port = patch.verge_mixed_port;
#[cfg(target_os = "macos")]
let tray_icon = patch.tray_icon;
#[cfg(not(target_os = "macos"))]
let tray_icon: Option<String> = None;
let common_tray_icon = patch.common_tray_icon;
let sysproxy_tray_icon = patch.sysproxy_tray_icon;
let tun_tray_icon = patch.tun_tray_icon;
@@ -165,34 +169,26 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
let socks_port = patch.verge_socks_port;
let http_enabled = patch.verge_http_enabled;
let http_port = patch.verge_port;
let res = {
let service_mode = patch.enable_service_mode;
let mut generated = false;
if service_mode.is_some() {
log::debug!(target: "app", "change service mode to {}", service_mode.unwrap());
if !generated {
Config::generate().await?;
CoreManager::global().run_core().await?;
generated = true;
}
} else if tun_mode.is_some() {
update_core_config().await?;
let res: std::result::Result<(), anyhow::Error> = {
let mut should_restart_core = false;
let mut should_update_clash_config = false;
let mut should_update_launch = false;
let mut should_update_sysproxy = false;
let mut should_update_systray_part = false;
if tun_mode.is_some() {
should_update_clash_config = true;
}
#[cfg(not(target_os = "windows"))]
if redir_enabled.is_some() || redir_port.is_some() {
if !generated {
Config::generate().await?;
CoreManager::global().run_core().await?;
generated = true;
}
should_restart_core = true;
}
#[cfg(target_os = "linux")]
if tproxy_enabled.is_some() || tproxy_port.is_some() {
if !generated {
Config::generate().await?;
CoreManager::global().run_core().await?;
generated = true;
}
should_restart_core = true;
}
if socks_enabled.is_some()
|| http_enabled.is_some()
@@ -200,13 +196,10 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
|| http_port.is_some()
|| mixed_port.is_some()
{
if !generated {
Config::generate().await?;
CoreManager::global().run_core().await?;
}
should_restart_core = true;
}
if auto_launch.is_some() {
sysopt::Sysopt::global().update_launch()?;
should_update_launch = true;
}
if system_proxy.is_some()
|| proxy_bypass.is_some()
@@ -214,30 +207,39 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
|| pac.is_some()
|| pac_content.is_some()
{
sysopt::Sysopt::global().update_sysproxy()?;
sysopt::Sysopt::global().guard_proxy();
should_update_sysproxy = true;
}
if let Some(true) = patch.enable_proxy_guard {
sysopt::Sysopt::global().guard_proxy();
if language.is_some()
|| system_proxy.is_some()
|| tun_mode.is_some()
|| common_tray_icon.is_some()
|| sysproxy_tray_icon.is_some()
|| tun_tray_icon.is_some()
|| tray_icon.is_some()
{
should_update_systray_part = true;
}
if should_restart_core {
Config::generate().await?;
CoreManager::global().restart_core().await?;
}
if should_update_clash_config {
update_core_config(false).await?;
}
if should_update_launch {
sysopt::Sysopt::global().update_launch()?;
}
if should_update_sysproxy {
sysopt::Sysopt::global().update_sysproxy().await?;
}
if let Some(hotkeys) = patch.hotkeys {
hotkey::Hotkey::global().update(hotkeys)?;
}
if language.is_some() {
handle::Handle::update_systray()?;
} else if system_proxy.is_some()
|| tun_mode.is_some()
|| common_tray_icon.is_some()
|| sysproxy_tray_icon.is_some()
|| tun_tray_icon.is_some()
{
handle::Handle::update_systray_part()?;
}
#[cfg(target_os = "macos")]
if tray_icon.is_some() {
if should_update_systray_part {
handle::Handle::update_systray_part()?;
}
@@ -247,6 +249,7 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
Ok(()) => {
Config::verge().apply();
Config::verge().data().save_file()?;
Ok(())
}
Err(err) => {
@@ -288,29 +291,34 @@ pub async fn update_profile(uid: String, option: Option<PrfOption>) -> Result<()
};
if should_update {
update_core_config().await?;
update_core_config(true).await?;
}
Ok(())
}
/// 更新订阅
async fn update_core_config() -> Result<()> {
async fn update_core_config(notice: bool) -> Result<()> {
match CoreManager::global().update_config().await {
Ok(_) => {
handle::Handle::refresh_clash();
handle::Handle::notice_message("set_config::ok", "ok");
if notice {
handle::Handle::notice_message("set_config::ok", "ok");
}
Ok(())
}
Err(err) => {
handle::Handle::notice_message("set_config::error", format!("{err}"));
if notice {
handle::Handle::notice_message("set_config::error", format!("{err}"));
}
Err(err)
}
}
}
/// copy env variable
pub fn copy_clash_env(app_handle: &AppHandle) {
pub fn copy_clash_env() {
let app_handle = handle::Handle::global().app_handle().unwrap();
let port = { Config::verge().latest().verge_mixed_port.unwrap_or(7897) };
let http_proxy = format!("http://127.0.0.1:{}", port);
let socks5_proxy = format!("socks5://127.0.0.1:{}", port);

View File

@@ -0,0 +1,179 @@
mod cmds;
mod config;
mod core;
mod enhance;
mod feat;
mod utils;
use crate::core::hotkey;
use crate::utils::{resolve, resolve::resolve_scheme, server};
#[cfg(target_os = "macos")]
use tauri::Listener;
pub fn run() {
// 单例检测
let app_exists: bool = tauri::async_runtime::block_on(async move {
if server::check_singleton().await.is_err() {
println!("app exists");
true
} else {
false
}
});
if app_exists {
return;
}
#[cfg(target_os = "linux")]
std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
#[cfg(debug_assertions)]
let devtools = tauri_plugin_devtools::init();
#[allow(unused_mut)]
let mut builder = tauri::Builder::default()
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_deep_link::init())
.setup(|app| {
#[cfg(target_os = "linux")]
{
use tauri_plugin_deep_link::DeepLinkExt;
app.deep_link().register_all()?;
}
#[cfg(target_os = "macos")]
{
app.listen("deep-link://new-url", |event| {
tauri::async_runtime::spawn(async move {
let payload = event.payload();
log_err!(resolve_scheme(payload.to_owned()).await);
});
});
}
tauri::async_runtime::block_on(async move {
resolve::resolve_setup(app).await;
#[cfg(not(target_os = "macos"))]
{
let argvs: Vec<String> = std::env::args().collect();
if argvs.len() > 1 {
log_err!(resolve_scheme(argvs[1].to_owned()).await);
}
}
});
Ok(())
})
.invoke_handler(tauri::generate_handler![
// common
cmds::get_sys_proxy,
cmds::get_auto_proxy,
cmds::open_app_dir,
cmds::open_logs_dir,
cmds::open_web_url,
cmds::open_core_dir,
cmds::get_portable_flag,
cmds::get_network_interfaces,
// cmds::kill_sidecar,
cmds::restart_sidecar,
// clash
cmds::get_clash_info,
cmds::get_clash_logs,
cmds::patch_clash_config,
cmds::change_clash_core,
cmds::get_runtime_config,
cmds::get_runtime_yaml,
cmds::get_runtime_exists,
cmds::get_runtime_logs,
cmds::uwp::invoke_uwp_tool,
cmds::copy_clash_env,
// verge
cmds::get_verge_config,
cmds::patch_verge_config,
cmds::test_delay,
cmds::get_app_dir,
cmds::copy_icon_file,
cmds::download_icon_cache,
cmds::open_devtools,
cmds::exit_app,
cmds::get_network_interfaces_info,
// cmds::update_hotkeys,
// profile
cmds::get_profiles,
cmds::enhance_profiles,
cmds::patch_profiles_config,
cmds::view_profile,
cmds::patch_profile,
cmds::create_profile,
cmds::import_profile,
cmds::reorder_profile,
cmds::update_profile,
cmds::delete_profile,
cmds::read_profile_file,
cmds::save_profile_file,
// service mode
cmds::service::check_service,
// clash api
cmds::clash_api_get_proxy_delay
]);
#[cfg(debug_assertions)]
{
builder = builder.plugin(devtools);
}
let app = builder
.build(tauri::generate_context!())
.expect("error while running tauri application");
app.run(|_, e| match e {
tauri::RunEvent::ExitRequested { api, code, .. } => {
if code.is_none() {
api.prevent_exit();
}
}
tauri::RunEvent::WindowEvent { label, event, .. } => {
if label == "main" {
match event {
tauri::WindowEvent::CloseRequested { .. } => {
println!("closing window...");
let _ = resolve::save_window_size_position(true);
}
tauri::WindowEvent::Moved(_) | tauri::WindowEvent::Resized(_) => {
let _ = resolve::save_window_size_position(false);
}
tauri::WindowEvent::Focused(true) => {
#[cfg(target_os = "macos")]
{
log_err!(hotkey::Hotkey::global().register("CMD+Q", "quit"));
}
#[cfg(not(target_os = "macos"))]
{
log_err!(hotkey::Hotkey::global().register("Control+Q", "quit"));
};
}
tauri::WindowEvent::Destroyed => {
#[cfg(target_os = "macos")]
{
log_err!(hotkey::Hotkey::global().unregister("CMD+Q"));
}
#[cfg(not(target_os = "macos"))]
{
log_err!(hotkey::Hotkey::global().unregister("Control+Q"));
};
}
_ => {}
}
}
}
_ => {}
});
}

141
clash-verge-rev/src-tauri/src/main.rs Normal file → Executable file
View File

@@ -1,139 +1,4 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
mod cmds;
mod config;
mod core;
mod enhance;
mod feat;
mod utils;
use crate::utils::{resolve, server};
fn main() -> std::io::Result<()> {
// 单例检测
let app_exists: bool = tauri::async_runtime::block_on(async move {
if server::check_singleton().await.is_err() {
println!("app exists");
true
} else {
false
}
});
if app_exists {
return Ok(());
}
#[cfg(target_os = "linux")]
std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
#[cfg(debug_assertions)]
let devtools = tauri_plugin_devtools::init();
#[allow(unused_mut)]
let mut builder = tauri::Builder::default()
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_shell::init())
.setup(|app| {
tauri::async_runtime::block_on(async move {
resolve::resolve_setup(app).await;
});
Ok(())
})
.invoke_handler(tauri::generate_handler![
// common
cmds::get_sys_proxy,
cmds::get_auto_proxy,
cmds::open_app_dir,
cmds::open_logs_dir,
cmds::open_web_url,
cmds::open_core_dir,
cmds::get_portable_flag,
cmds::get_network_interfaces,
// cmds::kill_sidecar,
cmds::restart_sidecar,
// clash
cmds::get_clash_info,
cmds::get_clash_logs,
cmds::patch_clash_config,
cmds::change_clash_core,
cmds::get_runtime_config,
cmds::get_runtime_yaml,
cmds::get_runtime_exists,
cmds::get_runtime_logs,
cmds::uwp::invoke_uwp_tool,
cmds::copy_clash_env,
// verge
cmds::get_verge_config,
cmds::patch_verge_config,
cmds::test_delay,
cmds::get_app_dir,
cmds::copy_icon_file,
cmds::download_icon_cache,
cmds::open_devtools,
cmds::exit_app,
cmds::get_network_interfaces_info,
// cmds::update_hotkeys,
// profile
cmds::get_profiles,
cmds::enhance_profiles,
cmds::patch_profiles_config,
cmds::view_profile,
cmds::patch_profile,
cmds::create_profile,
cmds::import_profile,
cmds::reorder_profile,
cmds::update_profile,
cmds::delete_profile,
cmds::read_profile_file,
cmds::save_profile_file,
// service mode
cmds::service::check_service,
cmds::service::install_service,
cmds::service::uninstall_service,
// clash api
cmds::clash_api_get_proxy_delay
]);
#[cfg(debug_assertions)]
{
builder = builder.plugin(devtools);
}
let app = builder
.build(tauri::generate_context!())
.expect("error while running tauri application");
app.run(|app_handle, e| match e {
tauri::RunEvent::ExitRequested { api, .. } => {
api.prevent_exit();
}
tauri::RunEvent::WindowEvent { label, event, .. } => {
if label == "main" {
match event {
tauri::WindowEvent::Destroyed => {
let _ = resolve::save_window_size_position(app_handle, true);
}
tauri::WindowEvent::CloseRequested { .. } => {
let _ = resolve::save_window_size_position(app_handle, true);
}
tauri::WindowEvent::Moved(_) | tauri::WindowEvent::Resized(_) => {
let _ = resolve::save_window_size_position(app_handle, false);
}
_ => {}
}
}
}
_ => {}
});
Ok(())
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}

View File

@@ -44,40 +44,27 @@ pub fn app_home_dir() -> Result<PathBuf> {
.ok_or(anyhow::anyhow!("failed to get the portable app dir"))?;
return Ok(PathBuf::from(app_dir).join(".config").join(APP_ID));
}
let app_handle = handle::Handle::global().app_handle().unwrap();
let handle = handle::Handle::global();
let app_handle = handle.app_handle.lock();
if let Some(app_handle) = app_handle.as_ref() {
match app_handle.path().data_dir() {
Ok(dir) => {
return Ok(dir.join(APP_ID));
}
Err(e) => {
log::error!("Failed to get the app home directory: {}", e);
return Err(anyhow::anyhow!("Failed to get the app homedirectory"));
}
match app_handle.path().data_dir() {
Ok(dir) => Ok(dir.join(APP_ID)),
Err(e) => {
log::error!(target:"app", "Failed to get the app home directory: {}", e);
Err(anyhow::anyhow!("Failed to get the app homedirectory"))
}
}
Err(anyhow::anyhow!("failed to get the app home dir"))
}
/// get the resources dir
pub fn app_resources_dir() -> Result<PathBuf> {
let handle = handle::Handle::global();
let app_handle = handle.app_handle.lock();
if let Some(app_handle) = app_handle.as_ref() {
match app_handle.path().resource_dir() {
Ok(dir) => {
return Ok(dir.join("resources"));
}
Err(e) => {
log::error!("Failed to get the resource directory: {}", e);
return Err(anyhow::anyhow!("Failed to get the resource directory"));
}
};
};
Err(anyhow::anyhow!("failed to get the resource dir"))
let app_handle = handle::Handle::global().app_handle().unwrap();
match app_handle.path().resource_dir() {
Ok(dir) => Ok(dir.join("resources")),
Err(e) => {
log::error!(target:"app", "Failed to get the resource directory: {}", e);
Err(anyhow::anyhow!("Failed to get the resource directory"))
}
}
}
/// profiles dir
@@ -102,11 +89,7 @@ pub fn profiles_path() -> Result<PathBuf> {
Ok(app_home_dir()?.join(PROFILE_YAML))
}
pub fn clash_pid_path() -> Result<PathBuf> {
Ok(app_home_dir()?.join("clash.pid"))
}
#[cfg(not(target_os = "windows"))]
#[cfg(target_os = "macos")]
pub fn service_path() -> Result<PathBuf> {
Ok(app_resources_dir()?.join("clash-verge-service"))
}

View File

@@ -0,0 +1,40 @@
use crate::log_err;
use anyhow;
use std::{
backtrace::{Backtrace, BacktraceStatus},
thread,
};
pub fn redirect_panic_to_log() {
std::panic::set_hook(Box::new(move |panic_info| {
let thread = thread::current();
let thread_name = thread.name().unwrap_or("<unnamed>");
let payload = panic_info.payload();
let payload = if let Some(s) = payload.downcast_ref::<&str>() {
&**s
} else if let Some(s) = payload.downcast_ref::<String>() {
s
} else {
&format!("{:?}", payload)
};
let location = panic_info
.location()
.map(|l| l.to_string())
.unwrap_or("unknown location".to_string());
let backtrace = Backtrace::capture();
let backtrace = if backtrace.status() == BacktraceStatus::Captured {
&format!("stack backtrace:\n{}", backtrace)
} else {
"note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace"
};
let err: Result<(), anyhow::Error> = Err(anyhow::anyhow!(format!(
"thread '{}' panicked at {}:\n{}\n{}",
thread_name, location, payload, backtrace
)));
log_err!(err);
}));
}

View File

@@ -105,6 +105,26 @@ pub fn open_file(app: tauri::AppHandle, path: PathBuf) -> Result<()> {
Ok(())
}
#[cfg(target_os = "linux")]
pub fn linux_elevator() -> String {
use std::process::Command;
match Command::new("which").arg("pkexec").output() {
Ok(output) => {
if !output.stdout.is_empty() {
// Convert the output to a string slice
if let Ok(path) = std::str::from_utf8(&output.stdout) {
path.trim().to_string()
} else {
"sudo".to_string()
}
} else {
"sudo".to_string()
}
}
Err(_) => "sudo".to_string(),
}
}
#[macro_export]
macro_rules! error {
($result: expr) => {

View File

@@ -1,4 +1,5 @@
use crate::config::*;
use crate::core::handle;
use crate::utils::{dirs, help};
use anyhow::Result;
use chrono::{Local, TimeZone};
@@ -10,7 +11,6 @@ use log4rs::encode::pattern::PatternEncoder;
use std::fs::{self, DirEntry};
use std::path::PathBuf;
use std::str::FromStr;
use tauri::AppHandle;
use tauri_plugin_shell::ShellExt;
/// initialize this instance's log file
@@ -44,21 +44,9 @@ fn init_log() -> Result<()> {
let log_more = log_level == LevelFilter::Trace || log_level == LevelFilter::Debug;
#[cfg(feature = "verge-dev")]
{
logger_builder = logger_builder.appenders(["file", "stdout"]);
if log_more {
root_builder = root_builder.appenders(["file", "stdout"]);
} else {
root_builder = root_builder.appenders(["stdout"]);
}
}
#[cfg(not(feature = "verge-dev"))]
{
logger_builder = logger_builder.appenders(["file"]);
if log_more {
root_builder = root_builder.appenders(["file"]);
}
logger_builder = logger_builder.appenders(["file"]);
if log_more {
root_builder = root_builder.appenders(["file"]);
}
let (config, _) = log4rs::config::Config::builder()
@@ -207,8 +195,10 @@ pub fn init_resources() -> Result<()> {
#[cfg(target_os = "windows")]
let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];
#[cfg(not(target_os = "windows"))]
#[cfg(target_os = "macos")]
let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];
#[cfg(target_os = "linux")]
let file_list: [&str; 0] = [];
// copy the resource file
// if the source file is newer than the destination file, copy it over
@@ -216,12 +206,13 @@ pub fn init_resources() -> Result<()> {
let src_path = res_dir.join(file);
let dest_path = app_dir.join(file);
let test_dest_path = test_dir.join(file);
log::info!(target: "app", "src_path: {src_path:?}, dest_path: {dest_path:?}");
let handle_copy = |dest: &PathBuf| {
match fs::copy(&src_path, dest) {
Ok(_) => log::debug!(target: "app", "resources copied '{file}'"),
Err(err) => {
log::error!(target: "app", "failed to copy resources '{file}', {err}")
log::error!(target: "app", "failed to copy resources '{file}' to '{dest:?}', {err}")
}
};
};
@@ -297,7 +288,9 @@ pub fn init_scheme() -> Result<()> {
Ok(())
}
pub async fn startup_script(app_handle: &AppHandle) -> Result<()> {
pub async fn startup_script() -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let script_path = {
let verge = Config::verge();
let verge = verge.latest();
@@ -330,7 +323,7 @@ pub async fn startup_script(app_handle: &AppHandle) -> Result<()> {
app_handle
.shell()
.command(shell_type)
.current_dir(working_dir.to_path_buf())
.current_dir(working_dir)
.args(&[script_path])
.output()
.await?;

View File

@@ -1,4 +1,5 @@
pub mod dirs;
pub mod error;
pub mod help;
pub mod init;
pub mod resolve;

View File

@@ -1,12 +1,15 @@
use crate::cmds::import_profile;
use crate::config::IVerge;
use crate::{config::Config, core::*, utils::init, utils::server};
use crate::{log_err, trace_err};
use anyhow::Result;
use crate::utils::error;
use crate::{config::Config, config::PrfItem, core::*, utils::init, utils::server};
use crate::{log_err, trace_err, wrap_err};
use anyhow::{bail, Result};
use once_cell::sync::OnceCell;
use percent_encoding::percent_decode_str;
use serde_yaml::Mapping;
use std::net::TcpListener;
use tauri::{App, AppHandle, Manager};
use tauri::{App, Manager};
use url::Url;
//#[cfg(not(target_os = "linux"))]
// use window_shadows::set_shadow;
use tauri_plugin_notification::NotificationExt;
@@ -32,90 +35,66 @@ pub fn find_unused_port() -> Result<u16> {
/// handle something when start app
pub async fn resolve_setup(app: &mut App) {
error::redirect_panic_to_log();
#[cfg(target_os = "macos")]
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
let version = app.package_info().version.to_string();
handle::Handle::global().init(app.app_handle());
VERSION.get_or_init(|| version.clone());
log_err!(init::init_config());
log_err!(init::init_resources());
log_err!(init::init_scheme());
log_err!(init::startup_script(app.app_handle()).await);
log_err!(init::startup_script().await);
// 处理随机端口
let enable_random_port = Config::verge().latest().enable_random_port.unwrap_or(false);
let mut port = Config::verge()
.latest()
.verge_mixed_port
.unwrap_or(Config::clash().data().get_mixed_port());
if enable_random_port {
port = find_unused_port().unwrap_or(
Config::verge()
.latest()
.verge_mixed_port
.unwrap_or(Config::clash().data().get_mixed_port()),
);
}
Config::verge().data().patch_config(IVerge {
verge_mixed_port: Some(port),
..IVerge::default()
});
let _ = Config::verge().data().save_file();
let mut mapping = Mapping::new();
mapping.insert("mixed-port".into(), port.into());
Config::clash().data().patch_config(mapping);
let _ = Config::clash().data().save_config();
log_err!(resolve_random_port_config());
// 启动核心
log::trace!("init config");
log::trace!(target:"app", "init config");
log_err!(Config::init_config().await);
log::trace!("launch core");
log_err!(CoreManager::global().init(app.app_handle()));
if service::check_service().await.is_err() {
log_err!(service::reinstall_service().await);
std::thread::sleep(std::time::Duration::from_millis(1000));
}
log::trace!(target: "app", "launch core");
log_err!(CoreManager::global().init().await);
// setup a simple http server for singleton
log::trace!("launch embed server");
server::embed_server(app.app_handle());
log::trace!(target: "app", "launch embed server");
server::embed_server();
log::trace!("init system tray");
log_err!(tray::Tray::update_systray(&app.app_handle()));
log::trace!(target: "app", "init system tray");
log_err!(tray::Tray::create_systray());
let silent_start = { Config::verge().data().enable_silent_start };
if !silent_start.unwrap_or(false) {
create_window(&app.app_handle());
create_window();
}
log_err!(sysopt::Sysopt::global().init_launch());
log_err!(sysopt::Sysopt::global().init_sysproxy());
log_err!(sysopt::Sysopt::global().update_sysproxy().await);
log_err!(sysopt::Sysopt::global().init_guard_sysproxy());
log_err!(handle::Handle::update_systray_part());
log_err!(hotkey::Hotkey::global().init(app.app_handle()));
log_err!(hotkey::Hotkey::global().init());
log_err!(timer::Timer::global().init());
let argvs: Vec<String> = std::env::args().collect();
if argvs.len() > 1 {
let param = argvs[1].as_str();
if param.starts_with("clash:") {
log_err!(resolve_scheme(argvs[1].to_owned()).await);
}
}
}
/// reset system proxy
pub fn resolve_reset() {
log_err!(sysopt::Sysopt::global().reset_sysproxy());
tauri::async_runtime::block_on(async move {
log_err!(sysopt::Sysopt::global().reset_sysproxy().await);
log_err!(CoreManager::global().stop_core().await);
log_err!(service::unset_dns_by_service().await);
});
}
/// create main window
pub fn create_window(app_handle: &AppHandle) {
if let Some(window) = app_handle.get_webview_window("main") {
pub fn create_window() {
let app_handle = handle::Handle::global().app_handle().unwrap();
if let Some(window) = handle::Handle::global().get_window() {
trace_err!(window.unminimize(), "set win unminimize");
trace_err!(window.show(), "set win visible");
trace_err!(window.set_focus(), "set win focus");
@@ -123,7 +102,7 @@ pub fn create_window(app_handle: &AppHandle) {
}
let mut builder = tauri::WebviewWindowBuilder::new(
app_handle,
&app_handle,
"main".to_string(),
tauri::WebviewUrl::App("index.html".into()),
)
@@ -179,7 +158,7 @@ pub fn create_window(app_handle: &AppHandle) {
.latest()
.window_is_maximized
.unwrap_or(false);
log::trace!("try to calculate the monitor size");
log::trace!(target:"app", "try to calculate the monitor size");
let center = (|| -> Result<bool> {
let mut center = false;
let monitor = win.current_monitor()?.ok_or(anyhow::anyhow!(""))?;
@@ -212,7 +191,8 @@ pub fn create_window(app_handle: &AppHandle) {
}
/// save window size and position
pub fn save_window_size_position(app_handle: &AppHandle, save_to_file: bool) -> Result<()> {
pub fn save_window_size_position(save_to_file: bool) -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let verge = Config::verge();
let mut verge = verge.latest();
@@ -238,34 +218,103 @@ pub fn save_window_size_position(app_handle: &AppHandle, save_to_file: bool) ->
}
pub async fn resolve_scheme(param: String) -> Result<()> {
let url = param
.trim_start_matches("clash://install-config/?url=")
.trim_start_matches("clash://install-config?url=");
log::info!(target:"app", "received deep link: {}", param);
let handle = handle::Handle::global();
let app_handle = handle.app_handle.lock().clone();
if let Some(app_handle) = app_handle.as_ref() {
match import_profile(url.to_string(), None).await {
Ok(_) => {
app_handle
.notification()
.builder()
.title("Clash Verge")
.body("Import profile success")
.show()
.unwrap();
}
Err(e) => {
app_handle
.notification()
.builder()
.title("Clash Verge")
.body(format!("Import profile failed: {e}"))
.show()
.unwrap();
log::error!("Import profile failed: {e}");
let app_handle = handle::Handle::global().app_handle().unwrap();
let param_str = if param.starts_with("[") && param.len() > 4 {
param
.get(2..param.len() - 2)
.ok_or_else(|| anyhow::anyhow!("Invalid string slice boundaries"))?
} else {
param.as_str()
};
// 解析 URL
let link_parsed = match Url::parse(param_str) {
Ok(url) => url,
Err(e) => {
bail!("failed to parse deep link: {:?}, param: {:?}", e, param);
}
};
if link_parsed.scheme() == "clash" || link_parsed.scheme() == "clash-verge" {
let name = link_parsed
.query_pairs()
.find(|(key, _)| key == "name")
.map(|(_, value)| value.into_owned());
let encode_url = link_parsed
.query_pairs()
.find(|(key, _)| key == "url")
.map(|(_, value)| value.into_owned());
match encode_url {
Some(url) => {
let url = percent_decode_str(url.as_ref())
.decode_utf8_lossy()
.to_string();
create_window();
match PrfItem::from_url(url.as_ref(), name, None, None).await {
Ok(item) => {
let uid = item.uid.clone().unwrap();
let _ = wrap_err!(Config::profiles().data().append_item(item));
app_handle
.notification()
.builder()
.title("Clash Verge")
.body("Import profile success")
.show()
.unwrap();
handle::Handle::notice_message("import_sub_url::ok", uid);
}
Err(e) => {
app_handle
.notification()
.builder()
.title("Clash Verge")
.body(format!("Import profile failed: {e}"))
.show()
.unwrap();
handle::Handle::notice_message("import_sub_url::error", e.to_string());
bail!("Failed to add subscriptions: {e}");
}
}
}
None => bail!("failed to get profile url"),
}
}
Ok(())
}
fn resolve_random_port_config() -> Result<()> {
let verge_config = Config::verge();
let clash_config = Config::clash();
let enable_random_port = verge_config.latest().enable_random_port.unwrap_or(false);
let default_port = verge_config
.latest()
.verge_mixed_port
.unwrap_or(clash_config.data().get_mixed_port());
let port = if enable_random_port {
find_unused_port().unwrap_or(default_port)
} else {
default_port
};
verge_config.data().patch_config(IVerge {
verge_mixed_port: Some(port),
..IVerge::default()
});
verge_config.data().save_file()?;
let mut mapping = Mapping::new();
mapping.insert("mixed-port".into(), port.into());
clash_config.data().patch_config(mapping);
clash_config.data().save_config()?;
Ok(())
}

View File

@@ -2,11 +2,10 @@ extern crate warp;
use super::resolve;
use crate::config::{Config, IVerge, DEFAULT_PAC};
use crate::log_err;
use anyhow::{bail, Result};
use port_scanner::local_port_available;
use std::convert::Infallible;
use tauri::AppHandle;
use warp::http::StatusCode;
use warp::Filter;
#[derive(serde::Deserialize, Debug)]
@@ -17,36 +16,24 @@ struct QueryParam {
/// check whether there is already exists
pub async fn check_singleton() -> Result<()> {
let port = IVerge::get_singleton_port();
if !local_port_available(port) {
let resp = reqwest::get(format!("http://127.0.0.1:{port}/commands/ping"))
.await?
.text()
.await?;
if &resp == "ok" {
let argvs: Vec<String> = std::env::args().collect();
if argvs.len() > 1 {
let argvs: Vec<String> = std::env::args().collect();
if argvs.len() > 1 {
#[cfg(not(target_os = "macos"))]
{
let param = argvs[1].as_str();
if param.starts_with("clash:") {
reqwest::get(format!(
let _ = reqwest::get(format!(
"http://127.0.0.1:{port}/commands/scheme?param={param}"
))
.await?
.text()
.await?;
.await;
}
} else {
reqwest::get(format!("http://127.0.0.1:{port}/commands/visible"))
.await?
.text()
.await?;
}
bail!("app exists");
} else {
let _ = reqwest::get(format!("http://127.0.0.1:{port}/commands/visible")).await;
}
log::error!("failed to setup singleton listen server");
Ok(())
bail!("app exists");
} else {
Ok(())
}
@@ -54,15 +41,12 @@ pub async fn check_singleton() -> Result<()> {
/// The embed server only be used to implement singleton process
/// maybe it can be used as pac server later
pub fn embed_server(app_handle: &AppHandle) {
pub fn embed_server() {
let port = IVerge::get_singleton_port();
let handle = app_handle.clone();
tauri::async_runtime::spawn(async move {
let ping = warp::path!("commands" / "ping").map(move || "ok");
let visible = warp::path!("commands" / "visible").map(move || {
resolve::create_window(&handle);
resolve::create_window();
"ok"
});
@@ -82,21 +66,15 @@ pub fn embed_server(app_handle: &AppHandle) {
.body(content)
.unwrap_or_default()
});
async fn scheme_handler(query: QueryParam) -> Result<impl warp::Reply, Infallible> {
log_err!(resolve::resolve_scheme(query.param).await);
Ok("ok")
}
let scheme = warp::path!("commands" / "scheme")
.and(warp::query::<QueryParam>())
.and_then(scheme_handler);
async fn scheme_handler(query: QueryParam) -> Result<impl warp::Reply, Infallible> {
let result = resolve::resolve_scheme(query.param).await;
Ok(match result {
Ok(_) => warp::reply::with_status("Ok", StatusCode::OK),
Err(_) => {
warp::reply::with_status("Internal Error", StatusCode::INTERNAL_SERVER_ERROR)
}
})
}
let commands = ping.or(visible).or(pac).or(scheme);
let commands = visible.or(scheme).or(pac);
warp::serve(commands).run(([127, 0, 0, 1], port)).await;
});
}

14
clash-verge-rev/src-tauri/tauri.conf.json Normal file → Executable file
View File

@@ -2,7 +2,7 @@
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"bundle": {
"active": true,
"longDescription": "A Clash Meta GUI based on tauri.",
"longDescription": "Clash Verge Rev",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
@@ -15,7 +15,7 @@
"externalBin": ["sidecar/verge-mihomo", "sidecar/verge-mihomo-alpha"],
"copyright": "GNU General Public License v3.0",
"category": "DeveloperTool",
"shortDescription": "A Clash Meta GUI based on tauri.",
"shortDescription": "Clash Verge Rev",
"createUpdaterArtifacts": "v1Compatible"
},
"build": {
@@ -25,7 +25,7 @@
"devUrl": "http://localhost:3000/"
},
"productName": "Clash Verge",
"version": "2.0.0",
"version": "2.0.0-rc.2",
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"plugins": {
"updater": {
@@ -34,6 +34,11 @@
"https://download.clashverge.dev/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-proxy.json",
"https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update.json"
]
},
"deep-link": {
"desktop": {
"schemes": ["clash", "clash-verge"]
}
}
},
"app": {
@@ -44,7 +49,6 @@
"enable": true
},
"csp": null
},
"windows": []
}
}
}

View File

@@ -1,5 +1,6 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"bundle": {
"targets": ["deb", "rpm"],
"linux": {
@@ -17,7 +18,14 @@
"conflicts": ["clash-verge"],
"obsoletes": ["clash-verge"]
}
}
},
"externalBin": [
"./resources/clash-verge-service",
"./resources/install-service",
"./resources/uninstall-service",
"./sidecar/verge-mihomo",
"./sidecar/verge-mihomo-alpha"
]
},
"app": {
"trayIcon": {

View File

@@ -1,5 +1,6 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"bundle": {
"targets": ["app", "dmg"],
"macOS": {

View File

@@ -1,5 +1,6 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"bundle": {
"targets": ["nsis"],
"windows": {
@@ -23,6 +24,7 @@
"trayIcon": {
"iconPath": "icons/tray-icon.ico",
"iconAsTemplate": true
}
},
"windows": []
}
}

View File

@@ -95,7 +95,7 @@ export const LayoutControl = () => {
svg: { transform: "scale(1.05)" },
":hover": { bgcolor: "#ff000090" },
}}
onClick={() => appWindow.close()}
onClick={() => appWindow.hide()}
>
<CloseRounded fontSize="small" />
</Button>

View File

@@ -196,8 +196,8 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
},
],
});
if (selected?.path.length) {
await copyIconFile(`${selected.path}`, "common");
if (selected) {
await copyIconFile(`${selected}`, "common");
await initIconPath();
onChangeData({ common_tray_icon: true });
patchVerge({ common_tray_icon: true });
@@ -242,8 +242,8 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
},
],
});
if (selected?.path.length) {
await copyIconFile(`${selected.path}`, "sysproxy");
if (selected) {
await copyIconFile(`${selected}`, "sysproxy");
await initIconPath();
onChangeData({ sysproxy_tray_icon: true });
patchVerge({ sysproxy_tray_icon: true });
@@ -281,13 +281,13 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
multiple: false,
filters: [
{
name: "Tray Icon Image",
name: "Tun Icon Image",
extensions: ["png", "ico"],
},
],
});
if (selected?.path.length) {
await copyIconFile(`${selected.path}`, "tun");
if (selected) {
await copyIconFile(`${selected}`, "tun");
await initIconPath();
onChangeData({ tun_tray_icon: true });
patchVerge({ tun_tray_icon: true });

View File

@@ -1,134 +0,0 @@
import { KeyedMutator } from "swr";
import { useState } from "react";
import { useLockFn } from "ahooks";
import { useTranslation } from "react-i18next";
import { installService, uninstallService } from "@/services/cmds";
import { Notice } from "@/components/base";
import { LoadingButton } from "@mui/lab";
import { PasswordInput } from "./password-input";
import getSystem from "@/utils/get-system";
interface Props {
status: "active" | "installed" | "unknown" | "uninstall";
mutate: KeyedMutator<"active" | "installed" | "unknown" | "uninstall">;
patchVerge: (value: Partial<IVergeConfig>) => Promise<void>;
onChangeData: (patch: Partial<IVergeConfig>) => void;
}
export const ServiceSwitcher = (props: Props) => {
const { status, mutate, patchVerge, onChangeData } = props;
const isWindows = getSystem() === "windows";
const isActive = status === "active";
const isInstalled = status === "installed";
const isUninstall = status === "uninstall" || status === "unknown";
const { t } = useTranslation();
const [serviceLoading, setServiceLoading] = useState(false);
const [uninstallServiceLoaing, setUninstallServiceLoading] = useState(false);
const [openInstall, setOpenInstall] = useState(false);
const [openUninstall, setOpenUninstall] = useState(false);
async function install(passwd: string) {
try {
setOpenInstall(false);
await installService(passwd);
await mutate();
setTimeout(() => {
mutate();
}, 2000);
Notice.success(t("Service Installed Successfully"));
setServiceLoading(false);
} catch (err: any) {
await mutate();
setTimeout(() => {
mutate();
}, 2000);
Notice.error(err.message || err.toString());
setServiceLoading(false);
}
}
async function uninstall(passwd: string) {
try {
setOpenUninstall(false);
await uninstallService(passwd);
await mutate();
setTimeout(() => {
mutate();
}, 2000);
Notice.success(t("Service Uninstalled Successfully"));
setUninstallServiceLoading(false);
} catch (err: any) {
await mutate();
setTimeout(() => {
mutate();
}, 2000);
Notice.error(err.message || err.toString());
setUninstallServiceLoading(false);
}
}
const onInstallOrEnableService = useLockFn(async () => {
setServiceLoading(true);
if (isUninstall) {
// install service
if (isWindows) {
await install("");
} else {
setOpenInstall(true);
}
} else {
try {
// enable or disable service
await patchVerge({ enable_service_mode: !isActive });
onChangeData({ enable_service_mode: !isActive });
await mutate();
setTimeout(() => {
mutate();
}, 2000);
setServiceLoading(false);
} catch (err: any) {
await mutate();
Notice.error(err.message || err.toString());
setServiceLoading(false);
}
}
});
const onUninstallService = useLockFn(async () => {
setUninstallServiceLoading(true);
if (isWindows) {
await uninstall("");
} else {
setOpenUninstall(true);
}
});
return (
<>
{openInstall && <PasswordInput onConfirm={install} />}
{openUninstall && <PasswordInput onConfirm={uninstall} />}
<LoadingButton
size="small"
variant={isUninstall ? "outlined" : "contained"}
onClick={onInstallOrEnableService}
loading={serviceLoading}
>
{isActive ? t("Disable") : isInstalled ? t("Enable") : t("Install")}
</LoadingButton>
{isInstalled && (
<LoadingButton
size="small"
variant="outlined"
color="error"
sx={{ ml: 1 }}
onClick={onUninstallService}
loading={uninstallServiceLoaing}
>
{t("Uninstall")}
</LoadingButton>
)}
</>
);
};

View File

@@ -7,10 +7,11 @@ import { relaunch } from "@tauri-apps/plugin-process";
import { check as checkUpdate } from "@tauri-apps/plugin-updater";
import { BaseDialog, DialogRef, Notice } from "@/components/base";
import { useUpdateState, useSetUpdateState } from "@/services/states";
import { listen, Event, UnlistenFn } from "@tauri-apps/api/event";
import { Event, UnlistenFn } from "@tauri-apps/api/event";
import { portableFlag } from "@/pages/_layout";
import { open as openUrl } from "@tauri-apps/plugin-shell";
import ReactMarkdown from "react-markdown";
import { useListen } from "@/hooks/use-listen";
let eventListener: UnlistenFn | null = null;
@@ -21,6 +22,7 @@ export const UpdateViewer = forwardRef<DialogRef>((props, ref) => {
const updateState = useUpdateState();
const setUpdateState = useSetUpdateState();
const { addListener } = useListen();
const { data: updateInfo } = useSWR("checkUpdate", checkUpdate, {
errorRetryCount: 2,
@@ -66,7 +68,7 @@ export const UpdateViewer = forwardRef<DialogRef>((props, ref) => {
if (eventListener !== null) {
eventListener();
}
eventListener = await listen(
eventListener = await addListener(
"tauri://update-download-progress",
(e: Event<any>) => {
setTotal(e.payload.contentLength);

View File

@@ -7,7 +7,6 @@ import { useVerge } from "@/hooks/use-verge";
import { DialogRef, Notice, Switch } from "@/components/base";
import { SettingList, SettingItem } from "./mods/setting-comp";
import { GuardState } from "./mods/guard-state";
import { ServiceSwitcher } from "./mods/service-switcher";
import { SysproxyViewer } from "./mods/sysproxy-viewer";
import { TunViewer } from "./mods/tun-viewer";
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
@@ -67,34 +66,15 @@ const SettingSystem = ({ onError }: Props) => {
onCatch={onError}
onFormat={onSwitchFormat}
onChange={(e) => {
if (serviceStatus !== "active") {
onChangeData({ enable_tun_mode: false });
} else {
onChangeData({ enable_tun_mode: e });
}
onChangeData({ enable_tun_mode: e });
}}
onGuard={(e) => {
if (serviceStatus !== "active" && e) {
Notice.error(t("Please Enable Service Mode"));
return Promise.resolve();
} else {
return patchVerge({ enable_tun_mode: e });
}
return patchVerge({ enable_tun_mode: e });
}}
>
<Switch edge="end" />
</GuardState>
</SettingItem>
<SettingItem label={t("Service Mode")}>
<ServiceSwitcher
status={serviceStatus ?? "unknown"}
mutate={mutateServiceStatus}
patchVerge={patchVerge}
onChangeData={onChangeData}
/>
</SettingItem>
<SettingItem
label={t("System Proxy")}
extra={

View File

@@ -194,9 +194,9 @@ const SettingVerge = ({ onError }: Props) => {
},
],
});
if (selected?.path.length) {
onChangeData({ startup_script: `${selected.path}` });
patchVerge({ startup_script: `${selected.path}` });
if (selected) {
onChangeData({ startup_script: `${selected}` });
patchVerge({ startup_script: `${selected}` });
}
}}
>
@@ -243,7 +243,7 @@ const SettingVerge = ({ onError }: Props) => {
label={t("Runtime Config")}
/>
<SettingItem onClick={openAppDir} label={t("Open App Dir")} />
<SettingItem onClick={openAppDir} label={t("Open Conf Dir")} />
<SettingItem onClick={openCoreDir} label={t("Open Core Dir")} />

View File

@@ -18,9 +18,9 @@ import { Notice } from "@/components/base";
import { TestBox } from "./test-box";
import delayManager from "@/services/delay";
import { cmdTestDelay, downloadIconCache } from "@/services/cmds";
import { listen, UnlistenFn } from "@tauri-apps/api/event";
import { UnlistenFn } from "@tauri-apps/api/event";
import { convertFileSrc } from "@tauri-apps/api/core";
import { useListen } from "@/hooks/use-listen";
interface Props {
id: string;
itemData: IVergeTestItem;
@@ -47,6 +47,7 @@ export const TestItem = (props: Props) => {
const [delay, setDelay] = useState(-1);
const { uid, name, icon, url } = itemData;
const [iconCachePath, setIconCachePath] = useState("");
const { addListener } = useListen();
useEffect(() => {
initIconCachePath();
@@ -91,7 +92,7 @@ export const TestItem = (props: Props) => {
const listenTsetEvent = async () => {
eventListener();
eventListener = await listen("verge://test-all", () => {
eventListener = await addListener("verge://test-all", () => {
onDelay();
});
};

View File

@@ -67,6 +67,16 @@ export const TestViewer = forwardRef<TestViewerRef, Props>((props, ref) => {
let newList;
let uid;
if (form.icon && form.icon.startsWith("<svg")) {
const doc = new DOMParser().parseFromString(
form.icon,
"image/svg+xml"
);
if (doc.querySelector("parsererror")) {
throw new Error("`Icon`svg format error");
}
}
if (openType === "new") {
uid = nanoid();
const item = { ...form, uid };

View File

@@ -0,0 +1,31 @@
import { listen, UnlistenFn, EventCallback } from "@tauri-apps/api/event";
import { event } from "@tauri-apps/api";
import { useRef } from "react";
export const useListen = () => {
const unlistenFns = useRef<UnlistenFn[]>([]);
const addListener = async <T>(
eventName: string,
handler: EventCallback<T>
) => {
const unlisten = await listen(eventName, handler);
unlistenFns.current.push(unlisten);
return unlisten;
};
const removeAllListeners = () => {
unlistenFns.current.forEach((unlisten) => unlisten());
unlistenFns.current = [];
};
const setupCloseListener = async function () {
await event.once("tauri://close-requested", async () => {
removeAllListeners();
});
};
return {
addListener,
setupCloseListener,
};
};

View File

@@ -193,9 +193,9 @@
"Test URL": "Test URL",
"Settings": "Settings",
"System Setting": "System Setting",
"Tun Mode": "Tun Mode",
"Tun Mode": "Tun (Virtual NIC) Mode",
"Reset to Default": "Reset to Default",
"Tun Mode Info": "The Tun mode requires granting core-related permissions. Please enable service mode before using it",
"Tun Mode Info": "Tun (Virtual NIC) mode: Captures all system traffic, when enabled, there is no need to enable system proxy.",
"Stack": "Tun Stack",
"System and Mixed Can Only be Used in Service Mode": "System and Mixed Can Only be Used in Service Mode",
"Device": "Device Name",
@@ -205,7 +205,7 @@
"DNS Hijack": "DNS Hijack",
"MTU": "Max Transmission Unit",
"Service Mode": "Service Mode",
"Service Mode Info": "The core launched by the service can obtain corresponding permissions after installation and authorization of the service",
"Service Mode Info": "Please install the service mode before enabling TUN mode. The kernel process started by the service can obtain the permission to install the virtual network card (TUN mode)",
"Current State": "Current State",
"pending": "pending",
"installed": "installed",
@@ -331,14 +331,14 @@
"toggle_system_proxy": "Enable/Disable System Proxy",
"toggle_tun_mode": "Enable/Disable Tun Mode",
"Runtime Config": "Runtime Config",
"Open App Dir": "Open App Dir",
"Open Conf Dir": "Open Conf Dir",
"Open Core Dir": "Open Core Dir",
"Open Logs Dir": "Open Logs Dir",
"Check for Updates": "Check for Updates",
"Go to Release Page": "Go to Release Page",
"Portable Updater Error": "The portable version does not support in-app updates. Please manually download and replace it",
"Break Change Update Error": "This version is a major update and does not support in-app updates. Please uninstall it and manually download and install the new version",
"Open Dev Tools": "Open Dev Tools",
"Open Dev Tools": "Dev Tools",
"Exit": "Exit",
"Verge Version": "Verge Version",
"ReadOnly": "ReadOnly",
@@ -367,5 +367,6 @@
"Clash Core Restarted": "Clash Core Restarted",
"Switched to _clash Core": "Switched to {{core}} Core",
"GeoData Updated": "GeoData Updated",
"Currently on the Latest Version": "Currently on the Latest Version"
"Currently on the Latest Version": "Currently on the Latest Version",
"Import Subscription Successful": "Import subscription successful"
}

View File

@@ -191,9 +191,9 @@
"Test URL": "آدرس آزمون",
"Settings": "تنظیمات",
"System Setting": "تنظیمات سیستم",
"Tun Mode": "حالت Tun",
"Tun Mode": "Tun (کارت شبکه مجازی)",
"Reset to Default": "بازنشانی به پیش‌فرض",
"Tun Mode Info": "حالت Tun نیاز به اعطای مجوزهای مربوط به هسته دارد. لطفاً قبل از استفاده، حالت سرویس را فعال کنید",
"Tun Mode Info": "حالت Tun (NIC مجازی): تمام ترافیک سیستم را ضبط می کند، وقتی فعال باشد، نیازی به فعال کردن پروکسی سیستم نیست.",
"Stack": "انباشته Tun",
"System and Mixed Can Only be Used in Service Mode": "سیستم و ترکیبی تنها می‌توانند در حالت سرویس استفاده شوند",
"Device": "نام دستگاه",
@@ -203,7 +203,7 @@
"DNS Hijack": "ربایش DNS",
"MTU": "واحد حداکثر انتقال",
"Service Mode": "حالت سرویس",
"Service Mode Info": "هسته راه اندازی شده توسط سرویس می تواند مجوزهای مربوطه را پس از نصب و مجوز سرویس دریافت کند",
"Service Mode Info": "لطفاً قبل از فعال کردن حالت TUN، حالت سرویس را نصب کنید.",
"Current State": "وضعیت فعلی",
"pending": "در انتظار",
"installed": "نصب شده",
@@ -329,7 +329,7 @@
"toggle_system_proxy": "فعال/غیرفعال کردن پراکسی سیستم",
"toggle_tun_mode": "فعال/غیرفعال کردن حالت Tun",
"Runtime Config": "پیکربندی زمان اجرا",
"Open App Dir": "باز کردن پوشه برنامه",
"Open Conf Dir": "باز کردن پوشه برنامه",
"Open Core Dir": "باز کردن پوشه هسته",
"Open Logs Dir": "باز کردن پوشه لاگ‌ها",
"Check for Updates": "بررسی برای به‌روزرسانی‌ها",
@@ -365,5 +365,6 @@
"Clash Core Restarted": "هسته Clash مجدداً راه‌اندازی شد",
"Switched to _clash Core": "تغییر به هسته {{core}}",
"GeoData Updated": "GeoData به‌روزرسانی شد",
"Currently on the Latest Version": "در حال حاضر در آخرین نسخه"
"Currently on the Latest Version": "در حال حاضر در آخرین نسخه",
"Import Subscription Successfully": "عضویت با موفقیت وارد شد"
}

View File

@@ -191,9 +191,9 @@
"Test URL": "Тестовый URL",
"Settings": "Настройки",
"System Setting": "Настройки системы",
"Tun Mode": "Режим туннеля",
"Tun Mode": "Tun (виртуальный сетевой адаптер) режим",
"Reset to Default": "Сбросить настройки по умолчанию",
"Tun Mode Info": "Режим туннеля требует предоставления разрешений, связанных с ядрам. Пожалуйста, включите сервисный режим перед его использованием",
"Tun Mode Info": "Режим Tun (виртуальный сетевой адаптер): захватывает весь системный трафик, при включении нет необходимости включать системный прокси-сервер.",
"Stack": "Стек",
"System and Mixed Can Only be Used in Service Mode": "Система и смешанные могут использоваться только в сервисном режиме",
"Device": "Имя устройства",
@@ -203,7 +203,7 @@
"DNS Hijack": "DNS-перехват",
"MTU": "Максимальная единица передачи",
"Service Mode": "Режим сервиса",
"Service Mode Info": "Ядро, запущенное сервисом, может получить соответствующие разрешения после установки и авторизации сервиса",
"Service Mode Info": "Установите сервисный режим перед включением режима TUN. Процесс ядра, запущенный службой, может получить разрешение на установку виртуальной сетевой карты (режим TUN).",
"Current State": "Текущее состояние",
"pending": "Ожидающий",
"installed": "Установленный",
@@ -329,7 +329,7 @@
"toggle_system_proxy": "Включить/Отключить системный прокси",
"toggle_tun_mode": "Включить/Отключить режим туннеля",
"Runtime Config": "Используемый конфиг",
"Open App Dir": "Открыть папку приложения",
"Open Conf Dir": "Открыть папку приложения",
"Open Core Dir": "Открыть папку ядра",
"Open Logs Dir": "Открыть папку логов",
"Check for Updates": "Проверить обновления",
@@ -365,5 +365,6 @@
"Clash Core Restarted": "Clash ядра перезапущено",
"Switched to _clash Core": "Переключено на ядра {{core}}",
"GeoData Updated": "GeoData Обновлена",
"Currently on the Latest Version": "В настоящее время используется последняя версия"
"Currently on the Latest Version": "В настоящее время используется последняя версия",
"Import subscription successful": "Импорт подписки успешно"
}

View File

@@ -193,9 +193,9 @@
"Test URL": "测试地址",
"Settings": "设置",
"System Setting": "系统设置",
"Tun Mode": "Tun 模式",
"Tun Mode": "Tun(虚拟网卡)模式",
"Reset to Default": "重置为默认值",
"Tun Mode Info": "Tun模式需要授予内核相关权限,使用前请先开启服务模式",
"Tun Mode Info": "Tun(虚拟网卡)模式接管系统所有流量,启用时无须打开系统代理",
"Stack": "Tun 模式堆栈",
"System and Mixed Can Only be Used in Service Mode": "System 和 Mixed 只能在服务模式下使用",
"Device": "Tun 网卡名称",
@@ -205,7 +205,7 @@
"DNS Hijack": "DNS 劫持",
"MTU": "最大传输单元",
"Service Mode": "服务模式",
"Service Mode Info": "安装并授权服务后,由该服务启动的内核进程可获得相关权限",
"Service Mode Info": "启用TUN模式前请安装服务模式该服务启动的内核进程可获得安装虚拟网卡(TUN模式)的权限",
"Current State": "当前状态",
"pending": "等待中",
"installed": "已安装",
@@ -331,14 +331,14 @@
"toggle_system_proxy": "打开/关闭系统代理",
"toggle_tun_mode": "打开/关闭 Tun 模式",
"Runtime Config": "当前配置",
"Open App Dir": "应用目录",
"Open Conf Dir": "配置目录",
"Open Core Dir": "内核目录",
"Open Logs Dir": "日志目录",
"Check for Updates": "检查更新",
"Go to Release Page": "前往发布页",
"Portable Updater Error": "便携版不支持应用内更新,请手动下载替换",
"Break Change Update Error": "此版本为重大更新,不支持应用内更新,请卸载后手动下载安装",
"Open Dev Tools": "打开开发者工具",
"Open Dev Tools": "开发者工具",
"Exit": "退出",
"Verge Version": "Verge 版本",
"ReadOnly": "只读",
@@ -360,12 +360,13 @@
"Invalid Bypass Format": "无效的代理绕过格式",
"Clash Port Modified": "Clash 端口已修改",
"Port Conflict": "端口冲突",
"Restart Application to Apply Modifications": "重启应用程序以应用修改",
"Restart Application to Apply Modifications": "重启Verge以应用修改",
"External Controller Address Modified": "外部控制器监听地址已修改",
"Permissions Granted Successfully for _clash Core": "{{core}} 内核授权成功",
"Core Version Updated": "内核版本已更新",
"Clash Core Restarted": "已重启 Clash 内核",
"Switched to _clash Core": "已切换至 {{core}} 内核",
"GeoData Updated": "已更新 GeoData",
"Currently on the Latest Version": "当前已是最新版本"
"Currently on the Latest Version": "当前已是最新版本",
"Import Subscription Successful": "导入订阅成功"
}

View File

@@ -4,9 +4,8 @@ import relativeTime from "dayjs/plugin/relativeTime";
import { SWRConfig, mutate } from "swr";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useRoutes } from "react-router-dom";
import { useLocation, useRoutes, useNavigate } from "react-router-dom";
import { List, Paper, ThemeProvider, SvgIcon } from "@mui/material";
import { listen } from "@tauri-apps/api/event";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { routers } from "./_routers";
import { getAxios } from "@/services/api";
@@ -25,9 +24,10 @@ import getSystem from "@/utils/get-system";
import "dayjs/locale/ru";
import "dayjs/locale/zh-cn";
import { getPortableFlag } from "@/services/cmds";
import { useNavigate } from "react-router-dom";
import React from "react";
import { TransitionGroup, CSSTransition } from "react-transition-group";
import { useListen } from "@/hooks/use-listen";
const appWindow = getCurrentWebviewWindow();
export let portableFlag = false;
@@ -46,17 +46,13 @@ const Layout = () => {
const navigate = useNavigate();
const location = useLocation();
const routersEles = useRoutes(routers);
const { addListener, setupCloseListener } = useListen();
if (!routersEles) return null;
useEffect(() => {
window.addEventListener("keydown", (e) => {
// macOS有cmd+w
if (e.key === "Escape" && OS !== "macos") {
appWindow.close();
}
});
setupCloseListener();
listen("verge://refresh-clash-config", async () => {
useEffect(() => {
addListener("verge://refresh-clash-config", async () => {
// the clash info may be updated
await getAxios(true);
mutate("getProxies");
@@ -66,12 +62,21 @@ const Layout = () => {
});
// update the verge config
listen("verge://refresh-verge-config", () => mutate("getVergeConfig"));
addListener("verge://refresh-verge-config", () => mutate("getVergeConfig"));
// 设置提示监听
listen("verge://notice-message", ({ payload }) => {
addListener("verge://notice-message", ({ payload }) => {
const [status, msg] = payload as [string, string];
switch (status) {
case "import_sub_url::ok":
navigate("/profile", { state: { current: msg } });
Notice.success(t("Import Subscription Successful"));
break;
case "import_sub_url::error":
navigate("/profile");
Notice.error(msg);
break;
case "set_config::ok":
Notice.success(t("Clash Config Updated"));
break;

View File

@@ -47,13 +47,15 @@ import { useProfiles } from "@/hooks/use-profiles";
import { ConfigViewer } from "@/components/setting/mods/config-viewer";
import { throttle } from "lodash-es";
import { BaseStyledTextField } from "@/components/base/base-styled-text-field";
import { listen } from "@tauri-apps/api/event";
import { readTextFile } from "@tauri-apps/plugin-fs";
import { readText } from "@tauri-apps/plugin-clipboard-manager";
import { useLocation } from "react-router-dom";
import { useListen } from "@/hooks/use-listen";
const ProfilePage = () => {
const { t } = useTranslation();
const location = useLocation();
const { addListener } = useListen();
const [url, setUrl] = useState("");
const [disabled, setDisabled] = useState(false);
const [activatings, setActivatings] = useState<string[]>([]);
@@ -64,9 +66,10 @@ const ProfilePage = () => {
coordinateGetter: sortableKeyboardCoordinates,
})
);
const { current } = location.state || {};
useEffect(() => {
const unlisten = listen("tauri://file-drop", async (event) => {
const unlisten = addListener("tauri://file-drop", async (event) => {
const fileList = event.payload as string[];
for (let file of fileList) {
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) {
@@ -138,11 +141,11 @@ const ProfilePage = () => {
const remoteItem = newProfiles.items?.find((e) => e.type === "remote");
const profilesCount = newProfiles.items?.filter(
const itemsCount = newProfiles.items?.filter(
(e) => e.type === "remote" || e.type === "local"
).length as number;
if (remoteItem && (profilesCount == 1 || !newProfiles.current)) {
if (remoteItem && (itemsCount == 1 || !newProfiles.current)) {
const current = remoteItem.uid;
await patchProfiles({ current });
mutateLogs();
@@ -168,27 +171,40 @@ const ProfilePage = () => {
}
};
const onSelect = useLockFn(async (current: string, force: boolean) => {
if (!force && current === profiles.current) return;
const activateProfile = async (profile: string) => {
// 避免大多数情况下loading态闪烁
const reset = setTimeout(() => {
setActivatings([...currentActivatings(), current]);
setActivatings((prev) => [...prev, profile]);
}, 100);
try {
await patchProfiles({ current });
await patchProfiles({ current: profile });
await mutateLogs();
closeAllConnections();
activateSelected().then(() => {
Notice.success(t("Profile Switched"), 1000);
});
await activateSelected();
Notice.success(t("Profile Switched"), 1000);
} catch (err: any) {
Notice.error(err?.message || err.toString(), 4000);
} finally {
clearTimeout(reset);
setActivatings([]);
}
};
const onSelect = useLockFn(async (current: string, force: boolean) => {
if (!force && current === profiles.current) return;
await activateProfile(current);
});
useEffect(() => {
(async () => {
if (current && current !== profiles.current) {
console.log("current:", current);
await activateProfile(current);
}
})();
}, current);
const onEnhance = useLockFn(async () => {
setActivatings(currentActivatings());
try {

View File

@@ -200,15 +200,6 @@ export async function checkService() {
return "uninstall";
}
}
export async function installService(passwd: string) {
return invoke<void>("install_service", { passwd });
}
export async function uninstallService(passwd: string) {
return invoke<void>("uninstall_service", { passwd });
}
export async function invoke_uwp_tool() {
return invoke<void>("invoke_uwp_tool").catch((err) =>
Notice.error(err?.message || err.toString(), 1500)

View File

@@ -298,6 +298,13 @@ define U-Boot/Default/rk3588
TPL:=rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.16.bin
endef
define U-Boot/rock5b-rk3588
$(U-Boot/Default/rk3588)
NAME:=ROCK 5B
BUILD_DEVICES:= \
radxa_rock-5b
endef
define U-Boot/sige7-rk3588
$(U-Boot/Default/rk3588)
NAME:=Sige7
@@ -305,6 +312,29 @@ define U-Boot/sige7-rk3588
armsom_sige7
endef
define U-Boot/nanopc-t6-rk3588
$(U-Boot/Default/rk3588)
NAME:=NanoPC T6
BUILD_DEVICES:= \
friendlyarm_nanopc-t6
endef
# RK3588S boards
define U-Boot/nanopi-r6c-rk3588s
$(U-Boot/Default/rk3588)
NAME:=NanoPi R6C
BUILD_DEVICES:= \
friendlyarm_nanopi-r6c
endef
define U-Boot/nanopi-r6s-rk3588s
$(U-Boot/Default/rk3588)
NAME:=NanoPi R6S
BUILD_DEVICES:= \
friendlyarm_nanopi-r6s
endef
UBOOT_TARGETS := \
panther-x2-rk3566 \
rock-3c-rk3566 \
@@ -337,6 +367,10 @@ UBOOT_TARGETS := \
nanopi-r2s-rk3328 \
orangepi-r1-plus-rk3328 \
orangepi-r1-plus-lts-rk3328 \
nanopc-t6-rk3588 \
nanopi-r6c-rk3588s \
nanopi-r6s-rk3588s \
rock5b-rk3588 \
sige7-rk3588
UBOOT_CONFIGURE_VARS += USE_PRIVATE_LIBGCC=yes

View File

@@ -0,0 +1,10 @@
--- a/configs/rock5b-rk3588_defconfig
+++ b/configs/rock5b-rk3588_defconfig
@@ -27,7 +27,6 @@
CONFIG_DEBUG_UART=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
-CONFIG_SPL_FIT_SIGNATURE=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_BOARD_SETUP=y

View File

@@ -0,0 +1,823 @@
--- /dev/null
+++ b/arch/arm/dts/rk3588s-nanopi-r6s-u-boot.dtsi
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ */
+
+#include "rk3588s-u-boot.dtsi"
+
+/ {
+ aliases {
+ mmc0 = &sdmmc;
+ mmc1 = &sdhci;
+ };
+
+ chosen {
+ stdout-path = &uart2;
+ u-boot,spl-boot-order = "same-as-spl", &sdmmc, &sdhci;
+ };
+};
+
+&rng {
+ status = "okay";
+};
+
+&sdhci {
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_data_strobe &emmc_rstnout>;
+};
--- /dev/null
+++ b/arch/arm/dts/rk3588s-nanopi-r6s.dts
@@ -0,0 +1,713 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ *
+ * Copyright (c) 2022 FriendlyElec Computer Tech. Co., Ltd.
+ * (http://www.friendlyelec.com)
+ *
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588s.dtsi"
+
+/ {
+ model = "FriendlyElec NanoPi R6S";
+ compatible = "friendlyarm,nanopi-r6s", "rockchip,rk3588";
+
+ aliases {
+ ethernet0 = &gmac1;
+ mmc0 = &sdmmc;
+ mmc1 = &sdhci;
+ serial2 = &uart2;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&reset_button_pin>;
+
+ button-reset {
+ debounce-interval = <50>;
+ gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lan1_led_pin>, <&lan2_led_pin>, <&power_led_pin>, <&wan_led_pin>;
+
+ led-lan1 {
+ label = "green:lan1";
+ gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-lan2 {
+ label = "green:lan2";
+ gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
+ };
+
+ power_led: led-power {
+ label = "red:power";
+ gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-wan {
+ label = "green:wan";
+ gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_usb: vcc5v0-usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usb";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_host_20: vcc5v0-host-20-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host20_en>;
+ regulator-name = "vcc5v0_host_20";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
+ vcc_3v3_pcie20: vcc3v3-pcie20-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_pcie20";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v3_sd_en>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-name = "vcc_3v3_sd_s0";
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vbus5v0_typec: vbus5v0-typec-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vbus5v0_typec_en>;
+ regulator-name = "vbus5v0_typec";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ mem-supply = <&vdd_cpu_big0_mem_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+ mem-supply = <&vdd_cpu_big1_mem_s0>;
+};
+
+&gmac1 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac1_miim
+ &gmac1_tx_bus2
+ &gmac1_rx_bus2
+ &gmac1_rgmii_clk
+ &gmac1_rgmii_bus>;
+ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ /* Reset time is 20ms, 100ms for rtl8211f */
+ snps,reset-delays-us = <0 20000 100000>;
+ tx_delay = <0x42>;
+ /* rx_delay = <0x4f>; */
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: vdd_cpu_big0_mem_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: vdd_cpu_big1_mem_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ };
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&pinctrl {
+ gpio-leds {
+ lan1_led_pin: lan1-led-pin {
+ rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ lan2_led_pin: lan2-led-pin {
+ rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ power_led_pin: power-led-pin {
+ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wan_led_pin: wan-led-pin {
+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ rockchip-key {
+ reset_button_pin: reset-button-pin {
+ rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ sdmmc {
+ vcc3v3_sd_en: vcc3v3-sd-en {
+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ vbus5v0_typec_en: vbus5v0-typec-en {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc5v0_host20_en: vcc5v0-host20-en {
+ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdhci {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ mmc-hs200-1_8v;
+ no-sdio;
+ no-sd;
+ non-removable;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-sdio;
+ no-mmc;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>;
+ vmmc-supply = <&vcc_3v3_sd_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ num-cs = <1>;
+
+ rk806single: rk806single@0 {
+ compatible = "rockchip,rk806";
+ spi-max-frequency = <1000000>;
+ reg = <0x0>;
+
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs1_slp: dvs1-slp-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun1";
+ };
+
+ rk806_dvs1_pwrdn: dvs1-pwrdn-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun2";
+ };
+
+ rk806_dvs1_rst: dvs1-rst-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun3";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_slp: dvs2-slp-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun1";
+ };
+
+ rk806_dvs2_pwrdn: dvs2-pwrdn-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun2";
+ };
+
+ rk806_dvs2_rst: dvs2-rst-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun3";
+ };
+
+ rk806_dvs2_dvs: dvs2-dvs-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun4";
+ };
+
+ rk806_dvs2_gpio: dvs2-gpio-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun5";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_slp: dvs3-slp-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun1";
+ };
+
+ rk806_dvs3_pwrdn: dvs3-pwrdn-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun2";
+ };
+
+ rk806_dvs3_rst: dvs3-rst-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun3";
+ };
+
+ rk806_dvs3_dvs: dvs3-dvs-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun4";
+ };
+
+ rk806_dvs3_gpio: dvs3-gpio-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun5";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_log_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-init-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_vdenc_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
diff --git a/package/boot/uboot-rockchip/src/configs/nanopi-r6s-rk3588s_defconfig b/package/boot/uboot-rockchip/src/configs/nanopi-r6s-rk3588s_defconfig
new file mode 100644
index 0000000000..1e38954075
--- /dev/null
+++ b/configs/nanopi-r6s-rk3588s_defconfig
@@ -0,0 +1,68 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588s-nanopi-r6s"
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_EVB_RK3588=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFEB50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-nanopi-r6s.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_SYSRESET=y
+CONFIG_ERRNO_STR=y

View File

@@ -0,0 +1,99 @@
--- /dev/null
+++ b/arch/arm/dts/rk3588s-nanopi-r6c-u-boot.dtsi
@@ -0,0 +1,3 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rk3588s-nanopi-r6s-u-boot.dtsi"
--- /dev/null
+++ b/arch/arm/dts/rk3588s-nanopi-r6c.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+/dts-v1/;
+#include "rk3588s-nanopi-r6s.dts"
+
+/ {
+ model = "FriendlyElec NanoPi R6C";
+ compatible = "friendlyarm,nanopi-r6c", "rockchip,rk3588";
+
+ gpio-leds {
+ led-lan1 {
+ label = "green:lan";
+ };
+
+ led-lan2 {
+ label = "green:user";
+ };
+ };
+};
--- /dev/null
+++ b/configs/nanopi-r6c-rk3588s_defconfig
@@ -0,0 +1,68 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588s-nanopi-r6c"
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_EVB_RK3588=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFEB50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-nanopi-r6c.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_SYSRESET=y
+CONFIG_ERRNO_STR=y

View File

@@ -0,0 +1,896 @@
--- /dev/null
+++ b/arch/arm/dts/rk3588-nanopc-t6-u-boot.dtsi
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2023 Tianling Shen <cnsztl@gmail.com>
+ */
+
+#include "rk3588-u-boot.dtsi"
+
+/ {
+ aliases {
+ mmc0 = &sdmmc;
+ mmc1 = &sdhci;
+ };
+
+ chosen {
+ stdout-path = &uart2;
+ u-boot,spl-boot-order = "same-as-spl", &sdmmc, &sdhci;
+ };
+};
+
+&rng {
+ status = "okay";
+};
+
+&sdhci {
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_data_strobe &emmc_rstnout>;
+};
--- /dev/null
+++ b/arch/arm/dts/rk3588-nanopc-t6.dts
@@ -0,0 +1,785 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2022 FriendlyElec Computer Tech. Co., Ltd.
+ * (http://www.friendlyelec.com)
+ *
+ * Copyright (c) 2023 Thomas McKahan <tmckahan@singleboardsolutions.com>
+ * Copyright (c) 2023 Tianling Shen <cnsztl@gmail.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "FriendlyElec NanoPC T6";
+ compatible = "friendlyarm,nanopc-t6", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdmmc;
+ mmc1 = &sdhci;
+ serial2 = &uart2;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&power_led_pin>, <&wan_led_pin>;
+
+ power_led: led-power {
+ label = "red:power";
+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-wan {
+ label = "green:wan";
+ gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_usb: vcc5v0-usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usb";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_host_30: vcc5v0-host-30-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host_30";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc5v0_usb>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host30_en>;
+ };
+
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc5v0_sys>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_vcc3v3_en>;
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc5v0_sys>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_vcc3v3_en>;
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc_3v3_pcie20: vcc3v3-pcie20-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_pcie20";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-name = "vcc_3v3_sd_s0";
+ enable-active-high;
+ gpio = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc_3v3_s3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v3_sd_en>;
+ };
+
+ vbus5v0_typec: vbus5v0-typec-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vbus5v0_typec";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc5v0_usb>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vbus5v0_typec_en>;
+ };
+
+ vdd_4glte_3v3: vdd-4glte-3v3-regulator {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd_4glte_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <10000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ mem-supply = <&vdd_cpu_big0_mem_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+ mem-supply = <&vdd_cpu_big1_mem_s0>;
+};
+
+&gpio0 {
+ gpio-line-names = /* GPIO0 A0-A7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO0 B0-B7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO0 C0-C7 */
+ "", "", "", "",
+ "HEADER_10", "HEADER_08", "HEADER_32", "",
+ /* GPIO0 D0-D7 */
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpio1 {
+ gpio-line-names = /* GPIO1 A0-A7 */
+ "HEADER_27", "HEADER_28", "", "",
+ "", "", "", "HEADER_15",
+ /* GPIO1 B0-B7 */
+ "HEADER_26", "HEADER_21", "HEADER_19", "HEADER_23",
+ "HEADER_24", "HEADER_22", "", "",
+ /* GPIO1 C0-C7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO1 D0-D7 */
+ "", "", "", "",
+ "", "", "HEADER_05", "HEADER_03";
+};
+
+&gpio2 {
+ gpio-line-names = /* GPIO2 A0-A7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO2 B0-B7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO2 C0-C7 */
+ "", "CSI1_11", "CSI1_12", "",
+ "", "", "", "",
+ /* GPIO2 D0-D7 */
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpio3 {
+ gpio-line-names = /* GPIO3 A0-A7 */
+ "HEADER_35", "HEADER_38", "HEADER_40", "HEADER_36",
+ "HEADER_37", "", "DSI0_12", "",
+ /* GPIO3 B0-B7 */
+ "HEADER_33", "DSI0_10", "HEADER_07", "HEADER_16",
+ "HEADER_18", "HEADER_29", "HEADER_31", "HEADER_12",
+ /* GPIO3 C0-C7 */
+ "DSI0_08", "DSI0_14", "HEADER_11", "HEADER_13",
+ "", "", "", "",
+ /* GPIO3 D0-D7 */
+ "", "", "", "",
+ "", "DSI1_10", "", "";
+};
+
+&gpio4 {
+ gpio-line-names = /* GPIO4 A0-A7 */
+ "DSI1_08", "DSI1_14", "", "DSI1_12",
+ "", "", "", "",
+ /* GPIO4 B0-B7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO4 C0-C7 */
+ "", "", "", "",
+ "CSI0_11", "CSI0_12", "", "",
+ /* GPIO4 D0-D7 */
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: vdd_cpu_big0_mem_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: vdd_cpu_big1_mem_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ };
+};
+
+&pinctrl {
+ gpio-leds {
+ power_led_pin: power-led-pin {
+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wan_led_pin: wan-led-pin {
+ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pcie2 {
+ pcie2_0_vcc3v3_en: pcie2-0-vcc-en {
+ rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie3 {
+ pcie3_vcc3v3_en: pcie3-vcc3v3-en {
+ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ rockchip-key {
+ reset_button_pin: reset-button-pin {
+ rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ sdmmc {
+ vcc3v3_sd_en: vcc3v3-sd-en {
+ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ usbc0_int: usbc0-int {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ vbus5v0_typec_en: vbus5v0-typec-en {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc5v0_host30_en: vcc5v0-host30-en {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ };
+};
+
+&sdhci {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ max-frequency = <200000000>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ no-sdio;
+ no-sd;
+ non-removable;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-sdio;
+ no-mmc;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>;
+ vmmc-supply = <&vcc_3v3_sd_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ num-cs = <1>;
+
+ rk806single: rk806single@0 {
+ compatible = "rockchip,rk806";
+ spi-max-frequency = <1000000>;
+ reg = <0x0>;
+
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs1_slp: dvs1-slp-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun1";
+ };
+
+ rk806_dvs1_pwrdn: dvs1-pwrdn-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun2";
+ };
+
+ rk806_dvs1_rst: dvs1-rst-pins {
+ pins = "gpio_pwrctrl1";
+ function = "pin_fun3";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_slp: dvs2-slp-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun1";
+ };
+
+ rk806_dvs2_pwrdn: dvs2-pwrdn-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun2";
+ };
+
+ rk806_dvs2_rst: dvs2-rst-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun3";
+ };
+
+ rk806_dvs2_dvs: dvs2-dvs-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun4";
+ };
+
+ rk806_dvs2_gpio: dvs2-gpio-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun5";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_slp: dvs3-slp-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun1";
+ };
+
+ rk806_dvs3_pwrdn: dvs3-pwrdn-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun2";
+ };
+
+ rk806_dvs3_rst: dvs3-rst-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun3";
+ };
+
+ rk806_dvs3_dvs: dvs3-dvs-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun4";
+ };
+
+ rk806_dvs3_gpio: dvs3-gpio-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun5";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_log_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-init-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_vdenc_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
diff --git a/package/boot/uboot-rockchip/src/configs/nanopc-t6-rk3588_defconfig b/package/boot/uboot-rockchip/src/configs/nanopc-t6-rk3588_defconfig
new file mode 100644
index 0000000000..e8b46cf744
--- /dev/null
+++ b/configs/nanopc-t6-rk3588_defconfig
@@ -0,0 +1,68 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588-nanopc-t6"
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_EVB_RK3588=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFEB50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-nanopc-t6.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_SYSRESET=y
+CONFIG_ERRNO_STR=y

View File

@@ -6,9 +6,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git
PKG_SOURCE_DATE:=2024-04-16
PKG_SOURCE_VERSION:=1d51799e6768a304da7840b8346e7487efd77f49
PKG_MIRROR_HASH:=9cf0917532283c1a1708643022a5ed1ec4af6bb9ebaff57fc2f0f2c229f2469e
PKG_SOURCE_DATE:=2024-10-08
PKG_SOURCE_VERSION:=dcbab62272bf5cab2ed857bc655d240970e14f2a
PKG_MIRROR_HASH:=23fc47a0fd9f39defe272b9f5d5b08622e7762a57bc4830965972ee89d89f481
PKG_FLAGS:=nonshared

View File

@@ -3,7 +3,7 @@
"description": "Grant access to autocore",
"read": {
"ubus": {
"luci": [ "getCPUInfo", "getTempInfo" ]
"luci": [ "getCPUInfo", "getCPUUsage", "getTempInfo" ]
}
}
}

View File

@@ -18,6 +18,6 @@ DEFAULT_PACKAGES += \
kmod-qca-nss-ecm kmod-qca-nss-drv-bridge-mgr \
kmod-qca-nss-drv-vlan kmod-qca-nss-drv-pppoe \
kmod-ath11k-ahb wpad-openssl uboot-envtools \
e2fsprogs f2fsck mkf2fs losetup automount
e2fsprogs f2fsck mkf2fs losetup automount autocore-arm
$(eval $(call BuildTarget))

View File

@@ -71,6 +71,7 @@ define Device/jdcloud_re-cs-02
BLOCKSIZE := 64k
KERNEL_SIZE := 6144k
DEVICE_DTS_CONFIG := config@cp03-c3
SUPPORTED_DEVICES += jdcloud,ax6600
DEVICE_PACKAGES := ipq-wifi-jdcloud_ax6600 kmod-ath11k-pci ath11k-firmware-qcn9074
endef
TARGET_DEVICES += jdcloud_re-cs-02
@@ -84,6 +85,7 @@ define Device/jdcloud_re-ss-01
BLOCKSIZE := 64k
KERNEL_SIZE := 6144k
DEVICE_DTS_CONFIG := config@cp03-c2
SUPPORTED_DEVICES += jdcloud,ax1800-pro
DEVICE_PACKAGES := ipq-wifi-jdcloud_ax1800pro
endef
TARGET_DEVICES += jdcloud_re-ss-01

View File

@@ -0,0 +1,857 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include "rk3588.dtsi"
/ {
model = "Radxa ROCK 5B";
compatible = "radxa,rock-5b", "rockchip,rk3588";
aliases {
mmc0 = &sdhci;
mmc1 = &sdmmc;
mmc2 = &sdio;
led-boot = &status_led;
led-failsafe = &status_led;
led-running = &status_led;
led-upgrade = &status_led;
};
chosen {
stdout-path = "serial2:1500000n8";
};
analog-sound {
compatible = "audio-graph-card";
label = "rk3588-es8316";
widgets = "Microphone", "Mic Jack",
"Headphone", "Headphones";
routing = "MIC2", "Mic Jack",
"Headphones", "HPOL",
"Headphones", "HPOR";
dais = <&i2s0_8ch_p0>;
hp-det-gpio = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hp_detect>;
};
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&led_rgb_b>;
status_led: led_rgb_b {
function = LED_FUNCTION_STATUS;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
};
};
fan: pwm-fan {
compatible = "pwm-fan";
cooling-levels = <0 120 150 180 210 240 255>;
fan-supply = <&vcc5v0_sys>;
pwms = <&pwm1 0 50000 0>;
#cooling-cells = <2>;
};
rfkill {
compatible = "rfkill-gpio";
label = "rfkill-pcie-wlan";
radio-type = "wlan";
shutdown-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
};
vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
compatible = "regulator-fixed";
enable-active-high;
gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie2_0_vcc3v3_en>;
regulator-name = "vcc3v3_pcie2x1l0";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
startup-delay-us = <50000>;
vin-supply = <&vcc5v0_sys>;
};
vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_pcie2x1l2";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
startup-delay-us = <5000>;
vin-supply = <&vcc_3v3_s3>;
};
vcc3v3_pcie30: vcc3v3-pcie30-regulator {
compatible = "regulator-fixed";
enable-active-high;
gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie3_vcc3v3_en>;
regulator-name = "vcc3v3_pcie30";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
startup-delay-us = <5000>;
vin-supply = <&vcc5v0_sys>;
};
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_host";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_host_en>;
vin-supply = <&vcc5v0_sys>;
};
vcc5v0_sys: vcc5v0-sys-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_1v1_nldo_s3";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
vin-supply = <&vcc5v0_sys>;
};
};
&combphy0_ps {
status = "okay";
};
&combphy1_ps {
status = "okay";
};
&combphy2_psu {
status = "okay";
};
&cpu_b0 {
cpu-supply = <&vdd_cpu_big0_s0>;
};
&cpu_b1 {
cpu-supply = <&vdd_cpu_big0_s0>;
};
&cpu_b2 {
cpu-supply = <&vdd_cpu_big1_s0>;
};
&cpu_b3 {
cpu-supply = <&vdd_cpu_big1_s0>;
};
&cpu_l0 {
cpu-supply = <&vdd_cpu_lit_s0>;
};
&cpu_l1 {
cpu-supply = <&vdd_cpu_lit_s0>;
};
&cpu_l2 {
cpu-supply = <&vdd_cpu_lit_s0>;
};
&cpu_l3 {
cpu-supply = <&vdd_cpu_lit_s0>;
};
&gpu {
mali-supply = <&vdd_gpu_s0>;
status = "okay";
};
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0m2_xfer>;
status = "okay";
vdd_cpu_big0_s0: regulator@42 {
compatible = "rockchip,rk8602";
reg = <0x42>;
fcs,suspend-voltage-selector = <1>;
regulator-name = "vdd_cpu_big0_s0";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <2300>;
vin-supply = <&vcc5v0_sys>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdd_cpu_big1_s0: regulator@43 {
compatible = "rockchip,rk8603", "rockchip,rk8602";
reg = <0x43>;
fcs,suspend-voltage-selector = <1>;
regulator-name = "vdd_cpu_big1_s0";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <1050000>;
regulator-ramp-delay = <2300>;
vin-supply = <&vcc5v0_sys>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
};
&i2c6 {
status = "okay";
hym8563: rtc@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
#clock-cells = <0>;
clock-output-names = "hym8563";
pinctrl-names = "default";
pinctrl-0 = <&hym8563_int>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
wakeup-source;
};
};
&i2c7 {
status = "okay";
es8316: audio-codec@11 {
compatible = "everest,es8316";
reg = <0x11>;
clocks = <&cru I2S0_8CH_MCLKOUT>;
clock-names = "mclk";
assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
assigned-clock-rates = <12288000>;
#sound-dai-cells = <0>;
port {
es8316_p0_0: endpoint {
remote-endpoint = <&i2s0_8ch_p0_0>;
};
};
};
};
&i2s0_8ch {
pinctrl-names = "default";
pinctrl-0 = <&i2s0_lrck
&i2s0_mclk
&i2s0_sclk
&i2s0_sdi0
&i2s0_sdo0>;
status = "okay";
i2s0_8ch_p0: port {
i2s0_8ch_p0_0: endpoint {
dai-format = "i2s";
mclk-fs = <256>;
remote-endpoint = <&es8316_p0_0>;
};
};
};
&package_thermal {
polling-delay = <1000>;
trips {
package_fan0: package-fan0 {
temperature = <55000>;
hysteresis = <2000>;
type = "active";
};
package_fan1: package-fan1 {
temperature = <65000>;
hysteresis = <2000>;
type = "active";
};
};
cooling-maps {
map1 {
trip = <&package_fan0>;
cooling-device = <&fan THERMAL_NO_LIMIT 1>;
};
map2 {
trip = <&package_fan1>;
cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
};
};
};
&pcie2x1l0 {
pinctrl-names = "default";
pinctrl-0 = <&pcie2_0_rst>;
reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
status = "okay";
};
&pcie2x1l2 {
pinctrl-names = "default";
pinctrl-0 = <&pcie2_2_rst>;
reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
status = "okay";
};
&pcie30phy {
status = "okay";
};
&pcie3x4 {
pinctrl-names = "default";
pinctrl-0 = <&pcie3_rst>;
reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc3v3_pcie30>;
status = "okay";
};
&pinctrl {
hym8563 {
hym8563_int: hym8563-int {
rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
leds {
led_rgb_b: led-rgb-b {
rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
sound {
hp_detect: hp-detect {
rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
pcie2 {
pcie2_0_rst: pcie2-0-rst {
rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
};
pcie2_0_vcc3v3_en: pcie2-0-vcc-en {
rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
};
pcie2_2_rst: pcie2-2-rst {
rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
pcie3 {
pcie3_rst: pcie3-rst {
rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
};
pcie3_vcc3v3_en: pcie3-vcc3v3-en {
rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
usb {
vcc5v0_host_en: vcc5v0-host-en {
rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
&pwm1 {
status = "okay";
};
&saradc {
vref-supply = <&avcc_1v8_s0>;
status = "okay";
};
&sdhci {
bus-width = <8>;
no-sdio;
no-sd;
non-removable;
mmc-hs400-1_8v;
mmc-hs400-enhanced-strobe;
status = "okay";
};
&sdmmc {
max-frequency = <200000000>;
no-sdio;
no-mmc;
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
disable-wp;
sd-uhs-sdr50;
vmmc-supply = <&vcc_3v3_s3>;
vqmmc-supply = <&vccio_sd_s0>;
status = "okay";
};
&sdio {
max-frequency = <200000000>;
no-sd;
no-mmc;
non-removable;
bus-width = <4>;
cap-sdio-irq;
disable-wp;
keep-power-in-suspend;
wakeup-source;
sd-uhs-sdr12;
sd-uhs-sdr25;
sd-uhs-sdr50;
sd-uhs-sdr104;
vmmc-supply = <&vcc3v3_pcie2x1l0>;
vqmmc-supply = <&vcc_1v8_s3>;
pinctrl-names = "default";
pinctrl-0 = <&sdiom0_pins>;
status = "okay";
};
&sfc {
pinctrl-names = "default";
pinctrl-0 = <&fspim2_pins>;
status = "okay";
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <104000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <1>;
};
};
&uart6 {
pinctrl-names = "default";
pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
status = "okay";
};
&spi2 {
status = "okay";
assigned-clocks = <&cru CLK_SPI2>;
assigned-clock-rates = <200000000>;
pinctrl-names = "default";
pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
num-cs = <1>;
pmic@0 {
compatible = "rockchip,rk806";
spi-max-frequency = <1000000>;
reg = <0x0>;
interrupt-parent = <&gpio0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
<&rk806_dvs2_null>, <&rk806_dvs3_null>;
system-power-controller;
vcc1-supply = <&vcc5v0_sys>;
vcc2-supply = <&vcc5v0_sys>;
vcc3-supply = <&vcc5v0_sys>;
vcc4-supply = <&vcc5v0_sys>;
vcc5-supply = <&vcc5v0_sys>;
vcc6-supply = <&vcc5v0_sys>;
vcc7-supply = <&vcc5v0_sys>;
vcc8-supply = <&vcc5v0_sys>;
vcc9-supply = <&vcc5v0_sys>;
vcc10-supply = <&vcc5v0_sys>;
vcc11-supply = <&vcc_2v0_pldo_s3>;
vcc12-supply = <&vcc5v0_sys>;
vcc13-supply = <&vcc_1v1_nldo_s3>;
vcc14-supply = <&vcc_1v1_nldo_s3>;
vcca-supply = <&vcc5v0_sys>;
gpio-controller;
#gpio-cells = <2>;
rk806_dvs1_null: dvs1-null-pins {
pins = "gpio_pwrctrl1";
function = "pin_fun0";
};
rk806_dvs2_null: dvs2-null-pins {
pins = "gpio_pwrctrl2";
function = "pin_fun0";
};
rk806_dvs3_null: dvs3-null-pins {
pins = "gpio_pwrctrl3";
function = "pin_fun0";
};
regulators {
vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
regulator-boot-on;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
regulator-name = "vdd_gpu_s0";
regulator-enable-ramp-delay = <400>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
regulator-name = "vdd_cpu_lit_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdd_log_s0: dcdc-reg3 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <750000>;
regulator-ramp-delay = <12500>;
regulator-name = "vdd_log_s0";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <750000>;
};
};
vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <550000>;
regulator-max-microvolt = <950000>;
regulator-ramp-delay = <12500>;
regulator-name = "vdd_vdenc_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdd_ddr_s0: dcdc-reg5 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <675000>;
regulator-max-microvolt = <900000>;
regulator-ramp-delay = <12500>;
regulator-name = "vdd_ddr_s0";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <850000>;
};
};
vdd2_ddr_s3: dcdc-reg6 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vdd2_ddr_s3";
regulator-state-mem {
regulator-on-in-suspend;
};
};
vcc_2v0_pldo_s3: dcdc-reg7 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <2000000>;
regulator-max-microvolt = <2000000>;
regulator-ramp-delay = <12500>;
regulator-name = "vdd_2v0_pldo_s3";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <2000000>;
};
};
vcc_3v3_s3: dcdc-reg8 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc_3v3_s3";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vddq_ddr_s0: dcdc-reg9 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vddq_ddr_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc_1v8_s3: dcdc-reg10 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc_1v8_s3";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
avcc_1v8_s0: pldo-reg1 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "avcc_1v8_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc_1v8_s0: pldo-reg2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "vcc_1v8_s0";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
avdd_1v2_s0: pldo-reg3 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-name = "avdd_1v2_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc_3v3_s0: pldo-reg4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-ramp-delay = <12500>;
regulator-name = "vcc_3v3_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vccio_sd_s0: pldo-reg5 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-ramp-delay = <12500>;
regulator-name = "vccio_sd_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
pldo6_s3: pldo-reg6 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-name = "pldo6_s3";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vdd_0v75_s3: nldo-reg1 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <750000>;
regulator-name = "vdd_0v75_s3";
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <750000>;
};
};
vdd_ddr_pll_s0: nldo-reg2 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <850000>;
regulator-name = "vdd_ddr_pll_s0";
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <850000>;
};
};
avdd_0v75_s0: nldo-reg3 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <750000>;
regulator-name = "avdd_0v75_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdd_0v85_s0: nldo-reg4 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <850000>;
regulator-name = "vdd_0v85_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
vdd_0v75_s0: nldo-reg5 {
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <750000>;
regulator-name = "vdd_0v75_s0";
regulator-state-mem {
regulator-off-in-suspend;
};
};
};
};
};
&tsadc {
status = "okay";
};
&uart2 {
pinctrl-0 = <&uart2m0_xfer>;
status = "okay";
};
&u2phy1 {
status = "okay";
};
&u2phy1_otg {
status = "okay";
};
&u2phy2 {
status = "okay";
};
&u2phy2_host {
/* connected to USB hub, which is powered by vcc5v0_sys */
phy-supply = <&vcc5v0_sys>;
status = "okay";
};
&u2phy3 {
status = "okay";
};
&u2phy3_host {
phy-supply = <&vcc5v0_host>;
status = "okay";
};
&usbdp_phy1 {
status = "okay";
};
&usb_host0_ehci {
status = "okay";
};
&usb_host0_ohci {
status = "okay";
};
&usb_host1_ehci {
status = "okay";
};
&usb_host1_ohci {
status = "okay";
};
&usb_host1_xhci {
dr_mode = "host";
status = "okay";
};
&usb_host2_xhci {
status = "okay";
};

View File

@@ -123,6 +123,16 @@ define Device/friendlyarm_nanopi-neo3
endef
TARGET_DEVICES += friendlyarm_nanopi-neo3
define Device/friendlyarm_nanopc-t6
DEVICE_VENDOR := FriendlyARM
DEVICE_MODEL := NanoPC T6
SOC := rk3588
UBOOT_DEVICE_NAME := nanopc-t6-rk3588
IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata
DEVICE_PACKAGES := kmod-r8125-rss
endef
TARGET_DEVICES += friendlyarm_nanopc-t6
define Device/friendlyarm_nanopi-r2c
DEVICE_VENDOR := FriendlyARM
DEVICE_MODEL := NanoPi R2C
@@ -183,6 +193,26 @@ define Device/friendlyarm_nanopi-r5s
endef
TARGET_DEVICES += friendlyarm_nanopi-r5s
define Device/friendlyarm_nanopi-r6c
DEVICE_VENDOR := FriendlyARM
DEVICE_MODEL := NanoPi R6C
SOC := rk3588s
UBOOT_DEVICE_NAME := nanopi-r6c-rk3588s
IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata
DEVICE_PACKAGES := kmod-r8125-rss
endef
TARGET_DEVICES += friendlyarm_nanopi-r6c
define Device/friendlyarm_nanopi-r6s
DEVICE_VENDOR := FriendlyARM
DEVICE_MODEL := NanoPi R6S
SOC := rk3588s
UBOOT_DEVICE_NAME := nanopi-r6s-rk3588s
IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata
DEVICE_PACKAGES := kmod-r8125-rss
endef
TARGET_DEVICES += friendlyarm_nanopi-r6s
define Device/firefly_station-p2
DEVICE_VENDOR := Firefly
DEVICE_MODEL := Station P2
@@ -323,6 +353,16 @@ define Device/radxa_rock-pi-4
endef
TARGET_DEVICES += radxa_rock-pi-4
define Device/radxa_rock-5b
DEVICE_VENDOR := Radxa
DEVICE_MODEL := ROCK 5B
SOC := rk3588
UBOOT_DEVICE_NAME := rock5b-rk3588
IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata
DEVICE_PACKAGES := kmod-r8125-rss kmod-hwmon-pwmfan
endef
TARGET_DEVICES += radxa_rock-5b
define Device/rongpin_king3399
DEVICE_VENDOR := Rongpin
DEVICE_MODEL := King3399

View File

@@ -20,7 +20,6 @@ Link: https://lore.kernel.org/r/20231205164842.556684-2-heiko@sntech.de
arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 1 -
.../boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 1 -
arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts | 1 -
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 1 -
arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi | 2 --
.../boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 1 -
.../boot/dts/rockchip/rk3588s-khadas-edge2.dts | 1 -
@@ -64,16 +63,6 @@ Link: https://lore.kernel.org/r/20231205164842.556684-2-heiko@sntech.de
- serial2 = &uart2;
};
chosen {
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -12,7 +12,6 @@
aliases {
mmc0 = &sdhci;
mmc1 = &sdmmc;
- serial2 = &uart2;
};
chosen {
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts

View File

@@ -20,12 +20,12 @@ require (
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399
github.com/metacubex/chacha v0.1.0
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759
github.com/metacubex/quic-go v0.47.1-0.20240909010619-6b38f24bfcc4
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4
github.com/metacubex/sing-shadowsocks v0.2.8
github.com/metacubex/sing-shadowsocks2 v0.2.2
github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3
github.com/metacubex/tfo-go v0.0.0-20241006021335-daedaf0ca7aa
@@ -39,7 +39,7 @@ require (
github.com/sagernet/cors v1.2.1
github.com/sagernet/fswatch v0.1.1
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
github.com/sagernet/sing v0.5.0-alpha.13
github.com/sagernet/sing v0.5.0-rc.4
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
github.com/sagernet/sing-shadowtls v0.1.4
github.com/samber/lo v1.47.0
@@ -116,4 +116,4 @@ require (
golang.org/x/tools v0.24.0 // indirect
)
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a

View File

@@ -104,20 +104,20 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec h1:HxreOiFTUrJXJautEo8rnE1uKTVGY8wtZepY1Tii/Nc=
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw=
github.com/metacubex/quic-go v0.47.1-0.20240909010619-6b38f24bfcc4 h1:CgdUBRxmNlxEGkp35HwvgQ10jwOOUJKWdOxpi8yWi8o=
github.com/metacubex/quic-go v0.47.1-0.20240909010619-6b38f24bfcc4/go.mod h1:Y7yRGqFE6UQL/3aKPYmiYdjfVkeujJaStP4+jiZMcN8=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174 h1:GvigRPEU+cbnzdLWne47cxLrc28Abohl3ECtVdnrbq0=
github.com/metacubex/quic-go v0.48.1-0.20241021013658-51ca987e0174/go.mod h1:AiZ+UPgrkO1DTnmiAX4b+kRoV1Vfc65UkYD7RbFlIZA=
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297 h1:YG/JkwGPbca5rUtEMHIu8ZuqzR7BSVm1iqY8hNoMeMA=
github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a h1:JuR0/7RDxQtlZp/GOzrdqNq04HplTxavPRHrek8ouJk=
github.com/metacubex/sing v0.0.0-20241021005542-18b67490300a/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4 h1:HobpULaPK6OoxrHMmgcwLkwwIduXVmwdcznwUfH1GQM=
github.com/metacubex/sing-quic v0.0.0-20240827003841-cd97758ed8b4/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8=
github.com/metacubex/sing-shadowsocks v0.2.8 h1:wIhlaigswzjPw4hej75sEvWte3QR0+AJRafgwBHO5B4=
github.com/metacubex/sing-shadowsocks v0.2.8/go.mod h1:X3x88XtJpBxG0W0/ECOJL6Ib0SJ3xdniAkU/6/RMWU0=
github.com/metacubex/sing-shadowsocks2 v0.2.2 h1:eaf42uVx4Lr21S6MDYs0ZdTvGA0GEhDpb9no4+gdXPo=
github.com/metacubex/sing-shadowsocks2 v0.2.2/go.mod h1:BhOug03a/RbI7y6hp6q+6ITM1dXjnLTmeWBHSTwvv2Q=
github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1 h1:ypfofGDZbP8p3Y4P/m74JYu7sQViesi3c8nbmT6cS0Y=
github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1/go.mod h1:olbEx9yVcaw5tHTNlRamRoxmMKcvDvcVS1YLnQGzvWE=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c h1:qfUZ8xBrViOCZamvcC8CyV7Ii8sAUrn7RqZxFGn56tQ=
github.com/metacubex/sing-tun v0.2.7-0.20241021011113-857bcd6ee47c/go.mod h1:lCrP0AW7ieKnXG1JEeZLW+9h99QzjuOX0MfCQfz6TgE=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns=

View File

@@ -279,7 +279,7 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
return
}
defaultInterfaceMonitor, err = tun.NewDefaultInterfaceMonitor(networkUpdateMonitor, log.SingLogger, tun.DefaultInterfaceMonitorOptions{OverrideAndroidVPN: true})
defaultInterfaceMonitor, err = tun.NewDefaultInterfaceMonitor(networkUpdateMonitor, log.SingLogger, tun.DefaultInterfaceMonitorOptions{InterfaceFinder: interfaceFinder, OverrideAndroidVPN: true})
if err != nil {
err = E.Cause(err, "create DefaultInterfaceMonitor")
return

View File

@@ -1 +1 @@
9
10

View File

@@ -2,7 +2,7 @@ Source: shadowsocks-rust
Section: net
Priority: optional
Maintainer: Y. T. Chung <zonyitoo@gmail.com>
Build-Depends: debhelper (>=9), rustc, cargo, apg | pwgen, libcap2-bin [linux-any]
Build-Depends: debhelper (>=9), rustc, cargo, libcap2-bin [linux-any]
Standards-Version: 3.9.6
Homepage: https://github.com/shadowsocks/shadowsocks-rust

View File

@@ -13,6 +13,7 @@ After=network.target
Type=simple
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
DynamicUser=yes
ExecStart=/usr/bin/ssservice local --log-without-time -c /etc/shadowsocks-rust/%i.json
[Install]

View File

@@ -13,6 +13,7 @@ After=network.target
Type=simple
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
DynamicUser=yes
ExecStart=/usr/bin/ssservice server --log-without-time -c /etc/shadowsocks-rust/%i.json
[Install]

View File

@@ -27,8 +27,7 @@ case "$1" in
if [ ! -f /etc/shadowsocks-rust/config.json ]; then
set +e
passwd=$(/usr/bin/ssservice genkey -m "chacha20-ietf-poly1305")
passwd="${passwd//+/\\+}"
passwd="${passwd//\//\\/}"
passwd=$(echo $passwd | sed "s/+/\\\\+/g" | sed "s/\\//\\\\\\//g")
set -e
mkdir -p /etc/shadowsocks-rust
sed "s/barfoo/$passwd/" /usr/share/shadowsocks-rust/config.json \

View File

@@ -11,8 +11,7 @@ After=network.target
[Service]
Type=simple
EnvironmentFile=/etc/default/shadowsocks-rust
User=nobody
Group=nogroup
DynamicUser=yes
LimitNOFILE=32768
ExecStart=/usr/bin/ssservice server -c ${CONFFILE} ${DAEMON_ARGS}

View File

@@ -1,104 +0,0 @@
package adapter
import (
"context"
"net"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type ConnectionRouter interface {
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
func NewRouteHandler(
metadata InboundContext,
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeHandlerWrapper{
metadata: metadata,
router: router,
logger: logger,
}
}
func NewRouteContextHandler(
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeContextHandlerWrapper{
router: router,
logger: logger,
}
}
var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
type routeHandlerWrapper struct {
metadata InboundContext
router ConnectionRouter
logger logger.ContextLogger
}
func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, myMetadata)
}
func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, myMetadata)
}
func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)
type routeContextHandlerWrapper struct {
router ConnectionRouter
logger logger.ContextLogger
}
func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, *myMetadata)
}
func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, *myMetadata)
}
func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}

View File

@@ -6,27 +6,53 @@ import (
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
// Deprecated
type ConnectionHandler interface {
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
}
type ConnectionHandlerEx interface {
NewConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
// Deprecated: use PacketHandlerEx instead
type PacketHandler interface {
NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata InboundContext) error
}
type PacketHandlerEx interface {
NewPacketEx(buffer *buf.Buffer, source M.Socksaddr)
}
// Deprecated: use OOBPacketHandlerEx instead
type OOBPacketHandler interface {
NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, oob []byte, metadata InboundContext) error
}
type OOBPacketHandlerEx interface {
NewPacketEx(buffer *buf.Buffer, oob []byte, source M.Socksaddr)
}
// Deprecated
type PacketConnectionHandler interface {
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type PacketConnectionHandlerEx interface {
NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
type UpstreamHandlerAdapter interface {
N.TCPConnectionHandler
N.UDPConnectionHandler
E.Handler
}
type UpstreamHandlerAdapterEx interface {
N.TCPConnectionHandlerEx
N.UDPConnectionHandlerEx
}

View File

@@ -2,13 +2,11 @@ package adapter
import (
"context"
"net"
"net/netip"
"github.com/sagernet/sing-box/common/process"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type Inbound interface {
@@ -17,11 +15,14 @@ type Inbound interface {
Tag() string
}
type InjectableInbound interface {
type TCPInjectableInbound interface {
Inbound
Network() []string
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
ConnectionHandlerEx
}
type UDPInjectableInbound interface {
Inbound
PacketConnectionHandlerEx
}
type InboundContext struct {
@@ -43,16 +44,18 @@ type InboundContext struct {
// cache
InboundDetour string
LastInbound string
OriginDestination M.Socksaddr
InboundOptions option.InboundOptions
DestinationAddresses []netip.Addr
SourceGeoIPCode string
GeoIPCode string
ProcessInfo *process.Info
QueryType uint16
FakeIP bool
InboundDetour string
LastInbound string
OriginDestination M.Socksaddr
// Deprecated
InboundOptions option.InboundOptions
UDPDisableDomainUnmapping bool
DestinationAddresses []netip.Addr
SourceGeoIPCode string
GeoIPCode string
ProcessInfo *process.Info
QueryType uint16
FakeIP bool
// rule cache

View File

@@ -1,9 +1,6 @@
package adapter
import (
"context"
"net"
N "github.com/sagernet/sing/common/network"
)
@@ -15,6 +12,4 @@ type Outbound interface {
Network() []string
Dependencies() []string
N.Dialer
NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}

View File

@@ -2,6 +2,7 @@ package adapter
import (
"context"
"net"
"net/http"
"net/netip"
@@ -30,6 +31,7 @@ type Router interface {
FakeIPStore() FakeIPStore
ConnectionRouter
ConnectionRouterEx
GeoIPReader() *geoip.Reader
LoadGeosite(code string) (Rule, error)
@@ -66,6 +68,18 @@ type Router interface {
ResetNetwork() error
}
// Deprecated: Use ConnectionRouterEx instead.
type ConnectionRouter interface {
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
}
type ConnectionRouterEx interface {
ConnectionRouter
RouteConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
func ContextWithRouter(ctx context.Context, router Router) context.Context {
return service.ContextWith(ctx, router)
}
@@ -74,28 +88,6 @@ func RouterFromContext(ctx context.Context) Router {
return service.FromContext[Router](ctx)
}
type HeadlessRule interface {
Match(metadata *InboundContext) bool
String() string
}
type Rule interface {
HeadlessRule
Service
Type() string
UpdateGeosite() error
Outbound() string
}
type DNSRule interface {
Rule
DisableCache() bool
RewriteTTL() *uint32
ClientSubnet() *netip.Prefix
WithAddressLimit() bool
MatchAddressLimit(metadata *InboundContext) bool
}
type RuleSet interface {
Name() string
StartContext(ctx context.Context, startContext RuleSetStartContext) error

38
sing-box/adapter/rule.go Normal file
View File

@@ -0,0 +1,38 @@
package adapter
import (
C "github.com/sagernet/sing-box/constant"
)
type HeadlessRule interface {
Match(metadata *InboundContext) bool
String() string
}
type Rule interface {
HeadlessRule
Service
Type() string
UpdateGeosite() error
Action() RuleAction
}
type DNSRule interface {
Rule
WithAddressLimit() bool
MatchAddressLimit(metadata *InboundContext) bool
}
type RuleAction interface {
Type() string
String() string
}
func IsFinalAction(action RuleAction) bool {
switch action.Type() {
case C.RuleActionTypeSniff, C.RuleActionTypeResolve:
return false
default:
return true
}
}

View File

@@ -4,112 +4,165 @@ import (
"context"
"net"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type (
ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
ConnectionHandlerFuncEx = func(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
PacketConnectionHandlerFuncEx = func(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
)
func NewUpstreamHandler(
func NewUpstreamHandlerEx(
metadata InboundContext,
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamHandlerWrapper{
connectionHandler ConnectionHandlerFuncEx,
packetHandler PacketConnectionHandlerFuncEx,
) UpstreamHandlerAdapterEx {
return &myUpstreamHandlerWrapperEx{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
var _ UpstreamHandlerAdapterEx = (*myUpstreamHandlerWrapperEx)(nil)
type myUpstreamHandlerWrapper struct {
type myUpstreamHandlerWrapperEx struct {
metadata InboundContext
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
connectionHandler ConnectionHandlerFuncEx
packetHandler PacketConnectionHandlerFuncEx
}
func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
func (w *myUpstreamHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
if source.IsValid() {
myMetadata.Source = source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
if destination.IsValid() {
myMetadata.Destination = destination
}
return w.connectionHandler(ctx, conn, myMetadata)
w.connectionHandler(ctx, conn, myMetadata, onClose)
}
func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
func (w *myUpstreamHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
if source.IsValid() {
myMetadata.Source = source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
if destination.IsValid() {
myMetadata.Destination = destination
}
return w.packetHandler(ctx, conn, myMetadata)
w.packetHandler(ctx, conn, myMetadata, onClose)
}
func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
var _ UpstreamHandlerAdapterEx = (*myUpstreamContextHandlerWrapperEx)(nil)
type myUpstreamContextHandlerWrapperEx struct {
connectionHandler ConnectionHandlerFuncEx
packetHandler PacketConnectionHandlerFuncEx
}
func UpstreamMetadata(metadata InboundContext) M.Metadata {
return M.Metadata{
Source: metadata.Source,
Destination: metadata.Destination,
}
}
type myUpstreamContextHandlerWrapper struct {
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
}
func NewUpstreamContextHandler(
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamContextHandlerWrapper{
func NewUpstreamContextHandlerEx(
connectionHandler ConnectionHandlerFuncEx,
packetHandler PacketConnectionHandlerFuncEx,
) UpstreamHandlerAdapterEx {
return &myUpstreamContextHandlerWrapperEx{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
func (w *myUpstreamContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
if source.IsValid() {
myMetadata.Source = source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
if destination.IsValid() {
myMetadata.Destination = destination
}
return w.connectionHandler(ctx, conn, *myMetadata)
w.connectionHandler(ctx, conn, *myMetadata, onClose)
}
func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
func (w *myUpstreamContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
if source.IsValid() {
myMetadata.Source = source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
if destination.IsValid() {
myMetadata.Destination = destination
}
return w.packetHandler(ctx, conn, *myMetadata)
w.packetHandler(ctx, conn, *myMetadata, onClose)
}
func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
func NewRouteHandlerEx(
metadata InboundContext,
router ConnectionRouterEx,
) UpstreamHandlerAdapterEx {
return &routeHandlerWrapperEx{
metadata: metadata,
router: router,
}
}
var _ UpstreamHandlerAdapterEx = (*routeHandlerWrapperEx)(nil)
type routeHandlerWrapperEx struct {
metadata InboundContext
router ConnectionRouterEx
}
func (r *routeHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
if destination.IsValid() {
r.metadata.Destination = destination
}
r.router.RouteConnectionEx(ctx, conn, r.metadata, onClose)
}
func (r *routeHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
if destination.IsValid() {
r.metadata.Destination = destination
}
r.router.RoutePacketConnectionEx(ctx, conn, r.metadata, onClose)
}
func NewRouteContextHandlerEx(
router ConnectionRouterEx,
) UpstreamHandlerAdapterEx {
return &routeContextHandlerWrapperEx{
router: router,
}
}
var _ UpstreamHandlerAdapterEx = (*routeContextHandlerWrapperEx)(nil)
type routeContextHandlerWrapperEx struct {
router ConnectionRouterEx
}
func (r *routeContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
metadata := ContextFrom(ctx)
if source.IsValid() {
metadata.Source = source
}
if destination.IsValid() {
metadata.Destination = destination
}
r.router.RouteConnectionEx(ctx, conn, *metadata, onClose)
}
func (r *routeContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
metadata := ContextFrom(ctx)
if source.IsValid() {
metadata.Source = source
}
if destination.IsValid() {
metadata.Destination = destination
}
r.router.RoutePacketConnectionEx(ctx, conn, *metadata, onClose)
}

View File

@@ -0,0 +1,216 @@
package adapter
import (
"context"
"net"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
type (
// Deprecated
ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
// Deprecated
PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
)
// Deprecated
func NewUpstreamHandler(
metadata InboundContext,
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamHandlerWrapper{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
// Deprecated
type myUpstreamHandlerWrapper struct {
metadata InboundContext
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
}
func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, myMetadata)
}
func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, myMetadata)
}
func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated
func UpstreamMetadata(metadata InboundContext) M.Metadata {
return M.Metadata{
Source: metadata.Source,
Destination: metadata.Destination,
}
}
// Deprecated
type myUpstreamContextHandlerWrapper struct {
connectionHandler ConnectionHandlerFunc
packetHandler PacketConnectionHandlerFunc
errorHandler E.Handler
}
// Deprecated
func NewUpstreamContextHandler(
connectionHandler ConnectionHandlerFunc,
packetHandler PacketConnectionHandlerFunc,
errorHandler E.Handler,
) UpstreamHandlerAdapter {
return &myUpstreamContextHandlerWrapper{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.connectionHandler(ctx, conn, *myMetadata)
}
func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.packetHandler(ctx, conn, *myMetadata)
}
func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated: Use ConnectionRouterEx instead.
func NewRouteHandler(
metadata InboundContext,
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeHandlerWrapper{
metadata: metadata,
router: router,
logger: logger,
}
}
// Deprecated: Use ConnectionRouterEx instead.
func NewRouteContextHandler(
router ConnectionRouter,
logger logger.ContextLogger,
) UpstreamHandlerAdapter {
return &routeContextHandlerWrapper{
router: router,
logger: logger,
}
}
var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
type routeHandlerWrapper struct {
metadata InboundContext
router ConnectionRouter
logger logger.ContextLogger
}
func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, myMetadata)
}
func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, myMetadata)
}
func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
type routeContextHandlerWrapper struct {
router ConnectionRouter
logger logger.ContextLogger
}
func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RouteConnection(ctx, conn, *myMetadata)
}
func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
}
if metadata.Destination.IsValid() {
myMetadata.Destination = metadata.Destination
}
return w.router.RoutePacketConnection(ctx, conn, *myMetadata)
}
func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}

View File

@@ -10,7 +10,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/route"
"github.com/sagernet/sing-box/route/rule"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/json"
@@ -84,7 +84,7 @@ func ruleSetMatch(sourcePath string, domain string) error {
}
for i, ruleOptions := range plainRuleSet.Rules {
var currentRule adapter.HeadlessRule
currentRule, err = route.NewHeadlessRule(nil, ruleOptions)
currentRule, err = rule.NewHeadlessRule(nil, ruleOptions)
if err != nil {
return E.Cause(err, "parse rule_set.rules.[", i, "]")
}

View File

@@ -5,7 +5,7 @@ import (
"testing"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/route"
"github.com/sagernet/sing-box/route/rule"
"github.com/stretchr/testify/require"
)
@@ -26,7 +26,7 @@ example.arpa
`))
require.NoError(t, err)
require.Len(t, rules, 1)
rule, err := route.NewHeadlessRule(nil, rules[0])
rule, err := rule.NewHeadlessRule(nil, rules[0])
require.NoError(t, err)
matchDomain := []string{
"example.org",
@@ -85,7 +85,7 @@ func TestHosts(t *testing.T) {
`))
require.NoError(t, err)
require.Len(t, rules, 1)
rule, err := route.NewHeadlessRule(nil, rules[0])
rule, err := rule.NewHeadlessRule(nil, rules[0])
require.NoError(t, err)
matchDomain := []string{
"google.com",
@@ -115,7 +115,7 @@ www.example.org
`))
require.NoError(t, err)
require.Len(t, rules, 1)
rule, err := route.NewHeadlessRule(nil, rules[0])
rule, err := rule.NewHeadlessRule(nil, rules[0])
require.NoError(t, err)
matchDomain := []string{
"example.com",

Some files were not shown because too many files have changed in this diff Show More