From 6bab6ce6c43db0a596e995c784eaa8e46e763270 Mon Sep 17 00:00:00 2001 From: Alireza Ahmadi Date: Sun, 1 Feb 2026 00:51:53 +0100 Subject: [PATCH] Updates so far Co-authored-by: MHSanaei --- .github/workflows/docker.yml | 5 + .github/workflows/release.yml | 4 +- DockerInitFiles.sh | 2 +- config/config.go | 8 +- database/db.go | 35 ++ go.mod | 86 +++-- go.sum | 200 ++++++----- main.go | 2 +- sub/subJsonService.go | 62 +--- util/random/random.go | 19 +- web/assets/js/model/inbound.js | 78 ++++- web/assets/js/model/outbound.js | 329 ++++++++++++++++--- web/html/xui/form/inbound.html | 7 +- web/html/xui/form/outbound.html | 162 ++++++++- web/html/xui/form/protocol/tun.html | 44 +++ web/html/xui/form/protocol/vless.html | 29 ++ web/html/xui/form/stream/external_proxy.html | 4 +- web/html/xui/form/stream/stream_sockopt.html | 9 + web/html/xui/form/tls_settings.html | 7 + web/html/xui/inbound_modal.html | 42 +++ web/html/xui/settings.html | 22 +- web/html/xui/xray.html | 6 +- web/job/check_cpu_usage.go | 6 +- web/locale/locale.go | 6 +- web/service/inbound.go | 7 +- web/service/server.go | 61 +++- web/service/xray.go | 3 + web/translation/translate.en_US.toml | 6 + web/translation/translate.fa_IR.toml | 6 + web/translation/translate.ru_RU.toml | 6 + web/translation/translate.vi_VN.toml | 6 + web/translation/translate.zh_Hans.toml | 6 + web/web.go | 4 + x-ui.sh | 12 +- xray/api.go | 27 +- 35 files changed, 1021 insertions(+), 297 deletions(-) create mode 100644 web/html/xui/form/protocol/tun.html diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 59213b95..55a183ce 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,4 +1,9 @@ name: Docker Image CI + +permissions: + contents: read + packages: write + on: push: tags: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5c39d1b4..9c3abbc3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,7 +86,7 @@ jobs: cd x-ui/bin # Download dependencies - Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.9.11/" + Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v26.1.31/" if [ "${{ matrix.platform }}" == "amd64" ]; then wget -q ${Xray_URL}Xray-linux-64.zip unzip Xray-linux-64.zip @@ -182,7 +182,7 @@ jobs: cd x-ui\bin # Download Xray for Windows - $Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v25.9.11/" + $Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v26.1.31/" Invoke-WebRequest -Uri "${Xray_URL}Xray-windows-64.zip" -OutFile "Xray-windows-64.zip" Expand-Archive -Path "Xray-windows-64.zip" -DestinationPath . Remove-Item "Xray-windows-64.zip" diff --git a/DockerInitFiles.sh b/DockerInitFiles.sh index cc2b1621..30615d60 100755 --- a/DockerInitFiles.sh +++ b/DockerInitFiles.sh @@ -23,7 +23,7 @@ case $1 in esac mkdir -p build/bin cd build/bin -wget -q "https://github.com/XTLS/Xray-core/releases/download/v25.9.11/Xray-linux-${ARCH}.zip" +wget -q "https://github.com/XTLS/Xray-core/releases/download/v26.1.31/Xray-linux-${ARCH}.zip" unzip "Xray-linux-${ARCH}.zip" rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat LICENSE README.md mv xray "xray-linux-${FNAME}" diff --git a/config/config.go b/config/config.go index 7c7cdb3d..7973b655 100644 --- a/config/config.go +++ b/config/config.go @@ -18,10 +18,10 @@ var name string type LogLevel string const ( - Debug LogLevel = "debug" - Info LogLevel = "info" - Warn LogLevel = "warn" - Error LogLevel = "error" + Debug LogLevel = "debug" + Info LogLevel = "info" + Warning LogLevel = "warning" + Error LogLevel = "error" ) func GetVersion() string { diff --git a/database/db.go b/database/db.go index 4a05ec77..4a6e9115 100644 --- a/database/db.go +++ b/database/db.go @@ -9,6 +9,7 @@ import ( "github.com/alireza0/x-ui/config" "github.com/alireza0/x-ui/database/model" + "github.com/alireza0/x-ui/util/common" "github.com/alireza0/x-ui/xray" "gorm.io/driver/sqlite" @@ -94,6 +95,17 @@ func InitDB(dbPath string) error { return nil } +func CloseDB() error { + if db != nil { + sqlDB, err := db.DB() + if err != nil { + return err + } + return sqlDB.Close() + } + return nil +} + func GetDB() *gorm.DB { return db } @@ -120,3 +132,26 @@ func Checkpoint() error { } return nil } + +func ValidateSQLiteDB(dbPath string) error { + if _, err := os.Stat(dbPath); err != nil { // file must exist + return err + } + gdb, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{Logger: logger.Discard}) + if err != nil { + return err + } + sqlDB, err := gdb.DB() + if err != nil { + return err + } + defer sqlDB.Close() + var res string + if err := gdb.Raw("PRAGMA integrity_check;").Scan(&res).Error; err != nil { + return err + } + if res != "ok" { + return common.NewError("sqlite integrity check failed: " + res) + } + return nil +} diff --git a/go.mod b/go.mod index 83a31407..0f545c9c 100644 --- a/go.mod +++ b/go.mod @@ -1,41 +1,42 @@ module github.com/alireza0/x-ui -go 1.25.1 +go 1.25.6 require ( - github.com/gin-contrib/gzip v1.2.3 + github.com/gin-contrib/gzip v1.2.5 github.com/gin-contrib/sessions v1.0.4 - github.com/gin-gonic/gin v1.10.1 + github.com/gin-gonic/gin v1.11.0 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/goccy/go-json v0.10.5 - github.com/nicksnyder/go-i18n/v2 v2.6.0 + github.com/nicksnyder/go-i18n/v2 v2.6.1 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/pelletier/go-toml/v2 v2.2.4 github.com/robfig/cron/v3 v3.0.1 - github.com/shirou/gopsutil/v4 v4.25.8 - github.com/xtls/xray-core v1.250911.0 + github.com/shirou/gopsutil/v4 v4.25.12 + github.com/xtls/xray-core v1.260131.0 go.uber.org/atomic v1.11.0 - golang.org/x/text v0.29.0 - google.golang.org/grpc v1.75.1 + golang.org/x/text v0.33.0 + google.golang.org/grpc v1.78.0 gorm.io/driver/sqlite v1.6.0 gorm.io/gorm v1.31.0 ) require ( github.com/andybalholm/brotli v1.2.0 // indirect + github.com/apernet/quic-go v0.57.2-0.20260111184307-eec823306178 // indirect github.com/bytedance/gopkg v0.1.3 // indirect - github.com/bytedance/sonic v1.14.1 // indirect - github.com/bytedance/sonic/loader v0.3.0 // indirect - github.com/cloudflare/circl v1.6.1 // indirect + github.com/bytedance/sonic v1.15.0 // indirect + github.com/bytedance/sonic/loader v0.5.0 // indirect + github.com/cloudflare/circl v1.6.3 // indirect github.com/cloudwego/base64x v0.1.6 // indirect - github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect - github.com/ebitengine/purego v0.8.4 // indirect - github.com/gabriel-vasile/mimetype v1.4.10 // indirect + github.com/ebitengine/purego v0.9.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.12 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/go-playground/validator/v10 v10.30.1 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect github.com/google/btree v1.1.3 // indirect github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect @@ -45,50 +46,45 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/juju/ratelimit v1.0.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.3 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect - github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 // indirect + github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.32 // indirect - github.com/miekg/dns v1.1.68 // indirect + github.com/mattn/go-sqlite3 v1.14.33 // indirect + github.com/miekg/dns v1.1.72 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pires/go-proxyproto v0.8.1 // indirect + github.com/pires/go-proxyproto v0.9.2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/quic-go/qpack v0.5.1 // indirect - github.com/quic-go/quic-go v0.54.0 // indirect - github.com/refraction-networking/utls v1.8.0 // indirect - github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.59.0 // indirect + github.com/refraction-networking/utls v1.8.2 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/sagernet/sing v0.7.10 // indirect + github.com/sagernet/sing v0.7.17 // indirect github.com/sagernet/sing-shadowsocks v0.2.9 // indirect - github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.3.0 // indirect - github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect + github.com/ugorji/go/codec v1.3.1 // indirect github.com/vishvananda/netlink v1.3.1 // indirect github.com/vishvananda/netns v0.0.5 // indirect - github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c // indirect + github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.uber.org/mock v0.6.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/arch v0.21.0 // indirect - golang.org/x/crypto v0.42.0 // indirect - golang.org/x/mod v0.28.0 // indirect - golang.org/x/net v0.44.0 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/time v0.13.0 // indirect - golang.org/x/tools v0.37.0 // indirect + golang.org/x/arch v0.23.0 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/mod v0.32.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.41.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/protobuf v1.36.9 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect + google.golang.org/protobuf v1.36.11 // indirect + gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0 // indirect lukechampine.com/blake3 v1.4.1 // indirect ) diff --git a/go.sum b/go.sum index ac56ea4e..462dda28 100644 --- a/go.sum +++ b/go.sum @@ -1,38 +1,36 @@ -github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= -github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= +github.com/apernet/quic-go v0.57.2-0.20260111184307-eec823306178 h1:bSq8n+gX4oO/qnM3MKf4kroW75n+phO9Qp6nigJKZ1E= +github.com/apernet/quic-go v0.57.2-0.20260111184307-eec823306178/go.mod h1:N1WIjPphkqs4efXWuyDNQ6OjjIK04vM3h+bEgwV+eVU= github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= -github.com/bytedance/sonic v1.14.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w= -github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc= -github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= -github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= -github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= -github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= +github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= +github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= +github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= +github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= -github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 h1:ucRHb6/lvW/+mTEIGbvhcYU3S8+uSNkuMjx/qZFfhtM= -github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= -github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= -github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0= -github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A= +github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw= +github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4= github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= -github.com/gin-contrib/gzip v1.2.3 h1:dAhT722RuEG330ce2agAs75z7yB+NKvX/ZM1r8w0u2U= -github.com/gin-contrib/gzip v1.2.3/go.mod h1:ad72i4Bzmaypk8M762gNXa2wkxxjbz0icRNnuLJ9a/c= +github.com/gin-contrib/gzip v1.2.5 h1:fIZs0S+l17pIu1P5XRJOo/YNqfIuPCrZZ3TWB7pjckI= +github.com/gin-contrib/gzip v1.2.5/go.mod h1:aomRgR7ftdZV3uWY0gW/m8rChfxau0n8YVvwlOHONzw= github.com/gin-contrib/sessions v1.0.4 h1:ha6CNdpYiTOK/hTp05miJLbpTSNfOnFg5Jm2kbcqy8U= github.com/gin-contrib/sessions v1.0.4/go.mod h1:ccmkrb2z6iU2osiAHZG3x3J4suJK+OU27oqzlWOqQgs= github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= -github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= -github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -46,12 +44,14 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 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.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= -github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= +github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U= github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -81,8 +81,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI= github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw= +github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -91,153 +91,151 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 h1:mFWunSatvkQQDhpdyuFAYwyAan3hzCuma+Pz8sqvOfg= -github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= +github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= -github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA= -github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= +github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= +github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= +github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/nicksnyder/go-i18n/v2 v2.6.0 h1:C/m2NNWNiTB6SK4Ao8df5EWm3JETSTIGNXBpMJTxzxQ= -github.com/nicksnyder/go-i18n/v2 v2.6.0/go.mod h1:88sRqr0C6OPyJn0/KRNaEz1uWorjxIKP7rUUcvycecE= +github.com/nicksnyder/go-i18n/v2 v2.6.1 h1:JDEJraFsQE17Dut9HFDHzCoAWGEQJom5s0TRd17NIEQ= +github.com/nicksnyder/go-i18n/v2 v2.6.1/go.mod h1:Vee0/9RD3Quc/NmwEjzzD7VTZ+Ir7QbXocrkhOzmUKA= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= -github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0= -github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU= +github.com/pires/go-proxyproto v0.9.2 h1:H1UdHn695zUVVmB0lQ354lOWHOy6TZSpzBl3tgN0s1U= +github.com/pires/go-proxyproto v0.9.2/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -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.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= -github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= -github.com/refraction-networking/utls v1.8.0 h1:L38krhiTAyj9EeiQQa2sg+hYb4qwLCqdMcpZrRfbONE= -github.com/refraction-networking/utls v1.8.0/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM= -github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= -github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw= +github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= +github.com/refraction-networking/utls v1.8.2 h1:j4Q1gJj0xngdeH+Ox/qND11aEfhpgoEvV+S9iJ2IdQo= +github.com/refraction-networking/utls v1.8.2/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/sagernet/sing v0.7.10 h1:2yPhZFx+EkyHPH8hXNezgyRSHyGY12CboId7CtwLROw= -github.com/sagernet/sing v0.7.10/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.7.17 h1:Jg4RUYIaQWTi7iY5ROHi3/Zsgxn4SPoRTwbdt35mt50= +github.com/sagernet/sing v0.7.17/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing-shadowsocks v0.2.9 h1:Paep5zCszRKsEn8587O0MnhFWKJwDW1Y4zOYYlIxMkM= github.com/sagernet/sing-shadowsocks v0.2.9/go.mod h1:TE/Z6401Pi8tgr0nBZcM/xawAI6u3F6TTbz4nH/qw+8= -github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4= -github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg= -github.com/shirou/gopsutil/v4 v4.25.8 h1:NnAsw9lN7587WHxjJA9ryDnqhJpFH6A+wagYWTOH970= -github.com/shirou/gopsutil/v4 v4.25.8/go.mod h1:q9QdMmfAOVIw7a+eF86P7ISEU6ka+NLgkUxlopV4RwI= +github.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY= +github.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= -github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= -github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI= -github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU= +github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= +github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= -github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c h1:LHLhQY3mKXSpTcQAkjFR4/6ar3rXjQryNeM7khK3AHU= -github.com/xtls/reality v0.0.0-20250904214705-431b6ff8c67c/go.mod h1:XxvnCCgBee4WWE0bc4E+a7wbk8gkJ/rS0vNVNtC5qp0= -github.com/xtls/xray-core v1.250911.0 h1:KMN8zVurAjHFixiUoFV/jwmzYohf27dQRntjV+8LQno= -github.com/xtls/xray-core v1.250911.0/go.mod h1:LkqA/BFVtPS2e5fRzg/bkYas9nQu4Uztlx+/fjlLM9k= +github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237 h1:UXjrmniKlY+ZbIqpN91lejB3pszQQQRVu1vqH/p/aGM= +github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237/go.mod h1:vbHCV/3VWUvy1oKvTxxWJRPEWSeR1sYgQHIh6u/JiZQ= +github.com/xtls/xray-core v1.260131.0 h1:gPBykLhUvRZ8sfubNerkwWqV3c15UtmSYQG2cgKqrV4= +github.com/xtls/xray-core v1.260131.0/go.mod h1:cxzYFZrxu1B1NtPjHsqv4UzgDvRA71mV4rXYH4KtO7Q= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -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.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= -golang.org/x/arch v0.21.0 h1:iTC9o7+wP6cPWpDWkivCvQFGAHDQ59SrSxsLPcnkArw= -golang.org/x/arch v0.21.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= -golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg= +golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= -golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= -golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A= golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 h1:/OQuEa4YWtDt7uQWHd3q3sUMb+QOLQUg1xa8CEsRv5w= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= -google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY= gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= -gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c h1:m/r7OM+Y2Ty1sgBQ7Qb27VgIMBW8ZZhT4gLnUyDIhzI= -gvisor.dev/gvisor v0.0.0-20250503011706-39ed1f5ac29c/go.mod h1:3r5CMtNQMKIvBlrmM9xWUNamjKBYPOWyXOjmg5Kts3g= +gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0 h1:Lk6hARj5UPY47dBep70OD/TIMwikJ5fGUGX0Rm3Xigk= +gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0/go.mod h1:QkHjoMIBaYtpVufgwv3keYAbln78mBoCuShZrPrer1Q= lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= diff --git a/main.go b/main.go index f6441f3e..f1121bb0 100644 --- a/main.go +++ b/main.go @@ -33,7 +33,7 @@ func runWebServer() { logger.InitLogger(logging.DEBUG) case config.Info: logger.InitLogger(logging.INFO) - case config.Warn: + case config.Warning: logger.InitLogger(logging.WARNING) case config.Error: logger.InitLogger(logging.ERROR) diff --git a/sub/subJsonService.go b/sub/subJsonService.go index ef3673ea..1da1da85 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -171,12 +171,12 @@ func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client, case "tls": if newStream["security"] != "tls" { newStream["security"] = "tls" - newStream["tslSettings"] = map[string]interface{}{} + newStream["tlsSettings"] = map[string]interface{}{} } case "none": if newStream["security"] != "none" { newStream["security"] = "none" - delete(newStream, "tslSettings") + delete(newStream, "tlsSettings") } } streamSettings, _ := json.MarshalIndent(newStream, "", " ") @@ -291,21 +291,6 @@ func (s *SubJsonService) realityData(rData map[string]interface{}) map[string]in func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_util.RawMessage, client model.Client, encryption string) json_util.RawMessage { outbound := Outbound{} - usersData := make([]UserVnext, 1) - - usersData[0].ID = client.ID - usersData[0].Level = 8 - if inbound.Protocol == model.VLESS { - usersData[0].Flow = client.Flow - usersData[0].Encryption = encryption - } - - vnextData := make([]VnextSetting, 1) - vnextData[0] = VnextSetting{ - Address: inbound.Listen, - Port: inbound.Port, - Users: usersData, - } outbound.Protocol = string(inbound.Protocol) outbound.Tag = "proxy" @@ -313,9 +298,15 @@ func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_ut outbound.Mux = json_util.RawMessage(s.mux) } outbound.StreamSettings = streamSettings - outbound.Settings = OutboundSettings{ - Vnext: vnextData, + settings := make(map[string]any) + settings["address"] = inbound.Listen + settings["port"] = inbound.Port + settings["id"] = client.ID + if inbound.Protocol == model.VLESS { + settings["flow"] = client.Flow + settings["encryption"] = encryption } + outbound.Settings = settings result, _ := json.MarshalIndent(outbound, "", " ") return result @@ -352,8 +343,8 @@ func (s *SubJsonService) genServer(inbound *model.Inbound, streamSettings json_u outbound.Mux = json_util.RawMessage(s.mux) } outbound.StreamSettings = streamSettings - outbound.Settings = OutboundSettings{ - Servers: serverData, + outbound.Settings = map[string]any{ + "servers": serverData, } result, _ := json.MarshalIndent(outbound, "", " ") @@ -361,30 +352,11 @@ func (s *SubJsonService) genServer(inbound *model.Inbound, streamSettings json_u } type Outbound struct { - Protocol string `json:"protocol"` - Tag string `json:"tag"` - StreamSettings json_util.RawMessage `json:"streamSettings"` - Mux json_util.RawMessage `json:"mux,omitempty"` - ProxySettings map[string]interface{} `json:"proxySettings,omitempty"` - Settings OutboundSettings `json:"settings,omitempty"` -} - -type OutboundSettings struct { - Vnext []VnextSetting `json:"vnext,omitempty"` - Servers []ServerSetting `json:"servers,omitempty"` -} - -type VnextSetting struct { - Address string `json:"address"` - Port int `json:"port"` - Users []UserVnext `json:"users"` -} - -type UserVnext struct { - Encryption string `json:"encryption,omitempty"` - Flow string `json:"flow,omitempty"` - ID string `json:"id"` - Level int `json:"level"` + Protocol string `json:"protocol"` + Tag string `json:"tag"` + StreamSettings json_util.RawMessage `json:"streamSettings"` + Mux json_util.RawMessage `json:"mux,omitempty"` + Settings map[string]any `json:"settings,omitempty"` } type ServerSetting struct { diff --git a/util/random/random.go b/util/random/random.go index 2de615b2..cf5c4876 100644 --- a/util/random/random.go +++ b/util/random/random.go @@ -1,8 +1,8 @@ package random import ( - "math/rand" - "time" + "crypto/rand" + "math/big" ) var ( @@ -15,8 +15,6 @@ var ( ) func init() { - rand.Seed(time.Now().UnixNano()) - for i := 0; i < 10; i++ { numSeq[i] = rune('0' + i) } @@ -39,11 +37,20 @@ func init() { func Seq(n int) string { runes := make([]rune, n) for i := 0; i < n; i++ { - runes[i] = allSeq[rand.Intn(len(allSeq))] + idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(allSeq)))) + if err != nil { + panic("crypto/rand failed: " + err.Error()) + } + runes[i] = allSeq[idx.Int64()] } return string(runes) } func Num(n int) int { - return rand.Intn(n) + bn := big.NewInt(int64(n)) + r, err := rand.Int(rand.Reader, bn) + if err != nil { + panic("crypto/rand failed: " + err.Error()) + } + return int(r.Int64()) } diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js index ddf982ac..6c0ec1ce 100644 --- a/web/assets/js/model/inbound.js +++ b/web/assets/js/model/inbound.js @@ -7,6 +7,7 @@ const Protocols = { SOCKS: 'socks', HTTP: 'http', WIREGUARD: 'wireguard', + TUN: 'tun', }; const SSMethods = { @@ -317,7 +318,7 @@ TcpStreamSettings.TcpResponse = class extends XrayCommonClass { class KcpStreamSettings extends XrayCommonClass { constructor( - mtu = 1350, + mtu = 1250, tti = 50, uplinkCapacity = 5, downlinkCapacity = 20, @@ -553,7 +554,6 @@ class TlsStreamSettings extends XrayCommonClass { maxVersion = TLS_VERSION_OPTION.TLS13, cipherSuites = '', rejectUnknownSni = false, - verifyPeerCertInNames = ['dns.google', 'cloudflare-dns.com'], disableSystemRoot = false, enableSessionResumption = false, certificates = [new TlsStreamSettings.Cert()], @@ -568,7 +568,6 @@ class TlsStreamSettings extends XrayCommonClass { this.maxVersion = maxVersion; this.cipherSuites = cipherSuites; this.rejectUnknownSni = rejectUnknownSni; - this.verifyPeerCertInNames = Array.isArray(verifyPeerCertInNames) ? verifyPeerCertInNames.join(",") : verifyPeerCertInNames; this.disableSystemRoot = disableSystemRoot; this.enableSessionResumption = enableSessionResumption; this.certs = certificates; @@ -602,7 +601,6 @@ class TlsStreamSettings extends XrayCommonClass { json.maxVersion, json.cipherSuites, json.rejectUnknownSni, - json.verifyPeerCertInNames, json.disableSystemRoot, json.enableSessionResumption, certs, @@ -620,7 +618,6 @@ class TlsStreamSettings extends XrayCommonClass { maxVersion: this.maxVersion, cipherSuites: this.cipherSuites, rejectUnknownSni: this.rejectUnknownSni, - verifyPeerCertInNames: this.verifyPeerCertInNames.split(","), disableSystemRoot: this.disableSystemRoot, enableSessionResumption: this.enableSessionResumption, certificates: TlsStreamSettings.toJsonArray(this.certs), @@ -712,20 +709,20 @@ TlsStreamSettings.Settings = class extends XrayCommonClass { super(); this.allowInsecure = allowInsecure; this.fingerprint = fingerprint; - this.echConfigList = echConfigList + this.echConfigList = echConfigList; } static fromJson(json = {}) { return new TlsStreamSettings.Settings( json.allowInsecure, json.fingerprint, - json.echConfigList + json.echConfigList, ); } toJson() { return { allowInsecure: this.allowInsecure, fingerprint: this.fingerprint, - echConfigList: this.echConfigList + echConfigList: this.echConfigList, }; } }; @@ -855,6 +852,7 @@ class SockoptStreamSettings extends XrayCommonClass { V6Only = false, tcpWindowClamp = 600, interfaceName = "", + trustedXForwardedFor = [], ) { super(); this.acceptProxyProtocol = acceptProxyProtocol; @@ -873,6 +871,7 @@ class SockoptStreamSettings extends XrayCommonClass { this.V6Only = V6Only; this.tcpWindowClamp = tcpWindowClamp; this.interfaceName = interfaceName; + this.trustedXForwardedFor = trustedXForwardedFor; } static fromJson(json = {}) { @@ -894,11 +893,12 @@ class SockoptStreamSettings extends XrayCommonClass { json.V6Only, json.tcpWindowClamp, json.interface, + json.trustedXForwardedFor || [], ); } toJson() { - return { + const result = { acceptProxyProtocol: this.acceptProxyProtocol, tcpFastOpen: this.tcpFastOpen, mark: this.mark, @@ -916,6 +916,10 @@ class SockoptStreamSettings extends XrayCommonClass { tcpWindowClamp: this.tcpWindowClamp, interface: this.interfaceName, }; + if (this.trustedXForwardedFor && this.trustedXForwardedFor.length > 0) { + result.trustedXForwardedFor = this.trustedXForwardedFor; + } + return result; } } @@ -1212,6 +1216,13 @@ class Inbound extends XrayCommonClass { return false; } + canEnableVisionSeed() { + if (!this.canEnableTlsFlow()) return false; + const clients = this.settings?.vlesses; + if (!Array.isArray(clients)) return false; + return clients.some(c => c?.flow === TLS_FLOW_CONTROL.VISION || c?.flow === TLS_FLOW_CONTROL.VISION_UDP443); + } + canEnableReality() { if (![Protocols.VLESS, Protocols.TROJAN].includes(this.protocol)) return false; return ["tcp", "http", "grpc", "xhttp"].includes(this.network); @@ -1722,6 +1733,7 @@ Inbound.Settings = class extends XrayCommonClass { case Protocols.SOCKS: return new Inbound.SocksSettings(protocol); case Protocols.HTTP: return new Inbound.HttpSettings(protocol); case Protocols.WIREGUARD: return new Inbound.WireguardSettings(protocol); + case Protocols.TUN: return new Inbound.TunSettings(protocol); default: return null; } } @@ -1736,6 +1748,7 @@ Inbound.Settings = class extends XrayCommonClass { case Protocols.SOCKS: return Inbound.SocksSettings.fromJson(json); case Protocols.HTTP: return Inbound.HttpSettings.fromJson(json); case Protocols.WIREGUARD: return Inbound.WireguardSettings.fromJson(json); + case Protocols.TUN: return Inbound.TunSettings.fromJson(json); default: return null; } } @@ -1856,6 +1869,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings { encryption = "none", fallbacks = [], selectedAuth = undefined, + testseed = [900, 500, 900, 256], ) { super(protocol); this.vlesses = vlesses; @@ -1863,6 +1877,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings { this.encryption = encryption; this.fallbacks = fallbacks; this.selectedAuth = selectedAuth; + this.testseed = testseed; } addFallback() { @@ -1874,13 +1889,19 @@ Inbound.VLESSSettings = class extends Inbound.Settings { } static fromJson(json = {}) { + let testseed = [900, 500, 900, 256]; + if (json.testseed && Array.isArray(json.testseed) && json.testseed.length >= 4) { + testseed = json.testseed; + } + const obj = new Inbound.VLESSSettings( Protocols.VLESS, (json.clients || []).map(client => Inbound.VLESSSettings.VLESS.fromJson(client)), json.decryption, json.encryption, Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks || []), - json.selectedAuth + json.selectedAuth, + testseed ); return obj; } @@ -1906,6 +1927,10 @@ Inbound.VLESSSettings = class extends Inbound.Settings { json.selectedAuth = this.selectedAuth; } + if (this.testseed && this.testseed.length >= 4) { + json.testseed = this.testseed; + } + return json; } }; @@ -2418,7 +2443,7 @@ Inbound.HttpSettings.HttpAccount = class extends XrayCommonClass { Inbound.WireguardSettings = class extends XrayCommonClass { constructor( protocol, - mtu = 1420, + mtu = 1250, secretKey = Wireguard.generateKeypair().privateKey, peers = [new Inbound.WireguardSettings.Peer()], kernelMode = false @@ -2498,3 +2523,34 @@ Inbound.WireguardSettings.Peer = class extends XrayCommonClass { }; } }; + +Inbound.TunSettings = class extends Inbound.Settings { + constructor( + protocol, + name = 'xray0', + mtu = 1500, + userLevel = 0 + ) { + super(protocol); + this.name = name; + this.mtu = mtu; + this.userLevel = userLevel; + } + + static fromJson(json = {}) { + return new Inbound.TunSettings( + Protocols.TUN, + json.name ?? 'xray0', + json.mtu ?? json.MTU ?? 1500, + json.userLevel ?? 0 + ); + } + + toJson() { + return { + name: this.name || 'xray0', + mtu: this.mtu || 1500, + userLevel: this.userLevel || 0, + }; + } +}; \ No newline at end of file diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js index a298c75c..35626ef5 100644 --- a/web/assets/js/model/outbound.js +++ b/web/assets/js/model/outbound.js @@ -8,7 +8,8 @@ const Protocols = { Shadowsocks: "shadowsocks", Socks: "socks", HTTP: "http", - Wireguard: "wireguard" + Wireguard: "wireguard", + Hysteria: "hysteria" }; const SSMethods = { @@ -162,7 +163,7 @@ class TcpStreamSettings extends CommonClass { class KcpStreamSettings extends CommonClass { constructor( - mtu = 1350, + mtu = 1250, tti = 50, uplinkCapacity = 5, downlinkCapacity = 20, @@ -354,6 +355,7 @@ class TlsStreamSettings extends CommonClass { fingerprint = '', allowInsecure = false, echConfigList = '', + verifyPeerCertByName = [] ) { super(); this.serverName = serverName; @@ -361,6 +363,7 @@ class TlsStreamSettings extends CommonClass { this.fingerprint = fingerprint; this.allowInsecure = allowInsecure; this.echConfigList = echConfigList; + this.verifyPeerCertByName = Array.isArray(verifyPeerCertByName) ? verifyPeerCertByName.join(",") : verifyPeerCertByName; } static fromJson(json = {}) { @@ -370,6 +373,7 @@ class TlsStreamSettings extends CommonClass { json.fingerprint, json.allowInsecure, json.echConfigList, + json.verifyPeerCertByName ); } @@ -380,6 +384,7 @@ class TlsStreamSettings extends CommonClass { fingerprint: this.fingerprint, allowInsecure: this.allowInsecure, echConfigList: this.echConfigList, + verifyPeerCertByName: this.verifyPeerCertByName.length > 0 ? this.verifyPeerCertByName.split(",") : undefined, }; } } @@ -422,6 +427,91 @@ class RealityStreamSettings extends CommonClass { }; } }; + +class HysteriaStreamSettings extends CommonClass { + constructor( + version = 2, + auth = '', + congestion = '', + up = '0', + down = '0', + udphopPort = '', + udphopInterval = 30, + initStreamReceiveWindow = 8388608, + maxStreamReceiveWindow = 8388608, + initConnectionReceiveWindow = 20971520, + maxConnectionReceiveWindow = 20971520, + maxIdleTimeout = 30, + keepAlivePeriod = 0, + disablePathMTUDiscovery = false + ) { + super(); + this.version = version; + this.auth = auth; + this.congestion = congestion; + this.up = up; + this.down = down; + this.udphopPort = udphopPort; + this.udphopInterval = udphopInterval; + this.initStreamReceiveWindow = initStreamReceiveWindow; + this.maxStreamReceiveWindow = maxStreamReceiveWindow; + this.initConnectionReceiveWindow = initConnectionReceiveWindow; + this.maxConnectionReceiveWindow = maxConnectionReceiveWindow; + this.maxIdleTimeout = maxIdleTimeout; + this.keepAlivePeriod = keepAlivePeriod; + this.disablePathMTUDiscovery = disablePathMTUDiscovery; + } + + static fromJson(json = {}) { + let udphopPort = ''; + let udphopInterval = 30; + if (json.udphop) { + udphopPort = json.udphop.port || ''; + udphopInterval = json.udphop.interval || 30; + } + return new HysteriaStreamSettings( + json.version, + json.auth, + json.congestion, + json.up, + json.down, + udphopPort, + udphopInterval, + json.initStreamReceiveWindow, + json.maxStreamReceiveWindow, + json.initConnectionReceiveWindow, + json.maxConnectionReceiveWindow, + json.maxIdleTimeout, + json.keepAlivePeriod, + json.disablePathMTUDiscovery + ); + } + + toJson() { + const result = { + version: this.version, + auth: this.auth, + congestion: this.congestion, + up: this.up, + down: this.down, + initStreamReceiveWindow: this.initStreamReceiveWindow, + maxStreamReceiveWindow: this.maxStreamReceiveWindow, + initConnectionReceiveWindow: this.initConnectionReceiveWindow, + maxConnectionReceiveWindow: this.maxConnectionReceiveWindow, + maxIdleTimeout: this.maxIdleTimeout, + keepAlivePeriod: this.keepAlivePeriod, + disablePathMTUDiscovery: this.disablePathMTUDiscovery + }; + if (this.udphopPort) { + result.udphop = { + port: this.udphopPort, + interval: this.udphopInterval + }; + } + return result; + } +}; + class SockoptStreamSettings extends CommonClass { constructor( dialerProxy = "", @@ -430,6 +520,7 @@ class SockoptStreamSettings extends CommonClass { tcpMptcp = false, penetrate = false, addressPortStrategy = Address_Port_Strategy.NONE, + trustedXForwardedFor = [], ) { super(); this.dialerProxy = dialerProxy; @@ -438,6 +529,7 @@ class SockoptStreamSettings extends CommonClass { this.tcpMptcp = tcpMptcp; this.penetrate = penetrate; this.addressPortStrategy = addressPortStrategy; + this.trustedXForwardedFor = trustedXForwardedFor; } static fromJson(json = {}) { @@ -448,12 +540,13 @@ class SockoptStreamSettings extends CommonClass { json.tcpKeepAliveInterval, json.tcpMptcp, json.penetrate, - json.addressPortStrategy + json.addressPortStrategy, + json.trustedXForwardedFor || [] ); } toJson() { - return { + const result = { dialerProxy: this.dialerProxy, tcpFastOpen: this.tcpFastOpen, tcpKeepAliveInterval: this.tcpKeepAliveInterval, @@ -461,6 +554,34 @@ class SockoptStreamSettings extends CommonClass { penetrate: this.penetrate, addressPortStrategy: this.addressPortStrategy }; + if (this.trustedXForwardedFor && this.trustedXForwardedFor.length > 0) { + result.trustedXForwardedFor = this.trustedXForwardedFor; + } + return result; + } +} + +class UdpMask extends CommonClass { + constructor(type = 'salamander', password = '') { + super(); + this.type = type; + this.password = password; + } + + static fromJson(json = {}) { + return new UdpMask( + json.type, + json.settings?.password || '' + ); + } + + toJson() { + return { + type: this.type, + settings: { + password: this.password + } + }; } } @@ -476,6 +597,8 @@ class StreamSettings extends CommonClass { grpcSettings = new GrpcStreamSettings(), httpupgradeSettings = new HttpUpgradeStreamSettings(), xhttpSettings = new xHTTPStreamSettings(), + hysteriaSettings = new HysteriaStreamSettings(), + udpmasks = [], sockopt = undefined, ) { super(); @@ -489,9 +612,19 @@ class StreamSettings extends CommonClass { this.grpc = grpcSettings; this.httpupgrade = httpupgradeSettings; this.xhttp = xhttpSettings; + this.hysteria = hysteriaSettings; + this.udpmasks = udpmasks; this.sockopt = sockopt; } + addUdpMask() { + this.udpmasks.push(new UdpMask()); + } + + delUdpMask(index) { + this.udpmasks.splice(index, 1); + } + get isTls() { return this.security === 'tls'; } @@ -520,6 +653,8 @@ class StreamSettings extends CommonClass { GrpcStreamSettings.fromJson(json.grpcSettings), HttpUpgradeStreamSettings.fromJson(json.httpupgradeSettings), xHTTPStreamSettings.fromJson(json.xhttpSettings), + HysteriaStreamSettings.fromJson(json.hysteriaSettings), + json.udpmasks ? json.udpmasks.map(mask => UdpMask.fromJson(mask)) : [], SockoptStreamSettings.fromJson(json.sockopt), ); } @@ -537,6 +672,8 @@ class StreamSettings extends CommonClass { grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined, httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined, xhttpSettings: network === 'xhttp' ? this.xhttp.toJson() : undefined, + hysteriaSettings: network === 'hysteria' ? this.hysteria.toJson() : undefined, + udpmasks: this.udpmasks.length > 0 ? this.udpmasks.map(mask => mask.toJson()) : undefined, sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined, }; } @@ -596,11 +733,12 @@ class Outbound extends CommonClass { set protocol(protocol) { this._protocol = protocol; this.settings = Outbound.Settings.getSettings(protocol); - this.stream = new StreamSettings(); + this.stream = new StreamSettings(protocol === Protocols.Hysteria ? 'hysteria' : 'tcp'); } canEnableTls() { - if (![Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks].includes(this.protocol)) return false; + if (![Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks, Protocols.Hysteria].includes(this.protocol)) return false; + if (this.protocol === Protocols.Hysteria) return this.stream.network === 'hysteria'; return ["tcp", "ws", "http", "grpc", "httpupgrade", "xhttp"].includes(this.stream.network); } @@ -612,13 +750,19 @@ class Outbound extends CommonClass { return false; } + canEnableVisionSeed() { + if (!this.canEnableTlsFlow()) return false; + const flow = this.settings?.flow; + return flow === TLS_FLOW_CONTROL.VISION || flow === TLS_FLOW_CONTROL.VISION_UDP443; + } + canEnableReality() { if (![Protocols.VLESS, Protocols.Trojan].includes(this.protocol)) return false; return ["tcp", "http", "grpc", "xhttp"].includes(this.stream.network); } canEnableStream() { - return [Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks].includes(this.protocol); + return [Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks, Protocols.Hysteria].includes(this.protocol); } canEnableMux() { @@ -645,10 +789,6 @@ class Outbound extends CommonClass { ].includes(this.protocol); } - hasVnext() { - return [Protocols.VMess, Protocols.VLESS].includes(this.protocol); - } - hasServers() { return [Protocols.Trojan, Protocols.Shadowsocks, Protocols.Socks, Protocols.HTTP].includes(this.protocol); } @@ -661,7 +801,8 @@ class Outbound extends CommonClass { Protocols.Trojan, Protocols.Shadowsocks, Protocols.Socks, - Protocols.HTTP + Protocols.HTTP, + Protocols.Hysteria ].includes(this.protocol); } @@ -688,13 +829,19 @@ class Outbound extends CommonClass { if (this.stream?.sockopt) stream = { sockopt: this.stream.sockopt.toJson() }; } + let settingsOut = this.settings instanceof CommonClass ? this.settings.toJson() : this.settings; + if (settingsOut && typeof settingsOut === 'object') { + Object.keys(settingsOut).forEach(k => { + if (settingsOut[k] === undefined || settingsOut[k] === null) delete settingsOut[k]; + }); + } return { - tag: this.tag == '' ? undefined : this.tag, protocol: this.protocol, - settings: this.settings instanceof CommonClass ? this.settings.toJson() : this.settings, - streamSettings: stream, - sendThrough: this.sendThrough != "" ? this.sendThrough : undefined, - mux: this.mux?.enabled ? this.mux : undefined, + settings: settingsOut, + ...(this.tag ? { tag: this.tag } : {}), + ...(stream ? { streamSettings: stream } : {}), + ...(this.sendThrough ? { sendThrough: this.sendThrough } : {}), + ...(this.mux?.enabled ? { mux: this.mux } : {}), }; } @@ -708,6 +855,9 @@ class Outbound extends CommonClass { case Protocols.Trojan: case 'ss': return this.fromParamLink(link); + case 'hysteria2': + case Protocols.Hysteria: + return this.fromHysteriaLink(link); default: return null; } @@ -828,6 +978,65 @@ class Outbound extends CommonClass { remark = remark.length > 0 ? remark.substring(1) : 'out-' + protocol + '-' + port; return new Outbound(remark, protocol, settings, stream); } + + static fromHysteriaLink(link) { + const regex = /^hysteria2?:\/\/([^@]+)@([^:?#]+):(\d+)([^#]*)(#.*)?$/; + const match = link.match(regex); + + if (!match) return null; + + let [, password, address, port, params, hash] = match; + port = parseInt(port); + let urlParams = new URLSearchParams(params); + let stream = new StreamSettings('hysteria', 'none'); + + stream.hysteria.auth = password; + stream.hysteria.congestion = urlParams.get('congestion') ?? ''; + stream.hysteria.up = urlParams.get('up') ?? '0'; + stream.hysteria.down = urlParams.get('down') ?? '0'; + stream.hysteria.udphopPort = urlParams.get('mport') ?? urlParams.get('udphopPort') ?? ''; + stream.hysteria.udphopInterval = parseInt(urlParams.get('udphopInterval') ?? '30'); + + if (urlParams.has('initStreamReceiveWindow')) { + stream.hysteria.initStreamReceiveWindow = parseInt(urlParams.get('initStreamReceiveWindow')); + } + if (urlParams.has('maxStreamReceiveWindow')) { + stream.hysteria.maxStreamReceiveWindow = parseInt(urlParams.get('maxStreamReceiveWindow')); + } + if (urlParams.has('initConnectionReceiveWindow')) { + stream.hysteria.initConnectionReceiveWindow = parseInt(urlParams.get('initConnectionReceiveWindow')); + } + if (urlParams.has('maxConnectionReceiveWindow')) { + stream.hysteria.maxConnectionReceiveWindow = parseInt(urlParams.get('maxConnectionReceiveWindow')); + } + if (urlParams.has('maxIdleTimeout')) { + stream.hysteria.maxIdleTimeout = parseInt(urlParams.get('maxIdleTimeout')); + } + if (urlParams.has('keepAlivePeriod')) { + stream.hysteria.keepAlivePeriod = parseInt(urlParams.get('keepAlivePeriod')); + } + if (urlParams.has('disablePathMTUDiscovery')) { + stream.hysteria.disablePathMTUDiscovery = urlParams.get('disablePathMTUDiscovery') === 'true'; + } + if (urlParams.has('obfs')) { + stream.udpmasks[0] = new UdpMask(urlParams.get('obfs'), urlParams.get('obfs-password')); + } + if (urlParams.has('security')){ + stream.security = urlParams.get('security'); + stream.tls = new TlsStreamSettings( + urlParams.get('sni'), + urlParams.get('alpn') ? urlParams.get('alpn').split(',') : [], + urlParams.get('fp') ?? undefined, + urlParams.get('insecure') ?? urlParams.get('allowInsecure') ?? false, + ); + } + + let settings = new Outbound.HysteriaSettings(address, port, 2); + + let remark = hash ? decodeURIComponent(hash.substring(1)) : `out-hysteria-${port}`; + + return new Outbound(remark, Protocols.Hysteria, settings, stream); + } } Outbound.Settings = class extends CommonClass { @@ -848,6 +1057,7 @@ Outbound.Settings = class extends CommonClass { case Protocols.Socks: return new Outbound.SocksSettings(); case Protocols.HTTP: return new Outbound.HttpSettings(); case Protocols.Wireguard: return new Outbound.WireguardSettings(); + case Protocols.Hysteria: return new Outbound.HysteriaSettings(); default: return null; } } @@ -864,6 +1074,7 @@ Outbound.Settings = class extends CommonClass { case Protocols.Socks: return Outbound.SocksSettings.fromJson(json); case Protocols.HTTP: return Outbound.HttpSettings.fromJson(json); case Protocols.Wireguard: return Outbound.WireguardSettings.fromJson(json); + case Protocols.Hysteria: return Outbound.HysteriaSettings.fromJson(json); default: return null; } } @@ -1017,54 +1228,64 @@ Outbound.VmessSettings = class extends CommonClass { } static fromJson(json = {}) { - if (ObjectUtil.isArrEmpty(json.vnext)) return new Outbound.VmessSettings(); + if (ObjectUtil.isEmpty(json.address) || ObjectUtil.isEmpty(json.port)) return new Outbound.VmessSettings(); return new Outbound.VmessSettings( - json.vnext[0].address, - json.vnext[0].port, - json.vnext[0].users[0].id, - json.vnext[0].users[0].security, + json.address, + json.port, + json.id, + json.security, ); } toJson() { return { - vnext: [{ - address: this.address, - port: this.port, - users: [{ id: this.id, security: this.security }], - }], + address: this.address, + port: this.port, + id: this.id, + security: this.security, }; } }; Outbound.VLESSSettings = class extends CommonClass { - constructor(address, port, id, flow, encryption) { + constructor(address, port, id, flow, encryption, testpre = 0, testseed = [900, 500, 900, 256]) { super(); this.address = address; this.port = port; this.id = id; this.flow = flow; this.encryption = encryption; + this.testpre = testpre; + this.testseed = testseed; } static fromJson(json = {}) { - if (ObjectUtil.isArrEmpty(json.vnext)) return new Outbound.VLESSSettings(); + if (ObjectUtil.isEmpty(json.address) || ObjectUtil.isEmpty(json.port)) return new Outbound.VLESSSettings(); return new Outbound.VLESSSettings( - json.vnext[0].address, - json.vnext[0].port, - json.vnext[0].users[0].id, - json.vnext[0].users[0].flow, - json.vnext[0].users[0].encryption, + json.address, + json.port, + json.id, + json.flow, + json.encryption, + json.testpre || 0, + json.testseed && json.testseed.length >= 4 ? json.testseed : [900, 500, 900, 256] ); } toJson() { - return { - vnext: [{ - address: this.address, - port: this.port, - users: [{ id: this.id, flow: this.flow, encryption: this.encryption }], - }], + const result = { + address: this.address, + port: this.port, + id: this.id, + flow: this.flow, + encryption: this.encryption, }; + if (this.testpre > 0) { + result.testpre = this.testpre; + } + if (this.testseed && this.testseed.length >= 4) { + result.testseed = this.testseed; + } + return result; } }; Outbound.TrojanSettings = class extends CommonClass { @@ -1195,7 +1416,7 @@ Outbound.HttpSettings = class extends CommonClass { Outbound.WireguardSettings = class extends CommonClass { constructor( - mtu = 1420, + mtu = 1250, secretKey = '', address = [''], workers = 2, @@ -1286,4 +1507,30 @@ Outbound.WireguardSettings.Peer = class extends CommonClass { keepAlive: this.keepAlive ?? undefined, }; } +}; + +Outbound.HysteriaSettings = class extends CommonClass { + constructor(address = '', port = 443, version = 2) { + super(); + this.address = address; + this.port = port; + this.version = version; + } + + static fromJson(json = {}) { + if (Object.keys(json).length === 0) return new Outbound.HysteriaSettings(); + return new Outbound.HysteriaSettings( + json.address, + json.port, + json.version + ); + } + + toJson() { + return { + address: this.address, + port: this.port, + version: this.version + }; + } }; \ No newline at end of file diff --git a/web/html/xui/form/inbound.html b/web/html/xui/form/inbound.html index d7fb16b6..24aafe38 100644 --- a/web/html/xui/form/inbound.html +++ b/web/html/xui/form/inbound.html @@ -28,7 +28,7 @@ - + @@ -100,6 +100,11 @@ {{template "form/wireguard"}} + + + - + @@ -253,7 +285,14 @@ - + + + @@ -261,12 +300,17 @@ - TCP - mKCP - WebSocket - gRPC - HTTPUpgrade - XHTTP + + + + + + + + @@ -433,6 +561,9 @@ + + + @@ -488,6 +619,15 @@ + + + CF-Connecting-IP + X-Real-IP + True-Client-IP + X-Client-IP + + @@ -514,7 +654,7 @@ - Link: + Link: diff --git a/web/html/xui/form/protocol/tun.html b/web/html/xui/form/protocol/tun.html new file mode 100644 index 00000000..3eade22b --- /dev/null +++ b/web/html/xui/form/protocol/tun.html @@ -0,0 +1,44 @@ +{{define "form/tun"}} + + + + + + + + + + + + + + +{{end}} \ No newline at end of file diff --git a/web/html/xui/form/protocol/vless.html b/web/html/xui/form/protocol/vless.html index 1f972260..75a5f8be 100644 --- a/web/html/xui/form/protocol/vless.html +++ b/web/html/xui/form/protocol/vless.html @@ -75,4 +75,33 @@ + {{end}} diff --git a/web/html/xui/form/stream/external_proxy.html b/web/html/xui/form/stream/external_proxy.html index 88600e41..46afaf9f 100644 --- a/web/html/xui/form/stream/external_proxy.html +++ b/web/html/xui/form/stream/external_proxy.html @@ -17,10 +17,10 @@ - + - -{{end}} +{{end}} \ No newline at end of file diff --git a/web/html/xui/form/stream/stream_sockopt.html b/web/html/xui/form/stream/stream_sockopt.html index 4480594a..062b83df 100644 --- a/web/html/xui/form/stream/stream_sockopt.html +++ b/web/html/xui/form/stream/stream_sockopt.html @@ -61,6 +61,15 @@ + + + CF-Connecting-IP + X-Real-IP + True-Client-IP + X-Client-IP + + {{end}} diff --git a/web/html/xui/form/tls_settings.html b/web/html/xui/form/tls_settings.html index 87407ce6..2aa2d642 100644 --- a/web/html/xui/form/tls_settings.html +++ b/web/html/xui/form/tls_settings.html @@ -52,6 +52,13 @@ + + + + + + +