diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 182e9c8f..6a33808b 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -7,7 +7,7 @@ on:
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
@@ -31,6 +31,8 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
+ with:
+ install: true
- name: Login to Docker Hub
uses: docker/login-action@v3
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index cdc12733..e0b9ee51 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -72,7 +72,7 @@ jobs:
export GOARCH=s390x
export CC=s390x-linux-gnu-gcc
fi
- go build -o xui-release -v main.go
+ go build -ldflags "-w -s" -o xui-release -v main.go
mkdir x-ui
cp xui-release x-ui/
@@ -85,41 +85,41 @@ jobs:
# Download dependencies
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.1.1/"
if [ "${{ matrix.platform }}" == "amd64" ]; then
- wget ${Xray_URL}Xray-linux-64.zip
+ wget -q ${Xray_URL}Xray-linux-64.zip
unzip Xray-linux-64.zip
rm -f Xray-linux-64.zip
elif [ "${{ matrix.platform }}" == "arm64" ]; then
- wget ${Xray_URL}Xray-linux-arm64-v8a.zip
+ wget -q ${Xray_URL}Xray-linux-arm64-v8a.zip
unzip Xray-linux-arm64-v8a.zip
rm -f Xray-linux-arm64-v8a.zip
elif [ "${{ matrix.platform }}" == "armv7" ]; then
- wget ${Xray_URL}Xray-linux-arm32-v7a.zip
+ wget -q ${Xray_URL}Xray-linux-arm32-v7a.zip
unzip Xray-linux-arm32-v7a.zip
rm -f Xray-linux-arm32-v7a.zip
elif [ "${{ matrix.platform }}" == "armv6" ]; then
- wget ${Xray_URL}Xray-linux-arm32-v6.zip
+ wget -q ${Xray_URL}Xray-linux-arm32-v6.zip
unzip Xray-linux-arm32-v6.zip
rm -f Xray-linux-arm32-v6.zip
elif [ "${{ matrix.platform }}" == "386" ]; then
- wget ${Xray_URL}Xray-linux-32.zip
+ wget -q ${Xray_URL}Xray-linux-32.zip
unzip Xray-linux-32.zip
rm -f Xray-linux-32.zip
elif [ "${{ matrix.platform }}" == "armv5" ]; then
- wget ${Xray_URL}Xray-linux-arm32-v5.zip
+ wget -q ${Xray_URL}Xray-linux-arm32-v5.zip
unzip Xray-linux-arm32-v5.zip
rm -f Xray-linux-arm32-v5.zip
elif [ "${{ matrix.platform }}" == "s390x" ]; then
- wget ${Xray_URL}Xray-linux-s390x.zip
+ wget -q ${Xray_URL}Xray-linux-s390x.zip
unzip Xray-linux-s390x.zip
rm -f Xray-linux-s390x.zip
fi
rm -f geoip.dat geosite.dat
- wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
- wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
- wget -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
- wget -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
- wget -O geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat
- wget -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
+ wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
+ wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
+ wget -q -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
+ wget -q -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
+ wget -q -O geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat
+ wget -q -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
mv xray xray-linux-${{ matrix.platform }}
cd ../..
diff --git a/DockerInit.sh b/DockerInit.sh
index 017f158f..fccc2042 100755
--- a/DockerInit.sh
+++ b/DockerInit.sh
@@ -27,14 +27,14 @@ case $1 in
esac
mkdir -p build/bin
cd build/bin
-wget "https://github.com/XTLS/Xray-core/releases/download/v25.1.1/Xray-linux-${ARCH}.zip"
+wget -q "https://github.com/XTLS/Xray-core/releases/download/v25.1.1/Xray-linux-${ARCH}.zip"
unzip "Xray-linux-${ARCH}.zip"
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
mv xray "xray-linux-${FNAME}"
-wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
-wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
-wget -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
-wget -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
-wget -O geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat
-wget -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
+wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
+wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
+wget -q -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
+wget -q -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
+wget -q -O geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat
+wget -q -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
cd ../../
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 2d223181..36f5235c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,7 @@ COPY . .
ENV CGO_ENABLED=1
ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE"
-RUN go build -o build/x-ui main.go
+RUN go build -ldflags "-w -s" -o build/x-ui main.go
RUN ./DockerInit.sh "$TARGETARCH"
# ========================================================
diff --git a/config/version b/config/version
index e393c3c5..fad066f8 100644
--- a/config/version
+++ b/config/version
@@ -1 +1 @@
-2.4.11
\ No newline at end of file
+2.5.0
\ No newline at end of file
diff --git a/go.mod b/go.mod
index f8f34963..483f05da 100644
--- a/go.mod
+++ b/go.mod
@@ -8,23 +8,23 @@ require (
github.com/gin-gonic/gin v1.10.0
github.com/goccy/go-json v0.10.4
github.com/mymmrac/telego v0.32.0
- github.com/nicksnyder/go-i18n/v2 v2.4.1
+ github.com/nicksnyder/go-i18n/v2 v2.5.0
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/pelletier/go-toml/v2 v2.2.3
github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil/v4 v4.24.12
github.com/valyala/fasthttp v1.58.0
- github.com/xtls/xray-core v1.8.25-0.20250119133207-ca9a90221348
+ github.com/xtls/xray-core v1.8.25-0.20250126155934-7b59379d73c3
go.uber.org/atomic v1.11.0
golang.org/x/text v0.21.0
- google.golang.org/grpc v1.69.4
+ google.golang.org/grpc v1.70.0
gorm.io/driver/sqlite v1.5.7
gorm.io/gorm v1.25.12
)
require (
github.com/andybalholm/brotli v1.1.1 // indirect
- github.com/bytedance/sonic v1.12.7 // indirect
+ github.com/bytedance/sonic v1.12.8 // indirect
github.com/bytedance/sonic/loader v0.2.3 // indirect
github.com/cloudflare/circl v1.5.0 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
@@ -39,7 +39,7 @@ require (
github.com/go-playground/validator/v10 v10.24.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/btree v1.1.3 // indirect
- github.com/google/pprof v0.0.0-20250121033306-997b0b79cac0 // indirect
+ github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 // indirect
github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.4.0 // indirect
@@ -61,6 +61,7 @@ require (
github.com/pires/go-proxyproto v0.8.0 // 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.49.0 // indirect
github.com/refraction-networking/utls v1.6.7 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
@@ -77,7 +78,6 @@ require (
github.com/valyala/fastjson v1.6.4 // indirect
github.com/vishvananda/netlink v1.3.0 // indirect
github.com/vishvananda/netns v0.0.5 // indirect
- github.com/xtls/quic-go v0.48.2 // indirect
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/mock v0.5.0 // indirect
@@ -93,8 +93,8 @@ require (
golang.org/x/tools v0.29.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
- google.golang.org/protobuf v1.36.3 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 // indirect
+ google.golang.org/protobuf v1.36.4 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gvisor.dev/gvisor v0.0.0-20240320123526-dc6abceb7ff0 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
diff --git a/go.sum b/go.sum
index c8cce312..84ebd740 100644
--- a/go.sum
+++ b/go.sum
@@ -4,8 +4,8 @@ github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 h1:Wo41lDOevRJS
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0/go.mod h1:FVGavL/QEBQDcBpr3fAojoK17xX5k9bicBphrOpP7uM=
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
-github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q=
-github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I=
+github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs=
+github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0=
github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
@@ -67,8 +67,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20250121033306-997b0b79cac0 h1:EinjE47mmVVsxcjIwVKQWNY+3P+5R2BhkbULjhEDThc=
-github.com/google/pprof v0.0.0-20250121033306-997b0b79cac0/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 h1:my2ucqBZmv+cWHIhZNSIYKzgN8EBGyHdC7zD5sASRAg=
+github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
@@ -114,8 +114,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mymmrac/telego v0.32.0 h1:4X8C1l3k+opkk86r95+eQE8DxiS2LYlR61L/G7yreDY=
github.com/mymmrac/telego v0.32.0/go.mod h1:qS6NaRhJgcuEEBEMVCV79S2xCAuHq9O+ixwfLuRW31M=
-github.com/nicksnyder/go-i18n/v2 v2.4.1 h1:zwzjtX4uYyiaU02K5Ia3zSkpJZrByARkRB4V3YPrr0g=
-github.com/nicksnyder/go-i18n/v2 v2.4.1/go.mod h1:++Pl70FR6Cki7hdzZRnEEqdc2dJt+SAGotyFg/SvZMk=
+github.com/nicksnyder/go-i18n/v2 v2.5.0 h1:3wH1gpaekcgGuwzWdSu7JwJhH9Tk87k1ezt0i1p2/Is=
+github.com/nicksnyder/go-i18n/v2 v2.5.0/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
@@ -134,6 +134,8 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt
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.49.0 h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94=
+github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s=
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
@@ -186,26 +188,24 @@ github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
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/quic-go v0.48.2 h1:59Gs+E9qtc9s0uniXYDA649gNEZlMWcNpFLyp9jfkuE=
-github.com/xtls/quic-go v0.48.2/go.mod h1:rcyY5J0JT+1d5pa5Y+FbCsXM7Zu79jE87ZSFOBfiH7Q=
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 h1:g1Cj7d+my6k/HHxLAyxPwyX8i7FGRr6ulBDMkBzg2BM=
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463/go.mod h1:BjIOLmkEEtAgloAiVUcYj0Mt+YU00JARZw8AEU0IwAg=
-github.com/xtls/xray-core v1.8.25-0.20250119133207-ca9a90221348 h1:x54/hGG4meg32o8wR0EkIKyVJy7Fv+ey+bmSZuXWkJE=
-github.com/xtls/xray-core v1.8.25-0.20250119133207-ca9a90221348/go.mod h1:51y3AycMua6m1VFYnc3vJmgXeiL0qTsRGsDpjEaoXXc=
+github.com/xtls/xray-core v1.8.25-0.20250126155934-7b59379d73c3 h1:JzofxKb13MvNZeSLPS9B07Few0fu11dPEa40EQNV/hE=
+github.com/xtls/xray-core v1.8.25-0.20250126155934-7b59379d73c3/go.mod h1:KmpYBu4IFdODX7qgG7DP7v9sHJBcHpdKE+qxUZ2N304=
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/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
-go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
-go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
-go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
-go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
-go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
-go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
-go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
-go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
-go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
+go.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.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.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
@@ -242,12 +242,12 @@ golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeu
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
-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.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
-google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
-google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
-google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 h1:91mG8dNTpkC0uChJUQ9zCiRqx3GEEFOWaRZ0mI6Oj2I=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
+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/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
+google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
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=
diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js
index dab45509..f4ab4f53 100644
--- a/web/assets/js/model/inbound.js
+++ b/web/assets/js/model/inbound.js
@@ -493,7 +493,7 @@ class xHTTPStreamSettings extends XrayCommonClass {
headers = [],
scMaxBufferedPosts = 30,
scMaxEachPostBytes = "1000000",
- scStreamUpServerSecs = "0",
+ scStreamUpServerSecs = "20-80",
noSSEHeader = false,
xPaddingBytes = "100-1000",
mode = MODE_OPTION.AUTO,
@@ -554,6 +554,7 @@ class TlsStreamSettings extends XrayCommonClass {
maxVersion = TLS_VERSION_OPTION.TLS13,
cipherSuites = '',
rejectUnknownSni = false,
+ serverNameToVerify = 'dns.google',
disableSystemRoot = false,
enableSessionResumption = false,
certificates = [new TlsStreamSettings.Cert()],
@@ -566,6 +567,7 @@ class TlsStreamSettings extends XrayCommonClass {
this.maxVersion = maxVersion;
this.cipherSuites = cipherSuites;
this.rejectUnknownSni = rejectUnknownSni;
+ this.serverNameToVerify = serverNameToVerify;
this.disableSystemRoot = disableSystemRoot;
this.enableSessionResumption = enableSessionResumption;
this.certs = certificates;
@@ -597,6 +599,7 @@ class TlsStreamSettings extends XrayCommonClass {
json.maxVersion,
json.cipherSuites,
json.rejectUnknownSni,
+ json.serverNameToVerify,
json.disableSystemRoot,
json.enableSessionResumption,
certs,
@@ -612,6 +615,7 @@ class TlsStreamSettings extends XrayCommonClass {
maxVersion: this.maxVersion,
cipherSuites: this.cipherSuites,
rejectUnknownSni: this.rejectUnknownSni,
+ serverNameToVerify: this.serverNameToVerify,
disableSystemRoot: this.disableSystemRoot,
enableSessionResumption: this.enableSessionResumption,
certificates: TlsStreamSettings.toJsonArray(this.certs),
diff --git a/web/assets/js/util/utils.js b/web/assets/js/util/utils.js
index 28ec95c7..10825490 100644
--- a/web/assets/js/util/utils.js
+++ b/web/assets/js/util/utils.js
@@ -81,7 +81,7 @@ class HttpUtil {
},
body: JSON.stringify(data),
};
- const resp = await fetch(url, requestOptions);
+ const resp = await fetch(basePath + url.replace(/^\/+|\/+$/g, ''), requestOptions);
const response = await resp.json();
msg = this._respToMsg({data : response});
diff --git a/web/html/xui/client_modal.html b/web/html/xui/client_modal.html
index de7915a5..f2ea30d0 100644
--- a/web/html/xui/client_modal.html
+++ b/web/html/xui/client_modal.html
@@ -36,12 +36,13 @@
ok() {
if (app.subSettings.enable && clientModal.group.isGroup && clientModal.group.canGroup) {
const currentClient = clientModal.group.currentClient;
- const { limitIp, totalGB, expiryTime, reset, enable, subId, tgId, flow } = currentClient;
+ const { limitIp, comment, totalGB, expiryTime, reset, enable, subId, tgId, flow } = currentClient;
const uniqueEmails = clientModalApp.makeGroupEmailsUnique(clientModal.dbInbounds, currentClient.email, clientModal.group.clients);
clientModal.group.clients.forEach((client, index) => {
client.email = uniqueEmails[index];
client.limitIp = limitIp;
+ client.comment = comment;
client.totalGB = totalGB;
client.expiryTime = expiryTime;
client.reset = reset;
@@ -119,9 +120,11 @@
this.group.isGroup = true;
dbInbounds.forEach((dbInboundItem) => {
this.showProcess(dbInboundItem);
- this.addClient(this.inbound.protocol, this.clients);
- this.group.inbounds.push(dbInboundItem.id)
- this.group.clients.push(this.clients[this.index])
+ if (this.dbInbound.isMultiUser()) {
+ this.addClient(this.inbound.protocol, this.clients);
+ this.group.inbounds.push(dbInboundItem.id)
+ this.group.clients.push(this.clients[this.index])
+ }
})
this.group.currentClient = this.clients[this.index]
}
@@ -139,9 +142,11 @@
showProcess(dbInbound, index = null) {
this.dbInbound = new DBInbound(dbInbound);
this.inbound = dbInbound.toInbound();
- this.clients = this.inbound.clients;
- this.index = index === null ? this.clients.length : index;
- this.delayedStart = false;
+ if (this.dbInbound.isMultiUser()) {
+ this.clients = this.inbound.clients;
+ this.index = index === null ? this.clients.length : index;
+ this.delayedStart = false;
+ }
},
singleEditClientProcess(index) {
if (this.clients[index].expiryTime < 0) {
@@ -259,6 +264,23 @@
return generatedEmails;
},
+ async getDBClientIps(email) {
+ const msg = await HttpUtil.post(`/panel/inbound/clientIps/${email}`);
+ if (!msg.success) {
+ document.getElementById("clientIPs").value = msg.obj;
+ return;
+ }
+ let ips = msg.obj;
+ if (typeof ips === 'string' && ips.startsWith('[') && ips.endsWith(']')) {
+ try {
+ ips = JSON.parse(ips);
+ ips = Array.isArray(ips) ? ips.join("\n") : ips;
+ } catch (e) {
+ console.error('Error parsing JSON:', e);
+ }
+ }
+ document.getElementById("clientIPs").value = ips;
+ },
async clearDBClientIps(email) {
try {
const msg = await HttpUtil.post(`/panel/inbound/clearClientIps/${email}`);
diff --git a/web/html/xui/form/stream/stream_xhttp.html b/web/html/xui/form/stream/stream_xhttp.html
index 2731511d..601d0cb4 100644
--- a/web/html/xui/form/stream/stream_xhttp.html
+++ b/web/html/xui/form/stream/stream_xhttp.html
@@ -33,7 +33,7 @@
-
+
diff --git a/web/html/xui/form/tls_settings.html b/web/html/xui/form/tls_settings.html
index 4eff7698..70ad7d05 100644
--- a/web/html/xui/form/tls_settings.html
+++ b/web/html/xui/form/tls_settings.html
@@ -57,6 +57,9 @@
+
+
+
diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html
index 5d4d918b..1cd1be1a 100644
--- a/web/html/xui/inbounds.html
+++ b/web/html/xui/inbounds.html
@@ -1195,35 +1195,48 @@
}
},
getSubGroupClients(dbInbounds, currentClient) {
- const response = {
- inbounds: [],
- clients: [],
- editIds: []
+ const response = {
+ inbounds: [],
+ clients: [],
+ editIds: [],
+ };
+
+ if (!Array.isArray(dbInbounds) || dbInbounds.length === 0) {
+ return response;
+ }
+ if (!currentClient || !currentClient.subId) {
+ return response;
+ }
+
+ dbInbounds.forEach((dbInboundItem) => {
+ try {
+ const dbInbound = new DBInbound(dbInboundItem);
+ if (!dbInbound) {
+ return;
}
- if (dbInbounds && dbInbounds.length > 0 && currentClient) {
- dbInbounds.forEach((dbInboundItem) => {
- const dbInbound = new DBInbound(dbInboundItem);
- if (dbInbound) {
- const inbound = dbInbound.toInbound();
- if (inbound) {
- const clients = inbound.clients;
- if (clients.length > 0) {
- clients.forEach((client) => {
- if (client['subId'] === currentClient['subId']) {
- client['inboundId'] = dbInboundItem.id
- client['clientId'] = this.getClientId(dbInbound.protocol, client)
- response.inbounds.push(dbInboundItem.id)
- response.clients.push(client)
- response.editIds.push(client['clientId'])
- }
- })
- }
- }
- }
- })
+
+ const inbound = dbInbound.toInbound();
+ if (!inbound || !Array.isArray(inbound.clients)) {
+ return;
}
- return response;
- },
+
+ inbound.clients.forEach((client) => {
+ if (client.subId === currentClient.subId) {
+ client.inboundId = dbInboundItem.id;
+ client.clientId = this.getClientId(dbInbound.protocol, client);
+
+ response.inbounds.push(dbInboundItem.id);
+ response.clients.push(client);
+ response.editIds.push(client.clientId);
+ }
+ });
+ } catch (error) {
+ console.error("Error processing dbInboundItem:", dbInboundItem, error);
+ }
+ });
+
+ return response;
+ },
getClientId(protocol, client) {
switch (protocol) {
case Protocols.TROJAN: return client.password;
@@ -1455,7 +1468,7 @@
if (clients != null){
clients.forEach(c => {
if (c.subId && c.subId.length>0){
- subLinks.push(this.subSettings.subURI + c.subId + "?name=" + c.subId)
+ subLinks.push(this.subSettings.subURI + c.subId)
}
})
}
@@ -1482,7 +1495,7 @@
if (clients != null){
clients.forEach(c => {
if (c.subId && c.subId.length>0){
- subLinks.push(this.subSettings.subURI + c.subId + "?name=" + c.subId)
+ subLinks.push(this.subSettings.subURI + c.subId)
}
})
}
diff --git a/web/html/xui/settings.html b/web/html/xui/settings.html
index fa56baf7..ee4c7fe7 100644
--- a/web/html/xui/settings.html
+++ b/web/html/xui/settings.html
@@ -382,14 +382,40 @@
-
-
-
+
+
+
+
+
+
+
+
+ [[ p.label ]]
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+ [[ p.label ]]
+
+
+
+
@@ -477,25 +503,26 @@
]
},
],
- IPsOptions: [
- { label: 'Private IP', value: 'private' },
- { label: '🇮🇷 Iran', value: 'ir' },
- { label: '🇨🇳 China', value: 'cn' },
- { label: '🇷🇺 Russia', value: 'ru' },
- { label: '🇻🇳 Vietnam', value: 'vn' },
- { label: '🇪🇸 Spain', value: 'es' },
- { label: '🇮🇩 Indonesia', value: 'id' },
- { label: '🇺🇦 Ukraine', value: 'ua' },
- { label: '🇹🇷 Türkiye', value: 'tr' },
- { label: '🇧🇷 Brazil', value: 'br' },
+ directIPsOptions: [
+ { label: 'Private IP', value: 'geoip:private' },
+ { label: '🇮🇷 Iran', value: 'geoip:ir' },
+ { label: '🇨🇳 China', value: 'geoip:cn' },
+ { label: '🇷🇺 Russia', value: 'geoip:ru' },
+ { label: '🇻🇳 Vietnam', value: 'geoip:vn' },
+ { label: '🇪🇸 Spain', value: 'geoip:es' },
+ { label: '🇮🇩 Indonesia', value: 'geoip:id' },
+ { label: '🇺🇦 Ukraine', value: 'geoip:ua' },
+ { label: '🇹🇷 Türkiye', value: 'geoip:tr' },
+ { label: '🇧🇷 Brazil', value: 'geoip:br' },
],
- DomainsOptions: [
- { label: '🇮🇷 Iran', value: 'ir' },
- { label: '🇨🇳 China', value: 'cn' },
- { label: '🇷🇺 Russia', value: 'ru' },
- { label: 'Apple', value: 'apple' },
- { label: 'Meta', value: 'meta' },
- { label: 'Google', value: 'google' },
+ diretDomainsOptions: [
+ { label: 'Private DNS', value: 'geosite:private' },
+ { label: '🇮🇷 Iran', value: 'geosite:category-ir' },
+ { label: '🇨🇳 China', value: 'geosite:cn' },
+ { label: '🇷🇺 Russia', value: 'geosite:category-ru' },
+ { label: 'Apple', value: 'geosite:apple' },
+ { label: 'Meta', value: 'geosite:meta' },
+ { label: 'Google', value: 'geosite:google' },
],
get remarkModel() {
rm = this.allSetting.remarkModel;
@@ -753,7 +780,7 @@
const rules = JSON.parse(this.allSetting.subJsonRules);
if (!Array.isArray(rules)) return [];
const ipRule = rules.find(r => r.ip);
- return ipRule?.ip.map(d => d.replace("geoip:", "")) ?? [];
+ return ipRule?.ip ?? [];
},
set: function (v) {
let rules = JSON.parse(this.allSetting.subJsonRules);
@@ -767,7 +794,7 @@
rules[ruleIndex].ip = [];
v.forEach(d => {
- rules[ruleIndex].ip.push("geoip:" + d);
+ rules[ruleIndex].ip.push(d);
});
}
this.allSetting.subJsonRules = JSON.stringify(rules);
@@ -779,34 +806,18 @@
const rules = JSON.parse(this.allSetting.subJsonRules);
if (!Array.isArray(rules)) return [];
const domainRule = rules.find(r => r.domain);
- return domainRule?.domain.map(d => {
- if (d.startsWith("geosite:category-")) {
- return d.replace("geosite:category-", "");
- }
- return d.replace("geosite:", "");
- })
- ?? [];
+ return domainRule?.domain ?? [];
},
set: function (v) {
let rules = JSON.parse(this.allSetting.subJsonRules);
if (!Array.isArray(rules)) return;
-
if (v.length == 0) {
rules = rules.filter(r => !r.domain);
} else {
let ruleIndex = rules.findIndex(r => r.domain);
if (ruleIndex == -1) ruleIndex = rules.push(this.defaultRules[0]) - 1;
- rules[ruleIndex].domain = [];
- v.forEach(d => {
- let category = '';
- if (["cn", "apple", "meta", "google"].includes(d)) {
- category = "";
- } else if (["ru", "ir"].includes(d)) {
- category = "category-";
- }
- rules[ruleIndex].domain.push("geosite:" + category + d);
- });
+ rules[ruleIndex].domain = v;
}
this.allSetting.subJsonRules = JSON.stringify(rules);
}
@@ -839,4 +850,4 @@
});