Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
438a9684ee | ||
|
|
a6000f22a2 | ||
|
|
2ec5eeb442 | ||
|
|
d319476eb6 | ||
|
|
93d52bc86c | ||
|
|
bda5c2c915 | ||
|
|
b838fe2e74 | ||
|
|
604b9be4a0 | ||
|
|
7b8ef98846 | ||
|
|
2c7c6c260a | ||
|
|
b8c3555b09 | ||
|
|
2d2b30daf1 | ||
|
|
3e3ed4ed52 | ||
|
|
d8d9c64847 | ||
|
|
c489673130 | ||
|
|
2544305fb9 | ||
|
|
519d228db2 | ||
|
|
4cd89f4379 | ||
|
|
fdfc29f6cd | ||
|
|
4ec104c5ee | ||
|
|
bae89272b0 | ||
|
|
8408a45eff | ||
|
|
a37b1bde4c | ||
|
|
953b5d3dea | ||
|
|
c7906e8598 | ||
|
|
e1bc43da5f |
14
.github/FUNDING.yml
vendored
Normal 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']
|
||||
2
.github/workflows/release.yml
vendored
@@ -83,7 +83,7 @@ jobs:
|
||||
cd x-ui/bin
|
||||
|
||||
# Download dependencies
|
||||
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v1.8.21/"
|
||||
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v1.8.23/"
|
||||
if [ "${{ matrix.platform }}" == "amd64" ]; then
|
||||
wget ${Xray_URL}Xray-linux-64.zip
|
||||
unzip Xray-linux-64.zip
|
||||
|
||||
@@ -27,7 +27,7 @@ case $1 in
|
||||
esac
|
||||
mkdir -p build/bin
|
||||
cd build/bin
|
||||
wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.21/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"
|
||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
|
||||
mv xray "xray-linux-${FNAME}"
|
||||
|
||||
@@ -14,7 +14,11 @@
|
||||
|
||||
**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`
|
||||
- MATIC (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
@@ -28,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## 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
|
||||
|
||||
14
README.md
@@ -14,7 +14,11 @@
|
||||
|
||||
**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`
|
||||
- MATIC (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
@@ -28,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## Install Custom Version
|
||||
|
||||
To install your desired version, add the version to the end of the installation command. e.g., ver `v2.3.10`:
|
||||
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.10
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.13
|
||||
```
|
||||
|
||||
## SSL Certificate
|
||||
@@ -246,6 +250,7 @@ Our platform offers compatibility with a diverse range of architectures and devi
|
||||
- Spanish
|
||||
- Indonesian
|
||||
- Ukrainian
|
||||
- Turkish
|
||||
|
||||
|
||||
## Features
|
||||
@@ -254,7 +259,7 @@ Our platform offers compatibility with a diverse range of architectures and devi
|
||||
- Search within all inbounds and clients
|
||||
- Dark/Light theme
|
||||
- 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
|
||||
- Traffic statistics, traffic limit, expiration time limit
|
||||
- Customizable Xray configuration templates
|
||||
@@ -455,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` | `"/get/:id"` | Get inbound with inbound.id |
|
||||
| `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 |
|
||||
| `POST` | `"/add"` | Add inbound |
|
||||
| `POST` | `"/del/:id"` | Delete Inbound |
|
||||
|
||||
10
README.zh.md
@@ -14,7 +14,11 @@
|
||||
|
||||
**如果此项目对你有用,请给一个**: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`
|
||||
- MATIC (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
@@ -28,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 认证
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.3.10
|
||||
2.3.13
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
type Protocol string
|
||||
|
||||
const (
|
||||
VMess Protocol = "vmess"
|
||||
VMESS Protocol = "vmess"
|
||||
VLESS Protocol = "vless"
|
||||
DOKODEMO Protocol = "dokodemo-door"
|
||||
HTTP Protocol = "http"
|
||||
@@ -86,6 +86,7 @@ type Setting struct {
|
||||
|
||||
type Client struct {
|
||||
ID string `json:"id"`
|
||||
Security string `json:"security"`
|
||||
Password string `json:"password"`
|
||||
Flow string `json:"flow"`
|
||||
Email string `json:"email"`
|
||||
|
||||
38
go.mod
@@ -12,11 +12,11 @@ require (
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||
github.com/pelletier/go-toml/v2 v2.2.2
|
||||
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/xtls/xray-core v1.8.21
|
||||
github.com/xtls/xray-core v1.8.23
|
||||
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
|
||||
gorm.io/driver/sqlite v1.5.6
|
||||
gorm.io/gorm v1.25.11
|
||||
@@ -24,15 +24,15 @@ require (
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/bytedance/sonic v1.11.9 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/bytedance/sonic v1.12.1 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.9 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
||||
github.com/fasthttp/router v1.5.2 // 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/go-ole/go-ole v1.3.0 // 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-task/slim-sprig/v3 v3.0.0 // 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/securecookie v1.1.2 // indirect
|
||||
github.com/gorilla/sessions v1.3.0 // indirect
|
||||
@@ -57,11 +57,11 @@ require (
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // 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/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // 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/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
@@ -83,18 +83,18 @@ require (
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
golang.org/x/mod v0.19.0 // indirect
|
||||
golang.org/x/net v0.27.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.23.0 // indirect
|
||||
golang.org/x/arch v0.9.0 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
golang.org/x/tools v0.24.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
|
||||
|
||||
85
go.sum
@@ -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/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/bytedance/sonic v1.11.9 h1:LFHENlIY/SLzDWverzdOvgMztTxcfcF+cqNsz9pK5zg=
|
||||
github.com/bytedance/sonic v1.11.9/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24=
|
||||
github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
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/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
|
||||
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/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
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.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
|
||||
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
|
||||
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.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=
|
||||
@@ -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/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-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
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.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
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/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-20240711041743-f6c9dda6c6da h1:xRmpO92tb8y+Z85iUOMOicpCfaYcv7o3Cg3wKrIpg8g=
|
||||
github.com/google/pprof v0.0.0-20240711041743-f6c9dda6c6da/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
|
||||
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 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
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/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/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
|
||||
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
|
||||
github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw=
|
||||
github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
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/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
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/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/quic-go v0.45.1 h1:tPfeYCk+uZHjmDRwHHQmvHRYL2t44ROTujLeFVBmjCA=
|
||||
github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
|
||||
github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=
|
||||
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/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
@@ -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/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||
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.6/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA=
|
||||
github.com/shirou/gopsutil/v4 v4.24.7 h1:V9UGTK4gQ8HvcnPKf6Zt3XHyQq/peaekfxpJ2HSocJk=
|
||||
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/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
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/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/xray-core v1.8.21 h1:cNdepud+R9PENKzXlSZsq0je4BWI6liXAuep6CD6xvk=
|
||||
github.com/xtls/xray-core v1.8.21/go.mod h1:0CwyMPNA5Cs+ukPXHbYQGgne/ug0PuXOSVqBu7zyXOc=
|
||||
github.com/xtls/xray-core v1.8.23 h1:A8Wr50ildMYLpaNu3EiK+Stg/tps6i0h7z5Hr4f9H2k=
|
||||
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/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
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/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
|
||||
golang.org/x/arch v0.9.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/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-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
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-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
|
||||
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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
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.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
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-20180826012351-8a410e7b638d/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-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.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
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-20181017192945-9dcd33a902f4/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-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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
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-20180909124046-d0be0721c37e/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.5.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.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
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.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.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
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-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.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
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-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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
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/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
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-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/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A=
|
||||
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 h1:EKiZZXueP9/T68B8Nl0GAx9cjbQnCId0yP3qPMgaaHs=
|
||||
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.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
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/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
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/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
|
||||
@@ -123,7 +123,7 @@ install_base() {
|
||||
|
||||
gen_random_string() {
|
||||
local length="$1"
|
||||
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w "$length" | head -n 1)
|
||||
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' </dev/urandom | fold -w "$length" | head -n 1)
|
||||
echo "$random_string"
|
||||
}
|
||||
|
||||
|
||||
4
main.go
@@ -73,11 +73,11 @@ func runWebServer() {
|
||||
|
||||
err := server.Stop()
|
||||
if err != nil {
|
||||
logger.Warning("Error stopping web server:", err)
|
||||
logger.Debug("Error stopping web server:", err)
|
||||
}
|
||||
err = subServer.Stop()
|
||||
if err != nil {
|
||||
logger.Warning("Error stopping sub server:", err)
|
||||
logger.Debug("Error stopping sub server:", err)
|
||||
}
|
||||
|
||||
server = web.NewServer()
|
||||
|
||||
BIN
media/1.png
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 59 KiB |
BIN
media/2.png
|
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 91 KiB |
BIN
media/3.png
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 35 KiB |
BIN
media/4.png
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 26 KiB |
BIN
media/5.png
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 71 KiB |
BIN
media/6.png
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 42 KiB |
BIN
media/7.png
|
Before Width: | Height: | Size: 261 KiB After Width: | Height: | Size: 60 KiB |
BIN
media/buymeacoffe.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
@@ -3,6 +3,7 @@ package sub
|
||||
import (
|
||||
"encoding/base64"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -54,7 +55,10 @@ func (a *SUBController) initRouter(g *gin.RouterGroup) {
|
||||
|
||||
func (a *SUBController) subs(c *gin.Context) {
|
||||
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 == "" {
|
||||
host = c.GetHeader("X-Real-IP")
|
||||
}
|
||||
@@ -89,7 +93,10 @@ func (a *SUBController) subs(c *gin.Context) {
|
||||
|
||||
func (a *SUBController) subJsons(c *gin.Context) {
|
||||
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 == "" {
|
||||
host = c.GetHeader("X-Real-IP")
|
||||
}
|
||||
@@ -113,3 +120,14 @@ func (a *SUBController) subJsons(c *gin.Context) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -282,6 +282,9 @@ func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_ut
|
||||
|
||||
usersData[0].ID = client.ID
|
||||
usersData[0].Level = 8
|
||||
if inbound.Protocol == model.VMESS {
|
||||
usersData[0].Security = client.Security
|
||||
}
|
||||
if inbound.Protocol == model.VLESS {
|
||||
usersData[0].Flow = client.Flow
|
||||
usersData[0].Encryption = "none"
|
||||
@@ -371,6 +374,7 @@ type UserVnext struct {
|
||||
Encryption string `json:"encryption,omitempty"`
|
||||
Flow string `json:"flow,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Security string `json:"security,omitempty"`
|
||||
Level int `json:"level"`
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ func (s *SubService) getLink(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 ""
|
||||
}
|
||||
obj := map[string]interface{}{
|
||||
@@ -281,6 +281,7 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
|
||||
}
|
||||
}
|
||||
obj["id"] = clients[clientIndex].ID
|
||||
obj["scy"] = clients[clientIndex].Security
|
||||
|
||||
externalProxies, _ := stream["externalProxy"].([]interface{})
|
||||
|
||||
|
||||
@@ -39,6 +39,11 @@ const supportLangs = [
|
||||
value: 'uk-UA',
|
||||
icon: '🇺🇦',
|
||||
},
|
||||
{
|
||||
name: 'Türkçe',
|
||||
value: 'tr-TR',
|
||||
icon: '🇹🇷',
|
||||
},
|
||||
];
|
||||
|
||||
function getLang() {
|
||||
|
||||
@@ -69,12 +69,23 @@ const WireguardDomainStrategy = [
|
||||
"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(SSMethods);
|
||||
Object.freeze(TLS_FLOW_CONTROL);
|
||||
Object.freeze(UTLS_FINGERPRINT);
|
||||
Object.freeze(ALPN_OPTION);
|
||||
Object.freeze(OutboundDomainStrategies);
|
||||
Object.freeze(WireguardDomainStrategy);
|
||||
Object.freeze(USERS_SECURITY);
|
||||
|
||||
|
||||
class CommonClass {
|
||||
|
||||
@@ -90,30 +101,30 @@ class CommonClass {
|
||||
return this;
|
||||
}
|
||||
|
||||
toString(format=true) {
|
||||
toString(format = true) {
|
||||
return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
class TcpStreamSettings extends CommonClass {
|
||||
constructor(type='none', host, path) {
|
||||
constructor(type = 'none', host, path) {
|
||||
super();
|
||||
this.type = type;
|
||||
this.host = host;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
let header = json.header;
|
||||
if (!header) return new TcpStreamSettings();
|
||||
if(header.type == 'http' && header.request){
|
||||
if (header.type == 'http' && header.request) {
|
||||
return new TcpStreamSettings(
|
||||
header.type,
|
||||
header.request.headers.Host.join(','),
|
||||
header.request.path.join(','),
|
||||
);
|
||||
}
|
||||
return new TcpStreamSettings(header.type,'','');
|
||||
return new TcpStreamSettings(header.type, '', '');
|
||||
}
|
||||
|
||||
toJson() {
|
||||
@@ -132,15 +143,17 @@ class TcpStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class KcpStreamSettings extends CommonClass {
|
||||
constructor(mtu=1350, tti=20,
|
||||
uplinkCapacity=5,
|
||||
downlinkCapacity=20,
|
||||
congestion=false,
|
||||
readBufferSize=2,
|
||||
writeBufferSize=2,
|
||||
type='none',
|
||||
seed='',
|
||||
) {
|
||||
constructor(
|
||||
mtu = 1350,
|
||||
tti = 50,
|
||||
uplinkCapacity = 5,
|
||||
downlinkCapacity = 20,
|
||||
congestion = false,
|
||||
readBufferSize = 2,
|
||||
writeBufferSize = 2,
|
||||
type = 'none',
|
||||
seed = '',
|
||||
) {
|
||||
super();
|
||||
this.mtu = mtu;
|
||||
this.tti = tti;
|
||||
@@ -153,7 +166,7 @@ class KcpStreamSettings extends CommonClass {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new KcpStreamSettings(
|
||||
json.mtu,
|
||||
json.tti,
|
||||
@@ -185,13 +198,13 @@ class KcpStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class WsStreamSettings extends CommonClass {
|
||||
constructor(path='/', host='') {
|
||||
constructor(path = '/', host = '') {
|
||||
super();
|
||||
this.path = path;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new WsStreamSettings(
|
||||
json.path,
|
||||
json.host,
|
||||
@@ -207,13 +220,13 @@ class WsStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class HttpStreamSettings extends CommonClass {
|
||||
constructor(path='/', host='') {
|
||||
constructor(path = '/', host = '') {
|
||||
super();
|
||||
this.path = path;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new HttpStreamSettings(
|
||||
json.path,
|
||||
json.host ? json.host.join(',') : '',
|
||||
@@ -229,15 +242,18 @@ class HttpStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class QuicStreamSettings extends CommonClass {
|
||||
constructor(security='none',
|
||||
key='', type='none') {
|
||||
constructor(
|
||||
security = 'none',
|
||||
key = '',
|
||||
type = 'none'
|
||||
) {
|
||||
super();
|
||||
this.security = security;
|
||||
this.key = key;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new QuicStreamSettings(
|
||||
json.security,
|
||||
json.key,
|
||||
@@ -257,15 +273,19 @@ class QuicStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class GrpcStreamSettings extends CommonClass {
|
||||
constructor(serviceName="", authority="", multiMode=false) {
|
||||
constructor(
|
||||
serviceName = "",
|
||||
authority = "",
|
||||
multiMode = false
|
||||
) {
|
||||
super();
|
||||
this.serviceName = serviceName;
|
||||
this.authority = authority;
|
||||
this.multiMode = multiMode;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
return new GrpcStreamSettings(json.serviceName, json.authority, json.multiMode );
|
||||
static fromJson(json = {}) {
|
||||
return new GrpcStreamSettings(json.serviceName, json.authority, json.multiMode);
|
||||
}
|
||||
|
||||
toJson() {
|
||||
@@ -278,13 +298,13 @@ class GrpcStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class HttpUpgradeStreamSettings extends CommonClass {
|
||||
constructor(path='/', host='') {
|
||||
constructor(path = '/', host = '') {
|
||||
super();
|
||||
this.path = path;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new HttpUpgradeStreamSettings(
|
||||
json.path,
|
||||
json.host,
|
||||
@@ -300,13 +320,13 @@ class HttpUpgradeStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class SplitHTTPStreamSettings extends CommonClass {
|
||||
constructor(path='/', host='') {
|
||||
constructor(path = '/', host = '') {
|
||||
super();
|
||||
this.path = path;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new SplitHTTPStreamSettings(
|
||||
json.path,
|
||||
json.host,
|
||||
@@ -322,10 +342,12 @@ class SplitHTTPStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class TlsStreamSettings extends CommonClass {
|
||||
constructor(serverName='',
|
||||
alpn=[],
|
||||
fingerprint = '',
|
||||
allowInsecure = false) {
|
||||
constructor(
|
||||
serverName = '',
|
||||
alpn = [],
|
||||
fingerprint = '',
|
||||
allowInsecure = false
|
||||
) {
|
||||
super();
|
||||
this.serverName = serverName;
|
||||
this.alpn = alpn;
|
||||
@@ -333,7 +355,7 @@ class TlsStreamSettings extends CommonClass {
|
||||
this.allowInsecure = allowInsecure;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new TlsStreamSettings(
|
||||
json.serverName,
|
||||
json.alpn,
|
||||
@@ -353,7 +375,13 @@ class TlsStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class RealityStreamSettings extends CommonClass {
|
||||
constructor(publicKey = '', fingerprint = '', serverName = '', shortId = '', spiderX = '/') {
|
||||
constructor(
|
||||
publicKey = '',
|
||||
fingerprint = '',
|
||||
serverName = '',
|
||||
shortId = '',
|
||||
spiderX = '/'
|
||||
) {
|
||||
super();
|
||||
this.publicKey = publicKey;
|
||||
this.fingerprint = fingerprint;
|
||||
@@ -381,7 +409,13 @@ class RealityStreamSettings 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();
|
||||
this.dialerProxy = dialerProxy;
|
||||
this.tcpFastOpen = tcpFastOpen;
|
||||
@@ -413,20 +447,21 @@ class SockoptStreamSettings extends CommonClass {
|
||||
}
|
||||
|
||||
class StreamSettings extends CommonClass {
|
||||
constructor(network='tcp',
|
||||
security='none',
|
||||
tlsSettings=new TlsStreamSettings(),
|
||||
realitySettings = new RealityStreamSettings(),
|
||||
tcpSettings=new TcpStreamSettings(),
|
||||
kcpSettings=new KcpStreamSettings(),
|
||||
wsSettings=new WsStreamSettings(),
|
||||
httpSettings=new HttpStreamSettings(),
|
||||
quicSettings=new QuicStreamSettings(),
|
||||
grpcSettings=new GrpcStreamSettings(),
|
||||
httpupgradeSettings=new HttpUpgradeStreamSettings(),
|
||||
splithttpSettings=new SplitHTTPStreamSettings(),
|
||||
sockopt = undefined,
|
||||
) {
|
||||
constructor(
|
||||
network = 'tcp',
|
||||
security = 'none',
|
||||
tlsSettings = new TlsStreamSettings(),
|
||||
realitySettings = new RealityStreamSettings(),
|
||||
tcpSettings = new TcpStreamSettings(),
|
||||
kcpSettings = new KcpStreamSettings(),
|
||||
wsSettings = new WsStreamSettings(),
|
||||
httpSettings = new HttpStreamSettings(),
|
||||
quicSettings = new QuicStreamSettings(),
|
||||
grpcSettings = new GrpcStreamSettings(),
|
||||
httpupgradeSettings = new HttpUpgradeStreamSettings(),
|
||||
splithttpSettings = new SplitHTTPStreamSettings(),
|
||||
sockopt = undefined,
|
||||
) {
|
||||
super();
|
||||
this.network = network;
|
||||
this.security = security;
|
||||
@@ -442,7 +477,7 @@ class StreamSettings extends CommonClass {
|
||||
this.splithttp = splithttpSettings;
|
||||
this.sockopt = sockopt;
|
||||
}
|
||||
|
||||
|
||||
get isTls() {
|
||||
return this.security === 'tls';
|
||||
}
|
||||
@@ -459,7 +494,7 @@ class StreamSettings extends CommonClass {
|
||||
this.sockopt = value ? new SockoptStreamSettings() : undefined;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new StreamSettings(
|
||||
json.network,
|
||||
json.security,
|
||||
@@ -528,9 +563,9 @@ class Mux extends CommonClass {
|
||||
|
||||
class Outbound extends CommonClass {
|
||||
constructor(
|
||||
tag='',
|
||||
protocol=Protocols.VMess,
|
||||
settings=null,
|
||||
tag = '',
|
||||
protocol = Protocols.VMess,
|
||||
settings = null,
|
||||
streamSettings = new StreamSettings(),
|
||||
sendThrough,
|
||||
mux = new Mux(),
|
||||
@@ -556,7 +591,7 @@ class Outbound extends CommonClass {
|
||||
|
||||
canEnableTls() {
|
||||
if (![Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks].includes(this.protocol)) return false;
|
||||
return ["tcp", "ws", "http", "quic", "grpc", "httpupgrade" , "splithttp"].includes(this.stream.network);
|
||||
return ["tcp", "ws", "http", "quic", "grpc", "httpupgrade", "splithttp"].includes(this.stream.network);
|
||||
}
|
||||
|
||||
//this is used for xtls-rprx-vision
|
||||
@@ -577,7 +612,7 @@ class Outbound extends CommonClass {
|
||||
}
|
||||
|
||||
canEnableMux() {
|
||||
if (this.settings.flow && this.settings.flow != ''){
|
||||
if (this.settings.flow && this.settings.flow != '') {
|
||||
this.mux.enabled = false;
|
||||
return false;
|
||||
}
|
||||
@@ -608,7 +643,7 @@ class Outbound extends CommonClass {
|
||||
return [Protocols.Socks, Protocols.HTTP].includes(this.protocol);
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new Outbound(
|
||||
json.tag,
|
||||
json.protocol,
|
||||
@@ -639,8 +674,8 @@ class Outbound extends CommonClass {
|
||||
|
||||
static fromLink(link) {
|
||||
data = link.split('://');
|
||||
if(data.length !=2) return null;
|
||||
switch(data[0].toLowerCase()){
|
||||
if (data.length != 2) return null;
|
||||
switch (data[0].toLowerCase()) {
|
||||
case Protocols.VMess:
|
||||
return this.fromVmessLink(JSON.parse(Base64.decode(data[1])));
|
||||
case Protocols.VLESS:
|
||||
@@ -652,7 +687,7 @@ class Outbound extends CommonClass {
|
||||
}
|
||||
}
|
||||
|
||||
static fromVmessLink(json={}){
|
||||
static fromVmessLink(json = {}) {
|
||||
let stream = new StreamSettings(json.net, json.tls);
|
||||
|
||||
let network = json.net;
|
||||
@@ -666,7 +701,7 @@ class Outbound extends CommonClass {
|
||||
stream.type = json.type;
|
||||
stream.seed = json.path;
|
||||
} else if (network === 'ws') {
|
||||
stream.ws = new WsStreamSettings(json.path,json.host);
|
||||
stream.ws = new WsStreamSettings(json.path, json.host);
|
||||
} else if (network === 'http' || network == 'h2') {
|
||||
stream.network = 'http'
|
||||
stream.http = new HttpStreamSettings(
|
||||
@@ -680,12 +715,12 @@ class Outbound extends CommonClass {
|
||||
} else if (network === 'grpc') {
|
||||
stream.grpc = new GrpcStreamSettings(json.path, json.authority, json.type == 'multi');
|
||||
} else if (network === 'httpupgrade') {
|
||||
stream.httpupgrade = new HttpUpgradeStreamSettings(json.path,json.host);
|
||||
stream.httpupgrade = new HttpUpgradeStreamSettings(json.path, json.host);
|
||||
} else if (network === 'splithttp') {
|
||||
stream.splithttp = new SplitHTTPStreamSettings(json.path,json.host);
|
||||
stream.splithttp = new SplitHTTPStreamSettings(json.path, json.host);
|
||||
}
|
||||
|
||||
if(json.tls && json.tls == 'tls'){
|
||||
if (json.tls && json.tls == 'tls') {
|
||||
stream.tls = new TlsStreamSettings(
|
||||
json.sni,
|
||||
json.alpn ? json.alpn.split(',') : [],
|
||||
@@ -695,10 +730,10 @@ class Outbound extends CommonClass {
|
||||
|
||||
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) {
|
||||
const url = new URL(link);
|
||||
let type = url.searchParams.get('type') ?? 'tcp';
|
||||
let security = url.searchParams.get('security') ?? 'none';
|
||||
@@ -715,9 +750,9 @@ class Outbound extends CommonClass {
|
||||
stream.kcp.type = headerType ?? 'none';
|
||||
stream.kcp.seed = path;
|
||||
} else if (type === 'ws') {
|
||||
stream.ws = new WsStreamSettings(path,host);
|
||||
stream.ws = new WsStreamSettings(path, host);
|
||||
} else if (type === 'http' || type == 'h2') {
|
||||
stream.http = new HttpStreamSettings(path,host);
|
||||
stream.http = new HttpStreamSettings(path, host);
|
||||
} else if (type === 'quic') {
|
||||
stream.quic = new QuicStreamSettings(
|
||||
url.searchParams.get('quicSecurity') ?? 'none',
|
||||
@@ -729,25 +764,25 @@ class Outbound extends CommonClass {
|
||||
url.searchParams.get('authority') ?? '',
|
||||
url.searchParams.get('mode') == 'multi');
|
||||
} else if (type === 'httpupgrade') {
|
||||
stream.httpupgrade = new HttpUpgradeStreamSettings(path,host);
|
||||
stream.httpupgrade = new HttpUpgradeStreamSettings(path, host);
|
||||
} else if (type === 'splithttp') {
|
||||
stream.splithttp = new SplitHTTPStreamSettings(path,host);
|
||||
stream.splithttp = new SplitHTTPStreamSettings(path, host);
|
||||
}
|
||||
|
||||
if(security == 'tls'){
|
||||
let fp=url.searchParams.get('fp') ?? 'none';
|
||||
let alpn=url.searchParams.get('alpn');
|
||||
let allowInsecure=url.searchParams.get('allowInsecure');
|
||||
let sni=url.searchParams.get('sni') ?? '';
|
||||
if (security == 'tls') {
|
||||
let fp = url.searchParams.get('fp') ?? 'none';
|
||||
let alpn = url.searchParams.get('alpn');
|
||||
let allowInsecure = url.searchParams.get('allowInsecure');
|
||||
let sni = url.searchParams.get('sni') ?? '';
|
||||
stream.tls = new TlsStreamSettings(sni, alpn ? alpn.split(',') : [], fp, allowInsecure == 1);
|
||||
}
|
||||
|
||||
if(security == 'reality'){
|
||||
let pbk=url.searchParams.get('pbk');
|
||||
let fp=url.searchParams.get('fp');
|
||||
let sni=url.searchParams.get('sni') ?? '';
|
||||
let sid=url.searchParams.get('sid') ?? '';
|
||||
let spx=url.searchParams.get('spx') ?? '';
|
||||
if (security == 'reality') {
|
||||
let pbk = url.searchParams.get('pbk');
|
||||
let fp = url.searchParams.get('fp');
|
||||
let sni = url.searchParams.get('sni') ?? '';
|
||||
let sid = url.searchParams.get('sid') ?? '';
|
||||
let spx = url.searchParams.get('spx') ?? '';
|
||||
stream.reality = new RealityStreamSettings(pbk, fp, sni, sid, spx);
|
||||
}
|
||||
|
||||
@@ -755,14 +790,14 @@ class Outbound extends CommonClass {
|
||||
const match = link.match(regex);
|
||||
|
||||
if (!match) return null;
|
||||
let [, protocol, userData, address, port, ] = match;
|
||||
let [, protocol, userData, address, port,] = match;
|
||||
port *= 1;
|
||||
if(protocol == 'ss') {
|
||||
if (protocol == 'ss') {
|
||||
protocol = 'shadowsocks';
|
||||
userData = atob(userData).split(':');
|
||||
}
|
||||
var settings;
|
||||
switch(protocol){
|
||||
switch (protocol) {
|
||||
case Protocols.VLESS:
|
||||
settings = new Outbound.VLESSSettings(address, port, userData, url.searchParams.get('flow') ?? '');
|
||||
break;
|
||||
@@ -770,7 +805,7 @@ class Outbound extends CommonClass {
|
||||
settings = new Outbound.TrojanSettings(address, port, userData);
|
||||
break;
|
||||
case Protocols.Shadowsocks:
|
||||
let method = userData.splice(0,1)[0];
|
||||
let method = userData.splice(0, 1)[0];
|
||||
settings = new Outbound.ShadowsocksSettings(address, port, userData.join(":"), method, true);
|
||||
break;
|
||||
default:
|
||||
@@ -826,13 +861,13 @@ Outbound.Settings = class extends CommonClass {
|
||||
}
|
||||
};
|
||||
Outbound.FreedomSettings = class extends CommonClass {
|
||||
constructor(domainStrategy='', fragment={}) {
|
||||
constructor(domainStrategy = '', fragment = {}) {
|
||||
super();
|
||||
this.domainStrategy = domainStrategy;
|
||||
this.fragment = fragment;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new Outbound.FreedomSettings(
|
||||
json.domainStrategy,
|
||||
json.fragment ? Outbound.FreedomSettings.Fragment.fromJson(json.fragment) : undefined,
|
||||
@@ -847,14 +882,14 @@ Outbound.FreedomSettings = class extends CommonClass {
|
||||
}
|
||||
};
|
||||
Outbound.FreedomSettings.Fragment = class extends CommonClass {
|
||||
constructor(packets='1-3',length='',interval=''){
|
||||
constructor(packets = '1-3', length = '', interval = '') {
|
||||
super();
|
||||
this.packets = packets;
|
||||
this.length = length;
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new Outbound.FreedomSettings.Fragment(
|
||||
json.packets,
|
||||
json.length,
|
||||
@@ -868,7 +903,7 @@ Outbound.BlackholeSettings = class extends CommonClass {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
return new Outbound.BlackholeSettings(
|
||||
json.response ? json.response.type : undefined,
|
||||
);
|
||||
@@ -876,19 +911,19 @@ Outbound.BlackholeSettings = class extends CommonClass {
|
||||
|
||||
toJson() {
|
||||
return {
|
||||
response: ObjectUtil.isEmpty(this.type) ? undefined : {type: this.type},
|
||||
response: ObjectUtil.isEmpty(this.type) ? undefined : { type: this.type },
|
||||
};
|
||||
}
|
||||
};
|
||||
Outbound.DNSSettings = class extends CommonClass {
|
||||
constructor(network='udp', address='1.1.1.1', port=53) {
|
||||
constructor(network = 'udp', address = '1.1.1.1', port = 53) {
|
||||
super();
|
||||
this.network = network;
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
static fromJson(json={}){
|
||||
static fromJson(json = {}) {
|
||||
return new Outbound.DNSSettings(
|
||||
json.network,
|
||||
json.address,
|
||||
@@ -897,19 +932,21 @@ Outbound.DNSSettings = class extends CommonClass {
|
||||
}
|
||||
};
|
||||
Outbound.VmessSettings = class extends CommonClass {
|
||||
constructor(address, port, id) {
|
||||
constructor(address, port, id, security) {
|
||||
super();
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
this.id = id;
|
||||
this.security = security;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
if(ObjectUtil.isArrEmpty(json.vnext)) return new Outbound.VmessSettings();
|
||||
static fromJson(json = {}) {
|
||||
if (ObjectUtil.isArrEmpty(json.vnext)) return new Outbound.VmessSettings();
|
||||
return new Outbound.VmessSettings(
|
||||
json.vnext[0].address,
|
||||
json.vnext[0].port,
|
||||
json.vnext[0].users[0].id,
|
||||
json.vnext[0].users[0].security,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -918,13 +955,13 @@ Outbound.VmessSettings = class extends CommonClass {
|
||||
vnext: [{
|
||||
address: this.address,
|
||||
port: this.port,
|
||||
users: [{id: this.id}],
|
||||
users: [{ id: this.id, security: this.security }],
|
||||
}],
|
||||
};
|
||||
}
|
||||
};
|
||||
Outbound.VLESSSettings = class extends CommonClass {
|
||||
constructor(address, port, id, flow, encryption='none') {
|
||||
constructor(address, port, id, flow, encryption = 'none') {
|
||||
super();
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
@@ -933,8 +970,8 @@ Outbound.VLESSSettings = class extends CommonClass {
|
||||
this.encryption = encryption
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
if(ObjectUtil.isArrEmpty(json.vnext)) return new Outbound.VLESSSettings();
|
||||
static fromJson(json = {}) {
|
||||
if (ObjectUtil.isArrEmpty(json.vnext)) return new Outbound.VLESSSettings();
|
||||
return new Outbound.VLESSSettings(
|
||||
json.vnext[0].address,
|
||||
json.vnext[0].port,
|
||||
@@ -949,7 +986,7 @@ Outbound.VLESSSettings = class extends CommonClass {
|
||||
vnext: [{
|
||||
address: this.address,
|
||||
port: this.port,
|
||||
users: [{id: this.id, flow: this.flow, encryption: 'none',}],
|
||||
users: [{ id: this.id, flow: this.flow, encryption: 'none', }],
|
||||
}],
|
||||
};
|
||||
}
|
||||
@@ -962,8 +999,8 @@ Outbound.TrojanSettings = class extends CommonClass {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
if(ObjectUtil.isArrEmpty(json.servers)) return new Outbound.TrojanSettings();
|
||||
static fromJson(json = {}) {
|
||||
if (ObjectUtil.isArrEmpty(json.servers)) return new Outbound.TrojanSettings();
|
||||
return new Outbound.TrojanSettings(
|
||||
json.servers[0].address,
|
||||
json.servers[0].port,
|
||||
@@ -992,9 +1029,9 @@ Outbound.ShadowsocksSettings = class extends CommonClass {
|
||||
this.UoTVersion = UoTVersion;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
let servers = json.servers;
|
||||
if(ObjectUtil.isArrEmpty(servers)) servers=[{}];
|
||||
if (ObjectUtil.isArrEmpty(servers)) servers = [{}];
|
||||
return new Outbound.ShadowsocksSettings(
|
||||
servers[0].address,
|
||||
servers[0].port,
|
||||
@@ -1028,9 +1065,9 @@ Outbound.SocksSettings = class extends CommonClass {
|
||||
this.pass = pass;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
let servers = json.servers;
|
||||
if(ObjectUtil.isArrEmpty(servers)) servers=[{users: [{}]}];
|
||||
if (ObjectUtil.isArrEmpty(servers)) servers = [{ users: [{}] }];
|
||||
return new Outbound.SocksSettings(
|
||||
servers[0].address,
|
||||
servers[0].port,
|
||||
@@ -1044,7 +1081,7 @@ Outbound.SocksSettings = class extends CommonClass {
|
||||
servers: [{
|
||||
address: this.address,
|
||||
port: this.port,
|
||||
users: ObjectUtil.isEmpty(this.user) ? [] : [{user: this.user, pass: this.pass}],
|
||||
users: ObjectUtil.isEmpty(this.user) ? [] : [{ user: this.user, pass: this.pass }],
|
||||
}],
|
||||
};
|
||||
}
|
||||
@@ -1058,9 +1095,9 @@ Outbound.HttpSettings = class extends CommonClass {
|
||||
this.pass = pass;
|
||||
}
|
||||
|
||||
static fromJson(json={}) {
|
||||
static fromJson(json = {}) {
|
||||
let servers = json.servers;
|
||||
if(ObjectUtil.isArrEmpty(servers)) servers=[{users: [{}]}];
|
||||
if (ObjectUtil.isArrEmpty(servers)) servers = [{ users: [{}] }];
|
||||
return new Outbound.HttpSettings(
|
||||
servers[0].address,
|
||||
servers[0].port,
|
||||
@@ -1074,7 +1111,7 @@ Outbound.HttpSettings = class extends CommonClass {
|
||||
servers: [{
|
||||
address: this.address,
|
||||
port: this.port,
|
||||
users: ObjectUtil.isEmpty(this.user) ? [] : [{user: this.user, pass: this.pass}],
|
||||
users: ObjectUtil.isEmpty(this.user) ? [] : [{ user: this.user, pass: this.pass }],
|
||||
}],
|
||||
};
|
||||
}
|
||||
@@ -1082,17 +1119,23 @@ Outbound.HttpSettings = class extends CommonClass {
|
||||
|
||||
Outbound.WireguardSettings = class extends CommonClass {
|
||||
constructor(
|
||||
mtu=1420, secretKey='',
|
||||
address=[''], workers=2, domainStrategy='', reserved='',
|
||||
peers=[new Outbound.WireguardSettings.Peer()], kernelMode=false) {
|
||||
mtu = 1420,
|
||||
secretKey = '',
|
||||
address = [''],
|
||||
workers = 2,
|
||||
domainStrategy = '',
|
||||
reserved = '',
|
||||
peers = [new Outbound.WireguardSettings.Peer()],
|
||||
kernelMode = false
|
||||
) {
|
||||
super();
|
||||
this.mtu = mtu;
|
||||
this.secretKey = secretKey;
|
||||
this.pubKey = secretKey.length>0 ? Wireguard.generateKeypair(secretKey).publicKey : '';
|
||||
this.address = address instanceof Array ? address.join(',') : address;
|
||||
this.pubKey = secretKey.length > 0 ? Wireguard.generateKeypair(secretKey).publicKey : '';
|
||||
this.address = Array.isArray(address) ? address.join(',') : address;
|
||||
this.workers = workers;
|
||||
this.domainStrategy = domainStrategy;
|
||||
this.reserved = reserved instanceof Array ? reserved.join(',') : reserved;
|
||||
this.reserved = Array.isArray(reserved) ? reserved.join(',') : reserved;
|
||||
this.peers = peers;
|
||||
this.kernelMode = kernelMode;
|
||||
}
|
||||
@@ -1105,7 +1148,7 @@ Outbound.WireguardSettings = class extends CommonClass {
|
||||
this.peers.splice(index, 1);
|
||||
}
|
||||
|
||||
static fromJson(json={}){
|
||||
static fromJson(json = {}) {
|
||||
return new Outbound.WireguardSettings(
|
||||
json.mtu,
|
||||
json.secretKey,
|
||||
@@ -1120,10 +1163,10 @@ Outbound.WireguardSettings = class extends CommonClass {
|
||||
|
||||
toJson() {
|
||||
return {
|
||||
mtu: this.mtu?? undefined,
|
||||
mtu: this.mtu ?? undefined,
|
||||
secretKey: this.secretKey,
|
||||
address: this.address ? this.address.split(",") : [],
|
||||
workers: this.workers?? undefined,
|
||||
workers: this.workers ?? undefined,
|
||||
domainStrategy: WireguardDomainStrategy.includes(this.domainStrategy) ? this.domainStrategy : undefined,
|
||||
reserved: this.reserved ? this.reserved.split(",").map(Number) : undefined,
|
||||
peers: Outbound.WireguardSettings.Peer.toJsonArray(this.peers),
|
||||
@@ -1133,7 +1176,13 @@ Outbound.WireguardSettings = 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();
|
||||
this.publicKey = publicKey;
|
||||
this.psk = psk;
|
||||
@@ -1142,7 +1191,7 @@ Outbound.WireguardSettings.Peer = class extends CommonClass {
|
||||
this.keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
static fromJson(json={}){
|
||||
static fromJson(json = {}) {
|
||||
return new Outbound.WireguardSettings.Peer(
|
||||
json.publicKey,
|
||||
json.preSharedKey,
|
||||
@@ -1155,10 +1204,10 @@ Outbound.WireguardSettings.Peer = class extends CommonClass {
|
||||
toJson() {
|
||||
return {
|
||||
publicKey: this.publicKey,
|
||||
preSharedKey: this.psk.length>0 ? this.psk : undefined,
|
||||
preSharedKey: this.psk.length > 0 ? this.psk : undefined,
|
||||
allowedIPs: this.allowedIPs ? this.allowedIPs : undefined,
|
||||
endpoint: this.endpoint,
|
||||
keepAlive: this.keepAlive?? undefined,
|
||||
keepAlive: this.keepAlive ?? undefined,
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -7,10 +7,10 @@ class AllSetting {
|
||||
this.webCertFile = "";
|
||||
this.webKeyFile = "";
|
||||
this.webBasePath = "/";
|
||||
this.sessionMaxAge = "";
|
||||
this.sessionMaxAge = 0;
|
||||
this.pageSize = 50;
|
||||
this.expireDiff = "";
|
||||
this.trafficDiff = "";
|
||||
this.expireDiff = 0;
|
||||
this.trafficDiff = 0;
|
||||
this.remarkModel = "-ieo";
|
||||
this.datepicker = "gregorian";
|
||||
this.tgBotEnable = false;
|
||||
@@ -19,22 +19,22 @@ class AllSetting {
|
||||
this.tgBotChatId = "";
|
||||
this.tgRunTime = "@daily";
|
||||
this.tgBotBackup = false;
|
||||
this.tgBotLoginNotify = false;
|
||||
this.tgCpu = "";
|
||||
this.tgBotLoginNotify = true;
|
||||
this.tgCpu = 80;
|
||||
this.tgLang = "en-US";
|
||||
this.xrayTemplateConfig = "";
|
||||
this.secretEnable = false;
|
||||
this.subEnable = false;
|
||||
this.subListen = "";
|
||||
this.subPort = "2096";
|
||||
this.subPort = 2096;
|
||||
this.subPath = "/sub/";
|
||||
this.subJsonPath = "/json/";
|
||||
this.subDomain = "";
|
||||
this.subCertFile = "";
|
||||
this.subKeyFile = "";
|
||||
this.subUpdates = 0;
|
||||
this.subUpdates = 12;
|
||||
this.subEncrypt = true;
|
||||
this.subShowInfo = false;
|
||||
this.subShowInfo = true;
|
||||
this.subURI = "";
|
||||
this.subJsonURI = "";
|
||||
this.subJsonFragment = "";
|
||||
|
||||
@@ -16,6 +16,9 @@ class HttpUtil {
|
||||
}
|
||||
|
||||
static _respToMsg(resp) {
|
||||
if (!resp || !resp.data) {
|
||||
return new Msg(false, 'No response data');
|
||||
}
|
||||
const { data } = resp;
|
||||
if (data == null) {
|
||||
return new Msg(true);
|
||||
@@ -34,7 +37,7 @@ class HttpUtil {
|
||||
return msg;
|
||||
} catch (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);
|
||||
return errorMsg;
|
||||
}
|
||||
@@ -48,7 +51,7 @@ class HttpUtil {
|
||||
return msg;
|
||||
} catch (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);
|
||||
return errorMsg;
|
||||
}
|
||||
@@ -97,12 +100,22 @@ class RandomUtil {
|
||||
}
|
||||
|
||||
static randomShortId() {
|
||||
let str = '';
|
||||
for (let i = 0; i < 8; ++i) {
|
||||
str += seq[this.randomInt(16)];
|
||||
const lengths = [2, 4, 6, 8, 10, 12, 14, 16];
|
||||
for (let i = lengths.length - 1; i > 0; i--) {
|
||||
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) {
|
||||
let str = '';
|
||||
|
||||
@@ -33,6 +33,7 @@ func (a *APIController) initRouter(g *gin.RouterGroup) {
|
||||
{"GET", "/list", a.inboundController.getInbounds},
|
||||
{"GET", "/get/:id", a.inboundController.getInbound},
|
||||
{"GET", "/getClientTraffics/:email", a.inboundController.getClientTraffics},
|
||||
{"GET", "/getClientTrafficsById/:id", a.inboundController.getClientTrafficsById},
|
||||
{"POST", "/add", a.inboundController.addInbound},
|
||||
{"POST", "/del/:id", a.inboundController.delInbound},
|
||||
{"POST", "/update/:id", a.inboundController.updateInbound},
|
||||
|
||||
@@ -77,6 +77,16 @@ func (a *InboundController) getClientTraffics(c *gin.Context) {
|
||||
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) {
|
||||
inbound := &model.Inbound{}
|
||||
err := c.ShouldBind(inbound)
|
||||
|
||||
@@ -83,11 +83,13 @@ func (a *IndexController) login(c *gin.Context) {
|
||||
logger.Warning("Unable to get session's max age from DB")
|
||||
}
|
||||
|
||||
if sessionMaxAge > 0 {
|
||||
err = session.SetMaxAge(c, sessionMaxAge*60)
|
||||
if err != nil {
|
||||
logger.Warning("Unable to set session's max age")
|
||||
}
|
||||
if sessionMaxAge <= 0 {
|
||||
sessionMaxAge = 60
|
||||
}
|
||||
|
||||
err = session.SetMaxAge(c, sessionMaxAge*60)
|
||||
if err != nil {
|
||||
logger.Warning("Unable to set session's max age")
|
||||
}
|
||||
|
||||
err = session.SetLoginUser(c, user)
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
<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-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-select v-model="clientsBulkModal.flow" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
||||
@@ -146,6 +151,7 @@
|
||||
emailPostfix: "",
|
||||
subId: "",
|
||||
tgId: '',
|
||||
security: "auto",
|
||||
flow: "",
|
||||
delayedStart: false,
|
||||
reset: 0,
|
||||
@@ -168,6 +174,7 @@
|
||||
newClient.email += useNum ? prefix + i.toString() + postfix : prefix + postfix;
|
||||
if (clientsBulkModal.subId.length > 0) newClient.subId = clientsBulkModal.subId;
|
||||
newClient.tgId = clientsBulkModal.tgId;
|
||||
newClient.security = clientsBulkModal.security;
|
||||
newClient.limitIp = clientsBulkModal.limitIp;
|
||||
newClient._totalGB = clientsBulkModal.totalGB;
|
||||
newClient._expiryTime = clientsBulkModal.expiryTime;
|
||||
@@ -203,6 +210,7 @@
|
||||
this.emailPostfix = "";
|
||||
this.subId = "";
|
||||
this.tgId = '';
|
||||
this.security = "auto";
|
||||
this.flow = "";
|
||||
this.dbInbound = new DBInbound(dbInbound);
|
||||
this.inbound = dbInbound.toInbound();
|
||||
@@ -211,7 +219,7 @@
|
||||
},
|
||||
newClient(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.TROJAN: return new Inbound.TrojanSettings.Trojan();
|
||||
case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings.Shadowsocks(clientsBulkModal.inbound.settings.shadowsockses[0].method);
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
},
|
||||
addClient(protocol, clients) {
|
||||
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.TROJAN: return clients.push(new Inbound.TrojanSettings.Trojan());
|
||||
case Protocols.SHADOWSOCKS: return clients.push(new Inbound.ShadowsocksSettings.Shadowsocks(clients[0].method));
|
||||
|
||||
@@ -39,6 +39,11 @@
|
||||
</template>
|
||||
<a-input v-model.trim="client.id"></a-input>
|
||||
</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">
|
||||
<template slot="label">
|
||||
<a-tooltip>
|
||||
|
||||
@@ -160,6 +160,11 @@
|
||||
<a-form-item label='ID'>
|
||||
<a-input v-model.trim="outbound.settings.id"></a-input>
|
||||
</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 -->
|
||||
<template v-if="outbound.canEnableTlsFlow()">
|
||||
|
||||
@@ -9,12 +9,10 @@
|
||||
<table width="100%">
|
||||
<tr class="client-table-header">
|
||||
<th>{{ i18n "pages.inbounds.email" }}</th>
|
||||
<th>Flow</th>
|
||||
<th>ID</th>
|
||||
</tr>
|
||||
<tr v-for="(client, index) in inbound.settings.vlesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
||||
<td>[[ client.email ]]</td>
|
||||
<td>[[ client.flow ]]</td>
|
||||
<td>[[ client.id ]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
<tr class="client-table-header">
|
||||
<th>{{ i18n "pages.inbounds.email" }}</th>
|
||||
<th>ID</th>
|
||||
<th>Security</th>
|
||||
</tr>
|
||||
<tr v-for="(client, index) in inbound.settings.vmesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
||||
<td>[[ client.email ]]</td>
|
||||
<td>[[ client.id ]]</td>
|
||||
<td>[[ client.security ]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
</a-collapse-panel>
|
||||
|
||||
@@ -19,11 +19,17 @@
|
||||
</a-input>
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="Max Upload Size (Byte)">
|
||||
<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-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>
|
||||
{{end}}
|
||||
|
||||
@@ -104,6 +104,9 @@
|
||||
<a-select-option v-for="key in USAGE_OPTION" :value="key">[[ key ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="Build Chain">
|
||||
<a-switch v-model="cert.buildChain"></a-switch>
|
||||
</a-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -523,7 +523,9 @@
|
||||
if (msg.success) {
|
||||
this.loading(true);
|
||||
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 url = buildURL({ host, port, isTLS, base, path: "panel/settings" });
|
||||
window.location.replace(url);
|
||||
|
||||
@@ -10,15 +10,9 @@ import (
|
||||
|
||||
func DomainValidatorMiddleware(domain string) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
host := c.GetHeader("X-Forwarded-Host")
|
||||
if host == "" {
|
||||
host = c.GetHeader("X-Real-IP")
|
||||
}
|
||||
if host == "" {
|
||||
host = c.Request.Host
|
||||
if colonIndex := strings.LastIndex(host, ":"); colonIndex != -1 {
|
||||
host, _, _ = net.SplitHostPort(host)
|
||||
}
|
||||
host := c.Request.Host
|
||||
if colonIndex := strings.LastIndex(host, ":"); colonIndex != -1 {
|
||||
host, _, _ = net.SplitHostPort(c.Request.Host)
|
||||
}
|
||||
|
||||
if host != domain {
|
||||
|
||||
@@ -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{}{
|
||||
"email": client.Email,
|
||||
"id": client.ID,
|
||||
"security": client.Security,
|
||||
"flow": client.Flow,
|
||||
"password": client.Password,
|
||||
"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{}{
|
||||
"email": clients[0].Email,
|
||||
"id": clients[0].ID,
|
||||
"security": clients[0].Security,
|
||||
"flow": clients[0].Flow,
|
||||
"password": clients[0].Password,
|
||||
"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{}{
|
||||
"email": client.Email,
|
||||
"id": client.ID,
|
||||
"security": client.Security,
|
||||
"flow": client.Flow,
|
||||
"password": client.Password,
|
||||
"cipher": cipher,
|
||||
@@ -1750,6 +1753,25 @@ func (s *InboundService) GetClientTrafficByEmail(email string) (traffic *xray.Cl
|
||||
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) {
|
||||
db := database.GetDB()
|
||||
inbound := &model.Inbound{}
|
||||
|
||||
@@ -45,7 +45,7 @@ var defaultValueMap = map[string]string{
|
||||
"tgRunTime": "@daily",
|
||||
"tgBotBackup": "false",
|
||||
"tgBotLoginNotify": "true",
|
||||
"tgCpu": "0",
|
||||
"tgCpu": "80",
|
||||
"tgLang": "en-US",
|
||||
"secretEnable": "false",
|
||||
"subEnable": "false",
|
||||
|
||||
@@ -9,7 +9,10 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const loginUser = "LOGIN_USER"
|
||||
const (
|
||||
loginUser = "LOGIN_USER"
|
||||
defaultPath = "/"
|
||||
)
|
||||
|
||||
func init() {
|
||||
gob.Register(model.User{})
|
||||
@@ -17,10 +20,6 @@ func init() {
|
||||
|
||||
func SetLoginUser(c *gin.Context, user *model.User) error {
|
||||
s := sessions.Default(c)
|
||||
s.Options(sessions.Options{
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
})
|
||||
s.Set(loginUser, user)
|
||||
return s.Save()
|
||||
}
|
||||
@@ -28,20 +27,24 @@ func SetLoginUser(c *gin.Context, user *model.User) error {
|
||||
func SetMaxAge(c *gin.Context, maxAge int) error {
|
||||
s := sessions.Default(c)
|
||||
s.Options(sessions.Options{
|
||||
Path: "/",
|
||||
MaxAge: maxAge,
|
||||
Path: defaultPath,
|
||||
MaxAge: maxAge,
|
||||
HttpOnly: true,
|
||||
})
|
||||
return s.Save()
|
||||
}
|
||||
|
||||
func GetLoginUser(c *gin.Context) *model.User {
|
||||
s := sessions.Default(c)
|
||||
if obj := s.Get(loginUser); obj != nil {
|
||||
if user, ok := obj.(model.User); ok {
|
||||
return &user
|
||||
}
|
||||
obj := s.Get(loginUser)
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
user, ok := obj.(model.User)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return &user
|
||||
}
|
||||
|
||||
func IsLogin(c *gin.Context) bool {
|
||||
@@ -52,12 +55,9 @@ func ClearSession(c *gin.Context) error {
|
||||
s := sessions.Default(c)
|
||||
s.Clear()
|
||||
s.Options(sessions.Options{
|
||||
Path: "/",
|
||||
MaxAge: -1,
|
||||
Path: defaultPath,
|
||||
MaxAge: -1,
|
||||
HttpOnly: true,
|
||||
})
|
||||
if err := s.Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.SetCookie("3x-ui", "", -1, "/", "", false, true)
|
||||
return nil
|
||||
return s.Save()
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"settings" = "Настройки панели"
|
||||
"xray" = "Настройки Xray"
|
||||
"logout" = "Выход"
|
||||
"link" = "менеджмент"
|
||||
"link" = "Менеджмент"
|
||||
|
||||
[pages.login]
|
||||
"hello" = "Привет"
|
||||
@@ -254,7 +254,7 @@
|
||||
"pageSize" = "Размер нумерации страниц"
|
||||
"pageSizeDesc" = "Определить размер страницы для входящей таблицы. Установите 0, чтобы отключить"
|
||||
"remarkModel" = "Модель примечания и символ разделения"
|
||||
"datepicker" = "выбор даты"
|
||||
"datepicker" = "Выбор даты"
|
||||
"datepickerPlaceholder" = "Выберите дату"
|
||||
"datepickerDescription" = "Тип календаря выбора указывает дату истечения срока действия."
|
||||
"sampleRemark" = "Пример замечания"
|
||||
@@ -412,7 +412,7 @@
|
||||
"Inbounds" = "Входящие"
|
||||
"InboundsDesc" = "Изменение шаблона конфигурации для подключения определенных пользователей"
|
||||
"Outbounds" = "Исходящие"
|
||||
"Balancers" = "Балансиры"
|
||||
"Balancers" = "Балансировщик нагрузки"
|
||||
"OutboundsDesc" = "Изменение шаблона конфигурации, чтобы определить исходящие пути для этого сервера"
|
||||
"Routings" = "Правила маршрутизации"
|
||||
"RoutingsDesc" = "Важен приоритет каждого правила!"
|
||||
|
||||
640
web/translation/translate.tr_TR.toml
Normal 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>"
|
||||
2
x-ui.sh
@@ -254,7 +254,7 @@ reset_user() {
|
||||
|
||||
gen_random_string() {
|
||||
local length="$1"
|
||||
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w "$length" | head -n 1)
|
||||
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' </dev/urandom | fold -w "$length" | head -n 1)
|
||||
echo "$random_string"
|
||||
}
|
||||
|
||||
|
||||
@@ -181,6 +181,10 @@ func (x *XrayAPI) GetTraffic(reset bool) ([]*Traffic, []*ClientTraffic, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
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})
|
||||
if err != nil {
|
||||
logger.Debug("Failed to query Xray stats:", err)
|
||||
|
||||