From abfa3f6b2cc19874848d7c3beeff71b5d58ed322 Mon Sep 17 00:00:00 2001 From: "github-action[bot]" Date: Sun, 6 Apr 2025 20:35:02 +0200 Subject: [PATCH] Update On Sun Apr 6 20:35:01 CEST 2025 --- .github/update.log | 1 + .../listener/sing_shadowsocks/server.go | 2 +- clash-meta/listener/sing_vless/server.go | 2 +- clash-meta/listener/sing_vmess/server.go | 2 +- clash-meta/transport/gun/server.go | 1 + clash-meta/transport/socks5/socks5.go | 17 +- clash-nyanpasu/backend/Cargo.lock | 28 ++-- clash-nyanpasu/manifest/version.json | 4 +- mihomo/listener/sing_shadowsocks/server.go | 2 +- mihomo/listener/sing_vless/server.go | 2 +- mihomo/listener/sing_vmess/server.go | 2 +- mihomo/transport/gun/server.go | 1 + mihomo/transport/socks5/socks5.go | 17 +- naiveproxy/README.md | 6 +- .../luci-app-lucky/lucky/Makefile | 45 +++--- .../.github/workflows/clippy-check.yml | 4 - shadowsocks-rust/Cargo.lock | 12 +- .../crates/shadowsocks/src/relay/socks5.rs | 6 +- sing-box/.github/workflows/lint.yml | 2 +- sing-box/adapter/router.go | 2 +- sing-box/box.go | 4 +- sing-box/common/sniff/bittorrent.go | 4 +- sing-box/common/sniff/bittorrent_test.go | 16 ++ sing-box/common/tls/ech.go | 6 +- sing-box/constant/protocol.go | 1 - sing-box/dns/transport/udp.go | 2 +- sing-box/docs/configuration/route/sniff.md | 4 +- sing-box/experimental/libbox/service.go | 2 +- sing-box/experimental/libbox/service_pause.go | 30 ++-- sing-box/go.mod | 6 +- sing-box/go.sum | 12 +- sing-box/protocol/group/urltest.go | 49 +++--- sing-box/protocol/wireguard/endpoint.go | 1 - sing-box/protocol/wireguard/outbound.go | 1 - sing-box/route/route.go | 15 +- sing-box/route/router.go | 6 +- sing-box/route/rule/rule_action.go | 3 + sing-box/route/rule/rule_set_remote.go | 23 +-- sing-box/transport/wireguard/endpoint.go | 14 +- small/naiveproxy/Makefile | 44 +++--- v2ray-core/core.go | 2 +- v2ray-core/go.mod | 26 +-- v2ray-core/go.sum | 70 ++++---- .../v2ray/ang/handler/UpdateCheckerManager.kt | 3 +- .../java/com/v2ray/ang/ui/AboutActivity.kt | 4 +- .../java/com/v2ray/ang/ui/MainActivity.kt | 137 +--------------- .../app/src/main/res/menu/menu_main.xml | 23 --- .../app/src/main/res/values-ar/strings.xml | 5 - .../app/src/main/res/values-bn/strings.xml | 5 - .../src/main/res/values-bqi-rIR/strings.xml | 45 +++--- .../app/src/main/res/values-fa/strings.xml | 5 - .../app/src/main/res/values-ru/strings.xml | 5 - .../app/src/main/res/values-vi/strings.xml | 5 - .../src/main/res/values-zh-rCN/strings.xml | 5 - .../src/main/res/values-zh-rTW/strings.xml | 5 - .../app/src/main/res/values/strings.xml | 5 - yt-dlp/yt_dlp/extractor/_extractors.py | 4 + yt-dlp/yt_dlp/extractor/agora.py | 27 ++-- yt-dlp/yt_dlp/extractor/common.py | 2 + yt-dlp/yt_dlp/extractor/mixcloud.py | 73 ++++----- yt-dlp/yt_dlp/extractor/parti.py | 101 ++++++++++++ yt-dlp/yt_dlp/extractor/yandexvideo.py | 149 ++++++++++-------- 62 files changed, 526 insertions(+), 581 deletions(-) create mode 100644 yt-dlp/yt_dlp/extractor/parti.py diff --git a/.github/update.log b/.github/update.log index 21dd343471..372c51de40 100644 --- a/.github/update.log +++ b/.github/update.log @@ -964,3 +964,4 @@ Update On Wed Apr 2 20:37:16 CEST 2025 Update On Thu Apr 3 20:36:49 CEST 2025 Update On Fri Apr 4 20:36:13 CEST 2025 Update On Sat Apr 5 20:32:49 CEST 2025 +Update On Sun Apr 6 20:34:52 CEST 2025 diff --git a/clash-meta/listener/sing_shadowsocks/server.go b/clash-meta/listener/sing_shadowsocks/server.go index 7ce1d4e916..fe934ee6bd 100644 --- a/clash-meta/listener/sing_shadowsocks/server.go +++ b/clash-meta/listener/sing_shadowsocks/server.go @@ -196,7 +196,7 @@ func (l *Listener) HandleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbou ctx := sing.WithAdditions(context.TODO(), additions...) err := l.service.NewConnection(ctx, conn, M.Metadata{ Protocol: "shadowsocks", - Source: M.ParseSocksaddr(conn.RemoteAddr().String()), + Source: M.SocksaddrFromNet(conn.RemoteAddr()), }) if err != nil { _ = conn.Close() diff --git a/clash-meta/listener/sing_vless/server.go b/clash-meta/listener/sing_vless/server.go index f1d5a8f956..0614e4e622 100644 --- a/clash-meta/listener/sing_vless/server.go +++ b/clash-meta/listener/sing_vless/server.go @@ -201,7 +201,7 @@ func (l *Listener) HandleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbou ctx := sing.WithAdditions(context.TODO(), additions...) err := l.service.NewConnection(ctx, conn, metadata.Metadata{ Protocol: "vless", - Source: metadata.ParseSocksaddr(conn.RemoteAddr().String()), + Source: metadata.SocksaddrFromNet(conn.RemoteAddr()), }) if err != nil { _ = conn.Close() diff --git a/clash-meta/listener/sing_vmess/server.go b/clash-meta/listener/sing_vmess/server.go index 4e887a119a..dd8f32af94 100644 --- a/clash-meta/listener/sing_vmess/server.go +++ b/clash-meta/listener/sing_vmess/server.go @@ -187,7 +187,7 @@ func (l *Listener) HandleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbou ctx := sing.WithAdditions(context.TODO(), additions...) err := l.service.NewConnection(ctx, conn, metadata.Metadata{ Protocol: "vmess", - Source: metadata.ParseSocksaddr(conn.RemoteAddr().String()), + Source: metadata.SocksaddrFromNet(conn.RemoteAddr()), }) if err != nil { _ = conn.Close() diff --git a/clash-meta/transport/gun/server.go b/clash-meta/transport/gun/server.go index f4f6e94839..953c487816 100644 --- a/clash-meta/transport/gun/server.go +++ b/clash-meta/transport/gun/server.go @@ -58,6 +58,7 @@ func NewServerHandler(options ServerOption) http.Handler { }, writer: writer, } + _ = conn.Init() wrapper := &h2ConnWrapper{ // gun.Conn can't correct handle ReadDeadline diff --git a/clash-meta/transport/socks5/socks5.go b/clash-meta/transport/socks5/socks5.go index 61b555f4fe..5f699bb03e 100644 --- a/clash-meta/transport/socks5/socks5.go +++ b/clash-meta/transport/socks5/socks5.go @@ -189,7 +189,7 @@ func ServerHandshake(rw net.Conn, authenticator auth.Authenticator) (addr Addr, switch command { case CmdConnect, CmdUDPAssociate: // Acquire server listened address info - localAddr := ParseAddr(rw.LocalAddr().String()) + localAddr := ParseAddrToSocksAddr(rw.LocalAddr()) if localAddr == nil { err = ErrAddressNotSupported } else { @@ -414,12 +414,15 @@ func ParseAddr(s string) Addr { func ParseAddrToSocksAddr(addr net.Addr) Addr { var hostip net.IP var port int - if udpaddr, ok := addr.(*net.UDPAddr); ok { - hostip = udpaddr.IP - port = udpaddr.Port - } else if tcpaddr, ok := addr.(*net.TCPAddr); ok { - hostip = tcpaddr.IP - port = tcpaddr.Port + switch addr := addr.(type) { + case *net.UDPAddr: + hostip = addr.IP + port = addr.Port + case *net.TCPAddr: + hostip = addr.IP + port = addr.Port + case nil: + return nil } // fallback parse diff --git a/clash-nyanpasu/backend/Cargo.lock b/clash-nyanpasu/backend/Cargo.lock index 39092898da..7da60e577d 100644 --- a/clash-nyanpasu/backend/Cargo.lock +++ b/clash-nyanpasu/backend/Cargo.lock @@ -1458,9 +1458,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.34" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", "clap_derive", @@ -1468,9 +1468,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.34" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstream", "anstyle", @@ -1681,7 +1681,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -2011,9 +2011,9 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.5" +version = "3.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c" dependencies = [ "nix 0.29.0", "windows-sys 0.59.0", @@ -2831,7 +2831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -4899,7 +4899,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -7272,7 +7272,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -7868,7 +7868,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -7881,7 +7881,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.3", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -9501,7 +9501,7 @@ dependencies = [ "getrandom 0.3.2", "once_cell", "rustix 1.0.3", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -11125,7 +11125,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index 853dbd58db..d41ecdd82f 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.4", - "mihomo_alpha": "alpha-190047c", + "mihomo_alpha": "alpha-2a08c44", "clash_rs": "v0.7.6", "clash_premium": "2023-09-05-gdcc8d87", "clash_rs_alpha": "0.7.6-alpha+sha.5af4aa5" @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-04-04T22:20:45.107Z" + "updated_at": "2025-04-05T22:20:47.286Z" } diff --git a/mihomo/listener/sing_shadowsocks/server.go b/mihomo/listener/sing_shadowsocks/server.go index 7ce1d4e916..fe934ee6bd 100644 --- a/mihomo/listener/sing_shadowsocks/server.go +++ b/mihomo/listener/sing_shadowsocks/server.go @@ -196,7 +196,7 @@ func (l *Listener) HandleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbou ctx := sing.WithAdditions(context.TODO(), additions...) err := l.service.NewConnection(ctx, conn, M.Metadata{ Protocol: "shadowsocks", - Source: M.ParseSocksaddr(conn.RemoteAddr().String()), + Source: M.SocksaddrFromNet(conn.RemoteAddr()), }) if err != nil { _ = conn.Close() diff --git a/mihomo/listener/sing_vless/server.go b/mihomo/listener/sing_vless/server.go index f1d5a8f956..0614e4e622 100644 --- a/mihomo/listener/sing_vless/server.go +++ b/mihomo/listener/sing_vless/server.go @@ -201,7 +201,7 @@ func (l *Listener) HandleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbou ctx := sing.WithAdditions(context.TODO(), additions...) err := l.service.NewConnection(ctx, conn, metadata.Metadata{ Protocol: "vless", - Source: metadata.ParseSocksaddr(conn.RemoteAddr().String()), + Source: metadata.SocksaddrFromNet(conn.RemoteAddr()), }) if err != nil { _ = conn.Close() diff --git a/mihomo/listener/sing_vmess/server.go b/mihomo/listener/sing_vmess/server.go index 4e887a119a..dd8f32af94 100644 --- a/mihomo/listener/sing_vmess/server.go +++ b/mihomo/listener/sing_vmess/server.go @@ -187,7 +187,7 @@ func (l *Listener) HandleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbou ctx := sing.WithAdditions(context.TODO(), additions...) err := l.service.NewConnection(ctx, conn, metadata.Metadata{ Protocol: "vmess", - Source: metadata.ParseSocksaddr(conn.RemoteAddr().String()), + Source: metadata.SocksaddrFromNet(conn.RemoteAddr()), }) if err != nil { _ = conn.Close() diff --git a/mihomo/transport/gun/server.go b/mihomo/transport/gun/server.go index f4f6e94839..953c487816 100644 --- a/mihomo/transport/gun/server.go +++ b/mihomo/transport/gun/server.go @@ -58,6 +58,7 @@ func NewServerHandler(options ServerOption) http.Handler { }, writer: writer, } + _ = conn.Init() wrapper := &h2ConnWrapper{ // gun.Conn can't correct handle ReadDeadline diff --git a/mihomo/transport/socks5/socks5.go b/mihomo/transport/socks5/socks5.go index 61b555f4fe..5f699bb03e 100644 --- a/mihomo/transport/socks5/socks5.go +++ b/mihomo/transport/socks5/socks5.go @@ -189,7 +189,7 @@ func ServerHandshake(rw net.Conn, authenticator auth.Authenticator) (addr Addr, switch command { case CmdConnect, CmdUDPAssociate: // Acquire server listened address info - localAddr := ParseAddr(rw.LocalAddr().String()) + localAddr := ParseAddrToSocksAddr(rw.LocalAddr()) if localAddr == nil { err = ErrAddressNotSupported } else { @@ -414,12 +414,15 @@ func ParseAddr(s string) Addr { func ParseAddrToSocksAddr(addr net.Addr) Addr { var hostip net.IP var port int - if udpaddr, ok := addr.(*net.UDPAddr); ok { - hostip = udpaddr.IP - port = udpaddr.Port - } else if tcpaddr, ok := addr.(*net.TCPAddr); ok { - hostip = tcpaddr.IP - port = tcpaddr.Port + switch addr := addr.(type) { + case *net.UDPAddr: + hostip = addr.IP + port = addr.Port + case *net.TCPAddr: + hostip = addr.IP + port = addr.Port + case nil: + return nil } // fallback parse diff --git a/naiveproxy/README.md b/naiveproxy/README.md index 877666df1a..6a334c7f3d 100644 --- a/naiveproxy/README.md +++ b/naiveproxy/README.md @@ -21,7 +21,7 @@ The Naïve server here works as a forward proxy and a packet length padding laye ## Download NaïveProxy -Download [here](https://github.com/klzgrad/naiveproxy/releases/latest). Supported platforms include: Windows, Android (with [Exclave](https://github.com/dyhkwong/Exclave), [NekoBox](https://github.com/MatsuriDayo/NekoBoxForAndroid)), Linux, Mac OS, and OpenWrt ([support status](https://github.com/klzgrad/naiveproxy/wiki/OpenWrt-Support)). +Download [here](https://github.com/klzgrad/naiveproxy/releases/latest). Supported platforms include: Windows, Android (with [Exclave](https://github.com/dyhkwong/Exclave), [husi](https://github.com/xchacha20-poly1305/husi), [NekoBox](https://github.com/MatsuriDayo/NekoBoxForAndroid)), Linux, Mac OS, and OpenWrt ([support status](https://github.com/klzgrad/naiveproxy/wiki/OpenWrt-Support)). Users should always use the latest version to keep signatures identical to Chrome. @@ -79,9 +79,7 @@ Or `quic://user:pass@example.com`, if it works better. See also [parameter usage ## Third-party integration -* [v2rayN](https://github.com/2dust/v2rayN), GUI client, Windows -* [NekoBox for Android](https://github.com/MatsuriDayo/NekoBoxForAndroid), Proxy toolchain, Android -* [NekoRay / NekoBox For PC](https://github.com/MatsuriDayo/nekoray), Qt based GUI, Windows, Linux +* [v2rayN](https://github.com/2dust/v2rayN), GUI client ## Notes for downstream diff --git a/openwrt-packages/luci-app-lucky/lucky/Makefile b/openwrt-packages/luci-app-lucky/lucky/Makefile index 67569df632..9319f55bb1 100644 --- a/openwrt-packages/luci-app-lucky/lucky/Makefile +++ b/openwrt-packages/luci-app-lucky/lucky/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=lucky -PKG_VERSION:=2.15.8 +PKG_VERSION:=2.15.10 PKG_RELEASE:=1 ifeq ($(ARCH),mipsel) @@ -17,50 +17,51 @@ endif ifeq ($(ARCH),mips) LUCKY_ARCH:=mips_softfloat endif -ifeq ($(ARCH),arm) - LUCKY_ARCH:=armv5 -endif -ifeq ($(BOARD),kirkwood) - LUCKY_ARCH:=armv5 -endif -ifeq ($(ARCH),armv7) - LUCKY_ARCH:=armv7 -endif -ifeq ($(ARCH),aarch64) - LUCKY_ARCH:=arm64 -endif -ifeq ($(ARCH),arm64) - LUCKY_ARCH:=arm64 -endif -ifeq ($(ARCH),armv8) - LUCKY_ARCH:=arm64 -endif ifeq ($(ARCH),i386) LUCKY_ARCH:=i386 endif ifeq ($(ARCH),x86_64) LUCKY_ARCH:=x86_64 endif +ifeq ($(ARCH),arm) + ifeq ($(BOARD),bcm53xx) + LUCKY_ARCH:=armv6 + else + LUCKY_ARCH:=armv7 +endif +endif +ifeq ($(BOARD),bcm53xx) + LUCKY_ARCH:=armv6 +ifeq ($(word 2,$(subst +,$(space),$(call qstrip,$(CONFIG_CPU_TYPE)))),) + LUCKY_ARCH:=armv5 +endif +endif +ifeq ($(BOARD),kirkwood) + LUCKY_ARCH:=armv5 +endif +ifeq ($(ARCH),aarch64) + LUCKY_ARCH:=arm64 +endif PKG_LICENSE:=GPL-3.0-only PKG_LICENSE_FILES:=LICENSE PKG_MAINTAINER:=GDY666 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=3626928d4a45ae606856b834614e45997b5da235 +PKG_HASH:=skip include $(INCLUDE_DIR)/package.mk define Package/$(PKG_NAME) SECTION:=net CATEGORY:=Network - TITLE:=Lucky dynamic domain name ddns-go service, socat,frp + TITLE:=Lucky gdy DEPENDS:=@(i386||x86_64||arm||aarch64||mipsel||mips) URL:=https://github.com/gdy666/lucky endef define Package/$(PKG_NAME)/description - Main functions of Lucky: dynamic domain name ddns-go service, socat,reverse proxy ,wake on lan + Main functions of Lucky: ipv4/ipv6 portforward,ddns,IOT wake on lan ,reverse proxy and more... endef define Build/Prepare diff --git a/shadowsocks-rust/.github/workflows/clippy-check.yml b/shadowsocks-rust/.github/workflows/clippy-check.yml index 1f8dbc177b..4ae180ecc9 100644 --- a/shadowsocks-rust/.github/workflows/clippy-check.yml +++ b/shadowsocks-rust/.github/workflows/clippy-check.yml @@ -21,10 +21,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - if: ${{ runner.os == 'Windows' }} uses: ilammy/setup-nasm@v1 - - name: Install Protoc - uses: arduino/setup-protoc@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install Rust run: | rustup set profile minimal diff --git a/shadowsocks-rust/Cargo.lock b/shadowsocks-rust/Cargo.lock index b2e71eab9f..36ef0fb394 100644 --- a/shadowsocks-rust/Cargo.lock +++ b/shadowsocks-rust/Cargo.lock @@ -846,9 +846,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -2380,9 +2380,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ "bitflags 2.9.0", "cfg-if", @@ -2421,9 +2421,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" dependencies = [ "cc", "libc", diff --git a/shadowsocks-rust/crates/shadowsocks/src/relay/socks5.rs b/shadowsocks-rust/crates/shadowsocks/src/relay/socks5.rs index 000cc79739..8ccb2b7a46 100644 --- a/shadowsocks-rust/crates/shadowsocks/src/relay/socks5.rs +++ b/shadowsocks-rust/crates/shadowsocks/src/relay/socks5.rs @@ -478,7 +478,7 @@ fn write_domain_name_address(dnaddr: &str, port: u16, buf: &mut B) { "domain name length must be smaller than 256" ); buf.put_u8(dnaddr.len() as u8); - buf.put_slice(dnaddr[..].as_bytes()); + buf.put_slice(dnaddr.as_bytes()); buf.put_u16(port); } @@ -837,7 +837,7 @@ impl UdpAssociateHeader { } } -/// Username/Password Authentication Inittial Negociation +/// Username/Password Authentication Initial Negotiation /// /// https://datatracker.ietf.org/doc/html/rfc1929 /// @@ -880,7 +880,7 @@ impl PasswdAuthRequest { let mut ver_buf = [0u8; 1]; let _ = r.read_exact(&mut ver_buf).await?; - // The only valid subnegociation version + // The only valid subnegotiation version if ver_buf[0] != 0x01 { return Err(Error::UnsupportedPasswdAuthVersion(ver_buf[0])); } diff --git a/sing-box/.github/workflows/lint.yml b/sing-box/.github/workflows/lint.yml index 022e46640a..7946d82a5c 100644 --- a/sing-box/.github/workflows/lint.yml +++ b/sing-box/.github/workflows/lint.yml @@ -30,7 +30,7 @@ jobs: with: go-version: ^1.24.2 - name: golangci-lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v7 with: version: latest args: --timeout=30m diff --git a/sing-box/adapter/router.go b/sing-box/adapter/router.go index b82cb5d8f2..0b7c8f4f74 100644 --- a/sing-box/adapter/router.go +++ b/sing-box/adapter/router.go @@ -24,7 +24,7 @@ type Router interface { RuleSet(tag string) (RuleSet, bool) NeedWIFIState() bool Rules() []Rule - SetTracker(tracker ConnectionTracker) + AppendTracker(tracker ConnectionTracker) ResetNetwork() } diff --git a/sing-box/box.go b/sing-box/box.go index 0f176474fc..db900a7a46 100644 --- a/sing-box/box.go +++ b/sing-box/box.go @@ -314,7 +314,7 @@ func New(options Options) (*Box, error) { if err != nil { return nil, E.Cause(err, "create clash-server") } - router.SetTracker(clashServer) + router.AppendTracker(clashServer) service.MustRegister[adapter.ClashServer](ctx, clashServer) services = append(services, clashServer) } @@ -324,7 +324,7 @@ func New(options Options) (*Box, error) { return nil, E.Cause(err, "create v2ray-server") } if v2rayServer.StatsService() != nil { - router.SetTracker(v2rayServer.StatsService()) + router.AppendTracker(v2rayServer.StatsService()) services = append(services, v2rayServer) service.MustRegister[adapter.V2RayServer](ctx, v2rayServer) } diff --git a/sing-box/common/sniff/bittorrent.go b/sing-box/common/sniff/bittorrent.go index 9fa7d8b84a..39c1959812 100644 --- a/sing-box/common/sniff/bittorrent.go +++ b/sing-box/common/sniff/bittorrent.go @@ -68,7 +68,9 @@ func UTP(_ context.Context, metadata *adapter.InboundContext, packet []byte) err if err != nil { return err } - + if extension > 0x04 { + return os.ErrInvalid + } var length byte err = binary.Read(reader, binary.BigEndian, &length) if err != nil { diff --git a/sing-box/common/sniff/bittorrent_test.go b/sing-box/common/sniff/bittorrent_test.go index 65f095bdac..f4762e3233 100644 --- a/sing-box/common/sniff/bittorrent_test.go +++ b/sing-box/common/sniff/bittorrent_test.go @@ -71,3 +71,19 @@ func TestSniffUDPTracker(t *testing.T) { require.Equal(t, C.ProtocolBitTorrent, metadata.Protocol) } } + +func TestSniffNotUTP(t *testing.T) { + t.Parallel() + + packets := []string{ + "0102736470696e674958d580121500000000000079aaed6717a39c27b07c0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + } + for _, pkt := range packets { + pkt, err := hex.DecodeString(pkt) + require.NoError(t, err) + + var metadata adapter.InboundContext + err = sniff.UTP(context.TODO(), &metadata, pkt) + require.Error(t, err) + } +} diff --git a/sing-box/common/tls/ech.go b/sing-box/common/tls/ech.go index 880ca27ca3..ddb9b5dda1 100644 --- a/sing-box/common/tls/ech.go +++ b/sing-box/common/tls/ech.go @@ -123,6 +123,7 @@ func (s *STDECHClientConfig) ClientHandshake(ctx context.Context, conn net.Conn) if response.Rcode != mDNS.RcodeSuccess { return nil, E.Cause(dns.RcodeError(response.Rcode), "fetch ECH config list") } + match: for _, rr := range response.Answer { switch resource := rr.(type) { case *mDNS.HTTPS: @@ -133,11 +134,14 @@ func (s *STDECHClientConfig) ClientHandshake(ctx context.Context, conn net.Conn) return nil, E.Cause(err, "decode ECH config") } s.config.EncryptedClientHelloConfigList = echConfigList + break match } } } } - return nil, E.New("no ECH config found in DNS records") + if len(s.config.EncryptedClientHelloConfigList) == 0 { + return nil, E.New("no ECH config found in DNS records") + } } tlsConn, err := s.Client(conn) if err != nil { diff --git a/sing-box/constant/protocol.go b/sing-box/constant/protocol.go index 6d6471695a..dbe16e51c4 100644 --- a/sing-box/constant/protocol.go +++ b/sing-box/constant/protocol.go @@ -11,7 +11,6 @@ const ( ProtocolSSH = "ssh" ProtocolRDP = "rdp" ProtocolNTP = "ntp" - ProtocolMTProto = "mtproto" ) const ( diff --git a/sing-box/dns/transport/udp.go b/sing-box/dns/transport/udp.go index 8d9f0515da..ec17c71b7d 100644 --- a/sing-box/dns/transport/udp.go +++ b/sing-box/dns/transport/udp.go @@ -212,8 +212,8 @@ type dnsConnection struct { func (c *dnsConnection) Close(err error) { c.closeOnce.Do(func() { - close(c.done) c.err = err + close(c.done) }) c.Conn.Close() } diff --git a/sing-box/docs/configuration/route/sniff.md b/sing-box/docs/configuration/route/sniff.md index 23067dfb54..0fb386f750 100644 --- a/sing-box/docs/configuration/route/sniff.md +++ b/sing-box/docs/configuration/route/sniff.md @@ -26,7 +26,7 @@ If enabled in the inbound, the protocol and domain name (if present) of by the c | QUIC Client | Type | |:------------------------:|:----------:| -| Chromium/Cronet | `chrimium` | +| Chromium/Cronet | `chromium` | | Safari/Apple Network API | `safari` | | Firefox / uquic firefox | `firefox` | -| quic-go / uquic chrome | `quic-go` | \ No newline at end of file +| quic-go / uquic chrome | `quic-go` | diff --git a/sing-box/experimental/libbox/service.go b/sing-box/experimental/libbox/service.go index 00b36237ab..48d614ff0d 100644 --- a/sing-box/experimental/libbox/service.go +++ b/sing-box/experimental/libbox/service.go @@ -39,7 +39,7 @@ type BoxService struct { clashServer adapter.ClashServer pauseManager pause.Manager - servicePauseFields + iOSPauseFields } func NewService(configContent string, platformInterface PlatformInterface) (*BoxService, error) { diff --git a/sing-box/experimental/libbox/service_pause.go b/sing-box/experimental/libbox/service_pause.go index 0fa9541f19..791684ecd4 100644 --- a/sing-box/experimental/libbox/service_pause.go +++ b/sing-box/experimental/libbox/service_pause.go @@ -1,31 +1,33 @@ package libbox import ( - "sync" "time" + + C "github.com/sagernet/sing-box/constant" ) -type servicePauseFields struct { - pauseAccess sync.Mutex - pauseTimer *time.Timer +type iOSPauseFields struct { + endPauseTimer *time.Timer } func (s *BoxService) Pause() { - s.pauseAccess.Lock() - defer s.pauseAccess.Unlock() - if s.pauseTimer != nil { - s.pauseTimer.Stop() + s.pauseManager.DevicePause() + if !C.IsIos { + s.instance.Router().ResetNetwork() + } else { + if s.endPauseTimer == nil { + s.endPauseTimer = time.AfterFunc(time.Minute, s.pauseManager.DeviceWake) + } else { + s.endPauseTimer.Reset(time.Minute) + } } - s.pauseTimer = time.AfterFunc(3*time.Second, s.ResetNetwork) } func (s *BoxService) Wake() { - s.pauseAccess.Lock() - defer s.pauseAccess.Unlock() - if s.pauseTimer != nil { - s.pauseTimer.Stop() + if !C.IsIos { + s.pauseManager.DeviceWake() + s.instance.Router().ResetNetwork() } - s.pauseTimer = time.AfterFunc(3*time.Minute, s.ResetNetwork) } func (s *BoxService) ResetNetwork() { diff --git a/sing-box/go.mod b/sing-box/go.mod index 8a2ca284c5..9b17432124 100644 --- a/sing-box/go.mod +++ b/sing-box/go.mod @@ -9,7 +9,7 @@ require ( github.com/cretz/bine v0.2.0 github.com/go-chi/chi/v5 v5.2.1 github.com/go-chi/render v1.0.3 - github.com/gofrs/uuid/v5 v5.3.1 + github.com/gofrs/uuid/v5 v5.3.2 github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 github.com/libdns/alidns v1.0.3 github.com/libdns/cloudflare v0.1.1 @@ -26,9 +26,9 @@ require ( github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb github.com/sagernet/quic-go v0.49.0-beta.1 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 - github.com/sagernet/sing v0.6.6-0.20250403102645-159e489fc399 + github.com/sagernet/sing v0.6.6-0.20250406122223-d47540857e58 github.com/sagernet/sing-mux v0.3.1 - github.com/sagernet/sing-quic v0.4.1-beta.1 + github.com/sagernet/sing-quic v0.4.1 github.com/sagernet/sing-shadowsocks v0.2.7 github.com/sagernet/sing-shadowsocks2 v0.2.0 github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056 diff --git a/sing-box/go.sum b/sing-box/go.sum index 9ab2098570..ecb7b612ef 100644 --- a/sing-box/go.sum +++ b/sing-box/go.sum @@ -66,8 +66,8 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU= -github.com/gofrs/uuid/v5 v5.3.1 h1:aPx49MwJbekCzOyhZDjJVb0hx3A0KLjlbLx6p2gY0p0= -github.com/gofrs/uuid/v5 v5.3.1/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0= +github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -178,12 +178,12 @@ github.com/sagernet/quic-go v0.49.0-beta.1/go.mod h1:uesWD1Ihrldq1M3XtjuEvIUqi8W github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo= -github.com/sagernet/sing v0.6.6-0.20250403102645-159e489fc399 h1:jQ5sGyxICxdPqoakOEE6TbSTYOf/grmt31e/ad749O4= -github.com/sagernet/sing v0.6.6-0.20250403102645-159e489fc399/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.6.6-0.20250406122223-d47540857e58 h1:hq0W1/K6/UOrv+tCm9YrZ/yDFZJlPVtLmBvayuwUxDM= +github.com/sagernet/sing v0.6.6-0.20250406122223-d47540857e58/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing-mux v0.3.1 h1:kvCc8HyGAskDHDQ0yQvoTi/7J4cZPB/VJMsAM3MmdQI= github.com/sagernet/sing-mux v0.3.1/go.mod h1:Mkdz8LnDstthz0HWuA/5foncnDIdcNN5KZ6AdJX+x78= -github.com/sagernet/sing-quic v0.4.1-beta.1 h1:V2VfMckT3EQR3ZdfSzJgZZDsvfZZH42QAZpnOnHKa0s= -github.com/sagernet/sing-quic v0.4.1-beta.1/go.mod h1:c+CytOEyeN20KCTFIP8YQUkNDVFLSzjrEPqP7Hlnxys= +github.com/sagernet/sing-quic v0.4.1 h1:pxlMa4efZu/M07RgGagNNDDyl6ZUwpmNUjRTpgHOWK4= +github.com/sagernet/sing-quic v0.4.1/go.mod h1:tqPa0/Wqa19MkkSlKVZZX5sHxtiDR9BROcn4ufcbVdY= github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8= github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg= diff --git a/sing-box/protocol/group/urltest.go b/sing-box/protocol/group/urltest.go index 0ebdc1ca28..05e7b9a639 100644 --- a/sing-box/protocol/group/urltest.go +++ b/sing-box/protocol/group/urltest.go @@ -19,6 +19,7 @@ import ( E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" + "github.com/sagernet/sing/common/x/list" "github.com/sagernet/sing/service" "github.com/sagernet/sing/service/pause" ) @@ -27,10 +28,7 @@ func RegisterURLTest(registry *outbound.Registry) { outbound.Register[option.URLTestOutboundOptions](registry, C.TypeURLTest, NewURLTest) } -var ( - _ adapter.OutboundGroup = (*URLTest)(nil) - _ adapter.InterfaceUpdateListener = (*URLTest)(nil) -) +var _ adapter.OutboundGroup = (*URLTest)(nil) type URLTest struct { outbound.Adapter @@ -172,15 +170,12 @@ func (s *URLTest) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, s.connection.NewPacketConnection(ctx, s, conn, metadata, onClose) } -func (s *URLTest) InterfaceUpdated() { - go s.group.CheckOutbounds(true) - return -} - type URLTestGroup struct { ctx context.Context router adapter.Router - outboundManager adapter.OutboundManager + outbound adapter.OutboundManager + pause pause.Manager + pauseCallback *list.Element[pause.Callback] logger log.Logger outbounds []adapter.Outbound link string @@ -189,17 +184,15 @@ type URLTestGroup struct { idleTimeout time.Duration history adapter.URLTestHistoryStorage checking atomic.Bool - pauseManager pause.Manager selectedOutboundTCP adapter.Outbound selectedOutboundUDP adapter.Outbound interruptGroup *interrupt.Group interruptExternalConnections bool - - access sync.Mutex - ticker *time.Ticker - close chan struct{} - started bool - lastActive atomic.TypedValue[time.Time] + access sync.Mutex + ticker *time.Ticker + close chan struct{} + started bool + lastActive atomic.TypedValue[time.Time] } func NewURLTestGroup(ctx context.Context, outboundManager adapter.OutboundManager, logger log.Logger, outbounds []adapter.Outbound, link string, interval time.Duration, tolerance uint16, idleTimeout time.Duration, interruptExternalConnections bool) (*URLTestGroup, error) { @@ -225,7 +218,7 @@ func NewURLTestGroup(ctx context.Context, outboundManager adapter.OutboundManage } return &URLTestGroup{ ctx: ctx, - outboundManager: outboundManager, + outbound: outboundManager, logger: logger, outbounds: outbounds, link: link, @@ -234,13 +227,15 @@ func NewURLTestGroup(ctx context.Context, outboundManager adapter.OutboundManage idleTimeout: idleTimeout, history: history, close: make(chan struct{}), - pauseManager: service.FromContext[pause.Manager](ctx), + pause: service.FromContext[pause.Manager](ctx), interruptGroup: interrupt.NewGroup(), interruptExternalConnections: interruptExternalConnections, }, nil } func (g *URLTestGroup) PostStart() { + g.access.Lock() + defer g.access.Unlock() g.started = true g.lastActive.Store(time.Now()) go g.CheckOutbounds(false) @@ -250,24 +245,25 @@ func (g *URLTestGroup) Touch() { if !g.started { return } + g.access.Lock() + defer g.access.Unlock() if g.ticker != nil { g.lastActive.Store(time.Now()) return } - g.access.Lock() - defer g.access.Unlock() - if g.ticker != nil { - return - } g.ticker = time.NewTicker(g.interval) go g.loopCheck() + g.pauseCallback = pause.RegisterTicker(g.pause, g.ticker, g.interval, nil) } func (g *URLTestGroup) Close() error { + g.access.Lock() + defer g.access.Unlock() if g.ticker == nil { return nil } g.ticker.Stop() + g.pause.UnregisterCallback(g.pauseCallback) close(g.close) return nil } @@ -331,10 +327,11 @@ func (g *URLTestGroup) loopCheck() { g.access.Lock() g.ticker.Stop() g.ticker = nil + g.pause.UnregisterCallback(g.pauseCallback) + g.pauseCallback = nil g.access.Unlock() return } - g.pauseManager.WaitActive() g.CheckOutbounds(false) } } @@ -367,7 +364,7 @@ func (g *URLTestGroup) urlTest(ctx context.Context, force bool) (map[string]uint continue } checked[realTag] = true - p, loaded := g.outboundManager.Outbound(realTag) + p, loaded := g.outbound.Outbound(realTag) if !loaded { continue } diff --git a/sing-box/protocol/wireguard/endpoint.go b/sing-box/protocol/wireguard/endpoint.go index e167bec166..dc315801f1 100644 --- a/sing-box/protocol/wireguard/endpoint.go +++ b/sing-box/protocol/wireguard/endpoint.go @@ -129,7 +129,6 @@ func (w *Endpoint) Close() error { func (w *Endpoint) InterfaceUpdated() { w.endpoint.BindUpdate() - return } func (w *Endpoint) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr) error { diff --git a/sing-box/protocol/wireguard/outbound.go b/sing-box/protocol/wireguard/outbound.go index edd8184c03..2591bd2953 100644 --- a/sing-box/protocol/wireguard/outbound.go +++ b/sing-box/protocol/wireguard/outbound.go @@ -133,7 +133,6 @@ func (o *Outbound) Close() error { func (o *Outbound) InterfaceUpdated() { o.endpoint.BindUpdate() - return } func (o *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { diff --git a/sing-box/route/route.go b/sing-box/route/route.go index 8de36897b2..50c38201e5 100644 --- a/sing-box/route/route.go +++ b/sing-box/route/route.go @@ -59,10 +59,6 @@ func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata } func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error { - if r.pauseManager.IsDevicePaused() { - return E.New("reject connection to ", metadata.Destination, " while device paused") - } - //nolint:staticcheck if metadata.InboundDetour != "" { if metadata.LastInbound == metadata.InboundDetour { @@ -139,8 +135,8 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad for _, buffer := range buffers { conn = bufio.NewCachedConn(conn, buffer) } - if r.tracker != nil { - conn = r.tracker.RoutedConnection(ctx, conn, metadata, selectedRule, selectedOutbound) + for _, tracker := range r.trackers { + conn = tracker.RoutedConnection(ctx, conn, metadata, selectedRule, selectedOutbound) } if outboundHandler, isHandler := selectedOutbound.(adapter.ConnectionHandlerEx); isHandler { outboundHandler.NewConnectionEx(ctx, conn, metadata, onClose) @@ -185,9 +181,6 @@ func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, } func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error { - if r.pauseManager.IsDevicePaused() { - return E.New("reject packet connection to ", metadata.Destination, " while device paused") - } //nolint:staticcheck if metadata.InboundDetour != "" { if metadata.LastInbound == metadata.InboundDetour { @@ -257,8 +250,8 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m conn = bufio.NewCachedPacketConn(conn, buffer.Buffer, buffer.Destination) N.PutPacketBuffer(buffer) } - if r.tracker != nil { - conn = r.tracker.RoutedPacketConnection(ctx, conn, metadata, selectedRule, selectedOutbound) + for _, tracker := range r.trackers { + conn = tracker.RoutedPacketConnection(ctx, conn, metadata, selectedRule, selectedOutbound) } if metadata.FakeIP { conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), metadata.OriginDestination, metadata.Destination) diff --git a/sing-box/route/router.go b/sing-box/route/router.go index 8961044526..ae2ecb5502 100644 --- a/sing-box/route/router.go +++ b/sing-box/route/router.go @@ -36,7 +36,7 @@ type Router struct { ruleSetMap map[string]adapter.RuleSet processSearcher process.Searcher pauseManager pause.Manager - tracker adapter.ConnectionTracker + trackers []adapter.ConnectionTracker platformInterface platform.Interface needWIFIState bool started bool @@ -203,8 +203,8 @@ func (r *Router) Rules() []adapter.Rule { return r.rules } -func (r *Router) SetTracker(tracker adapter.ConnectionTracker) { - r.tracker = tracker +func (r *Router) AppendTracker(tracker adapter.ConnectionTracker) { + r.trackers = append(r.trackers, tracker) } func (r *Router) ResetNetwork() { diff --git a/sing-box/route/rule/rule_action.go b/sing-box/route/rule/rule_action.go index f49baca615..098b9d3ad6 100644 --- a/sing-box/route/rule/rule_action.go +++ b/sing-box/route/rule/rule_action.go @@ -305,6 +305,9 @@ func (r *RuleActionReject) Error(ctx context.Context) error { default: panic(F.ToString("unknown reject method: ", r.Method)) } + if r.NoDrop { + return returnErr + } r.dropAccess.Lock() defer r.dropAccess.Unlock() timeNow := time.Now() diff --git a/sing-box/route/rule/rule_set_remote.go b/sing-box/route/rule/rule_set_remote.go index 8e89285bf8..16a95bb645 100644 --- a/sing-box/route/rule/rule_set_remote.go +++ b/sing-box/route/rule/rule_set_remote.go @@ -105,7 +105,7 @@ func (s *RemoteRuleSet) StartContext(ctx context.Context, startContext *adapter. } } if s.lastUpdated.IsZero() { - err := s.fetchOnce(ctx, startContext) + err := s.fetch(ctx, startContext) if err != nil { return E.Cause(err, "initial rule-set: ", s.options.Tag) } @@ -200,7 +200,7 @@ func (s *RemoteRuleSet) loadBytes(content []byte) error { func (s *RemoteRuleSet) loopUpdate() { if time.Since(s.lastUpdated) > s.updateInterval { - err := s.fetchOnce(s.ctx, nil) + err := s.fetch(s.ctx, nil) if err != nil { s.logger.Error("fetch rule-set ", s.options.Tag, ": ", err) } else if s.refs.Load() == 0 { @@ -213,18 +213,21 @@ func (s *RemoteRuleSet) loopUpdate() { case <-s.ctx.Done(): return case <-s.updateTicker.C: - s.pauseManager.WaitActive() - err := s.fetchOnce(s.ctx, nil) - if err != nil { - s.logger.Error("fetch rule-set ", s.options.Tag, ": ", err) - } else if s.refs.Load() == 0 { - s.rules = nil - } + s.updateOnce() } } } -func (s *RemoteRuleSet) fetchOnce(ctx context.Context, startContext *adapter.HTTPStartContext) error { +func (s *RemoteRuleSet) updateOnce() { + err := s.fetch(s.ctx, nil) + if err != nil { + s.logger.Error("fetch rule-set ", s.options.Tag, ": ", err) + } else if s.refs.Load() == 0 { + s.rules = nil + } +} + +func (s *RemoteRuleSet) fetch(ctx context.Context, startContext *adapter.HTTPStartContext) error { s.logger.Debug("updating rule-set ", s.options.Tag, " from URL: ", s.options.RemoteOptions.URL) var httpClient *http.Client if startContext != nil { diff --git a/sing-box/transport/wireguard/endpoint.go b/sing-box/transport/wireguard/endpoint.go index 69ce917020..17a58a6ce3 100644 --- a/sing-box/transport/wireguard/endpoint.go +++ b/sing-box/transport/wireguard/endpoint.go @@ -30,7 +30,7 @@ type Endpoint struct { allowedAddress []netip.Prefix tunDevice Device device *device.Device - pauseManager pause.Manager + pause pause.Manager pauseCallback *list.Element[pause.Callback] } @@ -187,9 +187,9 @@ func (e *Endpoint) Start(resolve bool) error { return E.Cause(err, "setup wireguard: \n", ipcConf) } e.device = wgDevice - e.pauseManager = service.FromContext[pause.Manager](e.options.Context) - if e.pauseManager != nil { - e.pauseCallback = e.pauseManager.RegisterCallback(e.onPauseUpdated) + e.pause = service.FromContext[pause.Manager](e.options.Context) + if e.pause != nil { + e.pauseCallback = e.pause.RegisterCallback(e.onPauseUpdated) } return nil } @@ -217,16 +217,16 @@ func (e *Endpoint) Close() error { e.device.Close() } if e.pauseCallback != nil { - e.pauseManager.UnregisterCallback(e.pauseCallback) + e.pause.UnregisterCallback(e.pauseCallback) } return nil } func (e *Endpoint) onPauseUpdated(event int) { switch event { - case pause.EventDevicePaused: + case pause.EventDevicePaused, pause.EventNetworkPause: e.device.Down() - case pause.EventDeviceWake: + case pause.EventDeviceWake, pause.EventNetworkWake: e.device.Up() } } diff --git a/small/naiveproxy/Makefile b/small/naiveproxy/Makefile index bbeec57047..dd29c5a9cd 100644 --- a/small/naiveproxy/Makefile +++ b/small/naiveproxy/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=naiveproxy -PKG_VERSION:=135.0.7049.38-1 +PKG_VERSION:=135.0.7049.38-2 PKG_RELEASE:=1 # intel 80386 & riscv64 & cortex-a76 @@ -20,47 +20,47 @@ else ifeq ($(ARCH_PREBUILT),riscv64_riscv64) endif ifeq ($(ARCH_PACKAGES),aarch64_cortex-a53) - PKG_HASH:=7711d714d9cec37eac9048a59fc0d1fa7c7bc0a637018c9b2e419c43368e3c53 + PKG_HASH:=b8976be510c3e1de4e814cd0f0a5980efcb845473577546428b898d1bdeb079b else ifeq ($(ARCH_PACKAGES),aarch64_cortex-a72) - PKG_HASH:=44253ecd8cb7c62ffd948901a1191ca2c1b65430ec19253322c5935551e13b7c + PKG_HASH:=4d0a93b889ab1b88e8f1f343c4481e42596759d4fed8b1d6041a2eb86c783500 else ifeq ($(ARCH_PACKAGES),aarch64_generic) - PKG_HASH:=7ba36313b0485d0bbb7d95debcd90a8add2d6ae40e756c702542fc64dc1e9c12 + PKG_HASH:=77ffe91387a29aaac22433b71c06bac3dcd28aad31ef3697e443a89bc8714c16 else ifeq ($(ARCH_PACKAGES),arm_arm1176jzf-s_vfp) - PKG_HASH:=15e33c0368cf8adca8dade760e1d65307f93ea3a7f9e83aa6fe8ab6410578c0e + PKG_HASH:=cb6ae58df88efcae821fff18327e660e4590761a09a4ab9e34cdc297b67884e6 else ifeq ($(ARCH_PACKAGES),arm_arm926ej-s) - PKG_HASH:=c7cca2201b9a582fb674984cf9521c237fa9ff8f5e8fbe6323d4be34b684c85e + PKG_HASH:=129dc86a2eb9fd1d5421098795ffd534248a02a9ca1f4436e9f052960d52da0f else ifeq ($(ARCH_PACKAGES),arm_cortex-a15_neon-vfpv4) - PKG_HASH:=474e3227c6bb0271e4d9e9a11f02bbf3a96171abbfad710b764a4cbf01276c39 + PKG_HASH:=d0560697e7457bbd10e5e08421c49d554c8e4b6ca1f522a467093a791f9bee17 else ifeq ($(ARCH_PACKAGES),arm_cortex-a5_vfpv4) - PKG_HASH:=d8267795f9221e3c9ef1194f67b5c132e61236135ba9f5130666782e6cb3b00e + PKG_HASH:=8e1caa8f57c954942fbf37cb237392b59ca966f261d697d7ba08be313da4501b else ifeq ($(ARCH_PACKAGES),arm_cortex-a7) - PKG_HASH:=519d116bea3d19ef3f9da782d2066c09cb4b9fcc1494f9bc2450f65e5d5895b7 + PKG_HASH:=3facbd55aa8c29727ae1ade020e879eb39cd8c58d87cb4055ce228349b15a2c9 else ifeq ($(ARCH_PACKAGES),arm_cortex-a7_neon-vfpv4) - PKG_HASH:=e2d8748b13867f9c0f9007b4570bdf2466d4717ed5fe112cdd5c5745dd9cda88 + PKG_HASH:=cb7d2c068419b4f0ce301cd905fa20e28496c8ed96376b9104803623e580f570 else ifeq ($(ARCH_PACKAGES),arm_cortex-a7_vfpv4) - PKG_HASH:=ee74875fa83dac7b79ea2945ee3320bd1b5c974b38e528217e8db514dfd4f015 + PKG_HASH:=8675b1b6faef33386a074dcb37321ad85b465e596afcd3a9a8e56933b9490d82 else ifeq ($(ARCH_PACKAGES),arm_cortex-a8_vfpv3) - PKG_HASH:=415aa150b519949cd89b0c8c22ba10681de2bfcd78894830e270c83412f247a7 + PKG_HASH:=52183593d9b405bf1dd007f103cb3e1e63d48fe1bb614d369204febc1d6cb259 else ifeq ($(ARCH_PACKAGES),arm_cortex-a9) - PKG_HASH:=62c9b107c4cef346de3d7f81fc39e37356b7635b7c86c2e5628a7c79d852f6e7 + PKG_HASH:=3b2c6c1641ae99fcbfb53be82e024a94d767fe65f9f45ab549415c77ba191215 else ifeq ($(ARCH_PACKAGES),arm_cortex-a9_neon) - PKG_HASH:=8e7b251f880f7249138c93b623c82037ea03a4e91cfad0a127d2f0860363ade6 + PKG_HASH:=26ce98095902be58375a826b8603057b7eac6cf0e65d0cd53ff1119e7cb0570b else ifeq ($(ARCH_PACKAGES),arm_cortex-a9_vfpv3-d16) - PKG_HASH:=83a8f4333c8a0ce14348d461a6f1b2e55078a2afb5cfa937b5141dd58f700c1c + PKG_HASH:=336f183d639fb05d48107598717588752c98db764c5dbefb18fc643c9c33a7ba else ifeq ($(ARCH_PACKAGES),arm_mpcore) - PKG_HASH:=c9d88844b79d77ba387275f707896df6f0ddb109eed15461f169b4193f55f5ae + PKG_HASH:=7cb546a80eb7466e14ebd10f7172c25088a7242bd6b0c428e860f9d228f3a0ce else ifeq ($(ARCH_PACKAGES),arm_xscale) - PKG_HASH:=d27f2d18fd5ce59c78af7f879d300e0700de05672cfb6265d252a4a7197a4df1 + PKG_HASH:=e31d7b7b8e0e063e33d8208c3ca1f7c0588030dcabe1df28e4959a4968707520 else ifeq ($(ARCH_PACKAGES),mipsel_24kc) - PKG_HASH:=054b2e9989ae30fbfc2ca4f69e1df686433a604d0c55827e6eb478b902d02cd1 + PKG_HASH:=db1eee25bc417f5785a9a537aee1503f4f6bffb6effcbbe202ed73576ee20ed5 else ifeq ($(ARCH_PACKAGES),mipsel_mips32) - PKG_HASH:=c6e7015b2e900e94244e66118b2b3c7c9f5ff5e0257311625497e7dc133a1071 + PKG_HASH:=4deae82fed26d9455cbeff2f12093e6037f3f993fbbc449446bfda16e49c869b else ifeq ($(ARCH_PACKAGES),riscv64) - PKG_HASH:=7a9a49046672eced503fb9adf8fcb0e158ffd01e8856123e04a1400c57be81b0 + PKG_HASH:=973930d0abda895d1414a611f9bea70a1a35c1b9965fc9062f2bb0900cbcd617 else ifeq ($(ARCH_PACKAGES),x86) - PKG_HASH:=ddf4599057756bb77e560454eb7b62591077af731f06baff4491f07a7bf59c57 + PKG_HASH:=574dfa733c671d7d3125f53cf01f3f52d758a49cafc8df0e216e5ad5b501a149 else ifeq ($(ARCH_PACKAGES),x86_64) - PKG_HASH:=41b982201463ebca5aac999efc80484d6261ddcd5763a69e078c1e41fb427ef6 + PKG_HASH:=8fabab9496f947f90d2a4b72379069d53c132cdb14a092898c628ed0e7879d4a else PKG_HASH:=dummy endif diff --git a/v2ray-core/core.go b/v2ray-core/core.go index 942e62c302..a41aafca9d 100644 --- a/v2ray-core/core.go +++ b/v2ray-core/core.go @@ -18,7 +18,7 @@ import ( ) var ( - version = "5.29.3" + version = "5.30.0" build = "Custom" codename = "V2Fly, a community-driven edition of V2Ray." intro = "A unified platform for anti-censorship." diff --git a/v2ray-core/go.mod b/v2ray-core/go.mod index 3b710eeb25..f1556446ce 100644 --- a/v2ray-core/go.mod +++ b/v2ray-core/go.mod @@ -1,6 +1,6 @@ module github.com/v2fly/v2ray-core/v5 -go 1.23 +go 1.23.0 toolchain go1.24.2 @@ -9,7 +9,7 @@ require ( github.com/apernet/quic-go v0.48.2-0.20241104191913-cb103fcecfe7 github.com/go-chi/chi/v5 v5.2.1 github.com/go-chi/render v1.0.3 - github.com/go-playground/validator/v10 v10.24.0 + github.com/go-playground/validator/v10 v10.26.0 github.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 @@ -18,13 +18,13 @@ require ( github.com/gorilla/websocket v1.5.3 github.com/improbable-eng/grpc-web v0.15.0 github.com/jhump/protoreflect v1.17.0 - github.com/miekg/dns v1.1.63 + github.com/miekg/dns v1.1.64 github.com/mustafaturan/bus v1.0.2 github.com/pelletier/go-toml v1.9.5 github.com/pion/dtls/v2 v2.2.12 github.com/pion/transport/v2 v2.2.10 github.com/pires/go-proxyproto v0.8.0 - github.com/quic-go/quic-go v0.49.0 + github.com/quic-go/quic-go v0.50.1 github.com/refraction-networking/utls v1.6.7 github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb github.com/stretchr/testify v1.10.0 @@ -37,11 +37,11 @@ require ( github.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432 go.starlark.net v0.0.0-20230612165344-9532f5667272 go4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 - golang.org/x/crypto v0.33.0 - golang.org/x/net v0.35.0 - golang.org/x/sync v0.11.0 - golang.org/x/sys v0.30.0 - google.golang.org/grpc v1.70.0 + golang.org/x/crypto v0.36.0 + golang.org/x/net v0.38.0 + golang.org/x/sync v0.12.0 + golang.org/x/sys v0.31.0 + google.golang.org/grpc v1.71.1 google.golang.org/protobuf v1.36.5 gopkg.in/yaml.v3 v3.0.1 gvisor.dev/gvisor v0.0.0-20231020174304-b8a429915ff1 @@ -88,10 +88,10 @@ require ( github.com/xtaci/smux v1.5.24 // indirect go.uber.org/mock v0.5.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/mod v0.23.0 // indirect + golang.org/x/text v0.23.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.22.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect + golang.org/x/tools v0.30.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect nhooyr.io/websocket v1.8.6 // indirect ) diff --git a/v2ray-core/go.sum b/v2ray-core/go.sum index 843e0001ca..5f85841bcf 100644 --- a/v2ray-core/go.sum +++ b/v2ray-core/go.sum @@ -142,8 +142,8 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg= -github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= +github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= +github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -319,8 +319,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= -github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= +github.com/miekg/dns v1.1.64 h1:wuZgD9wwCE6XMT05UU/mlSko71eRSXEAm2EbjQXLKnQ= +github.com/miekg/dns v1.1.64/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -442,8 +442,8 @@ github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.49.0 h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94= -github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s= +github.com/quic-go/quic-go v0.50.1 h1:unsgjFIUqW8a2oopkY7YNONpV1gYND6Nt9hnt1PN94Q= +github.com/quic-go/quic-go v0.50.1/go.mod h1:Vim6OmUvlYdwBhXP9ZVrtGmCMWa3wEqhq3NgYrI8b4E= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM= github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0= @@ -550,16 +550,18 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= -go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= -go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= -go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= -go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= -go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= -go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= -go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= -go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= -go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.starlark.net v0.0.0-20230612165344-9532f5667272 h1:2/wtqS591wZyD2OsClsVBKRPEvBsQt/Js+fsCiYhwu8= go.starlark.net v0.0.0-20230612165344-9532f5667272/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -590,8 +592,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -620,8 +622,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= +golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -653,8 +655,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -668,8 +670,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -717,8 +719,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -738,8 +740,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -775,8 +777,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -805,8 +807,8 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -821,8 +823,8 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= -google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/handler/UpdateCheckerManager.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/handler/UpdateCheckerManager.kt index fa5d0bcc18..518c780b8e 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/handler/UpdateCheckerManager.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/handler/UpdateCheckerManager.kt @@ -31,8 +31,7 @@ object UpdateCheckerManager { val latestRelease = if (includePreRelease) { JsonUtil.fromJson(response, Array::class.java) - .filter { it.prerelease } - .maxByOrNull { it.publishedAt } + .firstOrNull() ?: throw IllegalStateException("No pre-release found") } else { JsonUtil.fromJson(response, GitHubRelease::class.java) diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt index 3157316fcb..da79f3ed5b 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt @@ -105,11 +105,11 @@ class AboutActivity : BaseActivity() { } } - //If it is the Google Play version, not be displayed within 2 days after update + //If it is the Google Play version, not be displayed within 1 days after update if (Utils.isGoogleFlavor()) { val lastUpdateTime = AppManagerUtil.getLastUpdateTime(this) val currentTime = System.currentTimeMillis() - if ((currentTime - lastUpdateTime) < 2 * 24 * 60 * 60 * 1000L) { + if ((currentTime - lastUpdateTime) < 1 * 24 * 60 * 60 * 1000L) { binding.layoutCheckUpdate.visibility = View.GONE } } diff --git a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt index e6abbba317..b4e8ac4492 100644 --- a/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt +++ b/v2rayng/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt @@ -87,9 +87,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList Action.IMPORT_QR_CODE_CONFIG -> scanQRCodeForConfig.launch(Intent(this, ScannerActivity::class.java)) -// Action.IMPORT_QR_CODE_URL -> -// scanQRCodeForUrlToCustomConfig.launch(Intent(this, ScannerActivity::class.java)) - Action.READ_CONTENT_FROM_URI -> chooseFileForCustomConfig.launch(Intent.createChooser(Intent(Intent.ACTION_GET_CONTENT).apply { type = "*/*" @@ -110,8 +107,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList enum class Action { NONE, IMPORT_QR_CODE_CONFIG, - - //IMPORT_QR_CODE_URL, READ_CONTENT_FROM_URI, POST_NOTIFICATIONS } @@ -129,12 +124,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } } -// private val scanQRCodeForUrlToCustomConfig = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { -// if (it.resultCode == RESULT_OK) { -// importConfigCustomUrl(it.data?.getStringExtra("SCAN_RESULT")) -// } -// } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(binding.root) @@ -325,7 +314,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { R.id.import_qrcode -> { - importQRcode(true) + importQRcode() true } @@ -379,26 +368,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList true } -// R.id.import_config_custom_clipboard -> { -// importConfigCustomClipboard() -// true -// } -// -// R.id.import_config_custom_local -> { -// importConfigCustomLocal() -// true -// } -// -// R.id.import_config_custom_url -> { -// importConfigCustomUrlClipboard() -// true -// } -// -// R.id.import_config_custom_url_scan -> { -// importQRcode(false) -// true -// } - R.id.export_all -> { exportAll() true @@ -462,16 +431,12 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList /** * import config from qrcode */ - private fun importQRcode(forConfig: Boolean): Boolean { + private fun importQRcode(): Boolean { val permission = Manifest.permission.CAMERA if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) { - if (forConfig) { - scanQRCodeForConfig.launch(Intent(this, ScannerActivity::class.java)) - } else { - //scanQRCodeForUrlToCustomConfig.launch(Intent(this, ScannerActivity::class.java)) - } + scanQRCodeForConfig.launch(Intent(this, ScannerActivity::class.java)) } else { - pendingAction = Action.IMPORT_QR_CODE_CONFIG//if (forConfig) Action.IMPORT_QR_CODE_CONFIG else Action.IMPORT_QR_CODE_URL + pendingAction = Action.IMPORT_QR_CODE_CONFIG requestPermissionLauncher.launch(permission) } return true @@ -535,77 +500,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } -// private fun importConfigCustomClipboard() -// : Boolean { -// try { -// val configText = Utils.getClipboard(this) -// if (TextUtils.isEmpty(configText)) { -// toast(R.string.toast_none_data_clipboard) -// return false -// } -// importCustomizeConfig(configText) -// return true -// } catch (e: Exception) { -// e.printStackTrace() -// return false -// } -// } - - /** - * import config from local config file - */ -// private fun importConfigCustomLocal(): Boolean { -// try { -// showFileChooser() -// } catch (e: Exception) { -// e.printStackTrace() -// return false -// } -// return true -// } -// -// private fun importConfigCustomUrlClipboard() -// : Boolean { -// try { -// val url = Utils.getClipboard(this) -// if (TextUtils.isEmpty(url)) { -// toast(R.string.toast_none_data_clipboard) -// return false -// } -// return importConfigCustomUrl(url) -// } catch (e: Exception) { -// e.printStackTrace() -// return false -// } -// } - - /** - * import config from url - */ -// private fun importConfigCustomUrl(url: String?): Boolean { -// try { -// if (!Utils.isValidUrl(url)) { -// toast(R.string.toast_invalid_url) -// return false -// } -// lifecycleScope.launch(Dispatchers.IO) { -// val configText = try { -// HttpUtil.getUrlContentWithUserAgent(url) -// } catch (e: Exception) { -// e.printStackTrace() -// "" -// } -// launch(Dispatchers.Main) { -// importCustomizeConfig(configText) -// } -// } -// } catch (e: Exception) { -// e.printStackTrace() -// return false -// } -// return true -// } - /** * import config from sub */ @@ -755,29 +649,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } } -// /** -// * import customize config -// */ -// private fun importCustomizeConfig(server: String?) { -// try { -// if (server == null || TextUtils.isEmpty(server)) { -// toast(R.string.toast_none_data) -// return -// } -// if (mainViewModel.appendCustomConfigServer(server)) { -// mainViewModel.reloadServerList() -// toastSuccess(R.string.toast_success) -// } else { -// toastError(R.string.toast_failure) -// } -// //adapter.notifyItemInserted(mainViewModel.serverList.lastIndex) -// } catch (e: Exception) { -// ToastCompat.makeText(this, "${getString(R.string.toast_malformed_josn)} ${e.cause?.message}", Toast.LENGTH_LONG).show() -// e.printStackTrace() -// return -// } -// } - private fun setTestState(content: String?) { binding.tvTestState.text = content } diff --git a/v2rayng/V2rayNG/app/src/main/res/menu/menu_main.xml b/v2rayng/V2rayNG/app/src/main/res/menu/menu_main.xml index 1559333f09..ce231ae773 100644 --- a/v2rayng/V2rayNG/app/src/main/res/menu/menu_main.xml +++ b/v2rayng/V2rayNG/app/src/main/res/menu/menu_main.xml @@ -56,29 +56,6 @@ android:id="@+id/import_manually_hysteria2" android:title="@string/menu_item_import_config_manually_hysteria2" app:showAsAction="never" /> - - - - - - - - - - - - - - - - - - - - - - - الكتابة يدويًا [Trojan] الكتابة يدويًا [Wireguard] Type manually[Hysteria2] - تكوين مخصص - استيراد تكوين مخصص من الحافظة - استيراد تكوين مخصص من الجهاز - استيراد تكوين مخصص من عنوان URL - استيراد تكوين مخصص مسح عنوان URL تأكيد الحذف؟ Please test before deleting! Confirm delete ? ملاحظات diff --git a/v2rayng/V2rayNG/app/src/main/res/values-bn/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-bn/strings.xml index 7de4de1dab..9c6e7d7c69 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -35,11 +35,6 @@ ম্যানুয়ালি টাইপ করুন [Trojan] ম্যানুয়ালি টাইপ করুন [Wireguard] Type manually[Hysteria2] - কাস্টম কনফিগারেশন - ক্লিপবোর্ড থেকে কাস্টম কনফিগারেশন আমদানি করুন - স্থানীয়ভাবে কাস্টম কনফিগারেশন আমদানি করুন - URL থেকে কাস্টম কনফিগারেশন আমদানি করুন - কাস্টম কনফিগারেশন স্ক্যান URL আমদানি করুন মুছে ফেলুন নিশ্চিত করুন? Please test before deleting! Confirm delete ? মন্তব্য diff --git a/v2rayng/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 392ad3cd3c..0257338c8c 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -26,7 +26,7 @@ پاک کردن کانفیگ و من ٱووردن کانفیگ ز QRcode و من ٱووردن کانفیگ ز کلیپ بورد - Import config from locally + و من ٱووردن کانفیگ ز مهلی هؽل دستی[VMess] هؽل دستی[VLESS] هؽل دستی[Shadowsocks] @@ -35,15 +35,10 @@ هؽل دستی[Trojan] هؽل دستی[Wireguard] هؽل دستی[Hysteria2] - کانفیگ سفارشی - کانفیگ سفارشین ز کلیپ بورد و من بیار - کانفیگ سفارشین ز مهلی و من بیار - کانفیگ سفارشین ز آدرس اینترنتی و من بیار - نشۊوی اینترنتی اسکن کانفیگ سفارشین بزݩ پاک بۊ؟ پؽش ز پاک کردن کانفیگ نا موئتبر واجۊری کوݩ! پاک کردن کانفیگن قوۊل اکۊنی؟ نیشتنا - آدرس + نشۊوی پورت نوم من توری شناسه جایگۊزین @@ -73,7 +68,7 @@ Alpn اجازه نا ٱمن SNI - آدرس + نشۊوی پورت رزم ٱمنیت @@ -82,12 +77,12 @@ رزم نگاری جریان کیلیت پوی وولاتی - کیلیت رمز ناهاڌن ازاف (اختیاری) + کیلیت رزم ناهاڌن ازاف (اختیاری) ShortID SpiderX کیلیت سیخومی Reserved(اختیاری، وا کاما ز یک جوڌا ابۊن) - آدرس مهلی (اختیاری IPv4/IPv6، وا کاما ز یک جوڌا ابۊن) + نشۊوی مهلی (اختیاری IPv4/IPv6، وا کاما ز یک جوڌا ابۊن) Mtu(اختیاری، پؽش فرز 1420) وا مووفقیت ٱنجوم وابی شکست خرد @@ -101,11 +96,11 @@ موئتوا هیچ داده ای من کلیپ بورد وۊجۊڌ نڌاره نشۊوی اینترنتی نا موئتبر هڌ - آدرس اشتراک پوروتوکول نا ٱمن HTTP ن و کار مبرین + نشۊوی اشتراک پوروتوکول نا ٱمن HTTP ن و کار مبرین موتمعن بۊین ک پورت وۊرۊڌی وا سامووا ی جۊر هڌ کانفیگ زبال نؽڌ هاست(SNI)(اختیاری) - ای کار ممنۊ هڌ + ای کار ممنۊع هڌ رزم obfs پورت گوم (درگا سرورن ز نۊ هؽل اکونه) فاسله پورت گوم (سانیه) @@ -121,9 +116,9 @@ ازاف کردن فایل ازاف کردن لینگ اسکن QRcode - آدرس اینترنتی + نشۊوی اینترنتی دانلود فایلا - آدرس اینترنتی دارایین ازاف کۊنین + نشۊوی اینترنتی دارایین ازاف کۊنین فایلن نجوست ائزارات ز زیتر بیڌسۉݩ @@ -131,7 +126,7 @@ هون بار ونی بۊ پیتینیڌن پسند پوی - رزمان بزنین + رزما ن بزنین هالت Bypass پسند خوتکار پروکسی برنومه موئتوا هونی دانلود ابۊن @@ -155,7 +150,7 @@ زل تر، ٱما گاشڌ منپیز زی قت بۊ بارت دؽوۉداری، TCP، UDP و QUIC ن ای لم سفارشی کۊنین. منپیزا TCP (تلایه منجا 1-1024) منپیزا XUDP (تلایه منجا 1-1024) - دؽوۉداری QUIC من تونل mux + دؽوۉداری QUIC من تۊنل mux رڌ کردن موجاز @@ -168,13 +163,13 @@ ر وندن Sniffing دامنه sniff ن ز کتن امتهۉݩ کۊنین (پؽش فرز رۊشن) ر وندن routeOnly - ز نوم دامنه sniffed تینا سی تور جوستن استفاڌه کۊنین وو آدرس مورد نزرن و عونوان آدرس IP ووردارین. + ز نوم دامنه sniffed تینا سی تور جوستن استفاڌه کۊنین وو نشۊوی مۉرد نزرن و عونوان نشۊوی IP ووردارین. ر وندن DNS مهلی DNS پردازشت وابیڌه و دس هسته ماژول DNS (پؽشنهاڌ ابۊ، ٱر نیاز هڌ ک جوستن تور وو ولات ٱسلین دور زنی) ر وندن DNS جئلی - DNS مهلی آدرسا IP جئلی ن وورگنه (زل تر، ٱما گاشڌ من یقرد ز برنومیل کار نکونه) + DNS مهلی نشۊویا IP جئلی ن وورگنه (زل تر، ٱما گاشڌ من یقرد ز برنومه یل کار نکونه) ترجی IPv6 ترجی داڌن نشۊوی وو تورا IPv6 @@ -188,14 +183,14 @@ DNS منی (اختیاری) DNS - DNS هاست موستقیم (قالوو: دامنه: آدرس،...) - دامنه:آدرس،... + DNS هاست موستقیم (قالوو: دامنه: نشۊوی،...) + دامنه:نشۊوی،... - آدرس اینترنتی آزمایش تئخیر واقعی (http/https) + نشۊوی اینترنتی آزمایش تئخیر واقعی (http/https) نشۊوی اینترنتی هشتن منپیزا ز شبکه مهلی - پوی دسگایل ترن وا آدرس IP ایسا، ز ر socks/http و پروکسی منپیز بۊن، تینا من شبکه قابل اعتماد فعال بۊ تا ز منپیز غیر موجاز جلو گری بۊ. + پوی دسگایل ترن وا نشۊوی IP ایسا، ز ر socks/http و پروکسی منپیز بۊن، تینا من شبکه قابل اعتماد فعال بۊ تا ز منپیز غیر موجاز جلو گری بۊ. منپیزا ز شبکه مهلی ن موجار کۊنین، موتمعن بۊین ک من ی شبکه قابل ائتماڌ هڌین. اجازه نا ٱمن @@ -214,7 +209,7 @@ شؽواتگرن سی اسکن، زی مجال ر وندن بۊگۊشین، اندی ترین کودن اسکن کۊنین یا شؽواتی ن منه نوار ٱوزار پسند کۊنین. پروکسی HTTP ن و VPN ازاف کۊنین - پروکسی HTTP ن موسقیمن ز (مۊرۊرگر/ی قرد ز برنومیل لادراری بیڌه)، بؽ استفاڌه ز دسگا NIC مجازی (Android 10+) استفاڌه ابۊ. + پروکسی HTTP ن موسقیمن ز (مۊرۊرگر/ی قرد ز برنومه یل لادراری بیڌه)، بؽ استفاڌه ز دسگا NIC مجازی (Android 10+) استفاڌه ابۊ. ر وندن نشۉݩ داڌن دو سۊتۊنی نومگه نمایه یل من دو سۊتۊن نشۉݩ داڌه ابۊن وو چینۉ ترین موئتوا بیشتری ن سیل کۊنین. سی ر وستن وا برنومه ن ز نۊ ر ونین. @@ -269,9 +264,9 @@ Tcping کانفیگا جرگه سکویی تئخیر واقعی کانفیگا جرگه سکویی فایلا بونچک جوقرافیایی - ترتیب و ری نتیجیل آزمایش + ترتیب و ری نتیجه یل آزمایش فیلتر کردن کانفیگا - پوی جرگیل + پوی جرگه یل کانفیگ پاک کردن %d کانفیگ تکراری پاک کردن %d کانفیگ diff --git a/v2rayng/V2rayNG/app/src/main/res/values-fa/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-fa/strings.xml index 5862efefc6..3c0598f066 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -35,11 +35,6 @@ تایپ دستی[TROJAN] ‌تایپ دستی[WIREGUARD] تایپ دستی[HYSTERIA2] - کانفیگ سفارشی - کانفیگ سفارشی را از کلیپ ‌بورد وارد کنید - کانفیگ سفارشی را به صورت محلی وارد کنید - کانفیگ سفارشی را از طریق نشانی اینترنتی وارد کنید - نشانی اینترنتی اسکن کانفیگ سفارشی را وارد کنید حذف شود؟ لطفا قبل از حذف کانفیگ نامعتبر بررسی کنید! حذف کانفیگ را تایید می کنید؟ ملاحظات diff --git a/v2rayng/V2rayNG/app/src/main/res/values-ru/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-ru/strings.xml index 0b98c27552..2950d1a5d0 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -35,11 +35,6 @@ Ручной ввод Trojan Ручной ввод WireGuard Ручной ввод Hysteria2 - Другой профиль - Импорт из буфера обмена - Импорт из файла - Импорт из URL - Импорт сканированием URL Подтверждаете удаление? Выполните проверку перед удалением! Подтверждаете удаление? Название diff --git a/v2rayng/V2rayNG/app/src/main/res/values-vi/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-vi/strings.xml index c71d039389..8e3d7c2ae8 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -35,11 +35,6 @@ Nhập thủ công [Trojan] Nhập thủ công [WireGuard] Type manually[Hysteria2] - Nâng cao / Cấu hình tùy chỉnh - Nhập cấu hình tùy chỉnh từ Clipboard - Nhập cấu hình tùy chỉnh từ Tệp - Nhập cấu hình tùy chỉnh từ URL - Nhập cấu hình tùy chỉnh quét URL Xác nhận xóa? Please test before deleting! Confirm delete ? Tên cấu hình diff --git a/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index 7da94eef9e..44ec4fa861 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -35,11 +35,6 @@ 手动输入 [Trojan] 手动输入 [Wireguard] 手动输入 [Hysteria2] - 自定义配置 - 从剪贴板导入自定义配置 - 从本地导入自定义配置 - 剪贴板 URL 导入自定义配置 - 扫描 URL 导入自定义配置 确认删除? 删除前请先测试!确认删除? 别名 (remarks) diff --git a/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index 013117b97d..f6abbdcf6d 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -35,11 +35,6 @@ 手動鍵入 [Trojan] 手動鍵入 [Wireguard] 手動鍵入 [Hysteria2] - 自訂設定 - 從剪貼簿匯入自訂設定 - 從本地匯入自訂設定 - 從 URL 匯入自訂設定 - 掃描 URL 匯入自訂設定 確定刪除? 刪除前請先測試!確認刪除? 備註 diff --git a/v2rayng/V2rayNG/app/src/main/res/values/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values/strings.xml index cd2cfdf41d..a9570d42e7 100644 --- a/v2rayng/V2rayNG/app/src/main/res/values/strings.xml +++ b/v2rayng/V2rayNG/app/src/main/res/values/strings.xml @@ -36,11 +36,6 @@ Type manually[Trojan] Type manually[Wireguard] Type manually[Hysteria2] - Custom config - Import custom config from Clipboard - Import custom config from locally - Import custom config from URL - Import custom config scan URL Confirm delete ? Please test before deleting! Confirm delete ? remarks diff --git a/yt-dlp/yt_dlp/extractor/_extractors.py b/yt-dlp/yt_dlp/extractor/_extractors.py index 9fc8913654..a206a38e42 100644 --- a/yt-dlp/yt_dlp/extractor/_extractors.py +++ b/yt-dlp/yt_dlp/extractor/_extractors.py @@ -1493,6 +1493,10 @@ from .paramountplus import ( ) from .parler import ParlerIE from .parlview import ParlviewIE +from .parti import ( + PartiLivestreamIE, + PartiVideoIE, +) from .patreon import ( PatreonCampaignIE, PatreonIE, diff --git a/yt-dlp/yt_dlp/extractor/agora.py b/yt-dlp/yt_dlp/extractor/agora.py index 9835584254..e040db6010 100644 --- a/yt-dlp/yt_dlp/extractor/agora.py +++ b/yt-dlp/yt_dlp/extractor/agora.py @@ -146,7 +146,7 @@ class TokFMPodcastIE(InfoExtractor): 'url': 'https://audycje.tokfm.pl/podcast/91275,-Systemowy-rasizm-Czy-zamieszki-w-USA-po-morderstwie-w-Minneapolis-doprowadza-do-zmian-w-sluzbach-panstwowych', 'info_dict': { 'id': '91275', - 'ext': 'aac', + 'ext': 'mp3', 'title': 'md5:a9b15488009065556900169fb8061cce', 'episode': 'md5:a9b15488009065556900169fb8061cce', 'series': 'Analizy', @@ -164,23 +164,20 @@ class TokFMPodcastIE(InfoExtractor): raise ExtractorError('No such podcast', expected=True) metadata = metadata[0] - formats = [] - for ext in ('aac', 'mp3'): - url_data = self._download_json( - f'https://api.podcast.radioagora.pl/api4/getSongUrl?podcast_id={media_id}&device_id={uuid.uuid4()}&ppre=false&audio={ext}', - media_id, f'Downloading podcast {ext} URL') - # prevents inserting the mp3 (default) multiple times - if 'link_ssl' in url_data and f'.{ext}' in url_data['link_ssl']: - formats.append({ - 'url': url_data['link_ssl'], - 'ext': ext, - 'vcodec': 'none', - 'acodec': ext, - }) + mp3_url = self._download_json( + 'https://api.podcast.radioagora.pl/api4/getSongUrl', + media_id, 'Downloading podcast mp3 URL', query={ + 'podcast_id': media_id, + 'device_id': str(uuid.uuid4()), + 'ppre': 'false', + 'audio': 'mp3', + })['link_ssl'] return { 'id': media_id, - 'formats': formats, + 'url': mp3_url, + 'vcodec': 'none', + 'ext': 'mp3', 'title': metadata.get('podcast_name'), 'series': metadata.get('series_name'), 'episode': metadata.get('podcast_name'), diff --git a/yt-dlp/yt_dlp/extractor/common.py b/yt-dlp/yt_dlp/extractor/common.py index 4c1bc4cf47..d5607296df 100644 --- a/yt-dlp/yt_dlp/extractor/common.py +++ b/yt-dlp/yt_dlp/extractor/common.py @@ -1570,6 +1570,8 @@ class InfoExtractor: """Yield all json ld objects in the html""" if default is not NO_DEFAULT: fatal = False + if not fatal and not isinstance(html, str): + return for mobj in re.finditer(JSON_LD_RE, html): json_ld_item = self._parse_json( mobj.group('json_ld'), video_id, fatal=fatal, diff --git a/yt-dlp/yt_dlp/extractor/mixcloud.py b/yt-dlp/yt_dlp/extractor/mixcloud.py index 19b7fd4e70..852670fcba 100644 --- a/yt-dlp/yt_dlp/extractor/mixcloud.py +++ b/yt-dlp/yt_dlp/extractor/mixcloud.py @@ -10,7 +10,9 @@ from ..utils import ( parse_iso8601, strip_or_none, try_get, + url_or_none, ) +from ..utils.traversal import traverse_obj class MixcloudBaseIE(InfoExtractor): @@ -37,7 +39,7 @@ class MixcloudIE(MixcloudBaseIE): 'ext': 'm4a', 'title': 'Cryptkeeper', 'description': 'After quite a long silence from myself, finally another Drum\'n\'Bass mix with my favourite current dance floor bangers.', - 'uploader': 'Daniel Holbach', + 'uploader': 'dholbach', 'uploader_id': 'dholbach', 'thumbnail': r're:https?://.*\.jpg', 'view_count': int, @@ -46,10 +48,11 @@ class MixcloudIE(MixcloudBaseIE): 'uploader_url': 'https://www.mixcloud.com/dholbach/', 'artist': 'Submorphics & Chino , Telekinesis, Porter Robinson, Enei, Breakage ft Jess Mills', 'duration': 3723, - 'tags': [], + 'tags': ['liquid drum and bass', 'drum and bass'], 'comment_count': int, 'repost_count': int, 'like_count': int, + 'artists': list, }, 'params': {'skip_download': 'm3u8'}, }, { @@ -67,7 +70,7 @@ class MixcloudIE(MixcloudBaseIE): 'upload_date': '20150203', 'uploader_url': 'https://www.mixcloud.com/gillespeterson/', 'duration': 2992, - 'tags': [], + 'tags': ['jazz', 'soul', 'world music', 'funk'], 'comment_count': int, 'repost_count': int, 'like_count': int, @@ -149,8 +152,6 @@ class MixcloudIE(MixcloudBaseIE): elif reason: raise ExtractorError('Track is restricted', expected=True) - title = cloudcast['name'] - stream_info = cloudcast['streamInfo'] formats = [] @@ -182,47 +183,39 @@ class MixcloudIE(MixcloudBaseIE): self.raise_login_required(metadata_available=True) comments = [] - for edge in (try_get(cloudcast, lambda x: x['comments']['edges']) or []): - node = edge.get('node') or {} + for node in traverse_obj(cloudcast, ('comments', 'edges', ..., 'node', {dict})): text = strip_or_none(node.get('comment')) if not text: continue - user = node.get('user') or {} comments.append({ - 'author': user.get('displayName'), - 'author_id': user.get('username'), 'text': text, - 'timestamp': parse_iso8601(node.get('created')), + **traverse_obj(node, { + 'author': ('user', 'displayName', {str}), + 'author_id': ('user', 'username', {str}), + 'timestamp': ('created', {parse_iso8601}), + }), }) - tags = [] - for t in cloudcast.get('tags'): - tag = try_get(t, lambda x: x['tag']['name'], str) - if not tag: - tags.append(tag) - - get_count = lambda x: int_or_none(try_get(cloudcast, lambda y: y[x]['totalCount'])) - - owner = cloudcast.get('owner') or {} - return { 'id': track_id, - 'title': title, 'formats': formats, - 'description': cloudcast.get('description'), - 'thumbnail': try_get(cloudcast, lambda x: x['picture']['url'], str), - 'uploader': owner.get('displayName'), - 'timestamp': parse_iso8601(cloudcast.get('publishDate')), - 'uploader_id': owner.get('username'), - 'uploader_url': owner.get('url'), - 'duration': int_or_none(cloudcast.get('audioLength')), - 'view_count': int_or_none(cloudcast.get('plays')), - 'like_count': get_count('favorites'), - 'repost_count': get_count('reposts'), - 'comment_count': get_count('comments'), 'comments': comments, - 'tags': tags, - 'artist': ', '.join(cloudcast.get('featuringArtistList') or []) or None, + **traverse_obj(cloudcast, { + 'title': ('name', {str}), + 'description': ('description', {str}), + 'thumbnail': ('picture', 'url', {url_or_none}), + 'timestamp': ('publishDate', {parse_iso8601}), + 'duration': ('audioLength', {int_or_none}), + 'uploader': ('owner', 'displayName', {str}), + 'uploader_id': ('owner', 'username', {str}), + 'uploader_url': ('owner', 'url', {url_or_none}), + 'view_count': ('plays', {int_or_none}), + 'like_count': ('favorites', 'totalCount', {int_or_none}), + 'repost_count': ('reposts', 'totalCount', {int_or_none}), + 'comment_count': ('comments', 'totalCount', {int_or_none}), + 'tags': ('tags', ..., 'tag', 'name', {str}, filter, all, filter), + 'artists': ('featuringArtistList', ..., {str}, filter, all, filter), + }), } @@ -295,7 +288,7 @@ class MixcloudUserIE(MixcloudPlaylistBaseIE): 'url': 'http://www.mixcloud.com/dholbach/', 'info_dict': { 'id': 'dholbach_uploads', - 'title': 'Daniel Holbach (uploads)', + 'title': 'dholbach (uploads)', 'description': 'md5:a3f468a60ac8c3e1f8616380fc469b2b', }, 'playlist_mincount': 36, @@ -303,7 +296,7 @@ class MixcloudUserIE(MixcloudPlaylistBaseIE): 'url': 'http://www.mixcloud.com/dholbach/uploads/', 'info_dict': { 'id': 'dholbach_uploads', - 'title': 'Daniel Holbach (uploads)', + 'title': 'dholbach (uploads)', 'description': 'md5:a3f468a60ac8c3e1f8616380fc469b2b', }, 'playlist_mincount': 36, @@ -311,7 +304,7 @@ class MixcloudUserIE(MixcloudPlaylistBaseIE): 'url': 'http://www.mixcloud.com/dholbach/favorites/', 'info_dict': { 'id': 'dholbach_favorites', - 'title': 'Daniel Holbach (favorites)', + 'title': 'dholbach (favorites)', 'description': 'md5:a3f468a60ac8c3e1f8616380fc469b2b', }, # 'params': { @@ -337,7 +330,7 @@ class MixcloudUserIE(MixcloudPlaylistBaseIE): 'title': 'First Ear (stream)', 'description': 'we maraud for ears', }, - 'playlist_mincount': 269, + 'playlist_mincount': 267, }] _TITLE_KEY = 'displayName' @@ -361,7 +354,7 @@ class MixcloudPlaylistIE(MixcloudPlaylistBaseIE): 'id': 'maxvibes_jazzcat-on-ness-radio', 'title': 'Ness Radio sessions', }, - 'playlist_mincount': 59, + 'playlist_mincount': 58, }] _TITLE_KEY = 'name' _DESCRIPTION_KEY = 'description' diff --git a/yt-dlp/yt_dlp/extractor/parti.py b/yt-dlp/yt_dlp/extractor/parti.py new file mode 100644 index 0000000000..acadefc4e4 --- /dev/null +++ b/yt-dlp/yt_dlp/extractor/parti.py @@ -0,0 +1,101 @@ +from .common import InfoExtractor +from ..utils import UserNotLive, int_or_none, parse_iso8601, url_or_none, urljoin +from ..utils.traversal import traverse_obj + + +class PartiBaseIE(InfoExtractor): + def _call_api(self, path, video_id, note=None): + return self._download_json( + f'https://api-backend.parti.com/parti_v2/profile/{path}', video_id, note) + + +class PartiVideoIE(PartiBaseIE): + IE_NAME = 'parti:video' + _VALID_URL = r'https?://(?:www\.)?parti\.com/video/(?P\d+)' + _TESTS = [{ + 'url': 'https://parti.com/video/66284', + 'info_dict': { + 'id': '66284', + 'ext': 'mp4', + 'title': 'NOW LIVE ', + 'upload_date': '20250327', + 'categories': ['Gaming'], + 'thumbnail': 'https://assets.parti.com/351424_eb9e5250-2821-484a-9c5f-ca99aa666c87.png', + 'channel': 'ItZTMGG', + 'timestamp': 1743044379, + }, + 'params': {'skip_download': 'm3u8'}, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + data = self._call_api(f'get_livestream_channel_info/recent/{video_id}', video_id) + + return { + 'id': video_id, + 'formats': self._extract_m3u8_formats( + urljoin('https://watch.parti.com', data['livestream_recording']), video_id, 'mp4'), + **traverse_obj(data, { + 'title': ('event_title', {str}), + 'channel': ('user_name', {str}), + 'thumbnail': ('event_file', {url_or_none}), + 'categories': ('category_name', {str}, filter, all), + 'timestamp': ('event_start_ts', {int_or_none}), + }), + } + + +class PartiLivestreamIE(PartiBaseIE): + IE_NAME = 'parti:livestream' + _VALID_URL = r'https?://(?:www\.)?parti\.com/creator/(?P[\w]+)/(?P[\w/-]+)' + _TESTS = [{ + 'url': 'https://parti.com/creator/parti/Capt_Robs_Adventures', + 'info_dict': { + 'id': 'Capt_Robs_Adventures', + 'ext': 'mp4', + 'title': r"re:I'm Live on Parti \d{4}-\d{2}-\d{2} \d{2}:\d{2}", + 'view_count': int, + 'thumbnail': r're:https://assets\.parti\.com/.+\.png', + 'timestamp': 1743879776, + 'upload_date': '20250405', + 'live_status': 'is_live', + }, + 'params': {'skip_download': 'm3u8'}, + }, { + 'url': 'https://parti.com/creator/discord/sazboxgaming/0', + 'only_matching': True, + }] + + def _real_extract(self, url): + service, creator_slug = self._match_valid_url(url).group('service', 'id') + + encoded_creator_slug = creator_slug.replace('/', '%23') + creator_id = self._call_api( + f'get_user_by_social_media/{service}/{encoded_creator_slug}', + creator_slug, note='Fetching user ID') + + data = self._call_api( + f'get_livestream_channel_info/{creator_id}', creator_id, + note='Fetching user profile feed')['channel_info'] + + if not traverse_obj(data, ('channel', 'is_live', {bool})): + raise UserNotLive(video_id=creator_id) + + channel_info = data['channel'] + + return { + 'id': creator_slug, + 'formats': self._extract_m3u8_formats( + channel_info['playback_url'], creator_slug, live=True, query={ + 'token': channel_info['playback_auth_token'], + 'player_version': '1.17.0', + }), + 'is_live': True, + **traverse_obj(data, { + 'title': ('livestream_event_info', 'event_name', {str}), + 'description': ('livestream_event_info', 'event_description', {str}), + 'thumbnail': ('livestream_event_info', 'livestream_preview_file', {url_or_none}), + 'timestamp': ('stream', 'start_time', {parse_iso8601}), + 'view_count': ('stream', 'viewer_count', {int_or_none}), + }), + } diff --git a/yt-dlp/yt_dlp/extractor/yandexvideo.py b/yt-dlp/yt_dlp/extractor/yandexvideo.py index cdd32c5e4e..09e7c98785 100644 --- a/yt-dlp/yt_dlp/extractor/yandexvideo.py +++ b/yt-dlp/yt_dlp/extractor/yandexvideo.py @@ -2,15 +2,17 @@ import itertools from .common import InfoExtractor from ..utils import ( + bug_reports_message, determine_ext, - extract_attributes, int_or_none, lowercase_escape, parse_qs, - traverse_obj, + qualities, try_get, + update_url_query, url_or_none, ) +from ..utils.traversal import traverse_obj class YandexVideoIE(InfoExtractor): @@ -186,7 +188,22 @@ class YandexVideoPreviewIE(InfoExtractor): return self.url_result(data_json['video']['url']) -class ZenYandexIE(InfoExtractor): +class ZenYandexBaseIE(InfoExtractor): + def _fetch_ssr_data(self, url, video_id): + webpage = self._download_webpage(url, video_id) + redirect = self._search_json( + r'(?:var|let|const)\s+it\s*=', webpage, 'redirect', video_id, default={}).get('retpath') + if redirect: + video_id = self._match_id(redirect) + webpage = self._download_webpage(redirect, video_id, note='Redirecting') + return video_id, self._search_json( + r'(?:var|let|const)\s+_params\s*=\s*\(', webpage, 'metadata', video_id, + contains_pattern=r'{["\']ssrData.+}')['ssrData'] + + +class ZenYandexIE(ZenYandexBaseIE): + IE_NAME = 'dzen.ru' + IE_DESC = 'Дзен (dzen) formerly Яндекс.Дзен (Yandex Zen)' _VALID_URL = r'https?://(zen\.yandex|dzen)\.ru(?:/video)?/(media|watch)/(?:(?:id/[^/]+/|[^/]+/)(?:[a-z0-9-]+)-)?(?P[a-z0-9-]+)' _TESTS = [{ 'url': 'https://zen.yandex.ru/media/id/606fd806cc13cb3c58c05cf5/vot-eto-focus-dedy-morozy-na-gidrociklah-60c7c443da18892ebfe85ed7', @@ -216,6 +233,7 @@ class ZenYandexIE(InfoExtractor): 'timestamp': 1573465585, }, 'params': {'skip_download': 'm3u8'}, + 'skip': 'The page does not exist', }, { 'url': 'https://zen.yandex.ru/video/watch/6002240ff8b1af50bb2da5e3', 'info_dict': { @@ -227,6 +245,9 @@ class ZenYandexIE(InfoExtractor): 'uploader': 'TechInsider', 'timestamp': 1611378221, 'upload_date': '20210123', + 'view_count': int, + 'duration': 243, + 'tags': ['опыт', 'эксперимент', 'огонь'], }, 'params': {'skip_download': 'm3u8'}, }, { @@ -240,6 +261,9 @@ class ZenYandexIE(InfoExtractor): 'uploader': 'TechInsider', 'upload_date': '20210123', 'timestamp': 1611378221, + 'view_count': int, + 'duration': 243, + 'tags': ['опыт', 'эксперимент', 'огонь'], }, 'params': {'skip_download': 'm3u8'}, }, { @@ -252,44 +276,56 @@ class ZenYandexIE(InfoExtractor): def _real_extract(self, url): video_id = self._match_id(url) - webpage = self._download_webpage(url, video_id) - redirect = self._search_json(r'var it\s*=', webpage, 'redirect', id, default={}).get('retpath') - if redirect: - video_id = self._match_id(redirect) - webpage = self._download_webpage(redirect, video_id, note='Redirecting') - data_json = self._search_json( - r'("data"\s*:|data\s*=)', webpage, 'metadata', video_id, contains_pattern=r'{["\']_*serverState_*video.+}') - serverstate = self._search_regex(r'(_+serverState_+video-site_[^_]+_+)', webpage, 'server state') - uploader = self._search_regex(r'(]+>)', - webpage, 'uploader', default='') - uploader_name = extract_attributes(uploader).get('aria-label') - item_id = traverse_obj(data_json, (serverstate, 'videoViewer', 'openedItemId', {str})) - video_json = traverse_obj(data_json, (serverstate, 'videoViewer', 'items', item_id, {dict})) or {} + video_id, ssr_data = self._fetch_ssr_data(url, video_id) + video_data = ssr_data['videoMetaResponse'] formats, subtitles = [], {} - for s_url in traverse_obj(video_json, ('video', 'streams', ..., {url_or_none})): + quality = qualities(('4', '0', '1', '2', '3', '5', '6', '7')) + # Deduplicate stream URLs. The "dzen_dash" query parameter is present in some URLs but can be omitted + stream_urls = set(traverse_obj(video_data, ( + 'video', ('id', ('streams', ...), ('mp4Streams', ..., 'url'), ('oneVideoStreams', ..., 'url')), + {url_or_none}, {update_url_query(query={'dzen_dash': []})}))) + for s_url in stream_urls: ext = determine_ext(s_url) - if ext == 'mpd': - fmts, subs = self._extract_mpd_formats_and_subtitles(s_url, video_id, mpd_id='dash') - elif ext == 'm3u8': - fmts, subs = self._extract_m3u8_formats_and_subtitles(s_url, video_id, 'mp4') + content_type = traverse_obj(parse_qs(s_url), ('ct', 0)) + if ext == 'mpd' or content_type == '6': + fmts, subs = self._extract_mpd_formats_and_subtitles(s_url, video_id, mpd_id='dash', fatal=False) + elif ext == 'm3u8' or content_type == '8': + fmts, subs = self._extract_m3u8_formats_and_subtitles(s_url, video_id, 'mp4', m3u8_id='hls', fatal=False) + elif content_type == '0': + format_type = traverse_obj(parse_qs(s_url), ('type', 0)) + formats.append({ + 'url': s_url, + 'format_id': format_type, + 'ext': 'mp4', + 'quality': quality(format_type), + }) + continue + else: + self.report_warning(f'Unsupported stream URL: {s_url}{bug_reports_message()}') + continue formats.extend(fmts) - subtitles = self._merge_subtitles(subtitles, subs) + self._merge_subtitles(subs, target=subtitles) + return { 'id': video_id, - 'title': video_json.get('title') or self._og_search_title(webpage), 'formats': formats, 'subtitles': subtitles, - 'duration': int_or_none(video_json.get('duration')), - 'view_count': int_or_none(video_json.get('views')), - 'timestamp': int_or_none(video_json.get('publicationDate')), - 'uploader': uploader_name or data_json.get('authorName') or try_get(data_json, lambda x: x['publisher']['name']), - 'description': video_json.get('description') or self._og_search_description(webpage), - 'thumbnail': self._og_search_thumbnail(webpage) or try_get(data_json, lambda x: x['og']['imageUrl']), + **traverse_obj(video_data, { + 'title': ('title', {str}), + 'description': ('description', {str}), + 'thumbnail': ('image', {url_or_none}), + 'duration': ('video', 'duration', {int_or_none}), + 'view_count': ('video', 'views', {int_or_none}), + 'timestamp': ('publicationDate', {int_or_none}), + 'tags': ('tags', ..., {str}), + 'uploader': ('source', 'title', {str}), + }), } -class ZenYandexChannelIE(InfoExtractor): +class ZenYandexChannelIE(ZenYandexBaseIE): + IE_NAME = 'dzen.ru:channel' _VALID_URL = r'https?://(zen\.yandex|dzen)\.ru/(?!media|video)(?:id/)?(?P[a-z0-9-_]+)' _TESTS = [{ 'url': 'https://zen.yandex.ru/tok_media', @@ -323,8 +359,8 @@ class ZenYandexChannelIE(InfoExtractor): 'url': 'https://zen.yandex.ru/jony_me', 'info_dict': { 'id': 'jony_me', - 'description': 'md5:ce0a5cad2752ab58701b5497835b2cc5', - 'title': 'JONY ', + 'description': 'md5:7c30d11dc005faba8826feae99da3113', + 'title': 'JONY', }, 'playlist_count': 18, }, { @@ -333,9 +369,8 @@ class ZenYandexChannelIE(InfoExtractor): 'url': 'https://zen.yandex.ru/tatyanareva', 'info_dict': { 'id': 'tatyanareva', - 'description': 'md5:40a1e51f174369ec3ba9d657734ac31f', + 'description': 'md5:92e56fa730a932ca2483ba5c2186ad96', 'title': 'Татьяна Рева', - 'entries': 'maxcount:200', }, 'playlist_mincount': 46, }, { @@ -348,43 +383,31 @@ class ZenYandexChannelIE(InfoExtractor): 'playlist_mincount': 657, }] - def _entries(self, item_id, server_state_json, server_settings_json): - items = (traverse_obj(server_state_json, ('feed', 'items', ...)) - or traverse_obj(server_settings_json, ('exportData', 'items', ...))) - - more = (traverse_obj(server_state_json, ('links', 'more')) - or traverse_obj(server_settings_json, ('exportData', 'more', 'link'))) - + def _entries(self, feed_data, channel_id): next_page_id = None for page in itertools.count(1): - for item in items or []: - if item.get('type') != 'gif': - continue - video_id = traverse_obj(item, 'publication_id', 'publicationId') or '' - yield self.url_result(item['link'], ZenYandexIE, video_id.split(':')[-1]) + for item in traverse_obj(feed_data, ( + (None, ('items', lambda _, v: v['tab'] in ('shorts', 'longs'))), + 'items', lambda _, v: url_or_none(v['link']), + )): + yield self.url_result(item['link'], ZenYandexIE, item.get('id'), title=item.get('title')) + more = traverse_obj(feed_data, ('more', 'link', {url_or_none})) current_page_id = next_page_id next_page_id = traverse_obj(parse_qs(more), ('next_page_id', -1)) - if not all((more, items, next_page_id, next_page_id != current_page_id)): + if not all((more, next_page_id, next_page_id != current_page_id)): break - data = self._download_json(more, item_id, note=f'Downloading Page {page}') - items, more = data.get('items'), traverse_obj(data, ('more', 'link')) + feed_data = self._download_json(more, channel_id, note=f'Downloading Page {page}') def _real_extract(self, url): - item_id = self._match_id(url) - webpage = self._download_webpage(url, item_id) - redirect = self._search_json( - r'var it\s*=', webpage, 'redirect', item_id, default={}).get('retpath') - if redirect: - item_id = self._match_id(redirect) - webpage = self._download_webpage(redirect, item_id, note='Redirecting') - data = self._search_json( - r'("data"\s*:|data\s*=)', webpage, 'channel data', item_id, contains_pattern=r'{\"__serverState__.+}') - server_state_json = traverse_obj(data, lambda k, _: k.startswith('__serverState__'), get_all=False) - server_settings_json = traverse_obj(data, lambda k, _: k.startswith('__serverSettings__'), get_all=False) + channel_id = self._match_id(url) + channel_id, ssr_data = self._fetch_ssr_data(url, channel_id) + channel_data = ssr_data['exportResponse'] return self.playlist_result( - self._entries(item_id, server_state_json, server_settings_json), - item_id, traverse_obj(server_state_json, ('channel', 'source', 'title')), - traverse_obj(server_state_json, ('channel', 'source', 'description'))) + self._entries(channel_data['feedData'], channel_id), + channel_id, **traverse_obj(channel_data, ('channel', 'source', { + 'title': ('title', {str}), + 'description': ('description', {str}), + })))