Compare commits

...

30 Commits

Author SHA1 Message Date
Ilya
438a9684ee Fix #2470 (The subscription service gives two ports for VLESS) (#2479)
* Fix #2470
2024-08-11 18:26:43 +02:00
mhsanaei
a6000f22a2 v2.3.13 2024-08-11 12:43:47 +02:00
mhsanaei
2ec5eeb442 Dokodemo - default timeout to 30s 2024-08-11 12:41:21 +02:00
mhsanaei
d319476eb6 splithttp - change default to accept range (better upload now) 2024-08-11 11:38:59 +02:00
mhsanaei
93d52bc86c new - vmess security (inbound client side - outbound) 2024-08-11 00:47:44 +02:00
mhsanaei
bda5c2c915 small changes 2024-08-08 17:40:26 +02:00
mhsanaei
b838fe2e74 update dependencies 2024-08-08 17:39:50 +02:00
mhsanaei
604b9be4a0 Fix domain validation for Nginx/CDN compatibility #2450 2024-08-08 17:39:12 +02:00
mhsanaei
7b8ef98846 v2.3.12 2024-08-06 21:18:48 +02:00
mhsanaei
2c7c6c260a default setting 2024-08-06 21:17:12 +02:00
mhsanaei
b8c3555b09 improve randomShortId , format document 2024-08-06 17:10:42 +02:00
mhsanaei
2d2b30daf1 update dependencies 2024-08-06 13:45:07 +02:00
mhsanaei
3e3ed4ed52 fix session 2024-08-06 13:44:48 +02:00
mhsanaei
d8d9c64847 new - cert (build Chain) 2024-08-04 00:07:33 +02:00
Atageldi Didarov
c489673130 Added Turkish translation (#2442)
* create translate.tr_TR.toml

* added confirmToggle key

* Update langs.js
2024-08-02 11:32:56 +02:00
dependabot[bot]
2544305fb9 Bump github.com/shirou/gopsutil/v4 from 4.24.6 to 4.24.7 (#2444)
Bumps [github.com/shirou/gopsutil/v4](https://github.com/shirou/gopsutil) from 4.24.6 to 4.24.7.
- [Release notes](https://github.com/shirou/gopsutil/releases)
- [Commits](https://github.com/shirou/gopsutil/compare/v4.24.6...v4.24.7)

---
updated-dependencies:
- dependency-name: github.com/shirou/gopsutil/v4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-02 11:20:58 +02:00
Artem
519d228db2 translate improved - RU (#2441) 2024-08-02 11:20:39 +02:00
mhsanaei
4cd89f4379 v2.3.11 2024-07-29 13:17:55 +02:00
mhsanaei
fdfc29f6cd new - splithttp (noSSEHeader) 2024-07-29 13:16:07 +02:00
mhsanaei
4ec104c5ee new - splithttp (scMinPostsIntervalMs) 2024-07-29 13:05:05 +02:00
mhsanaei
bae89272b0 Xray Core v1.8.23 2024-07-29 12:33:46 +02:00
mhsanaei
8408a45eff update dependencies 2024-07-27 14:56:37 +02:00
mhsanaei
a37b1bde4c update pictures 2024-07-24 13:33:36 +02:00
mhsanaei
953b5d3dea buy me a coffee 2024-07-24 12:47:35 +02:00
mhsanaei
c7906e8598 API - Get client's traffic By ID
Co-Authored-By: Hassan Ali Gilani <mr.ajaxian@gmail.com>
2024-07-23 11:28:28 +02:00
yeer
e1bc43da5f fix bug for nil pointer (#2438) 2024-07-23 11:11:28 +02:00
mhsanaei
0630642849 v2.3.10 2024-07-22 00:14:48 +02:00
mhsanaei
8bd3827b41 Xray Core v1.8.21 2024-07-22 00:12:58 +02:00
mhsanaei
24b367b82f fix 2024-07-18 23:03:48 +02:00
mhsanaei
011443bfc1 update donate wallet 2024-07-17 18:13:12 +02:00
49 changed files with 1508 additions and 545 deletions

14
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: mhsanaei
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -83,7 +83,7 @@ jobs:
cd x-ui/bin cd x-ui/bin
# Download dependencies # Download dependencies
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v1.8.19/" Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v1.8.23/"
if [ "${{ matrix.platform }}" == "amd64" ]; then if [ "${{ matrix.platform }}" == "amd64" ]; then
wget ${Xray_URL}Xray-linux-64.zip wget ${Xray_URL}Xray-linux-64.zip
unzip Xray-linux-64.zip unzip Xray-linux-64.zip

View File

@@ -27,7 +27,7 @@ case $1 in
esac esac
mkdir -p build/bin mkdir -p build/bin
cd build/bin cd build/bin
wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.19/Xray-linux-${ARCH}.zip" wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.23/Xray-linux-${ARCH}.zip"
unzip "Xray-linux-${ARCH}.zip" unzip "Xray-linux-${ARCH}.zip"
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
mv xray "xray-linux-${FNAME}" mv xray "xray-linux-${FNAME}"

View File

@@ -14,9 +14,15 @@
**Si este proyecto te es útil, podrías considerar darle una**:star2: **Si este proyecto te es útil, podrías considerar darle una**:star2:
<p align="left"><a href="#"><img width="125" src="https://github.com/MHSanaei/3x-ui/assets/115543613/7aa895dd-048a-42e7-989b-afd41a74e2e1" alt="Image"></a></p> <p align="left">
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
<img src="./media/buymeacoffe.png" alt="Image">
</a>
</p>
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` - USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
- MATIC (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
## Instalar y Actualizar ## Instalar y Actualizar
@@ -26,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
## Instalar una Versión Personalizada ## Instalar una Versión Personalizada
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.3.6`: Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.3.13`:
``` ```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.6 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.13
``` ```
## Certificado SSL ## Certificado SSL

View File

@@ -14,9 +14,15 @@
**If this project is helpful to you, you may wish to give it a**:star2: **If this project is helpful to you, you may wish to give it a**:star2:
<p align="left"><a href="#"><img width="125" src="https://github.com/MHSanaei/3x-ui/assets/115543613/7aa895dd-048a-42e7-989b-afd41a74e2e1" alt="Image"></a></p> <p align="left">
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
<img src="./media/buymeacoffe.png" alt="Image">
</a>
</p>
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` - USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
- MATIC (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
## Install & Upgrade ## Install & Upgrade
@@ -26,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
## Install Custom Version ## Install Custom Version
To install your desired version, add the version to the end of the installation command. e.g., ver `v2.3.9`: To install your desired version, add the version to the end of the installation command. e.g., ver `v2.3.13`:
``` ```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.9 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.13
``` ```
## SSL Certificate ## SSL Certificate
@@ -244,6 +250,7 @@ Our platform offers compatibility with a diverse range of architectures and devi
- Spanish - Spanish
- Indonesian - Indonesian
- Ukrainian - Ukrainian
- Turkish
## Features ## Features
@@ -252,7 +259,7 @@ Our platform offers compatibility with a diverse range of architectures and devi
- Search within all inbounds and clients - Search within all inbounds and clients
- Dark/Light theme - Dark/Light theme
- Supports multi-user and multi-protocol - Supports multi-user and multi-protocol
- Supports protocols, including VMess, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard - Supports protocols, including VMESS, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard
- Supports XTLS native Protocols, including RPRX-Direct, Vision, REALITY - Supports XTLS native Protocols, including RPRX-Direct, Vision, REALITY
- Traffic statistics, traffic limit, expiration time limit - Traffic statistics, traffic limit, expiration time limit
- Customizable Xray configuration templates - Customizable Xray configuration templates
@@ -453,6 +460,7 @@ Enter the user ID in input field number 4. The Telegram accounts with this id wi
| `GET` | `"/list"` | Get all inbounds | | `GET` | `"/list"` | Get all inbounds |
| `GET` | `"/get/:id"` | Get inbound with inbound.id | | `GET` | `"/get/:id"` | Get inbound with inbound.id |
| `GET` | `"/getClientTraffics/:email"` | Get Client Traffics with email | | `GET` | `"/getClientTraffics/:email"` | Get Client Traffics with email |
| `GET` | `"/getClientTrafficsById/:id"` | Get client's traffic By ID |
| `GET` | `"/createbackup"` | Telegram bot sends backup to admins | | `GET` | `"/createbackup"` | Telegram bot sends backup to admins |
| `POST` | `"/add"` | Add inbound | | `POST` | `"/add"` | Add inbound |
| `POST` | `"/del/:id"` | Delete Inbound | | `POST` | `"/del/:id"` | Delete Inbound |

View File

@@ -14,9 +14,15 @@
**如果此项目对你有用,请给一个**:star2: **如果此项目对你有用,请给一个**:star2:
<p align="left"><a href="#"><img width="125" src="https://github.com/MHSanaei/3x-ui/assets/115543613/7aa895dd-048a-42e7-989b-afd41a74e2e1" alt="Image"></a></p> <p align="left">
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
<img src="./media/buymeacoffe.png" alt="Image">
</a>
</p>
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC` - USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
- MATIC (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
## 安装 & 升级 ## 安装 & 升级
@@ -26,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
## 安装指定版本 ## 安装指定版本
要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.6`: 要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.13`:
``` ```
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.6 bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.13
``` ```
## SSL 认证 ## SSL 认证

View File

@@ -1 +1 @@
2.3.9 2.3.13

View File

@@ -10,7 +10,7 @@ import (
type Protocol string type Protocol string
const ( const (
VMess Protocol = "vmess" VMESS Protocol = "vmess"
VLESS Protocol = "vless" VLESS Protocol = "vless"
DOKODEMO Protocol = "dokodemo-door" DOKODEMO Protocol = "dokodemo-door"
HTTP Protocol = "http" HTTP Protocol = "http"
@@ -86,6 +86,7 @@ type Setting struct {
type Client struct { type Client struct {
ID string `json:"id"` ID string `json:"id"`
Security string `json:"security"`
Password string `json:"password"` Password string `json:"password"`
Flow string `json:"flow"` Flow string `json:"flow"`
Email string `json:"email"` Email string `json:"email"`

40
go.mod
View File

@@ -12,11 +12,11 @@ require (
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/pelletier/go-toml/v2 v2.2.2 github.com/pelletier/go-toml/v2 v2.2.2
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil/v4 v4.24.6 github.com/shirou/gopsutil/v4 v4.24.7
github.com/valyala/fasthttp v1.55.0 github.com/valyala/fasthttp v1.55.0
github.com/xtls/xray-core v1.8.19 github.com/xtls/xray-core v1.8.23
go.uber.org/atomic v1.11.0 go.uber.org/atomic v1.11.0
golang.org/x/text v0.16.0 golang.org/x/text v0.17.0
google.golang.org/grpc v1.65.0 google.golang.org/grpc v1.65.0
gorm.io/driver/sqlite v1.5.6 gorm.io/driver/sqlite v1.5.6
gorm.io/gorm v1.25.11 gorm.io/gorm v1.25.11
@@ -24,15 +24,15 @@ require (
require ( require (
github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/bytedance/sonic v1.11.9 // indirect github.com/bytedance/sonic v1.12.1 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect
github.com/cloudflare/circl v1.3.9 // indirect github.com/cloudflare/circl v1.3.9 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect github.com/cloudwego/iasm v0.2.0 // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/fasthttp/router v1.5.2 // indirect github.com/fasthttp/router v1.5.2 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect github.com/francoispqt/gojay v1.2.13 // indirect
github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ole/go-ole v1.3.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/locales v0.14.1 // indirect
@@ -40,7 +40,7 @@ require (
github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-playground/validator/v10 v10.22.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/btree v1.1.2 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.3.0 // indirect github.com/gorilla/sessions v1.3.0 // indirect
@@ -57,15 +57,15 @@ require (
github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/onsi/ginkgo/v2 v2.20.0 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect github.com/pires/go-proxyproto v0.7.0 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/quic-go v0.45.1 // indirect github.com/quic-go/quic-go v0.46.0 // indirect
github.com/refraction-networking/utls v1.6.7 // indirect github.com/refraction-networking/utls v1.6.7 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/sagernet/sing v0.4.1 // indirect github.com/sagernet/sing v0.4.2 // indirect
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect
@@ -83,18 +83,18 @@ require (
github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/mock v0.4.0 // indirect go.uber.org/mock v0.4.0 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/arch v0.8.0 // indirect golang.org/x/arch v0.9.0 // indirect
golang.org/x/crypto v0.25.0 // indirect golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/mod v0.19.0 // indirect golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.27.0 // indirect golang.org/x/net v0.28.0 // indirect
golang.org/x/sync v0.7.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.22.0 // indirect golang.org/x/sys v0.24.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.23.0 // indirect golang.org/x/tools v0.24.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a // indirect
google.golang.org/protobuf v1.34.2 // indirect google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect

89
go.sum
View File

@@ -18,10 +18,11 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/bytedance/sonic v1.11.9 h1:LFHENlIY/SLzDWverzdOvgMztTxcfcF+cqNsz9pK5zg= github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24=
github.com/bytedance/sonic v1.11.9/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE= github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
@@ -43,8 +44,8 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
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 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
@@ -58,8 +59,8 @@ github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
@@ -97,8 +98,8 @@ 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/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da h1:xRmpO92tb8y+Z85iUOMOicpCfaYcv7o3Cg3wKrIpg8g= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -163,10 +164,10 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4= github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= 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/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
@@ -187,8 +188,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/quic-go v0.45.1 h1:tPfeYCk+uZHjmDRwHHQmvHRYL2t44ROTujLeFVBmjCA= github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=
github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM= 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/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
@@ -198,8 +199,8 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sagernet/sing v0.4.1 h1:zVlpE+7k7AFoC2pv6ReqLf0PIHjihL/jsBl5k05PQFk= github.com/sagernet/sing v0.4.2 h1:jzGNJdZVRI0xlAfFugsIQUPvyB9SuWvbJK7zQCXc4QM=
github.com/sagernet/sing v0.4.1/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls= github.com/sagernet/sing v0.4.2/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8= github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc= github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc=
@@ -207,8 +208,8 @@ github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEo
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4= 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/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil/v4 v4.24.6 h1:9qqCSYF2pgOU+t+NgJtp7Co5+5mHF/HyKBUckySQL64= github.com/shirou/gopsutil/v4 v4.24.7 h1:V9UGTK4gQ8HvcnPKf6Zt3XHyQq/peaekfxpJ2HSocJk=
github.com/shirou/gopsutil/v4 v4.24.6/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA= github.com/shirou/gopsutil/v4 v4.24.7/go.mod h1:0uW/073rP7FYLOkvxolUQM5rMOLTNmRXnFKafpb71rw=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
@@ -277,8 +278,8 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg= github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg=
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE= github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
github.com/xtls/xray-core v1.8.19 h1:mml7smcO2FM5HyyKdqnf5F2BUvi3br2ldrqmeemEFRE= github.com/xtls/xray-core v1.8.23 h1:A8Wr50ildMYLpaNu3EiK+Stg/tps6i0h7z5Hr4f9H2k=
github.com/xtls/xray-core v1.8.19/go.mod h1:0CwyMPNA5Cs+ukPXHbYQGgne/ug0PuXOSVqBu7zyXOc= github.com/xtls/xray-core v1.8.23/go.mod h1:0CwyMPNA5Cs+ukPXHbYQGgne/ug0PuXOSVqBu7zyXOc=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
@@ -289,23 +290,22 @@ go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= 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= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -314,8 +314,8 @@ golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -325,8 +325,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -339,22 +339,22 @@ golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= 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/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 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
@@ -371,8 +371,8 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a h1:EKiZZXueP9/T68B8Nl0GAx9cjbQnCId0yP3qPMgaaHs=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -406,6 +406,5 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

View File

@@ -73,11 +73,11 @@ func runWebServer() {
err := server.Stop() err := server.Stop()
if err != nil { if err != nil {
logger.Warning("Error stopping web server:", err) logger.Debug("Error stopping web server:", err)
} }
err = subServer.Stop() err = subServer.Stop()
if err != nil { if err != nil {
logger.Warning("Error stopping sub server:", err) logger.Debug("Error stopping sub server:", err)
} }
server = web.NewServer() server = web.NewServer()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 KiB

After

Width:  |  Height:  |  Size: 60 KiB

BIN
media/buymeacoffe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -3,6 +3,7 @@ package sub
import ( import (
"encoding/base64" "encoding/base64"
"net" "net"
"strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@@ -54,7 +55,10 @@ func (a *SUBController) initRouter(g *gin.RouterGroup) {
func (a *SUBController) subs(c *gin.Context) { func (a *SUBController) subs(c *gin.Context) {
subId := c.Param("subid") subId := c.Param("subid")
host := c.GetHeader("X-Forwarded-Host") var host string
if h, err := getHostFromXFH(c.GetHeader("X-Forwarded-Host")); err == nil {
host = h
}
if host == "" { if host == "" {
host = c.GetHeader("X-Real-IP") host = c.GetHeader("X-Real-IP")
} }
@@ -89,7 +93,10 @@ func (a *SUBController) subs(c *gin.Context) {
func (a *SUBController) subJsons(c *gin.Context) { func (a *SUBController) subJsons(c *gin.Context) {
subId := c.Param("subid") subId := c.Param("subid")
host := c.GetHeader("X-Forwarded-Host") var host string
if h, err := getHostFromXFH(c.GetHeader("X-Forwarded-Host")); err == nil {
host = h
}
if host == "" { if host == "" {
host = c.GetHeader("X-Real-IP") host = c.GetHeader("X-Real-IP")
} }
@@ -113,3 +120,14 @@ func (a *SUBController) subJsons(c *gin.Context) {
c.String(200, jsonSub) c.String(200, jsonSub)
} }
} }
func getHostFromXFH(s string) (string, error) {
if strings.Contains(s, ":") {
realHost, _, err := net.SplitHostPort(s)
if err != nil {
return "", err
}
return realHost, nil
}
return s, nil
}

View File

@@ -282,6 +282,9 @@ func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_ut
usersData[0].ID = client.ID usersData[0].ID = client.ID
usersData[0].Level = 8 usersData[0].Level = 8
if inbound.Protocol == model.VMESS {
usersData[0].Security = client.Security
}
if inbound.Protocol == model.VLESS { if inbound.Protocol == model.VLESS {
usersData[0].Flow = client.Flow usersData[0].Flow = client.Flow
usersData[0].Encryption = "none" usersData[0].Encryption = "none"
@@ -371,6 +374,7 @@ type UserVnext struct {
Encryption string `json:"encryption,omitempty"` Encryption string `json:"encryption,omitempty"`
Flow string `json:"flow,omitempty"` Flow string `json:"flow,omitempty"`
ID string `json:"id"` ID string `json:"id"`
Security string `json:"security,omitempty"`
Level int `json:"level"` Level int `json:"level"`
} }

View File

@@ -168,7 +168,7 @@ func (s *SubService) getLink(inbound *model.Inbound, email string) string {
} }
func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string { func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
if inbound.Protocol != model.VMess { if inbound.Protocol != model.VMESS {
return "" return ""
} }
obj := map[string]interface{}{ obj := map[string]interface{}{
@@ -281,6 +281,7 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
} }
} }
obj["id"] = clients[clientIndex].ID obj["id"] = clients[clientIndex].ID
obj["scy"] = clients[clientIndex].Security
externalProxies, _ := stream["externalProxy"].([]interface{}) externalProxies, _ := stream["externalProxy"].([]interface{})

View File

@@ -39,6 +39,11 @@ const supportLangs = [
value: 'uk-UA', value: 'uk-UA',
icon: '🇺🇦', icon: '🇺🇦',
}, },
{
name: 'Türkçe',
value: 'tr-TR',
icon: '🇹🇷',
},
]; ];
function getLang() { function getLang() {

View File

@@ -69,12 +69,23 @@ const WireguardDomainStrategy = [
"ForceIPv6v4" "ForceIPv6v4"
]; ];
const USERS_SECURITY = {
AES_128_GCM: "aes-128-gcm",
CHACHA20_POLY1305: "chacha20-poly1305",
AUTO: "auto",
NONE: "none",
ZERO: "zero",
};
Object.freeze(Protocols); Object.freeze(Protocols);
Object.freeze(SSMethods); Object.freeze(SSMethods);
Object.freeze(TLS_FLOW_CONTROL); Object.freeze(TLS_FLOW_CONTROL);
Object.freeze(UTLS_FINGERPRINT);
Object.freeze(ALPN_OPTION); Object.freeze(ALPN_OPTION);
Object.freeze(OutboundDomainStrategies); Object.freeze(OutboundDomainStrategies);
Object.freeze(WireguardDomainStrategy); Object.freeze(WireguardDomainStrategy);
Object.freeze(USERS_SECURITY);
class CommonClass { class CommonClass {
@@ -132,7 +143,9 @@ class TcpStreamSettings extends CommonClass {
} }
class KcpStreamSettings extends CommonClass { class KcpStreamSettings extends CommonClass {
constructor(mtu=1350, tti=20, constructor(
mtu = 1350,
tti = 50,
uplinkCapacity = 5, uplinkCapacity = 5,
downlinkCapacity = 20, downlinkCapacity = 20,
congestion = false, congestion = false,
@@ -229,8 +242,11 @@ class HttpStreamSettings extends CommonClass {
} }
class QuicStreamSettings extends CommonClass { class QuicStreamSettings extends CommonClass {
constructor(security='none', constructor(
key='', type='none') { security = 'none',
key = '',
type = 'none'
) {
super(); super();
this.security = security; this.security = security;
this.key = key; this.key = key;
@@ -257,7 +273,11 @@ class QuicStreamSettings extends CommonClass {
} }
class GrpcStreamSettings extends CommonClass { class GrpcStreamSettings extends CommonClass {
constructor(serviceName="", authority="", multiMode=false) { constructor(
serviceName = "",
authority = "",
multiMode = false
) {
super(); super();
this.serviceName = serviceName; this.serviceName = serviceName;
this.authority = authority; this.authority = authority;
@@ -322,10 +342,12 @@ class SplitHTTPStreamSettings extends CommonClass {
} }
class TlsStreamSettings extends CommonClass { class TlsStreamSettings extends CommonClass {
constructor(serverName='', constructor(
serverName = '',
alpn = [], alpn = [],
fingerprint = '', fingerprint = '',
allowInsecure = false) { allowInsecure = false
) {
super(); super();
this.serverName = serverName; this.serverName = serverName;
this.alpn = alpn; this.alpn = alpn;
@@ -353,7 +375,13 @@ class TlsStreamSettings extends CommonClass {
} }
class RealityStreamSettings extends CommonClass { class RealityStreamSettings extends CommonClass {
constructor(publicKey = '', fingerprint = '', serverName = '', shortId = '', spiderX = '/') { constructor(
publicKey = '',
fingerprint = '',
serverName = '',
shortId = '',
spiderX = '/'
) {
super(); super();
this.publicKey = publicKey; this.publicKey = publicKey;
this.fingerprint = fingerprint; this.fingerprint = fingerprint;
@@ -381,7 +409,13 @@ class RealityStreamSettings extends CommonClass {
} }
}; };
class SockoptStreamSettings extends CommonClass { class SockoptStreamSettings extends CommonClass {
constructor(dialerProxy = "", tcpFastOpen = false, tcpKeepAliveInterval = 0, tcpMptcp = false, tcpNoDelay = false) { constructor(
dialerProxy = "",
tcpFastOpen = false,
tcpKeepAliveInterval = 0,
tcpMptcp = false,
tcpNoDelay = false
) {
super(); super();
this.dialerProxy = dialerProxy; this.dialerProxy = dialerProxy;
this.tcpFastOpen = tcpFastOpen; this.tcpFastOpen = tcpFastOpen;
@@ -413,7 +447,8 @@ class SockoptStreamSettings extends CommonClass {
} }
class StreamSettings extends CommonClass { class StreamSettings extends CommonClass {
constructor(network='tcp', constructor(
network = 'tcp',
security = 'none', security = 'none',
tlsSettings = new TlsStreamSettings(), tlsSettings = new TlsStreamSettings(),
realitySettings = new RealityStreamSettings(), realitySettings = new RealityStreamSettings(),
@@ -695,7 +730,7 @@ class Outbound extends CommonClass {
const port = json.port * 1; const port = json.port * 1;
return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id), stream); return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id, json.scy), stream);
} }
static fromParamLink(link) { static fromParamLink(link) {
@@ -897,11 +932,12 @@ Outbound.DNSSettings = class extends CommonClass {
} }
}; };
Outbound.VmessSettings = class extends CommonClass { Outbound.VmessSettings = class extends CommonClass {
constructor(address, port, id) { constructor(address, port, id, security) {
super(); super();
this.address = address; this.address = address;
this.port = port; this.port = port;
this.id = id; this.id = id;
this.security = security;
} }
static fromJson(json = {}) { static fromJson(json = {}) {
@@ -910,6 +946,7 @@ Outbound.VmessSettings = class extends CommonClass {
json.vnext[0].address, json.vnext[0].address,
json.vnext[0].port, json.vnext[0].port,
json.vnext[0].users[0].id, json.vnext[0].users[0].id,
json.vnext[0].users[0].security,
); );
} }
@@ -918,7 +955,7 @@ Outbound.VmessSettings = class extends CommonClass {
vnext: [{ vnext: [{
address: this.address, address: this.address,
port: this.port, port: this.port,
users: [{id: this.id}], users: [{ id: this.id, security: this.security }],
}], }],
}; };
} }
@@ -1082,17 +1119,23 @@ Outbound.HttpSettings = class extends CommonClass {
Outbound.WireguardSettings = class extends CommonClass { Outbound.WireguardSettings = class extends CommonClass {
constructor( constructor(
mtu=1420, secretKey='', mtu = 1420,
address=[''], workers=2, domainStrategy='', reserved='', secretKey = '',
peers=[new Outbound.WireguardSettings.Peer()], kernelMode=false) { address = [''],
workers = 2,
domainStrategy = '',
reserved = '',
peers = [new Outbound.WireguardSettings.Peer()],
kernelMode = false
) {
super(); super();
this.mtu = mtu; this.mtu = mtu;
this.secretKey = secretKey; this.secretKey = secretKey;
this.pubKey = secretKey.length > 0 ? Wireguard.generateKeypair(secretKey).publicKey : ''; this.pubKey = secretKey.length > 0 ? Wireguard.generateKeypair(secretKey).publicKey : '';
this.address = address instanceof Array ? address.join(',') : address; this.address = Array.isArray(address) ? address.join(',') : address;
this.workers = workers; this.workers = workers;
this.domainStrategy = domainStrategy; this.domainStrategy = domainStrategy;
this.reserved = reserved instanceof Array ? reserved.join(',') : reserved; this.reserved = Array.isArray(reserved) ? reserved.join(',') : reserved;
this.peers = peers; this.peers = peers;
this.kernelMode = kernelMode; this.kernelMode = kernelMode;
} }
@@ -1133,7 +1176,13 @@ Outbound.WireguardSettings = class extends CommonClass {
}; };
Outbound.WireguardSettings.Peer = class extends CommonClass { Outbound.WireguardSettings.Peer = class extends CommonClass {
constructor(publicKey='', psk='', allowedIPs=['0.0.0.0/0','::/0'], endpoint='', keepAlive=0) { constructor(
publicKey = '',
psk = '',
allowedIPs = ['0.0.0.0/0', '::/0'],
endpoint = '',
keepAlive = 0
) {
super(); super();
this.publicKey = publicKey; this.publicKey = publicKey;
this.psk = psk; this.psk = psk;

View File

@@ -7,10 +7,10 @@ class AllSetting {
this.webCertFile = ""; this.webCertFile = "";
this.webKeyFile = ""; this.webKeyFile = "";
this.webBasePath = "/"; this.webBasePath = "/";
this.sessionMaxAge = ""; this.sessionMaxAge = 0;
this.pageSize = 50; this.pageSize = 50;
this.expireDiff = ""; this.expireDiff = 0;
this.trafficDiff = ""; this.trafficDiff = 0;
this.remarkModel = "-ieo"; this.remarkModel = "-ieo";
this.datepicker = "gregorian"; this.datepicker = "gregorian";
this.tgBotEnable = false; this.tgBotEnable = false;
@@ -19,22 +19,22 @@ class AllSetting {
this.tgBotChatId = ""; this.tgBotChatId = "";
this.tgRunTime = "@daily"; this.tgRunTime = "@daily";
this.tgBotBackup = false; this.tgBotBackup = false;
this.tgBotLoginNotify = false; this.tgBotLoginNotify = true;
this.tgCpu = ""; this.tgCpu = 80;
this.tgLang = "en-US"; this.tgLang = "en-US";
this.xrayTemplateConfig = ""; this.xrayTemplateConfig = "";
this.secretEnable = false; this.secretEnable = false;
this.subEnable = false; this.subEnable = false;
this.subListen = ""; this.subListen = "";
this.subPort = "2096"; this.subPort = 2096;
this.subPath = "/sub/"; this.subPath = "/sub/";
this.subJsonPath = "/json/"; this.subJsonPath = "/json/";
this.subDomain = ""; this.subDomain = "";
this.subCertFile = ""; this.subCertFile = "";
this.subKeyFile = ""; this.subKeyFile = "";
this.subUpdates = 0; this.subUpdates = 12;
this.subEncrypt = true; this.subEncrypt = true;
this.subShowInfo = false; this.subShowInfo = true;
this.subURI = ""; this.subURI = "";
this.subJsonURI = ""; this.subJsonURI = "";
this.subJsonFragment = ""; this.subJsonFragment = "";

View File

@@ -103,12 +103,21 @@ const DOMAIN_STRATEGY_OPTION = {
FORCE_IPV4V6: "ForceIPv4v6", FORCE_IPV4V6: "ForceIPv4v6",
FORCE_IPV4: "ForceIPv4", FORCE_IPV4: "ForceIPv4",
}; };
const TCP_CONGESTION_OPTION = { const TCP_CONGESTION_OPTION = {
BBR: "bbr", BBR: "bbr",
CUBIC: "cubic", CUBIC: "cubic",
RENO: "reno", RENO: "reno",
}; };
const USERS_SECURITY = {
AES_128_GCM: "aes-128-gcm",
CHACHA20_POLY1305: "chacha20-poly1305",
AUTO: "auto",
NONE: "none",
ZERO: "zero",
};
Object.freeze(Protocols); Object.freeze(Protocols);
Object.freeze(SSMethods); Object.freeze(SSMethods);
Object.freeze(XTLS_FLOW_CONTROL); Object.freeze(XTLS_FLOW_CONTROL);
@@ -121,6 +130,7 @@ Object.freeze(SNIFFING_OPTION);
Object.freeze(USAGE_OPTION); Object.freeze(USAGE_OPTION);
Object.freeze(DOMAIN_STRATEGY_OPTION); Object.freeze(DOMAIN_STRATEGY_OPTION);
Object.freeze(TCP_CONGESTION_OPTION); Object.freeze(TCP_CONGESTION_OPTION);
Object.freeze(USERS_SECURITY);
class XrayCommonClass { class XrayCommonClass {
@@ -180,7 +190,8 @@ class XrayCommonClass {
} }
class TcpStreamSettings extends XrayCommonClass { class TcpStreamSettings extends XrayCommonClass {
constructor(acceptProxyProtocol=false, constructor(
acceptProxyProtocol = false,
type = 'none', type = 'none',
request = new TcpStreamSettings.TcpRequest(), request = new TcpStreamSettings.TcpRequest(),
response = new TcpStreamSettings.TcpResponse(), response = new TcpStreamSettings.TcpResponse(),
@@ -217,7 +228,8 @@ class TcpStreamSettings extends XrayCommonClass {
} }
TcpStreamSettings.TcpRequest = class extends XrayCommonClass { TcpStreamSettings.TcpRequest = class extends XrayCommonClass {
constructor(version='1.1', constructor(
version = '1.1',
method = 'GET', method = 'GET',
path = ['/'], path = ['/'],
headers = [], headers = [],
@@ -265,7 +277,8 @@ TcpStreamSettings.TcpRequest = class extends XrayCommonClass {
}; };
TcpStreamSettings.TcpResponse = class extends XrayCommonClass { TcpStreamSettings.TcpResponse = class extends XrayCommonClass {
constructor(version='1.1', constructor(
version = '1.1',
status = '200', status = '200',
reason = 'OK', reason = 'OK',
headers = [], headers = [],
@@ -305,7 +318,9 @@ TcpStreamSettings.TcpResponse = class extends XrayCommonClass {
}; };
class KcpStreamSettings extends XrayCommonClass { class KcpStreamSettings extends XrayCommonClass {
constructor(mtu=1350, tti=20, constructor(
mtu = 1350,
tti = 50,
uplinkCapacity = 5, uplinkCapacity = 5,
downlinkCapacity = 20, downlinkCapacity = 20,
congestion = false, congestion = false,
@@ -358,7 +373,12 @@ class KcpStreamSettings extends XrayCommonClass {
} }
class WsStreamSettings extends XrayCommonClass { class WsStreamSettings extends XrayCommonClass {
constructor(acceptProxyProtocol=false, path='/', host='', headers=[]) { constructor(
acceptProxyProtocol = false,
path = '/',
host = '',
headers = []
) {
super(); super();
this.acceptProxyProtocol = acceptProxyProtocol; this.acceptProxyProtocol = acceptProxyProtocol;
this.path = path; this.path = path;
@@ -430,8 +450,11 @@ class HttpStreamSettings extends XrayCommonClass {
} }
class QuicStreamSettings extends XrayCommonClass { class QuicStreamSettings extends XrayCommonClass {
constructor(security='none', constructor(
key=RandomUtil.randomSeq(10), type='none') { security = 'none',
key = RandomUtil.randomSeq(10),
type = 'none'
) {
super(); super();
this.security = security; this.security = security;
this.key = key; this.key = key;
@@ -487,7 +510,12 @@ class GrpcStreamSettings extends XrayCommonClass {
} }
class HTTPUpgradeStreamSettings extends XrayCommonClass { class HTTPUpgradeStreamSettings extends XrayCommonClass {
constructor(acceptProxyProtocol=false, path='/', host='', headers=[]) { constructor(
acceptProxyProtocol = false,
path = '/',
host = '',
headers = []
) {
super(); super();
this.acceptProxyProtocol = acceptProxyProtocol; this.acceptProxyProtocol = acceptProxyProtocol;
this.path = path; this.path = path;
@@ -523,13 +551,23 @@ class HTTPUpgradeStreamSettings extends XrayCommonClass {
} }
class SplitHTTPStreamSettings extends XrayCommonClass { class SplitHTTPStreamSettings extends XrayCommonClass {
constructor(path='/', host='', headers=[] , maxUploadSize= 1000000, maxConcurrentUploads= 10) { constructor(
path = '/',
host = '',
headers = [],
scMaxConcurrentPosts = "100-200",
scMaxEachPostBytes = "1000000-2000000",
scMinPostsIntervalMs = "10-50",
noSSEHeader = false,
) {
super(); super();
this.path = path; this.path = path;
this.host = host; this.host = host;
this.headers = headers; this.headers = headers;
this.maxUploadSize = maxUploadSize; this.scMaxConcurrentPosts = scMaxConcurrentPosts;
this.maxConcurrentUploads = maxConcurrentUploads; this.scMaxEachPostBytes = scMaxEachPostBytes;
this.scMinPostsIntervalMs = scMinPostsIntervalMs;
this.noSSEHeader = noSSEHeader;
} }
addHeader(name, value) { addHeader(name, value) {
@@ -545,8 +583,10 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
json.path, json.path,
json.host, json.host,
XrayCommonClass.toHeaders(json.headers), XrayCommonClass.toHeaders(json.headers),
json.maxUploadSize, json.scMaxConcurrentPosts,
json.maxConcurrentUploads, json.scMaxEachPostBytes,
json.scMinPostsIntervalMs,
json.noSSEHeader,
); );
} }
@@ -555,14 +595,17 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
path: this.path, path: this.path,
host: this.host, host: this.host,
headers: XrayCommonClass.toV2Headers(this.headers, false), headers: XrayCommonClass.toV2Headers(this.headers, false),
maxUploadSize: this.maxUploadSize, scMaxConcurrentPosts: this.scMaxConcurrentPosts,
maxConcurrentUploads: this.maxConcurrentUploads, scMaxEachPostBytes: this.scMaxEachPostBytes,
scMinPostsIntervalMs: this.scMinPostsIntervalMs,
noSSEHeader: this.noSSEHeader,
}; };
} }
} }
class TlsStreamSettings extends XrayCommonClass { class TlsStreamSettings extends XrayCommonClass {
constructor(serverName='', constructor(
serverName = '',
minVersion = TLS_VERSION_OPTION.TLS12, minVersion = TLS_VERSION_OPTION.TLS12,
maxVersion = TLS_VERSION_OPTION.TLS13, maxVersion = TLS_VERSION_OPTION.TLS13,
cipherSuites = '', cipherSuites = '',
@@ -571,7 +614,8 @@ class TlsStreamSettings extends XrayCommonClass {
enableSessionResumption = false, enableSessionResumption = false,
certificates = [new TlsStreamSettings.Cert()], certificates = [new TlsStreamSettings.Cert()],
alpn = [ALPN_OPTION.H3, ALPN_OPTION.H2, ALPN_OPTION.HTTP1], alpn = [ALPN_OPTION.H3, ALPN_OPTION.H2, ALPN_OPTION.HTTP1],
settings=new TlsStreamSettings.Settings()) { settings = new TlsStreamSettings.Settings()
) {
super(); super();
this.sni = serverName; this.sni = serverName;
this.minVersion = minVersion; this.minVersion = minVersion;
@@ -634,16 +678,27 @@ class TlsStreamSettings extends XrayCommonClass {
} }
TlsStreamSettings.Cert = class extends XrayCommonClass { TlsStreamSettings.Cert = class extends XrayCommonClass {
constructor(useFile=true, certificateFile='', keyFile='', certificate='', key='', ocspStapling=3600, oneTimeLoading=false, usage=USAGE_OPTION.ENCIPHERMENT) { constructor(
useFile = true,
certificateFile = '',
keyFile = '',
certificate = '',
key = '',
ocspStapling = 3600,
oneTimeLoading = false,
usage = USAGE_OPTION.ENCIPHERMENT,
buildChain = false,
) {
super(); super();
this.useFile = useFile; this.useFile = useFile;
this.certFile = certificateFile; this.certFile = certificateFile;
this.keyFile = keyFile; this.keyFile = keyFile;
this.cert = certificate instanceof Array ? certificate.join('\n') : certificate; this.cert = Array.isArray(certificate) ? certificate.join('\n') : certificate;
this.key = key instanceof Array ? key.join('\n') : key; this.key = Array.isArray(key) ? key.join('\n') : key;
this.ocspStapling = ocspStapling; this.ocspStapling = ocspStapling;
this.oneTimeLoading = oneTimeLoading; this.oneTimeLoading = oneTimeLoading;
this.usage = usage; this.usage = usage;
this.buildChain = buildChain
} }
static fromJson(json = {}) { static fromJson(json = {}) {
@@ -655,6 +710,7 @@ TlsStreamSettings.Cert = class extends XrayCommonClass {
json.ocspStapling, json.ocspStapling,
json.oneTimeLoading, json.oneTimeLoading,
json.usage, json.usage,
json.buildChain,
); );
} else { } else {
return new TlsStreamSettings.Cert( return new TlsStreamSettings.Cert(
@@ -664,6 +720,7 @@ TlsStreamSettings.Cert = class extends XrayCommonClass {
json.ocspStapling, json.ocspStapling,
json.oneTimeLoading, json.oneTimeLoading,
json.usage, json.usage,
json.buildChain,
); );
} }
} }
@@ -676,6 +733,7 @@ TlsStreamSettings.Cert = class extends XrayCommonClass {
ocspStapling: this.ocspStapling, ocspStapling: this.ocspStapling,
oneTimeLoading: this.oneTimeLoading, oneTimeLoading: this.oneTimeLoading,
usage: this.usage, usage: this.usage,
buildChain: this.buildChain,
}; };
} else { } else {
return { return {
@@ -684,6 +742,7 @@ TlsStreamSettings.Cert = class extends XrayCommonClass {
ocspStapling: this.ocspStapling, ocspStapling: this.ocspStapling,
oneTimeLoading: this.oneTimeLoading, oneTimeLoading: this.oneTimeLoading,
usage: this.usage, usage: this.usage,
buildChain: this.buildChain,
}; };
} }
} }
@@ -710,10 +769,12 @@ TlsStreamSettings.Settings = class extends XrayCommonClass {
}; };
class XtlsStreamSettings extends XrayCommonClass { class XtlsStreamSettings extends XrayCommonClass {
constructor(serverName='', constructor(
serverName = '',
certificates = [new XtlsStreamSettings.Cert()], certificates = [new XtlsStreamSettings.Cert()],
alpn = [ALPN_OPTION.H3, ALPN_OPTION.H2, ALPN_OPTION.HTTP1], alpn = [ALPN_OPTION.H3, ALPN_OPTION.H2, ALPN_OPTION.HTTP1],
settings=new XtlsStreamSettings.Settings()) { settings = new XtlsStreamSettings.Settings()
) {
super(); super();
this.sni = serverName; this.sni = serverName;
this.certs = certificates; this.certs = certificates;
@@ -758,13 +819,22 @@ class XtlsStreamSettings extends XrayCommonClass {
} }
XtlsStreamSettings.Cert = class extends XrayCommonClass { XtlsStreamSettings.Cert = class extends XrayCommonClass {
constructor(useFile=true, certificateFile='', keyFile='', certificate='', key='', ocspStapling=3600, oneTimeLoading=false, usage=USAGE_OPTION.ENCIPHERMENT) { constructor(
useFile = true,
certificateFile = '',
keyFile = '',
certificate = '',
key = '',
ocspStapling = 3600,
oneTimeLoading = false,
usage = USAGE_OPTION.ENCIPHERMENT
) {
super(); super();
this.useFile = useFile; this.useFile = useFile;
this.certFile = certificateFile; this.certFile = certificateFile;
this.keyFile = keyFile; this.keyFile = keyFile;
this.cert = certificate instanceof Array ? certificate.join('\n') : certificate; this.cert = Array.isArray(certificate) ? certificate.join('\n') : certificate;
this.key = key instanceof Array ? key.join('\n') : key; this.key = Array.isArray(key) ? key.join('\n') : key;
this.ocspStapling = ocspStapling; this.ocspStapling = ocspStapling;
this.oneTimeLoading = oneTimeLoading; this.oneTimeLoading = oneTimeLoading;
this.usage = usage; this.usage = usage;
@@ -831,9 +901,9 @@ XtlsStreamSettings.Settings = class extends XrayCommonClass {
}; };
class RealityStreamSettings extends XrayCommonClass { class RealityStreamSettings extends XrayCommonClass {
constructor( constructor(
show = false,xver = 0, show = false,
xver = 0,
dest = 'yahoo.com:443', dest = 'yahoo.com:443',
serverNames = 'yahoo.com,www.yahoo.com', serverNames = 'yahoo.com,www.yahoo.com',
privateKey = '', privateKey = '',
@@ -847,20 +917,23 @@ class RealityStreamSettings extends XrayCommonClass {
this.show = show; this.show = show;
this.xver = xver; this.xver = xver;
this.dest = dest; this.dest = dest;
this.serverNames = serverNames instanceof Array ? serverNames.join(",") : serverNames; this.serverNames = Array.isArray(serverNames) ? serverNames.join(",") : serverNames;
this.privateKey = privateKey; this.privateKey = privateKey;
this.minClient = minClient; this.minClient = minClient;
this.maxClient = maxClient; this.maxClient = maxClient;
this.maxTimediff = maxTimediff; this.maxTimediff = maxTimediff;
this.shortIds = shortIds instanceof Array ? shortIds.join(",") : shortIds; this.shortIds = Array.isArray(shortIds) ? shortIds.join(",") : shortIds;
this.settings = settings; this.settings = settings;
} }
static fromJson(json = {}) { static fromJson(json = {}) {
let settings; let settings;
if (!ObjectUtil.isEmpty(json.settings)) { if (!ObjectUtil.isEmpty(json.settings)) {
settings = new RealityStreamSettings.Settings(json.settings.publicKey , json.settings.fingerprint, json.settings.serverName, json.settings.spiderX); settings = new RealityStreamSettings.Settings(
} json.settings.publicKey,
json.settings.fingerprint,
json.settings.serverName,
json.settings.spiderX);}
return new RealityStreamSettings( return new RealityStreamSettings(
json.show, json.show,
json.xver, json.xver,
@@ -873,8 +946,8 @@ class RealityStreamSettings extends XrayCommonClass {
json.shortIds, json.shortIds,
json.settings, json.settings,
); );
} }
toJson() { toJson() {
return { return {
show: this.show, show: this.show,
@@ -892,7 +965,12 @@ class RealityStreamSettings extends XrayCommonClass {
} }
RealityStreamSettings.Settings = class extends XrayCommonClass { RealityStreamSettings.Settings = class extends XrayCommonClass {
constructor(publicKey = '', fingerprint = UTLS_FINGERPRINT.UTLS_RANDOM, serverName = '', spiderX= '/') { constructor(
publicKey = '',
fingerprint = UTLS_FINGERPRINT.UTLS_RANDOM,
serverName = '',
spiderX = '/'
) {
super(); super();
this.publicKey = publicKey; this.publicKey = publicKey;
this.fingerprint = fingerprint; this.fingerprint = fingerprint;
@@ -1151,7 +1229,8 @@ class Sniffing extends XrayCommonClass {
} }
class Inbound extends XrayCommonClass { class Inbound extends XrayCommonClass {
constructor(port=RandomUtil.randomIntRange(10000, 60000), constructor(
port = RandomUtil.randomIntRange(10000, 60000),
listen = '', listen = '',
protocol = Protocols.VLESS, protocol = Protocols.VLESS,
settings = null, settings = null,
@@ -1376,20 +1455,21 @@ class Inbound extends XrayCommonClass {
this.sniffing = new Sniffing(); this.sniffing = new Sniffing();
} }
genVmessLink(address='', port=this.port, forceTls, remark='', clientId) { genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId, security) {
if (this.protocol !== Protocols.VMESS) { if (this.protocol !== Protocols.VMESS) {
return ''; return '';
} }
const security = forceTls == 'same' ? this.stream.security : forceTls; const tls = forceTls == 'same' ? this.stream.security : forceTls;
let obj = { let obj = {
v: '2', v: '2',
ps: remark, ps: remark,
add: address, add: address,
port: port, port: port,
id: clientId, id: clientId,
scy: security,
net: this.stream.network, net: this.stream.network,
type: 'none', type: 'none',
tls: security, tls: tls,
}; };
const network = this.stream.network; const network = this.stream.network;
if (network === 'tcp') { if (network === 'tcp') {
@@ -1800,7 +1880,7 @@ class Inbound extends XrayCommonClass {
genLink(address = '', port = this.port, forceTls = 'same', remark = '', client) { genLink(address = '', port = this.port, forceTls = 'same', remark = '', client) {
switch (this.protocol) { switch (this.protocol) {
case Protocols.VMESS: case Protocols.VMESS:
return this.genVmessLink(address, port, forceTls, remark, client.id); return this.genVmessLink(address, port, forceTls, remark, client.id, client.security);
case Protocols.VLESS: case Protocols.VLESS:
return this.genVLESSLink(address, port, forceTls, remark, client.id, client.flow); return this.genVLESSLink(address, port, forceTls, remark, client.id, client.flow);
case Protocols.SHADOWSOCKS: case Protocols.SHADOWSOCKS:
@@ -1937,24 +2017,24 @@ Inbound.Settings = class extends XrayCommonClass {
Inbound.VmessSettings = class extends Inbound.Settings { Inbound.VmessSettings = class extends Inbound.Settings {
constructor(protocol, constructor(protocol,
vmesses=[new Inbound.VmessSettings.Vmess()]) { vmesses = [new Inbound.VmessSettings.VMESS()]) {
super(protocol); super(protocol);
this.vmesses = vmesses; this.vmesses = vmesses;
} }
indexOfVmessById(id) { indexOfVmessById(id) {
return this.vmesses.findIndex(vmess => vmess.id === id); return this.vmesses.findIndex(VMESS => VMESS.id === id);
} }
addVmess(vmess) { addVmess(VMESS) {
if (this.indexOfVmessById(vmess.id) >= 0) { if (this.indexOfVmessById(VMESS.id) >= 0) {
return false; return false;
} }
this.vmesses.push(vmess); this.vmesses.push(VMESS);
} }
delVmess(vmess) { delVmess(VMESS) {
const i = this.indexOfVmessById(vmess.id); const i = this.indexOfVmessById(VMESS.id);
if (i >= 0) { if (i >= 0) {
this.vmesses.splice(i, 1); this.vmesses.splice(i, 1);
} }
@@ -1963,7 +2043,7 @@ Inbound.VmessSettings = class extends Inbound.Settings {
static fromJson(json = {}) { static fromJson(json = {}) {
return new Inbound.VmessSettings( return new Inbound.VmessSettings(
Protocols.VMESS, Protocols.VMESS,
json.clients.map(client => Inbound.VmessSettings.Vmess.fromJson(client)), json.clients.map(client => Inbound.VmessSettings.VMESS.fromJson(client)),
); );
} }
@@ -1973,10 +2053,23 @@ Inbound.VmessSettings = class extends Inbound.Settings {
}; };
} }
}; };
Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
constructor(id=RandomUtil.randomUUID(), email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16), reset=0) { Inbound.VmessSettings.VMESS = class extends XrayCommonClass {
constructor(
id = RandomUtil.randomUUID(),
security = USERS_SECURITY.AUTO,
email = RandomUtil.randomLowerAndNum(8),
limitIp = 0,
totalGB = 0,
expiryTime = 0,
enable = true,
tgId = '',
subId = RandomUtil.randomLowerAndNum(16),
reset = 0
) {
super(); super();
this.id = id; this.id = id;
this.security = security;
this.email = email; this.email = email;
this.limitIp = limitIp; this.limitIp = limitIp;
this.totalGB = totalGB; this.totalGB = totalGB;
@@ -1988,8 +2081,9 @@ Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
} }
static fromJson(json = {}) { static fromJson(json = {}) {
return new Inbound.VmessSettings.Vmess( return new Inbound.VmessSettings.VMESS(
json.id, json.id,
json.security,
json.email, json.email,
json.limitIp, json.limitIp,
json.totalGB, json.totalGB,
@@ -2028,10 +2122,12 @@ Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
}; };
Inbound.VLESSSettings = class extends Inbound.Settings { Inbound.VLESSSettings = class extends Inbound.Settings {
constructor(protocol, constructor(
protocol,
vlesses = [new Inbound.VLESSSettings.VLESS()], vlesses = [new Inbound.VLESSSettings.VLESS()],
decryption = 'none', decryption = 'none',
fallbacks=[]) { fallbacks = []
) {
super(protocol); super(protocol);
this.vlesses = vlesses; this.vlesses = vlesses;
this.decryption = decryption; this.decryption = decryption;
@@ -2065,7 +2161,18 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
}; };
Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16), reset=0) { constructor(
id = RandomUtil.randomUUID(),
flow = '',
email = RandomUtil.randomLowerAndNum(8),
limitIp = 0,
totalGB = 0,
expiryTime = 0,
enable = true,
tgId = '',
subId = RandomUtil.randomLowerAndNum(16),
reset = 0
) {
super(); super();
this.id = id; this.id = id;
this.flow = flow; this.flow = flow;
@@ -2189,8 +2296,20 @@ Inbound.TrojanSettings = class extends Inbound.Settings {
}; };
} }
}; };
Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { Inbound.TrojanSettings.Trojan = class extends XrayCommonClass {
constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16), reset=0) { constructor(
password = RandomUtil.randomSeq(10),
flow = '',
email = RandomUtil.randomLowerAndNum(8),
limitIp = 0,
totalGB = 0,
expiryTime = 0,
enable = true,
tgId = '',
subId = RandomUtil.randomLowerAndNum(16),
reset = 0
) {
super(); super();
this.password = password; this.password = password;
this.flow = flow; this.flow = flow;
@@ -2335,7 +2454,18 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings {
}; };
Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass { Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
constructor(method='', password=RandomUtil.randomShadowsocksPassword(), email=RandomUtil.randomLowerAndNum(8),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId=RandomUtil.randomLowerAndNum(16), reset=0) { constructor(
method = '',
password = RandomUtil.randomShadowsocksPassword(),
email = RandomUtil.randomLowerAndNum(8),
limitIp = 0,
totalGB = 0,
expiryTime = 0,
enable = true,
tgId = '',
subId = RandomUtil.randomLowerAndNum(16),
reset = 0
) {
super(); super();
this.method = method; this.method = method;
this.password = password; this.password = password;
@@ -2407,7 +2537,14 @@ Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
}; };
Inbound.DokodemoSettings = class extends Inbound.Settings { Inbound.DokodemoSettings = class extends Inbound.Settings {
constructor(protocol, address, port, network='tcp,udp', followRedirect=false, timeout=0) { constructor(
protocol,
address,
port,
network = 'tcp,udp',
followRedirect = false,
timeout = 30
) {
super(protocol); super(protocol);
this.address = address; this.address = address;
this.port = port; this.port = port;

View File

@@ -16,6 +16,9 @@ class HttpUtil {
} }
static _respToMsg(resp) { static _respToMsg(resp) {
if (!resp || !resp.data) {
return new Msg(false, 'No response data');
}
const { data } = resp; const { data } = resp;
if (data == null) { if (data == null) {
return new Msg(true); return new Msg(true);
@@ -34,7 +37,7 @@ class HttpUtil {
return msg; return msg;
} catch (error) { } catch (error) {
console.error('GET request failed:', error); console.error('GET request failed:', error);
const errorMsg = new Msg(false, error.response?.data?.message || error.message); const errorMsg = new Msg(false, error.response?.data?.message || error.message || 'Request failed');
this._handleMsg(errorMsg); this._handleMsg(errorMsg);
return errorMsg; return errorMsg;
} }
@@ -48,7 +51,7 @@ class HttpUtil {
return msg; return msg;
} catch (error) { } catch (error) {
console.error('POST request failed:', error); console.error('POST request failed:', error);
const errorMsg = new Msg(false, error.response?.data?.message || error.message); const errorMsg = new Msg(false, error.response?.data?.message || error.message || 'Request failed');
this._handleMsg(errorMsg); this._handleMsg(errorMsg);
return errorMsg; return errorMsg;
} }
@@ -97,11 +100,21 @@ class RandomUtil {
} }
static randomShortId() { static randomShortId() {
let str = ''; const lengths = [2, 4, 6, 8, 10, 12, 14, 16];
for (let i = 0; i < 8; ++i) { for (let i = lengths.length - 1; i > 0; i--) {
str += seq[this.randomInt(16)]; const j = Math.floor(Math.random() * (i + 1));
[lengths[i], lengths[j]] = [lengths[j], lengths[i]];
} }
return str;
let shortIds = [];
for (let length of lengths) {
let shortId = '';
for (let i = 0; i < length; i++) {
shortId += seq[this.randomInt(16)];
}
shortIds.push(shortId);
}
return shortIds;
} }
static randomLowerAndNum(len) { static randomLowerAndNum(len) {

View File

@@ -33,6 +33,7 @@ func (a *APIController) initRouter(g *gin.RouterGroup) {
{"GET", "/list", a.inboundController.getInbounds}, {"GET", "/list", a.inboundController.getInbounds},
{"GET", "/get/:id", a.inboundController.getInbound}, {"GET", "/get/:id", a.inboundController.getInbound},
{"GET", "/getClientTraffics/:email", a.inboundController.getClientTraffics}, {"GET", "/getClientTraffics/:email", a.inboundController.getClientTraffics},
{"GET", "/getClientTrafficsById/:id", a.inboundController.getClientTrafficsById},
{"POST", "/add", a.inboundController.addInbound}, {"POST", "/add", a.inboundController.addInbound},
{"POST", "/del/:id", a.inboundController.delInbound}, {"POST", "/del/:id", a.inboundController.delInbound},
{"POST", "/update/:id", a.inboundController.updateInbound}, {"POST", "/update/:id", a.inboundController.updateInbound},

View File

@@ -77,6 +77,16 @@ func (a *InboundController) getClientTraffics(c *gin.Context) {
jsonObj(c, clientTraffics, nil) jsonObj(c, clientTraffics, nil)
} }
func (a *InboundController) getClientTrafficsById(c *gin.Context) {
id := c.Param("id")
clientTraffics, err := a.inboundService.GetClientTrafficByID(id)
if err != nil {
jsonMsg(c, "Error getting traffics", err)
return
}
jsonObj(c, clientTraffics, nil)
}
func (a *InboundController) addInbound(c *gin.Context) { func (a *InboundController) addInbound(c *gin.Context) {
inbound := &model.Inbound{} inbound := &model.Inbound{}
err := c.ShouldBind(inbound) err := c.ShouldBind(inbound)

View File

@@ -83,12 +83,14 @@ func (a *IndexController) login(c *gin.Context) {
logger.Warning("Unable to get session's max age from DB") logger.Warning("Unable to get session's max age from DB")
} }
if sessionMaxAge > 0 { if sessionMaxAge <= 0 {
sessionMaxAge = 60
}
err = session.SetMaxAge(c, sessionMaxAge*60) err = session.SetMaxAge(c, sessionMaxAge*60)
if err != nil { if err != nil {
logger.Warning("Unable to set session's max age") logger.Warning("Unable to set session's max age")
} }
}
err = session.SetLoginUser(c, user) err = session.SetLoginUser(c, user)
logger.Infof("%s logged in successfully", user.Username) logger.Infof("%s logged in successfully", user.Username)

View File

@@ -28,6 +28,11 @@
<a-form-item label='{{ i18n "pages.client.clientCount" }}' v-if="clientsBulkModal.emailMethod < 2"> <a-form-item label='{{ i18n "pages.client.clientCount" }}' v-if="clientsBulkModal.emailMethod < 2">
<a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number> <a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number>
</a-form-item> </a-form-item>
<a-form-item v-if="inbound.protocol === Protocols.VMESS" label='Security'>
<a-select v-model="clientsBulkModal.security" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item label='Flow' v-if="clientsBulkModal.inbound.canEnableTlsFlow()"> <a-form-item label='Flow' v-if="clientsBulkModal.inbound.canEnableTlsFlow()">
<a-select v-model="clientsBulkModal.flow" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select v-model="clientsBulkModal.flow" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option> <a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
@@ -146,6 +151,7 @@
emailPostfix: "", emailPostfix: "",
subId: "", subId: "",
tgId: '', tgId: '',
security: "auto",
flow: "", flow: "",
delayedStart: false, delayedStart: false,
reset: 0, reset: 0,
@@ -168,6 +174,7 @@
newClient.email += useNum ? prefix + i.toString() + postfix : prefix + postfix; newClient.email += useNum ? prefix + i.toString() + postfix : prefix + postfix;
if (clientsBulkModal.subId.length > 0) newClient.subId = clientsBulkModal.subId; if (clientsBulkModal.subId.length > 0) newClient.subId = clientsBulkModal.subId;
newClient.tgId = clientsBulkModal.tgId; newClient.tgId = clientsBulkModal.tgId;
newClient.security = clientsBulkModal.security;
newClient.limitIp = clientsBulkModal.limitIp; newClient.limitIp = clientsBulkModal.limitIp;
newClient._totalGB = clientsBulkModal.totalGB; newClient._totalGB = clientsBulkModal.totalGB;
newClient._expiryTime = clientsBulkModal.expiryTime; newClient._expiryTime = clientsBulkModal.expiryTime;
@@ -203,6 +210,7 @@
this.emailPostfix = ""; this.emailPostfix = "";
this.subId = ""; this.subId = "";
this.tgId = ''; this.tgId = '';
this.security = "auto";
this.flow = ""; this.flow = "";
this.dbInbound = new DBInbound(dbInbound); this.dbInbound = new DBInbound(dbInbound);
this.inbound = dbInbound.toInbound(); this.inbound = dbInbound.toInbound();
@@ -211,7 +219,7 @@
}, },
newClient(protocol) { newClient(protocol) {
switch (protocol) { switch (protocol) {
case Protocols.VMESS: return new Inbound.VmessSettings.Vmess(); case Protocols.VMESS: return new Inbound.VmessSettings.VMESS();
case Protocols.VLESS: return new Inbound.VLESSSettings.VLESS(); case Protocols.VLESS: return new Inbound.VLESSSettings.VLESS();
case Protocols.TROJAN: return new Inbound.TrojanSettings.Trojan(); case Protocols.TROJAN: return new Inbound.TrojanSettings.Trojan();
case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings.Shadowsocks(clientsBulkModal.inbound.settings.shadowsockses[0].method); case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings.Shadowsocks(clientsBulkModal.inbound.settings.shadowsockses[0].method);

View File

@@ -61,7 +61,7 @@
}, },
addClient(protocol, clients) { addClient(protocol, clients) {
switch (protocol) { switch (protocol) {
case Protocols.VMESS: return clients.push(new Inbound.VmessSettings.Vmess()); case Protocols.VMESS: return clients.push(new Inbound.VmessSettings.VMESS());
case Protocols.VLESS: return clients.push(new Inbound.VLESSSettings.VLESS()); case Protocols.VLESS: return clients.push(new Inbound.VLESSSettings.VLESS());
case Protocols.TROJAN: return clients.push(new Inbound.TrojanSettings.Trojan()); case Protocols.TROJAN: return clients.push(new Inbound.TrojanSettings.Trojan());
case Protocols.SHADOWSOCKS: return clients.push(new Inbound.ShadowsocksSettings.Shadowsocks(clients[0].method)); case Protocols.SHADOWSOCKS: return clients.push(new Inbound.ShadowsocksSettings.Shadowsocks(clients[0].method));

View File

@@ -39,6 +39,11 @@
</template> </template>
<a-input v-model.trim="client.id"></a-input> <a-input v-model.trim="client.id"></a-input>
</a-form-item> </a-form-item>
<a-form-item v-if="inbound.protocol === Protocols.VMESS" label='Security'>
<a-select v-model="client.security" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item v-if="client.email && app.subSettings.enable"> <a-form-item v-if="client.email && app.subSettings.enable">
<template slot="label"> <template slot="label">
<a-tooltip> <a-tooltip>

View File

@@ -160,6 +160,11 @@
<a-form-item label='ID'> <a-form-item label='ID'>
<a-input v-model.trim="outbound.settings.id"></a-input> <a-input v-model.trim="outbound.settings.id"></a-input>
</a-form-item> </a-form-item>
<a-form-item label='Security'>
<a-select v-model="outbound.settings.security" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
<!-- vless settings --> <!-- vless settings -->
<template v-if="outbound.canEnableTlsFlow()"> <template v-if="outbound.canEnableTlsFlow()">

View File

@@ -9,12 +9,10 @@
<table width="100%"> <table width="100%">
<tr class="client-table-header"> <tr class="client-table-header">
<th>{{ i18n "pages.inbounds.email" }}</th> <th>{{ i18n "pages.inbounds.email" }}</th>
<th>Flow</th>
<th>ID</th> <th>ID</th>
</tr> </tr>
<tr v-for="(client, index) in inbound.settings.vlesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''"> <tr v-for="(client, index) in inbound.settings.vlesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
<td>[[ client.email ]]</td> <td>[[ client.email ]]</td>
<td>[[ client.flow ]]</td>
<td>[[ client.id ]]</td> <td>[[ client.id ]]</td>
</tr> </tr>
</table> </table>

View File

@@ -10,10 +10,12 @@
<tr class="client-table-header"> <tr class="client-table-header">
<th>{{ i18n "pages.inbounds.email" }}</th> <th>{{ i18n "pages.inbounds.email" }}</th>
<th>ID</th> <th>ID</th>
<th>Security</th>
</tr> </tr>
<tr v-for="(client, index) in inbound.settings.vmesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''"> <tr v-for="(client, index) in inbound.settings.vmesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
<td>[[ client.email ]]</td> <td>[[ client.email ]]</td>
<td>[[ client.id ]]</td> <td>[[ client.id ]]</td>
<td>[[ client.security ]]</td>
</tr> </tr>
</table> </table>
</a-collapse-panel> </a-collapse-panel>

View File

@@ -19,11 +19,17 @@
</a-input> </a-input>
</a-input-group> </a-input-group>
</a-form-item> </a-form-item>
<a-form-item label="Max Upload Size (MB)">
<a-input-number v-model="inbound.stream.splithttp.maxUploadSize" :min="0"></a-input-number>
</a-form-item>
<a-form-item label="Max Concurrent Upload"> <a-form-item label="Max Concurrent Upload">
<a-input-number v-model="inbound.stream.splithttp.maxConcurrentUploads" :min="0"></a-input-number> <a-input v-model.trim="inbound.stream.splithttp.scMaxConcurrentPosts"></a-input>
</a-form-item>
<a-form-item label="Max Upload Size (Byte)">
<a-input v-model.trim="inbound.stream.splithttp.scMaxEachPostBytes"></a-input>
</a-form-item>
<a-form-item label="Min Upload Interval (Ms)">
<a-input v-model.trim="inbound.stream.splithttp.scMinPostsIntervalMs"></a-input>
</a-form-item>
<a-form-item label="No SSE Header">
<a-switch v-model="inbound.stream.splithttp.noSSEHeader"></a-switch>
</a-form-item> </a-form-item>
</a-form> </a-form>
{{end}} {{end}}

View File

@@ -104,6 +104,9 @@
<a-select-option v-for="key in USAGE_OPTION" :value="key">[[ key ]]</a-select-option> <a-select-option v-for="key in USAGE_OPTION" :value="key">[[ key ]]</a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item label="Build Chain">
<a-switch v-model="cert.buildChain"></a-switch>
</a-form-item>
</template> </template>
</template> </template>

View File

@@ -523,7 +523,9 @@
if (msg.success) { if (msg.success) {
this.loading(true); this.loading(true);
await PromiseUtil.sleep(5000); await PromiseUtil.sleep(5000);
let { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting; var { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting;
if (host == this.oldAllSetting.webDomain) host = null;
if (port == this.oldAllSetting.webPort) port = null;
const isTLS = webCertFile !== "" || webKeyFile !== ""; const isTLS = webCertFile !== "" || webKeyFile !== "";
const url = buildURL({ host, port, isTLS, base, path: "panel/settings" }); const url = buildURL({ host, port, isTLS, base, path: "panel/settings" });
window.location.replace(url); window.location.replace(url);

View File

@@ -300,7 +300,7 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun
if limitIp < len(ips) { if limitIp < len(ips) {
j.disAllowedIps = append(j.disAllowedIps, ips[limitIp:]...) j.disAllowedIps = append(j.disAllowedIps, ips[limitIp:]...)
for i := limitIp; i < len(ips); i++ { for i := limitIp; i < len(ips); i++ {
logger.Debugf("[LIMIT_IP] Email = %s || SRC = %s", clientEmail, ips[i]) log.Printf("[LIMIT_IP] Email = %s || SRC = %s", clientEmail, ips[i])
} }
} }
} }

View File

@@ -10,15 +10,9 @@ import (
func DomainValidatorMiddleware(domain string) gin.HandlerFunc { func DomainValidatorMiddleware(domain string) gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
host := c.GetHeader("X-Forwarded-Host") host := c.Request.Host
if host == "" {
host = c.GetHeader("X-Real-IP")
}
if host == "" {
host = c.Request.Host
if colonIndex := strings.LastIndex(host, ":"); colonIndex != -1 { if colonIndex := strings.LastIndex(host, ":"); colonIndex != -1 {
host, _, _ = net.SplitHostPort(host) host, _, _ = net.SplitHostPort(c.Request.Host)
}
} }
if host != domain { if host != domain {

View File

@@ -490,6 +490,7 @@ func (s *InboundService) AddInboundClient(data *model.Inbound) (bool, error) {
err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{ err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{
"email": client.Email, "email": client.Email,
"id": client.ID, "id": client.ID,
"security": client.Security,
"flow": client.Flow, "flow": client.Flow,
"password": client.Password, "password": client.Password,
"cipher": cipher, "cipher": cipher,
@@ -711,6 +712,7 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{ err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{
"email": clients[0].Email, "email": clients[0].Email,
"id": clients[0].ID, "id": clients[0].ID,
"security": clients[0].Security,
"flow": clients[0].Flow, "flow": clients[0].Flow,
"password": clients[0].Password, "password": clients[0].Password,
"cipher": cipher, "cipher": cipher,
@@ -1559,6 +1561,7 @@ func (s *InboundService) ResetClientTraffic(id int, clientEmail string) (bool, e
err1 := s.xrayApi.AddUser(string(inbound.Protocol), inbound.Tag, map[string]interface{}{ err1 := s.xrayApi.AddUser(string(inbound.Protocol), inbound.Tag, map[string]interface{}{
"email": client.Email, "email": client.Email,
"id": client.ID, "id": client.ID,
"security": client.Security,
"flow": client.Flow, "flow": client.Flow,
"password": client.Password, "password": client.Password,
"cipher": cipher, "cipher": cipher,
@@ -1750,6 +1753,25 @@ func (s *InboundService) GetClientTrafficByEmail(email string) (traffic *xray.Cl
return nil, nil return nil, nil
} }
func (s *InboundService) GetClientTrafficByID(id string) ([]xray.ClientTraffic, error) {
db := database.GetDB()
var traffics []xray.ClientTraffic
err := db.Model(xray.ClientTraffic{}).Where(`email IN(
SELECT JSON_EXTRACT(client.value, '$.email') as email
FROM inbounds,
JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client
WHERE
JSON_EXTRACT(client.value, '$.id') in (?)
)`, id).Find(&traffics).Error
if err != nil {
logger.Debug(err)
return nil, err
}
return traffics, err
}
func (s *InboundService) SearchClientTraffic(query string) (traffic *xray.ClientTraffic, err error) { func (s *InboundService) SearchClientTraffic(query string) (traffic *xray.ClientTraffic, err error) {
db := database.GetDB() db := database.GetDB()
inbound := &model.Inbound{} inbound := &model.Inbound{}

View File

@@ -45,7 +45,7 @@ var defaultValueMap = map[string]string{
"tgRunTime": "@daily", "tgRunTime": "@daily",
"tgBotBackup": "false", "tgBotBackup": "false",
"tgBotLoginNotify": "true", "tgBotLoginNotify": "true",
"tgCpu": "0", "tgCpu": "80",
"tgLang": "en-US", "tgLang": "en-US",
"secretEnable": "false", "secretEnable": "false",
"subEnable": "false", "subEnable": "false",

View File

@@ -9,7 +9,10 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
const loginUser = "LOGIN_USER" const (
loginUser = "LOGIN_USER"
defaultPath = "/"
)
func init() { func init() {
gob.Register(model.User{}) gob.Register(model.User{})
@@ -17,10 +20,6 @@ func init() {
func SetLoginUser(c *gin.Context, user *model.User) error { func SetLoginUser(c *gin.Context, user *model.User) error {
s := sessions.Default(c) s := sessions.Default(c)
s.Options(sessions.Options{
Path: "/",
HttpOnly: true,
})
s.Set(loginUser, user) s.Set(loginUser, user)
return s.Save() return s.Save()
} }
@@ -28,21 +27,25 @@ func SetLoginUser(c *gin.Context, user *model.User) error {
func SetMaxAge(c *gin.Context, maxAge int) error { func SetMaxAge(c *gin.Context, maxAge int) error {
s := sessions.Default(c) s := sessions.Default(c)
s.Options(sessions.Options{ s.Options(sessions.Options{
Path: "/", Path: defaultPath,
MaxAge: maxAge, MaxAge: maxAge,
HttpOnly: true,
}) })
return s.Save() return s.Save()
} }
func GetLoginUser(c *gin.Context) *model.User { func GetLoginUser(c *gin.Context) *model.User {
s := sessions.Default(c) s := sessions.Default(c)
if obj := s.Get(loginUser); obj != nil { obj := s.Get(loginUser)
if user, ok := obj.(model.User); ok { if obj == nil {
return &user
}
}
return nil return nil
} }
user, ok := obj.(model.User)
if !ok {
return nil
}
return &user
}
func IsLogin(c *gin.Context) bool { func IsLogin(c *gin.Context) bool {
return GetLoginUser(c) != nil return GetLoginUser(c) != nil
@@ -52,12 +55,9 @@ func ClearSession(c *gin.Context) error {
s := sessions.Default(c) s := sessions.Default(c)
s.Clear() s.Clear()
s.Options(sessions.Options{ s.Options(sessions.Options{
Path: "/", Path: defaultPath,
MaxAge: -1, MaxAge: -1,
HttpOnly: true,
}) })
if err := s.Save(); err != nil { return s.Save()
return err
}
c.SetCookie("3x-ui", "", -1, "/", "", false, true)
return nil
} }

View File

@@ -67,7 +67,7 @@
"settings" = "Настройки панели" "settings" = "Настройки панели"
"xray" = "Настройки Xray" "xray" = "Настройки Xray"
"logout" = "Выход" "logout" = "Выход"
"link" = "менеджмент" "link" = "Менеджмент"
[pages.login] [pages.login]
"hello" = "Привет" "hello" = "Привет"
@@ -254,7 +254,7 @@
"pageSize" = "Размер нумерации страниц" "pageSize" = "Размер нумерации страниц"
"pageSizeDesc" = "Определить размер страницы для входящей таблицы. Установите 0, чтобы отключить" "pageSizeDesc" = "Определить размер страницы для входящей таблицы. Установите 0, чтобы отключить"
"remarkModel" = "Модель примечания и символ разделения" "remarkModel" = "Модель примечания и символ разделения"
"datepicker" = "выбор даты" "datepicker" = "Выбор даты"
"datepickerPlaceholder" = "Выберите дату" "datepickerPlaceholder" = "Выберите дату"
"datepickerDescription" = "Тип календаря выбора указывает дату истечения срока действия." "datepickerDescription" = "Тип календаря выбора указывает дату истечения срока действия."
"sampleRemark" = "Пример замечания" "sampleRemark" = "Пример замечания"
@@ -412,7 +412,7 @@
"Inbounds" = "Входящие" "Inbounds" = "Входящие"
"InboundsDesc" = "Изменение шаблона конфигурации для подключения определенных пользователей" "InboundsDesc" = "Изменение шаблона конфигурации для подключения определенных пользователей"
"Outbounds" = "Исходящие" "Outbounds" = "Исходящие"
"Balancers" = "Балансиры" "Balancers" = "Балансировщик нагрузки"
"OutboundsDesc" = "Изменение шаблона конфигурации, чтобы определить исходящие пути для этого сервера" "OutboundsDesc" = "Изменение шаблона конфигурации, чтобы определить исходящие пути для этого сервера"
"Routings" = "Правила маршрутизации" "Routings" = "Правила маршрутизации"
"RoutingsDesc" = "Важен приоритет каждого правила!" "RoutingsDesc" = "Важен приоритет каждого правила!"

View File

@@ -0,0 +1,640 @@
"username" = "Kullanıcı Adı"
"password" = "Şifre"
"login" = "Giriş Yap"
"confirm" = "Onayla"
"cancel" = "İptal"
"close" = "Kapat"
"copy" = "Kopyala"
"copied" = "Kopyalandı"
"download" = "İndir"
"remark" = "Açıklama"
"enable" = "Etkin"
"protocol" = "Protokol"
"search" = "Ara"
"filter" = "Filtrele"
"loading" = "Yükleniyor..."
"second" = "Saniye"
"minute" = "Dakika"
"hour" = "Saat"
"day" = "Gün"
"check" = "Kontrol Et"
"indefinite" = "Belirsiz"
"unlimited" = "Sınırsız"
"none" = "Hiçbiri"
"qrCode" = "QR Kod"
"info" = "Daha Fazla Bilgi"
"edit" = "Düzenle"
"delete" = "Sil"
"reset" = "Sıfırla"
"copySuccess" = "Başarıyla Kopyalandı"
"sure" = "Emin misiniz"
"encryption" = "Şifreleme"
"transmission" = "İletim"
"host" = "Sunucu"
"path" = "Yol"
"camouflage" = "Kandırma"
"status" = "Durum"
"enabled" = "Etkin"
"disabled" = "Devre Dışı"
"depleted" = "Bitti"
"depletingSoon" = "Bitmek Üzere"
"offline" = "Çevrimdışı"
"online" = "Çevrimiçi"
"domainName" = "Alan Adı"
"monitor" = "Dinleme IP"
"certificate" = "Dijital Sertifika"
"fail" = "Başarısız"
"success" = "Başarılı"
"getVersion" = "Sürümü Al"
"install" = "Yükle"
"clients" = "Müşteriler"
"usage" = "Kullanım"
"secretToken" = "Gizli Anahtar"
"remained" = "Kalan"
"security" = "Güvenlik"
"secAlertTitle" = "Güvenlik Uyarısı"
"secAlertSsl" = "Bu bağlantı güvenli değil. Verilerin korunması için TLS etkinleştirilene kadar hassas bilgiler girmekten kaçının."
"secAlertConf" = "Bazı ayarlar saldırılara açıktır. Olası ihlalleri önlemek için güvenlik protokollerini güçlendirmeniz önerilir."
"secAlertSSL" = "Panelde güvenli bağlantı yok. Verilerin korunması için TLS sertifikası yükleyin."
"secAlertPanelPort" = "Panel varsayılan portu savunmasız. Rastgele veya belirli bir port yapılandırın."
"secAlertPanelURI" = "Panel varsayılan URI yolu güvensiz. Karmaşık bir URI yolu yapılandırın."
"secAlertSubURI" = "Abonelik varsayılan URI yolu güvensiz. Karmaşık bir URI yolu yapılandırın."
"secAlertSubJsonURI" = "Abonelik JSON varsayılan URI yolu güvensiz. Karmaşık bir URI yolu yapılandırın."
[menu]
"dashboard" = "Genel Bakış"
"inbounds" = "Gelenler"
"settings" = "Panel Ayarları"
"xray" = "Xray Yapılandırmaları"
"logout" = ıkış Yap"
"link" = "Yönet"
[pages.login]
"hello" = "Merhaba"
"title" = "Hoş Geldiniz"
"loginAgain" = "Oturum süreniz doldu, lütfen tekrar giriş yapın"
[pages.login.toasts]
"invalidFormData" = "Girdi verisi formatı geçersiz."
"emptyUsername" = "Kullanıcı adı gerekli"
"emptyPassword" = "Şifre gerekli"
"wrongUsernameOrPassword" = "Geçersiz kullanıcı adı veya şifre veya gizli anahtar."
"successLogin" = "Giriş Başarılı"
[pages.index]
"title" = "Genel Bakış"
"memory" = "RAM"
"hard" = "Disk"
"xrayStatus" = "Xray"
"stopXray" = "Durdur"
"restartXray" = "Yeniden Başlat"
"xraySwitch" = "Sürüm"
"xraySwitchClick" = "Geçiş yapmak istediğiniz sürümü seçin."
"xraySwitchClickDesk" = "Dikkatli seçin, eski sürümler mevcut yapılandırmalarla uyumlu olmayabilir."
"operationHours" = "Çalışma Süresi"
"systemLoad" = "Sistem Yükü"
"systemLoadDesc" = "Geçmiş 1, 5 ve 15 dakika için sistem yük ortalaması"
"connectionTcpCountDesc" = "Sistem genelinde toplam TCP bağlantıları"
"connectionUdpCountDesc" = "Sistem genelinde toplam UDP bağlantıları"
"connectionCount" = "Bağlantı İstatistikleri"
"upSpeed" = "Sistem genelinde toplam yükleme hızı"
"downSpeed" = "Sistem genelinde toplam indirme hızı"
"totalSent" = "İşletim sistemi başlatıldığından beri sistem genelinde gönderilen toplam veri"
"totalReceive" = "İşletim sistemi başlatıldığından beri sistem genelinde alınan toplam veri"
"xraySwitchVersionDialog" = "Xray Sürümünü Değiştir"
"xraySwitchVersionDialogDesc" = "Xray sürümünü değiştirmek istediğinizden emin misiniz"
"dontRefresh" = "Kurulum devam ediyor, lütfen bu sayfayı yenilemeyin"
"logs" = "Günlükler"
"config" = "Yapılandırma"
"backup" = "Yedekle & Geri Yükle"
"backupTitle" = "Veritabanı Yedekleme & Geri Yükleme"
"backupDescription" = "Veritabanını geri yüklemeden önce yedek almanız önerilir."
"exportDatabase" = "Yedekle"
"importDatabase" = "Geri Yükle"
[pages.inbounds]
"title" = "Gelenler"
"totalDownUp" = "Toplam Gönderilen/Alınan"
"totalUsage" = "Toplam Kullanım"
"inboundCount" = "Toplam Gelen"
"operate" = "Menü"
"enable" = "Etkin"
"remark" = "Açıklama"
"protocol" = "Protokol"
"port" = "Port"
"traffic" = "Trafik"
"details" = "Detaylar"
"transportConfig" = "Taşıma"
"expireDate" = "Süre"
"resetTraffic" = "Trafiği Sıfırla"
"addInbound" = "Gelen Ekle"
"generalActions" = "Genel Eylemler"
"create" = "Oluştur"
"update" = "Güncelle"
"modifyInbound" = "Geleni Düzenle"
"deleteInbound" = "Geleni Sil"
"deleteInboundContent" = "Geleni silmek istediğinizden emin misiniz?"
"deleteClient" = "Müşteriyi Sil"
"deleteClientContent" = "Müşteriyi silmek istediğinizden emin misiniz?"
"resetTrafficContent" = "Trafiği sıfırlamak istediğinizden emin misiniz?"
"copyLink" = "URL'yi Kopyala"
"address" = "Adres"
"network" = "Ağ"
"destinationPort" = "Hedef Port"
"targetAddress" = "Hedef Adres"
"monitorDesc" = "Tüm IP'leri dinlemek için boş bırakın"
"meansNoLimit" = " = Sınırsız. (birim: GB)"
"totalFlow" = "Toplam Akış"
"leaveBlankToNeverExpire" = "Hiçbir zaman sona ermemesi için boş bırakın"
"noRecommendKeepDefault" = "Varsayılanı korumanız önerilir"
"certificatePath" = "Dosya Yolu"
"certificateContent" = "Dosya İçeriği"
"publicKey" = "Genel Anahtar"
"privatekey" = "Özel Anahtar"
"clickOnQRcode" = "Kopyalamak için QR Kodu Tıklayın"
"client" = "Müşteri"
"export" = "Tüm URL'leri Dışa Aktar"
"clone" = "Klonla"
"cloneInbound" = "Klonla"
"cloneInboundContent" = "Bu gelenin tüm ayarları, Port, Dinleme IP ve Müşteriler hariç, klona uygulanacaktır."
"cloneInboundOk" = "Klonla"
"resetAllTraffic" = "Tüm Gelen Trafiğini Sıfırla"
"resetAllTrafficTitle" = "Tüm Gelen Trafiğini Sıfırla"
"resetAllTrafficContent" = "Tüm gelenlerin trafiğini sıfırlamak istediğinizden emin misiniz?"
"resetInboundClientTraffics" = "Müşteri Trafiklerini Sıfırla"
"resetInboundClientTrafficTitle" = "Müşteri Trafiklerini Sıfırla"
"resetInboundClientTrafficContent" = "Bu gelenin müşterilerinin trafiğini sıfırlamak istediğinizden emin misiniz?"
"resetAllClientTraffics" = "Tüm Müşteri Trafiklerini Sıfırla"
"resetAllClientTrafficTitle" = "Tüm Müşteri Trafiklerini Sıfırla"
"resetAllClientTrafficContent" = "Tüm müşterilerin trafiğini sıfırlamak istediğinizden emin misiniz?"
"delDepletedClients" = "Bitmiş Müşterileri Sil"
"delDepletedClientsTitle" = "Bitmiş Müşterileri Sil"
"delDepletedClientsContent" = "Tüm bitmiş müşterileri silmek istediğinizden emin misiniz?"
"email" = "E-posta"
"emailDesc" = "Lütfen benzersiz bir e-posta adresi sağlayın."
"IPLimit" = "IP Limiti"
"IPLimitDesc" = "Sayının aşılması durumunda gelen devre dışı bırakılır. (0 = devre dışı)"
"IPLimitlog" = "IP Günlüğü"
"IPLimitlogDesc" = "IP geçmiş günlüğü. (devre dışı bırakıldıktan sonra gelini etkinleştirmek için günlüğü temizleyin)"
"IPLimitlogclear" = "Günlüğü Temizle"
"setDefaultCert" = "Panelden Sertifikayı Ayarla"
"xtlsDesc" = "Xray v1.7.5 olmalıdır"
"realityDesc" = "Xray v1.8.0+ olmalıdır"
"telegramDesc" = "Lütfen Telegram Sohbet Kimliği sağlayın. (botta '/id' komutunu kullanın) veya (@userinfobot)"
"subscriptionDesc" = "Abonelik URL'inizi bulmak için 'Detaylar'a gidin. Ayrıca, aynı adı birden fazla müşteri için kullanabilirsiniz."
"info" = "Bilgi"
"same" = "Aynı"
"inboundData" = "Gelenin Verileri"
"exportInbound" = "Geleni Dışa Aktar"
"import" = "İçe Aktar"
"importInbound" = "Bir Gelen İçe Aktar"
[pages.client]
"add" = "Müşteri Ekle"
"edit" = "Müşteriyi Düzenle"
"submitAdd" = "Müşteri Ekle"
"submitEdit" = "Değişiklikleri Kaydet"
"clientCount" = "Müşteri Sayısı"
"bulk" = "Toplu Ekle"
"method" = "Yöntem"
"first" = "İlk"
"last" = "Son"
"prefix" = "Önek"
"postfix" = "Sonek"
"delayedStart" = "İlk Kullanımdan Sonra Başlat"
"expireDays" = "Süre"
"days" = "Gün"
"renew" = "Otomatik Yenile"
"renewDesc" = "Süresi dolduktan sonra otomatik yenileme. (0 = devre dışı)(birim: gün)"
[pages.inbounds.toasts]
"obtain" = "Elde Et"
[pages.inbounds.stream.general]
"request" = "İstek"
"response" = "Yanıt"
"name" = "Ad"
"value" = "Değer"
[pages.inbounds.stream.tcp]
"version" = "Sürüm"
"method" = "Yöntem"
"path" = "Yol"
"status" = "Durum"
"statusDescription" = "Durum Açıklaması"
"requestHeader" = "İstek Başlığı"
"responseHeader" = "Yanıt Başlığı"
[pages.inbounds.stream.quic]
"encryption" = "Şifreleme"
[pages.settings]
"title" = "Panel Ayarları"
"save" = "Kaydet"
"infoDesc" = "Burada yapılan her değişikliğin kaydedilmesi gerekir. Değişikliklerin uygulanması için paneli yeniden başlatın."
"restartPanel" = "Paneli Yeniden Başlat"
"restartPanelDesc" = "Paneli yeniden başlatmak istediğinizden emin misiniz? Yeniden başlattıktan sonra panele erişemezseniz, sunucudaki panel günlük bilgilerini görüntüleyin."
"actions" = "Eylemler"
"resetDefaultConfig" = "Varsayılana Sıfırla"
"panelSettings" = "Genel"
"securitySettings" = "Kimlik Doğrulama"
"TGBotSettings" = "Telegram Bot"
"panelListeningIP" = "Dinleme IP"
"panelListeningIPDesc" = "Web paneli için IP adresi. (tüm IP'leri dinlemek için boş bırakın)"
"panelListeningDomain" = "Dinleme Alan Adı"
"panelListeningDomainDesc" = "Web paneli için alan adı. (tüm alan adlarını ve IP'leri dinlemek için boş bırakın)"
"panelPort" = "Dinleme Portu"
"panelPortDesc" = "Web paneli için port numarası. (kullanılmayan bir port olmalıdır)"
"publicKeyPath" = "Genel Anahtar Yolu"
"publicKeyPathDesc" = "Web paneli için genel anahtar dosya yolu. ('/' ile başlar)"
"privateKeyPath" = "Özel Anahtar Yolu"
"privateKeyPathDesc" = "Web paneli için özel anahtar dosya yolu. ('/' ile başlar)"
"panelUrlPath" = "URI Yolu"
"panelUrlPathDesc" = "Web paneli için URI yolu. ('/' ile başlar ve '/' ile biter)"
"pageSize" = "Sayfa Boyutu"
"pageSizeDesc" = "Gelenler tablosu için sayfa boyutunu belirleyin. (0 = devre dışı)"
"remarkModel" = "Açıklama Modeli & Ayırma Karakteri"
"datepicker" = "Takvim Türü"
"datepickerPlaceholder" = "Tarih Seçin"
"datepickerDescription" = "Planlanmış görevler bu takvime göre çalışacaktır."
"sampleRemark" = "Örnek Açıklama"
"oldUsername" = "Mevcut Kullanıcı Adı"
"currentPassword" = "Mevcut Şifre"
"newUsername" = "Yeni Kullanıcı Adı"
"newPassword" = "Yeni Şifre"
"telegramBotEnable" = "Telegram Botunu Etkinleştir"
"telegramBotEnableDesc" = "Telegram botunu etkinleştirir."
"telegramToken" = "Telegram Token"
"telegramTokenDesc" = "'@BotFather'dan alınan Telegram bot token."
"telegramProxy" = "SOCKS Proxy"
"telegramProxyDesc" = "Telegram'a bağlanmak için SOCKS5 proxy'sini etkinleştirir. (ayarları kılavuzda belirtilen şekilde ayarlayın)"
"telegramChatId" = "Yönetici Sohbet Kimliği"
"telegramChatIdDesc" = "Telegram Yönetici Sohbet Kimliği(leri). (virgülle ayrılmış)(buradan alın @userinfobot) veya (botta '/id' komutunu kullanın)"
"telegramNotifyTime" = "Bildirim Zamanı"
"telegramNotifyTimeDesc" = "Periyodik raporlar için ayarlanan Telegram bot bildirim zamanı. (crontab zaman formatını kullanın)"
"tgNotifyBackup" = "Veritabanı Yedeği"
"tgNotifyBackupDesc" = "Bir rapor ile birlikte veritabanı yedek dosyasını gönder."
"tgNotifyLogin" = "Giriş Bildirimi"
"tgNotifyLoginDesc" = "Birisi web panelinize giriş yapmaya çalıştığında kullanıcı adı, IP adresi ve zaman hakkında bildirim alın."
"sessionMaxAge" = "Oturum Süresi"
"sessionMaxAgeDesc" = "Giriş yaptıktan sonra oturum süresi. (birim: dakika)"
"expireTimeDiff" = "Son Kullanma Tarihi Bildirimi"
"expireTimeDiffDesc" = "Bu eşik seviyesine ulaşıldığında son kullanma tarihi hakkında bildirim alın. (birim: gün)"
"trafficDiff" = "Trafik Sınırı Bildirimi"
"trafficDiffDesc" = "Bu eşik seviyesine ulaşıldığında trafik sınırı hakkında bildirim alın. (birim: GB)"
"tgNotifyCpu" = "CPU Yükü Bildirimi"
"tgNotifyCpuDesc" = "CPU yükü bu eşik seviyesini aşarsa bildirim alın. (birim: %)"
"timeZone" = "Saat Dilimi"
"timeZoneDesc" = "Planlanmış görevler bu saat dilimine göre çalışacaktır."
"subSettings" = "Abonelik"
"subEnable" = "Abonelik Hizmetini Etkinleştir"
"subEnableDesc" = "Abonelik hizmetini etkinleştirir."
"subListen" = "Dinleme IP"
"subListenDesc" = "Abonelik hizmeti için IP adresi. (tüm IP'leri dinlemek için boş bırakın)"
"subPort" = "Dinleme Portu"
"subPortDesc" = "Abonelik hizmeti için port numarası. (kullanılmayan bir port olmalıdır)"
"subCertPath" = "Genel Anahtar Yolu"
"subCertPathDesc" = "Abonelik hizmeti için genel anahtar dosya yolu. ('/' ile başlar)"
"subKeyPath" = "Özel Anahtar Yolu"
"subKeyPathDesc" = "Abonelik hizmeti için özel anahtar dosya yolu. ('/' ile başlar)"
"subPath" = "URI Yolu"
"subPathDesc" = "Abonelik hizmeti için URI yolu. ('/' ile başlar ve '/' ile biter)"
"subDomain" = "Dinleme Alan Adı"
"subDomainDesc" = "Abonelik hizmeti için alan adı. (tüm alan adlarını ve IP'leri dinlemek için boş bırakın)"
"subUpdates" = "Güncelleme Aralıkları"
"subUpdatesDesc" = "Müşteri uygulamalarındaki abonelik URL'sinin güncelleme aralıkları. (birim: saat)"
"subEncrypt" = "Şifrele"
"subEncryptDesc" = "Abonelik hizmetinin döndürülen içeriği Base64 ile şifrelenir."
"subShowInfo" = "Kullanım Bilgisini Göster"
"subShowInfoDesc" = "Kalan trafik ve tarih müşteri uygulamalarında görüntülenir."
"subURI" = "Ters Proxy URI"
"subURIDesc" = "Proxy arkasında kullanılacak abonelik URL'sinin URI yolu."
"fragment" = "Parçalama"
"fragmentDesc" = "TLS merhaba paketinin parçalanmasını etkinleştir."
"fragmentSett" = "Parçalama Ayarları"
"mux" = "Mux"
"muxDesc" = "Kurulmuş bir veri akışında birden çok bağımsız veri akışını iletir."
"muxSett" = "Mux Ayarları"
"direct" = "Doğrudan Bağlantı"
"directDesc" = "Belirli bir ülkenin alan adları veya IP aralıkları ile doğrudan bağlantı kurar."
"directSett" = "Doğrudan Bağlantı Seçenekleri"
[pages.xray]
"title" = "Xray Yapılandırmaları"
"save" = "Kaydet"
"restart" = "Xray'i Yeniden Başlat"
"basicTemplate" = "Temeller"
"advancedTemplate" = "Gelişmiş"
"generalConfigs" = "Genel"
"generalConfigsDesc" = "Bu seçenekler genel ayarlamaları belirler."
"logConfigs" = "Günlük"
"logConfigsDesc" = "Günlükler sunucunuzun verimliliğini etkileyebilir. Yalnızca ihtiyaç durumunda akıllıca etkinleştirmeniz önerilir"
"blockConfigs" = "Koruma Kalkanı"
"blockConfigsDesc" = "Bu seçenekler belirli istek protokolleri ve web siteleri temelinde trafiği engeller."
"blockCountryConfigs" = "Ülke Engelleme"
"blockCountryConfigsDesc" = "Bu seçenekler belirli istek ülkesi temelinde trafiği engeller."
"directCountryConfigs" = "Doğrudan Ülke"
"directCountryConfigsDesc" = "Doğrudan bağlantı, belirli trafiğin başka bir sunucu üzerinden yönlendirilmemesini sağlar."
"ipv4Configs" = "IPv4 Yönlendirme"
"ipv4ConfigsDesc" = "Bu seçenekler belirli bir varış yerine IPv4 üzerinden trafiği yönlendirir."
"warpConfigs" = "WARP Yönlendirme"
"warpConfigsDesc" = "Bu seçenekler belirli bir varış yerine WARP üzerinden trafiği yönlendirir."
"Template" = "Gelişmiş Xray Yapılandırma Şablonu"
"TemplateDesc" = "Nihai Xray yapılandırma dosyası bu şablona göre oluşturulacaktır."
"FreedomStrategy" = "Freedom Protokol Stratejisi"
"FreedomStrategyDesc" = "Freedom Protokolünde ağın çıkış stratejisini ayarlayın."
"RoutingStrategy" = "Genel Yönlendirme Stratejisi"
"RoutingStrategyDesc" = "Tüm istekleri çözmek için genel trafik yönlendirme stratejisini ayarlayın."
"Torrent" = "BitTorrent Protokolünü Engelle"
"TorrentDesc" = "BitTorrent protokolünü engeller."
"PrivateIp" = "Özel IP'lere Bağlantıyı Engelle"
"PrivateIpDesc" = "Özel IP aralıklarına bağlantı kurmayı engeller."
"Ads" = "Reklamları Engelle"
"AdsDesc" = "Reklam web sitelerini engeller."
"Family" = "Aile Koruması"
"FamilyDesc" = "Yetişkin içerikli ve kötü amaçlı yazılım web sitelerini engeller."
"Security" = "Güvenlik Kalkanı"
"SecurityDesc" = "Kötü amaçlı yazılım, kimlik avı ve kripto madencilik web sitelerini engeller."
"Speedtest" = "Speedtest Bağlantısını Engelle"
"SpeedtestDesc" = "Speedtest web sitelerine bağlantı kurmayı engeller."
"IRIp" = "İran IP'lerine Bağlantıyı Engelle"
"IRIpDesc" = "İran IP aralıklarına bağlantı kurmayı engeller."
"IRDomain" = "İran Alan Adlarına Bağlantıyı Engelle"
"IRDomainDesc" = "İran alan adlarına bağlantı kurmayı engeller."
"ChinaIp" = "Çin IP'lerine Bağlantıyı Engelle"
"ChinaIpDesc" = "Çin IP aralıklarına bağlantı kurmayı engeller."
"ChinaDomain" = "Çin Alan Adlarına Bağlantıyı Engelle"
"ChinaDomainDesc" = "Çin alan adlarına bağlantı kurmayı engeller."
"RussiaIp" = "Rusya IP'lerine Bağlantıyı Engelle"
"RussiaIpDesc" = "Rusya IP aralıklarına bağlantı kurmayı engeller."
"RussiaDomain" = "Rusya Alan Adlarına Bağlantıyı Engelle"
"RussiaDomainDesc" = "Rusya alan adlarına bağlantı kurmayı engeller."
"VNIp" = "Vietnam IP'lerine Bağlantıyı Engelle"
"VNIpDesc" = "Vietnam IP aralıklarına bağlantı kurmayı engeller."
"VNDomain" = "Vietnam Alan Adlarına Bağlantıyı Engelle"
"VNDomainDesc" = "Vietnam alan adlarına bağlantı kurmayı engeller."
"DirectIRIp" = "İran IP'lerine Doğrudan Bağlantı"
"DirectIRIpDesc" = "İran IP aralıklarına doğrudan bağlantı kurar."
"DirectIRDomain" = "İran Alan Adlarına Doğrudan Bağlantı"
"DirectIRDomainDesc" = "İran alan adlarına doğrudan bağlantı kurar."
"DirectChinaIp" = "Çin IP'lerine Doğrudan Bağlantı"
"DirectChinaIpDesc" = "Çin IP aralıklarına doğrudan bağlantı kurar."
"DirectChinaDomain" = "Çin Alan Adlarına Doğrudan Bağlantı"
"DirectChinaDomainDesc" = "Çin alan adlarına doğrudan bağlantı kurar."
"DirectRussiaIp" = "Rusya IP'lerine Doğrudan Bağlantı"
"DirectRussiaIpDesc" = "Rusya IP aralıklarına doğrudan bağlantı kurar."
"DirectRussiaDomain" = "Rusya Alan Adlarına Doğrudan Bağlantı"
"DirectRussiaDomainDesc" = "Rusya alan adlarına doğrudan bağlantı kurar."
"DirectVNIp" = "Vietnam IP'lerine Doğrudan Bağlantı"
"DirectVNIpDesc" = "Vietnam IP aralıklarına doğrudan bağlantı kurar."
"DirectVNDomain" = "Vietnam Alan Adlarına Doğrudan Bağlantı"
"DirectVNDomainDesc" = "Vietnam alan adlarına doğrudan bağlantı kurar."
"GoogleIPv4" = "Google"
"GoogleIPv4Desc" = "Google'a trafiği IPv4 üzerinden yönlendirir."
"NetflixIPv4" = "Netflix"
"NetflixIPv4Desc" = "Netflix'e trafiği IPv4 üzerinden yönlendirir."
"GoogleWARP" = "Google"
"GoogleWARPDesc" = "Google'a trafiği WARP üzerinden yönlendirir."
"OpenAIWARP" = "ChatGPT"
"OpenAIWARPDesc" = "ChatGPT'ye trafiği WARP üzerinden yönlendirir."
"NetflixWARP" = "Netflix"
"NetflixWARPDesc" = "Netflix'e trafiği WARP üzerinden yönlendirir."
"MetaWARP" = "Meta"
"MetaWARPDesc" = "Meta'ya (Instagram, Facebook, WhatsApp, Threads,...) trafiği WARP üzerinden yönlendirir."
"AppleWARP" = "Apple"
"AppleWARPDesc" = "Apple'a trafiği WARP üzerinden yönlendirir."
"RedditWARP" = "Reddit"
"RedditWARPDesc" = "Reddit'e trafiği WARP üzerinden yönlendirir."
"SpotifyWARP" = "Spotify"
"SpotifyWARPDesc" = "Spotify'a trafiği WARP üzerinden yönlendirir."
"IRWARP" = "İran alan adları"
"IRWARPDesc" = "İran alan adlarına trafiği WARP üzerinden yönlendirir."
"Inbounds" = "Gelenler"
"InboundsDesc" = "Belirli müşterileri kabul eder."
"Outbounds" = "Gidenler"
"Balancers" = "Dengeler"
"OutboundsDesc" = "Giden trafiğin yolunu ayarlayın."
"Routings" = "Yönlendirme Kuralları"
"RoutingsDesc" = "Her kuralın önceliği önemlidir!"
"completeTemplate" = "Tümü"
"logLevel" = "Günlük Seviyesi"
"logLevelDesc" = "Hata günlükleri için günlük seviyesi, kaydedilmesi gereken bilgileri belirtir."
"accessLog" = "Erişim Günlüğü"
"accessLogDesc" = "Erişim günlüğü için dosya yolu. 'none' özel değeri erişim günlüklerini devre dışı bırakır"
"errorLog" = "Hata Günlüğü"
"errorLogDesc" = "Hata günlüğü için dosya yolu. 'none' özel değeri hata günlüklerini devre dışı bırakır"
[pages.xray.rules]
"first" = "İlk"
"last" = "Son"
"up" = "Yukarı"
"down" = "Aşağı"
"source" = "Kaynak"
"dest" = "Hedef"
"inbound" = "Gelen"
"outbound" = "Giden"
"balancer" = "Dengeler"
"info" = "Bilgi"
"add" = "Kural Ekle"
"edit" = "Kuralı Düzenle"
"useComma" = "Virgülle ayrılmış öğeler"
[pages.xray.outbound]
"addOutbound" = "Giden Ekle"
"addReverse" = "Ters Ekle"
"editOutbound" = "Gideni Düzenle"
"editReverse" = "Tersi Düzenle"
"tag" = "Etiket"
"tagDesc" = "Benzersiz Etiket"
"address" = "Adres"
"reverse" = "Ters"
"domain" = "Alan Adı"
"type" = "Tür"
"bridge" = "Köprü"
"portal" = "Portal"
"intercon" = "Bağlantı"
"settings" = "Ayarlar"
"accountInfo" = "Hesap Bilgileri"
"outboundStatus" = "Giden Durumu"
"sendThrough" = "Üzerinden Gönder"
[pages.xray.balancer]
"addBalancer" = "Dengeleyici Ekle"
"editBalancer" = "Dengeleyiciyi Düzenle"
"balancerStrategy" = "Strateji"
"balancerSelectors" = "Seçiciler"
"tag" = "Etiket"
"tagDesc" = "Benzersiz Etiket"
"balancerDesc" = "Dengeleyici Etiketi ve Giden Etiketi aynı anda kullanılamaz. Aynı anda kullanıldığında yalnızca giden etiketi çalışır."
[pages.xray.wireguard]
"secretKey" = "Gizli Anahtar"
"publicKey" = "Genel Anahtar"
"allowedIPs" = "İzin Verilen IP'ler"
"endpoint" = "Uç Nokta"
"psk" = "Ön Paylaşılan Anahtar"
"domainStrategy" = "Alan Adı Stratejisi"
[pages.xray.dns]
"enable" = "DNS'yi Etkinleştir"
"enableDesc" = "Dahili DNS sunucusunu etkinleştir"
"tag" = "DNS Gelen Etiketi"
"tagDesc" = "Bu etiket, yönlendirme kurallarında Gelen etiketi olarak kullanılabilir."
"strategy" = "Sorgu Stratejisi"
"strategyDesc" = "Alan adlarını çözmek için genel strateji"
"add" = "Sunucu Ekle"
"edit" = "Sunucuyu Düzenle"
"domains" = "Alan Adları"
[pages.xray.fakedns]
"add" = "Sahte DNS Ekle"
"edit" = "Sahte DNS'i Düzenle"
"ipPool" = "IP Havuzu Alt Ağı"
"poolSize" = "Havuz Boyutu"
[pages.settings.security]
"admin" = "Yönetici"
"secret" = "Gizli Anahtar"
"loginSecurity" = "Güvenli Giriş"
"loginSecurityDesc" = "Daha fazla güvenlik sağlamak için ek bir kimlik doğrulama katmanı ekler."
"secretToken" = "Gizli Anahtar"
"secretTokenDesc" = "Bu anahtarı güvenli bir yerde saklayın. Bu anahtar giriş için gereklidir ve geri alınamaz."
[pages.settings.toasts]
"modifySettings" = "Ayarları Değiştir"
"getSettings" = "Ayarları Al"
"modifyUser" = "Yönetici Değiştir"
"originalUserPassIncorrect" = "Mevcut kullanıcı adı veya şifre geçersiz"
"userPassMustBeNotEmpty" = "Yeni kullanıcı adı ve şifre boş olamaz"
[tgbot]
"keyboardClosed" = "❌ Özel klavye kapalı!"
"noResult" = "❗ Sonuç yok!"
"noQuery" = "❌ Sorgu bulunamadı! Lütfen komutu tekrar kullanın!"
"wentWrong" = "❌ Bir şeyler yanlış gitti!"
"noIpRecord" = "❗ IP Kaydı yok!"
"noInbounds" = "❗ Gelen bulunamadı!"
"unlimited" = "♾ Sınırsız(Sıfırla)"
"add" = "Ekle"
"month" = "Ay"
"months" = "Aylar"
"day" = "Gün"
"days" = "Günler"
"hours" = "Saatler"
"unknown" = "Bilinmiyor"
"inbounds" = "Gelenler"
"clients" = "Müşteriler"
"offline" = "🔴 Çevrimdışı"
"online" = "🟢 Çevrimiçi"
[tgbot.commands]
"unknown" = "❗ Bilinmeyen komut."
"pleaseChoose" = "👇 Lütfen seçin:\r\n"
"help" = "🤖 Bu bota hoş geldiniz! Web panelinden belirli verileri sunmak ve gerektiğinde değişiklik yapmanıza olanak tanımak için tasarlanmıştır.\r\n\r\n"
"start" = "👋 Merhaba <i>{{ .Firstname }}</i>.\r\n"
"welcome" = "🤖 <b>{{ .Hostname }}</b> yönetim botuna hoş geldiniz.\r\n"
"status" = "✅ Bot çalışıyor!"
"usage" = "❗ Lütfen aramak için bir metin sağlayın!"
"getID" = "🆔 Kimliğiniz: <code>{{ .ID }}</code>"
"helpAdminCommands" = "Bir müşteri e-postasını aramak için:\r\n<code>/usage [E-posta]</code>\r\n\r\nGelenleri aramak için (müşteri istatistikleri ile):\r\n<code>/inbound [Açıklama]</code>\r\n\r\nTelegram Sohbet Kimliği:\r\n<code>/id</code>"
"helpClientCommands" = "İstatistikleri aramak için şu komutu kullanın:\r\n\r\n<code>/usage [E-posta]</code>\r\n\r\nTelegram Sohbet Kimliği:\r\n<code>/id</code>"
[tgbot.messages]
"cpuThreshold" = "🔴 CPU Yükü {{ .Percent }}% eşiği {{ .Threshold }}%'yi aşıyor"
"selectUserFailed" = "❌ Kullanıcı seçiminde hata!"
"userSaved" = "✅ Telegram Kullanıcısı kaydedildi."
"loginSuccess" = "✅ Panele başarıyla giriş yapıldı.\r\n"
"loginFailed" = "❗Panele giriş denemesi başarısız oldu.\r\n"
"report" = "🕰 Planlanmış Raporlar: {{ .RunTime }}\r\n"
"datetime" = "⏰ Tarih&Zaman: {{ .DateTime }}\r\n"
"hostname" = "💻 Sunucu: {{ .Hostname }}\r\n"
"version" = "🚀 3X-UI Sürümü: {{ .Version }}\r\n"
"xrayVersion" = "📡 Xray Sürümü: {{ .XrayVersion }}\r\n"
"ipv6" = "🌐 IPv6: {{ .IPv6 }}\r\n"
"ipv4" = "🌐 IPv4: {{ .IPv4 }}\r\n"
"ip" = "🌐 IP: {{ .IP }}\r\n"
"ips" = "🔢 IP'ler:\r\n{{ .IPs }}\r\n"
"serverUpTime" = "⏳ Çalışma Süresi: {{ .UpTime }} {{ .Unit }}\r\n"
"serverLoad" = "📈 Sistem Yükü: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n"
"serverMemory" = "📋 RAM: {{ .Current }}/{{ .Total }}\r\n"
"tcpCount" = "🔹 TCP: {{ .Count }}\r\n"
"udpCount" = "🔸 UDP: {{ .Count }}\r\n"
"traffic" = "🚦 Trafik: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n"
"xrayStatus" = " Durum: {{ .State }}\r\n"
"username" = "👤 Kullanıcı Adı: {{ .Username }}\r\n"
"password" = "👤 Şifre: {{ .Password }}\r\n"
"time" = "⏰ Zaman: {{ .Time }}\r\n"
"inbound" = "📍 Gelen: {{ .Remark }}\r\n"
"port" = "🔌 Port: {{ .Port }}\r\n"
"expire" = "📅 Son Kullanma Tarihi: {{ .Time }}\r\n"
"expireIn" = "📅 Sona Erecek: {{ .Time }}\r\n"
"active" = "💡 Aktif: {{ .Enable }}\r\n"
"enabled" = "🚨 Etkin: {{ .Enable }}\r\n"
"online" = "🌐 Bağlantı durumu: {{ .Status }}\r\n"
"email" = "📧 E-posta: {{ .Email }}\r\n"
"upload" = "🔼 Yükleme: ↑{{ .Upload }}\r\n"
"download" = "🔽 İndirme: ↓{{ .Download }}\r\n"
"total" = "📊 Toplam: ↑↓{{ .UpDown }} / {{ .Total }}\r\n"
"TGUser" = "👤 Telegram Kullanıcısı: {{ .TelegramID }}\r\n"
"exhaustedMsg" = "🚨 Tükenmiş {{ .Type }}:\r\n"
"exhaustedCount" = "🚨 Tükenmiş {{ .Type }} sayısı:\r\n"
"onlinesCount" = "🌐 Çevrimiçi Müşteriler: {{ .Count }}\r\n"
"disabled" = "🛑 Devre Dışı: {{ .Disabled }}\r\n"
"depleteSoon" = "🔜 Yakında Tükenecek: {{ .Deplete }}\r\n\r\n"
"backupTime" = "🗄 Yedekleme Zamanı: {{ .Time }}\r\n"
"refreshedOn" = "\r\n📋🔄 Yenilendi: {{ .Time }}\r\n\r\n"
"yes" = "✅ Evet"
"no" = "❌ Hayır"
[tgbot.buttons]
"closeKeyboard" = "❌ Klavyeyi Kapat"
"cancel" = "❌ İptal"
"cancelReset" = "❌ Sıfırlamayı İptal Et"
"cancelIpLimit" = "❌ IP Limitini İptal Et"
"confirmResetTraffic" = "✅ Trafiği Sıfırlamayı Onayla?"
"confirmClearIps" = "✅ IP'leri Temizlemeyi Onayla?"
"confirmRemoveTGUser" = "✅ Telegram Kullanıcısını Kaldırmayı Onayla?"
"confirmToggle" = "✅ Kullanıcıyı Etkinleştirme/Devre Dışı Bırakmayı Onayla?"
"dbBackup" = "Veritabanı Yedeği Al"
"serverUsage" = "Sunucu Kullanımı"
"getInbounds" = "Gelenleri Al"
"depleteSoon" = "Yakında Tükenecek"
"clientUsage" = "Kullanımı Al"
"onlines" = "Çevrimiçi Müşteriler"
"commands" = "Komutlar"
"refresh" = "🔄 Yenile"
"clearIPs" = "❌ IP'leri Temizle"
"removeTGUser" = "❌ Telegram Kullanıcısını Kaldır"
"selectTGUser" = "👤 Telegram Kullanıcısını Seç"
"selectOneTGUser" = "👤 Bir Telegram Kullanıcısını Seçin:"
"resetTraffic" = "📈 Trafiği Sıfırla"
"resetExpire" = "📅 Son Kullanma Tarihini Değiştir"
"ipLog" = "🔢 IP Günlüğü"
"ipLimit" = "🔢 IP Limiti"
"setTGUser" = "👤 Telegram Kullanıcısını Ayarla"
"toggle" = "🔘 Etkinleştir / Devre Dışı Bırak"
"custom" = "🔢 Özel"
"confirmNumber" = "✅ Onayla: {{ .Num }}"
"confirmNumberAdd" = "✅ Ekleme onayı: {{ .Num }}"
"limitTraffic" = "🚧 Trafik Sınırı"
"getBanLogs" = "Yasak Günlüklerini Al"
[tgbot.answers]
"successfulOperation" = "✅ İşlem başarılı!"
"errorOperation" = "❗ İşlemde hata."
"getInboundsFailed" = "❌ Gelenler alınamadı."
"canceled" = "❌ {{ .Email }}: İşlem iptal edildi."
"clientRefreshSuccess" = "✅ {{ .Email }}: Müşteri başarıyla yenilendi."
"IpRefreshSuccess" = "✅ {{ .Email }}: IP'ler başarıyla yenilendi."
"TGIdRefreshSuccess" = "✅ {{ .Email }}: Müşterinin Telegram Kullanıcısı başarıyla yenilendi."
"resetTrafficSuccess" = "✅ {{ .Email }}: Trafik başarıyla sıfırlandı."
"setTrafficLimitSuccess" = "✅ {{ .Email }}: Trafik limiti başarıyla kaydedildi."
"expireResetSuccess" = "✅ {{ .Email }}: Son kullanma günleri başarıyla sıfırlandı."
"resetIpSuccess" = "✅ {{ .Email }}: IP limiti {{ .Count }} başarıyla kaydedildi."
"clearIpSuccess" = "✅ {{ .Email }}: IP'ler başarıyla temizlendi."
"getIpLog" = "✅ {{ .Email }}: IP Günlüğü alındı."
"getUserInfo" = "✅ {{ .Email }}: Telegram Kullanıcı Bilgisi alındı."
"removedTGUserSuccess" = "✅ {{ .Email }}: Telegram Kullanıcısı başarıyla kaldırıldı."
"enableSuccess" = "✅ {{ .Email }}: Başarıyla etkinleştirildi."
"disableSuccess" = "✅ {{ .Email }}: Başarıyla devre dışı bırakıldı."
"askToAddUserId" = "Yapılandırmanız bulunamadı!\r\nLütfen yöneticinizden yapılandırmalarınıza Telegram ID'nizi eklemesini isteyin.\r\n\r\nKullanıcı ID'niz: <code>{{ .TgUserID }}</code>"

View File

@@ -181,6 +181,10 @@ func (x *XrayAPI) GetTraffic(reset bool) ([]*Traffic, []*ClientTraffic, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel() defer cancel()
if x.StatsServiceClient == nil {
return nil, nil, common.NewError("xray StatusServiceClient is not initialized")
}
resp, err := (*x.StatsServiceClient).QueryStats(ctx, &statsService.QueryStatsRequest{Reset_: reset}) resp, err := (*x.StatsServiceClient).QueryStats(ctx, &statsService.QueryStatsRequest{Reset_: reset})
if err != nil { if err != nil {
logger.Debug("Failed to query Xray stats:", err) logger.Debug("Failed to query Xray stats:", err)