Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f26567d85d | ||
|
|
c8b1b162ff | ||
|
|
a55645584b | ||
|
|
f536307914 | ||
|
|
4494ffabb6 | ||
|
|
2dc59a601c | ||
|
|
4ad04e2032 | ||
|
|
f2ebe128cc |
@@ -32,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.14`:
|
||||
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.3.15`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.14
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.15
|
||||
```
|
||||
|
||||
## Certificado SSL
|
||||
|
||||
@@ -32,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.14`:
|
||||
To install your desired version, add the version to the end of the installation command. e.g., ver `v2.3.15`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.14
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.15
|
||||
```
|
||||
|
||||
## SSL Certificate
|
||||
|
||||
@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## Установка определённой версии
|
||||
|
||||
Чтобы установить нужную вам версию, добавьте номер версии в конец команды установки. Например, `v2.3.14`:
|
||||
Чтобы установить нужную вам версию, добавьте номер версии в конец команды установки. Например, `v2.3.15`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.14
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.15
|
||||
```
|
||||
|
||||
## SSL Сертификат
|
||||
|
||||
@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.14`:
|
||||
要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.15`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.14
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.15
|
||||
```
|
||||
|
||||
## SSL 认证
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.3.14
|
||||
2.3.15
|
||||
18
go.mod
18
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.3
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/shirou/gopsutil/v4 v4.24.7
|
||||
github.com/shirou/gopsutil/v4 v4.24.8
|
||||
github.com/valyala/fasthttp v1.55.0
|
||||
github.com/xtls/xray-core v1.8.24
|
||||
go.uber.org/atomic v1.11.0
|
||||
golang.org/x/text v0.17.0
|
||||
golang.org/x/text v0.18.0
|
||||
google.golang.org/grpc v1.66.0
|
||||
gorm.io/driver/sqlite v1.5.6
|
||||
gorm.io/gorm v1.25.11
|
||||
@@ -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.3 // indirect
|
||||
github.com/google/pprof v0.0.0-20240829160300-da1f7e9f2b25 // indirect
|
||||
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9 // indirect
|
||||
github.com/gorilla/context v1.1.2 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gorilla/sessions v1.4.0 // indirect
|
||||
@@ -54,13 +54,13 @@ require (
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.23 // 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.20.2 // 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/qpack v0.5.0 // 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
|
||||
@@ -83,13 +83,13 @@ 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.9.0 // indirect
|
||||
golang.org/x/arch v0.10.0 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect
|
||||
golang.org/x/mod v0.21.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/sys v0.25.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
|
||||
|
||||
36
go.sum
36
go.sum
@@ -98,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-20240829160300-da1f7e9f2b25 h1:sEDPKUw6iPjczdu33njxFjO6tYa9bfc0z/QyB/zSsBw=
|
||||
github.com/google/pprof v0.0.0-20240829160300-da1f7e9f2b25/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9 h1:q5g0N9eal4bmJwXHC5z0QCKs8qhS35hFfq0BAYsIwZI=
|
||||
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
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=
|
||||
@@ -146,8 +146,8 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0=
|
||||
github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
@@ -186,8 +186,8 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
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/qpack v0.5.0 h1:jldbr38Ef/swDfxtvNvvUIYNg5LNm3Oa9W+IZvCm4q0=
|
||||
github.com/quic-go/qpack v0.5.0/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
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=
|
||||
@@ -208,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.7 h1:V9UGTK4gQ8HvcnPKf6Zt3XHyQq/peaekfxpJ2HSocJk=
|
||||
github.com/shirou/gopsutil/v4 v4.24.7/go.mod h1:0uW/073rP7FYLOkvxolUQM5rMOLTNmRXnFKafpb71rw=
|
||||
github.com/shirou/gopsutil/v4 v4.24.8 h1:pVQjIenQkIhqO81mwTaXjTzOMT7d3TZkf43PlVFHENI=
|
||||
github.com/shirou/gopsutil/v4 v4.24.8/go.mod h1:wE0OrJtj4dG+hYkxqDH3QiBICdKSf04/npcvLLc/oRg=
|
||||
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=
|
||||
@@ -287,8 +287,8 @@ 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.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
|
||||
golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
|
||||
golang.org/x/arch v0.10.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=
|
||||
@@ -296,13 +296,13 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk
|
||||
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-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA=
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/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.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -336,12 +336,12 @@ golang.org/x/sys v0.2.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.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.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.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.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.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
|
||||
@@ -268,13 +268,13 @@ func (s *SubJsonService) realityData(rData map[string]interface{}) map[string]in
|
||||
rltyData["spiderX"] = "/" + random.Seq(15)
|
||||
shortIds, ok := rData["shortIds"].([]interface{})
|
||||
if ok && len(shortIds) > 0 {
|
||||
rltyData["shortId"] = shortIds[random.Num(len(shortIds))].(string)
|
||||
rltyData["shortId"] = shortIds
|
||||
} else {
|
||||
rltyData["shortId"] = ""
|
||||
}
|
||||
serverNames, ok := rData["serverNames"].([]interface{})
|
||||
if ok && len(serverNames) > 0 {
|
||||
rltyData["serverName"] = serverNames[random.Num(len(serverNames))].(string)
|
||||
rltyData["serverName"] = serverNames
|
||||
} else {
|
||||
rltyData["serverName"] = ""
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ const supportLangs = [
|
||||
value: 'tr-TR',
|
||||
icon: '🇹🇷',
|
||||
},
|
||||
{
|
||||
name: "Português",
|
||||
value: "pt-BR",
|
||||
icon: "🇧🇷",
|
||||
},
|
||||
];
|
||||
|
||||
function getLang() {
|
||||
|
||||
@@ -864,12 +864,14 @@ Outbound.FreedomSettings = class extends CommonClass {
|
||||
constructor(
|
||||
domainStrategy = '',
|
||||
timeout = '',
|
||||
redirect = '',
|
||||
fragment = {},
|
||||
noise = {}
|
||||
) {
|
||||
super();
|
||||
this.domainStrategy = domainStrategy;
|
||||
this.timeout = timeout;
|
||||
this.redirect = redirect;
|
||||
this.fragment = fragment;
|
||||
this.noise = noise;
|
||||
}
|
||||
@@ -878,6 +880,7 @@ Outbound.FreedomSettings = class extends CommonClass {
|
||||
return new Outbound.FreedomSettings(
|
||||
json.domainStrategy,
|
||||
json.timeout,
|
||||
json.redirect,
|
||||
json.fragment ? Outbound.FreedomSettings.Fragment.fromJson(json.fragment) : undefined,
|
||||
json.noise ? Outbound.FreedomSettings.Noise.fromJson(json.noise) : undefined,
|
||||
);
|
||||
@@ -887,6 +890,7 @@ Outbound.FreedomSettings = class extends CommonClass {
|
||||
return {
|
||||
domainStrategy: ObjectUtil.isEmpty(this.domainStrategy) ? undefined : this.domainStrategy,
|
||||
timeout: this.timeout,
|
||||
redirect: this.redirect,
|
||||
fragment: Object.keys(this.fragment).length === 0 ? undefined : this.fragment,
|
||||
noise: Object.keys(this.noise).length === 0 ? undefined : this.noise,
|
||||
};
|
||||
|
||||
@@ -914,7 +914,7 @@ class RealityStreamSettings extends XrayCommonClass {
|
||||
minClient = '',
|
||||
maxClient = '',
|
||||
maxTimediff = 0,
|
||||
shortIds = RandomUtil.randomShortId(),
|
||||
shortIds = RandomUtil.randomShortIds(),
|
||||
settings = new RealityStreamSettings.Settings()
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -99,7 +99,7 @@ class RandomUtil {
|
||||
return str;
|
||||
}
|
||||
|
||||
static randomShortId() {
|
||||
static randomShortIds() {
|
||||
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));
|
||||
@@ -114,8 +114,8 @@ class RandomUtil {
|
||||
}
|
||||
shortIds.push(shortId);
|
||||
}
|
||||
return shortIds;
|
||||
}
|
||||
return shortIds.join(',');
|
||||
}
|
||||
|
||||
static randomLowerAndNum(len) {
|
||||
let str = '';
|
||||
@@ -294,172 +294,172 @@ class ObjectUtil {
|
||||
}
|
||||
|
||||
class Wireguard {
|
||||
static gf(init) {
|
||||
var r = new Float64Array(16);
|
||||
if (init) {
|
||||
for (var i = 0; i < init.length; ++i)
|
||||
r[i] = init[i];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
static gf(init) {
|
||||
var r = new Float64Array(16);
|
||||
if (init) {
|
||||
for (var i = 0; i < init.length; ++i)
|
||||
r[i] = init[i];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static pack(o, n) {
|
||||
var b, m = this.gf(), t = this.gf();
|
||||
for (var i = 0; i < 16; ++i)
|
||||
t[i] = n[i];
|
||||
this.carry(t);
|
||||
this.carry(t);
|
||||
this.carry(t);
|
||||
for (var j = 0; j < 2; ++j) {
|
||||
m[0] = t[0] - 0xffed;
|
||||
for (var i = 1; i < 15; ++i) {
|
||||
m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
|
||||
m[i - 1] &= 0xffff;
|
||||
}
|
||||
m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
|
||||
b = (m[15] >> 16) & 1;
|
||||
m[14] &= 0xffff;
|
||||
this.cswap(t, m, 1 - b);
|
||||
}
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
o[2 * i] = t[i] & 0xff;
|
||||
o[2 * i + 1] = t[i] >> 8;
|
||||
}
|
||||
}
|
||||
static pack(o, n) {
|
||||
var b, m = this.gf(), t = this.gf();
|
||||
for (var i = 0; i < 16; ++i)
|
||||
t[i] = n[i];
|
||||
this.carry(t);
|
||||
this.carry(t);
|
||||
this.carry(t);
|
||||
for (var j = 0; j < 2; ++j) {
|
||||
m[0] = t[0] - 0xffed;
|
||||
for (var i = 1; i < 15; ++i) {
|
||||
m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
|
||||
m[i - 1] &= 0xffff;
|
||||
}
|
||||
m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
|
||||
b = (m[15] >> 16) & 1;
|
||||
m[14] &= 0xffff;
|
||||
this.cswap(t, m, 1 - b);
|
||||
}
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
o[2 * i] = t[i] & 0xff;
|
||||
o[2 * i + 1] = t[i] >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
static carry(o) {
|
||||
var c;
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
o[(i + 1) % 16] += (i < 15 ? 1 : 38) * Math.floor(o[i] / 65536);
|
||||
o[i] &= 0xffff;
|
||||
}
|
||||
}
|
||||
static carry(o) {
|
||||
var c;
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
o[(i + 1) % 16] += (i < 15 ? 1 : 38) * Math.floor(o[i] / 65536);
|
||||
o[i] &= 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
static cswap(p, q, b) {
|
||||
var t, c = ~(b - 1);
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
t = c & (p[i] ^ q[i]);
|
||||
p[i] ^= t;
|
||||
q[i] ^= t;
|
||||
}
|
||||
}
|
||||
static cswap(p, q, b) {
|
||||
var t, c = ~(b - 1);
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
t = c & (p[i] ^ q[i]);
|
||||
p[i] ^= t;
|
||||
q[i] ^= t;
|
||||
}
|
||||
}
|
||||
|
||||
static add(o, a, b) {
|
||||
for (var i = 0; i < 16; ++i)
|
||||
o[i] = (a[i] + b[i]) | 0;
|
||||
}
|
||||
static add(o, a, b) {
|
||||
for (var i = 0; i < 16; ++i)
|
||||
o[i] = (a[i] + b[i]) | 0;
|
||||
}
|
||||
|
||||
static subtract(o, a, b) {
|
||||
for (var i = 0; i < 16; ++i)
|
||||
o[i] = (a[i] - b[i]) | 0;
|
||||
}
|
||||
static subtract(o, a, b) {
|
||||
for (var i = 0; i < 16; ++i)
|
||||
o[i] = (a[i] - b[i]) | 0;
|
||||
}
|
||||
|
||||
static multmod(o, a, b) {
|
||||
var t = new Float64Array(31);
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
for (var j = 0; j < 16; ++j)
|
||||
t[i + j] += a[i] * b[j];
|
||||
}
|
||||
for (var i = 0; i < 15; ++i)
|
||||
t[i] += 38 * t[i + 16];
|
||||
for (var i = 0; i < 16; ++i)
|
||||
o[i] = t[i];
|
||||
this.carry(o);
|
||||
this.carry(o);
|
||||
}
|
||||
static multmod(o, a, b) {
|
||||
var t = new Float64Array(31);
|
||||
for (var i = 0; i < 16; ++i) {
|
||||
for (var j = 0; j < 16; ++j)
|
||||
t[i + j] += a[i] * b[j];
|
||||
}
|
||||
for (var i = 0; i < 15; ++i)
|
||||
t[i] += 38 * t[i + 16];
|
||||
for (var i = 0; i < 16; ++i)
|
||||
o[i] = t[i];
|
||||
this.carry(o);
|
||||
this.carry(o);
|
||||
}
|
||||
|
||||
static invert(o, i) {
|
||||
var c = this.gf();
|
||||
for (var a = 0; a < 16; ++a)
|
||||
c[a] = i[a];
|
||||
for (var a = 253; a >= 0; --a) {
|
||||
this.multmod(c, c, c);
|
||||
if (a !== 2 && a !== 4)
|
||||
static invert(o, i) {
|
||||
var c = this.gf();
|
||||
for (var a = 0; a < 16; ++a)
|
||||
c[a] = i[a];
|
||||
for (var a = 253; a >= 0; --a) {
|
||||
this.multmod(c, c, c);
|
||||
if (a !== 2 && a !== 4)
|
||||
this.multmod(c, c, i);
|
||||
}
|
||||
for (var a = 0; a < 16; ++a)
|
||||
o[a] = c[a];
|
||||
}
|
||||
}
|
||||
for (var a = 0; a < 16; ++a)
|
||||
o[a] = c[a];
|
||||
}
|
||||
|
||||
static clamp(z) {
|
||||
z[31] = (z[31] & 127) | 64;
|
||||
z[0] &= 248;
|
||||
}
|
||||
static clamp(z) {
|
||||
z[31] = (z[31] & 127) | 64;
|
||||
z[0] &= 248;
|
||||
}
|
||||
|
||||
static generatePublicKey(privateKey) {
|
||||
var r, z = new Uint8Array(32);
|
||||
var a = this.gf([1]),
|
||||
b = this.gf([9]),
|
||||
c = this.gf(),
|
||||
d = this.gf([1]),
|
||||
e = this.gf(),
|
||||
f = this.gf(),
|
||||
_121665 = this.gf([0xdb41, 1]),
|
||||
_9 = this.gf([9]);
|
||||
for (var i = 0; i < 32; ++i)
|
||||
z[i] = privateKey[i];
|
||||
this.clamp(z);
|
||||
for (var i = 254; i >= 0; --i) {
|
||||
r = (z[i >>> 3] >>> (i & 7)) & 1;
|
||||
this.cswap(a, b, r);
|
||||
this.cswap(c, d, r);
|
||||
this.add(e, a, c);
|
||||
this.subtract(a, a, c);
|
||||
this.add(c, b, d);
|
||||
this.subtract(b, b, d);
|
||||
this.multmod(d, e, e);
|
||||
this.multmod(f, a, a);
|
||||
this.multmod(a, c, a);
|
||||
this.multmod(c, b, e);
|
||||
this.add(e, a, c);
|
||||
this.subtract(a, a, c);
|
||||
this.multmod(b, a, a);
|
||||
this.subtract(c, d, f);
|
||||
this.multmod(a, c, _121665);
|
||||
this.add(a, a, d);
|
||||
this.multmod(c, c, a);
|
||||
this.multmod(a, d, f);
|
||||
this.multmod(d, b, _9);
|
||||
this.multmod(b, e, e);
|
||||
this.cswap(a, b, r);
|
||||
this.cswap(c, d, r);
|
||||
}
|
||||
this.invert(c, c);
|
||||
this.multmod(a, a, c);
|
||||
this.pack(z, a);
|
||||
return z;
|
||||
}
|
||||
static generatePublicKey(privateKey) {
|
||||
var r, z = new Uint8Array(32);
|
||||
var a = this.gf([1]),
|
||||
b = this.gf([9]),
|
||||
c = this.gf(),
|
||||
d = this.gf([1]),
|
||||
e = this.gf(),
|
||||
f = this.gf(),
|
||||
_121665 = this.gf([0xdb41, 1]),
|
||||
_9 = this.gf([9]);
|
||||
for (var i = 0; i < 32; ++i)
|
||||
z[i] = privateKey[i];
|
||||
this.clamp(z);
|
||||
for (var i = 254; i >= 0; --i) {
|
||||
r = (z[i >>> 3] >>> (i & 7)) & 1;
|
||||
this.cswap(a, b, r);
|
||||
this.cswap(c, d, r);
|
||||
this.add(e, a, c);
|
||||
this.subtract(a, a, c);
|
||||
this.add(c, b, d);
|
||||
this.subtract(b, b, d);
|
||||
this.multmod(d, e, e);
|
||||
this.multmod(f, a, a);
|
||||
this.multmod(a, c, a);
|
||||
this.multmod(c, b, e);
|
||||
this.add(e, a, c);
|
||||
this.subtract(a, a, c);
|
||||
this.multmod(b, a, a);
|
||||
this.subtract(c, d, f);
|
||||
this.multmod(a, c, _121665);
|
||||
this.add(a, a, d);
|
||||
this.multmod(c, c, a);
|
||||
this.multmod(a, d, f);
|
||||
this.multmod(d, b, _9);
|
||||
this.multmod(b, e, e);
|
||||
this.cswap(a, b, r);
|
||||
this.cswap(c, d, r);
|
||||
}
|
||||
this.invert(c, c);
|
||||
this.multmod(a, a, c);
|
||||
this.pack(z, a);
|
||||
return z;
|
||||
}
|
||||
|
||||
static generatePresharedKey() {
|
||||
var privateKey = new Uint8Array(32);
|
||||
window.crypto.getRandomValues(privateKey);
|
||||
return privateKey;
|
||||
}
|
||||
static generatePresharedKey() {
|
||||
var privateKey = new Uint8Array(32);
|
||||
window.crypto.getRandomValues(privateKey);
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
static generatePrivateKey() {
|
||||
var privateKey = this.generatePresharedKey();
|
||||
this.clamp(privateKey);
|
||||
return privateKey;
|
||||
}
|
||||
static generatePrivateKey() {
|
||||
var privateKey = this.generatePresharedKey();
|
||||
this.clamp(privateKey);
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
static encodeBase64(dest, src) {
|
||||
var input = Uint8Array.from([(src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63]);
|
||||
for (var i = 0; i < 4; ++i)
|
||||
dest[i] = input[i] + 65 +
|
||||
(((25 - input[i]) >> 8) & 6) -
|
||||
(((51 - input[i]) >> 8) & 75) -
|
||||
(((61 - input[i]) >> 8) & 15) +
|
||||
(((62 - input[i]) >> 8) & 3);
|
||||
}
|
||||
static encodeBase64(dest, src) {
|
||||
var input = Uint8Array.from([(src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63]);
|
||||
for (var i = 0; i < 4; ++i)
|
||||
dest[i] = input[i] + 65 +
|
||||
(((25 - input[i]) >> 8) & 6) -
|
||||
(((51 - input[i]) >> 8) & 75) -
|
||||
(((61 - input[i]) >> 8) & 15) +
|
||||
(((62 - input[i]) >> 8) & 3);
|
||||
}
|
||||
|
||||
static keyToBase64(key) {
|
||||
var i, base64 = new Uint8Array(44);
|
||||
for (i = 0; i < 32 / 3; ++i)
|
||||
static keyToBase64(key) {
|
||||
var i, base64 = new Uint8Array(44);
|
||||
for (i = 0; i < 32 / 3; ++i)
|
||||
this.encodeBase64(base64.subarray(i * 4), key.subarray(i * 3));
|
||||
this.encodeBase64(base64.subarray(i * 4), Uint8Array.from([key[i * 3 + 0], key[i * 3 + 1], 0]));
|
||||
base64[43] = 61;
|
||||
return String.fromCharCode.apply(null, base64);
|
||||
}
|
||||
base64[43] = 61;
|
||||
return String.fromCharCode.apply(null, base64);
|
||||
}
|
||||
|
||||
static keyFromBase64(encoded) {
|
||||
const binaryStr = atob(encoded);
|
||||
@@ -470,12 +470,12 @@ class Wireguard {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static generateKeypair(secretKey='') {
|
||||
var privateKey = secretKey.length>0 ? this.keyFromBase64(secretKey) : this.generatePrivateKey();
|
||||
static generateKeypair(secretKey = '') {
|
||||
var privateKey = secretKey.length > 0 ? this.keyFromBase64(secretKey) : this.generatePrivateKey();
|
||||
var publicKey = this.generatePublicKey(privateKey);
|
||||
return {
|
||||
publicKey: this.keyToBase64(publicKey),
|
||||
privateKey: secretKey.length>0 ? secretKey : this.keyToBase64(privateKey)
|
||||
privateKey: secretKey.length > 0 ? secretKey : this.keyToBase64(privateKey)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,13 @@
|
||||
<a-form-item label='Timeout'>
|
||||
<a-input-number v-model.number="outbound.settings.timeout" min="0" ></a-input-number>
|
||||
</a-form-item>
|
||||
<a-form-item label='Redirect'>
|
||||
<a-input v-model="outbound.settings.redirect"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='Fragment'>
|
||||
<a-switch :checked="Object.keys(outbound.settings.fragment).length >0" @change="checked => outbound.settings.fragment = checked ? new Outbound.FreedomSettings.Fragment() : {}"></a-switch>
|
||||
<a-switch :checked="Object.keys(outbound.settings.fragment).length >0"
|
||||
@change="checked => outbound.settings.fragment = checked ? new Outbound.FreedomSettings.Fragment() : {}">
|
||||
</a-switch>
|
||||
</a-form-item>
|
||||
<template v-if="Object.keys(outbound.settings.fragment).length >0">
|
||||
<a-form-item label='Packets'>
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
<span>{{ i18n "reset" }}</span>
|
||||
</template> Short ID <a-icon @click="inbound.stream.reality.shortIds = RandomUtil.randomShortId()" type="sync"></a-icon>
|
||||
</template> Short IDs <a-icon @click="inbound.stream.reality.shortIds = RandomUtil.randomShortIds()" type="sync"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model.trim="inbound.stream.reality.shortIds"></a-input>
|
||||
|
||||
@@ -296,18 +296,7 @@
|
||||
</a-row>
|
||||
<a-collapse v-if="fragment" style="margin-top: 14px;">
|
||||
<a-collapse-panel header='{{ i18n "pages.settings.fragmentSett"}}' v-if="fragment">
|
||||
<a-list-item style="padding: 10px 20px">
|
||||
<a-row>
|
||||
<a-col :lg="24" :xl="12">
|
||||
<a-list-item-meta title='Packets'></a-list-item-meta>
|
||||
</a-col>
|
||||
<a-col :lg="24" :xl="12">
|
||||
<a-select v-model="fragmentPackets" style="width: 100%" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option :value="p" :label="p" v-for="p in ['1-1', '1-3', 'tlshello']"> [[ p ]] </a-select-option>
|
||||
</a-select>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-list-item>
|
||||
<setting-list-item style="padding: 10px 20px" type="text" title='Packets' v-model="fragmentPackets" placeholder="1-1 | 1-3 | tlshello | ..."></setting-list-item>
|
||||
<setting-list-item style="padding: 10px 20px" type="text" title='Length' v-model="fragmentLength" placeholder="100-200"></setting-list-item>
|
||||
<setting-list-item style="padding: 10px 20px" type="text" title='Interval' v-model="fragmentInterval" placeholder="10-20"></setting-list-item>
|
||||
</a-collapse-panel>
|
||||
|
||||
@@ -534,11 +534,13 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
|
||||
|
||||
interfaceClients := settings["clients"].([]interface{})
|
||||
var newClients []interface{}
|
||||
needApiDel := false
|
||||
for _, client := range interfaceClients {
|
||||
c := client.(map[string]interface{})
|
||||
c_id := c[client_key].(string)
|
||||
if c_id == clientId {
|
||||
email = c["email"].(string)
|
||||
email, _ = c["email"].(string)
|
||||
needApiDel, _ = c["enable"].(bool)
|
||||
} else {
|
||||
newClients = append(newClients, client)
|
||||
}
|
||||
@@ -557,11 +559,6 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
|
||||
oldInbound.Settings = string(newSettings)
|
||||
|
||||
db := database.GetDB()
|
||||
err = s.DelClientStat(db, email)
|
||||
if err != nil {
|
||||
logger.Error("Delete stats Data Error")
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = s.DelClientIPs(db, email)
|
||||
if err != nil {
|
||||
@@ -569,17 +566,31 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
|
||||
return false, err
|
||||
}
|
||||
needRestart := false
|
||||
|
||||
if len(email) > 0 {
|
||||
s.xrayApi.Init(p.GetAPIPort())
|
||||
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, email)
|
||||
if err1 == nil {
|
||||
logger.Debug("Client deleted by api:", email)
|
||||
needRestart = false
|
||||
} else {
|
||||
logger.Debug("Unable to del client by api:", err1)
|
||||
needRestart = true
|
||||
notDepleted := true
|
||||
err = db.Model(xray.ClientTraffic{}).Select("enable").Where("email = ?", email).First(¬Depleted).Error
|
||||
if err != nil {
|
||||
logger.Error("Get stats error")
|
||||
return false, err
|
||||
}
|
||||
err = s.DelClientStat(db, email)
|
||||
if err != nil {
|
||||
logger.Error("Delete stats Data Error")
|
||||
return false, err
|
||||
}
|
||||
if needApiDel && notDepleted {
|
||||
s.xrayApi.Init(p.GetAPIPort())
|
||||
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, email)
|
||||
if err1 == nil {
|
||||
logger.Debug("Client deleted by api:", email)
|
||||
needRestart = false
|
||||
} else {
|
||||
logger.Debug("Unable to del client by api:", err1)
|
||||
needRestart = true
|
||||
}
|
||||
s.xrayApi.Close()
|
||||
}
|
||||
s.xrayApi.Close()
|
||||
}
|
||||
return needRestart, db.Save(oldInbound).Error
|
||||
}
|
||||
@@ -697,12 +708,14 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
|
||||
needRestart := false
|
||||
if len(oldEmail) > 0 {
|
||||
s.xrayApi.Init(p.GetAPIPort())
|
||||
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
|
||||
if err1 == nil {
|
||||
logger.Debug("Old client deleted by api:", clients[0].Email)
|
||||
} else {
|
||||
logger.Debug("Error in deleting client by api:", err1)
|
||||
needRestart = true
|
||||
if oldClients[clientIndex].Enable {
|
||||
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
|
||||
if err1 == nil {
|
||||
logger.Debug("Old client deleted by api:", clients[0].Email)
|
||||
} else {
|
||||
logger.Debug("Error in deleting client by api:", err1)
|
||||
needRestart = true
|
||||
}
|
||||
}
|
||||
if clients[0].Enable {
|
||||
cipher := ""
|
||||
|
||||
646
web/translation/translate.pt_BR.toml
Normal file
646
web/translation/translate.pt_BR.toml
Normal file
@@ -0,0 +1,646 @@
|
||||
"username" = "Nome de Usuário"
|
||||
"password" = "Senha"
|
||||
"login" = "Entrar"
|
||||
"confirm" = "Confirmar"
|
||||
"cancel" = "Cancelar"
|
||||
"close" = "Fechar"
|
||||
"copy" = "Copiar"
|
||||
"copied" = "Copiado"
|
||||
"download" = "Baixar"
|
||||
"remark" = "Observação"
|
||||
"enable" = "Ativado"
|
||||
"protocol" = "Protocolo"
|
||||
"search" = "Pesquisar"
|
||||
"filter" = "Filtrar"
|
||||
"loading" = "Carregando..."
|
||||
"second" = "Segundo"
|
||||
"minute" = "Minuto"
|
||||
"hour" = "Hora"
|
||||
"day" = "Dia"
|
||||
"check" = "Verificar"
|
||||
"indefinite" = "Indeterminado"
|
||||
"unlimited" = "Ilimitado"
|
||||
"none" = "Nada"
|
||||
"qrCode" = "Código QR"
|
||||
"info" = "Mais Informações"
|
||||
"edit" = "Editar"
|
||||
"delete" = "Excluir"
|
||||
"reset" = "Redefinir"
|
||||
"copySuccess" = "Copiado com Sucesso"
|
||||
"sure" = "Certo"
|
||||
"encryption" = "Criptografia"
|
||||
"transmission" = "Transmissão"
|
||||
"host" = "Servidor"
|
||||
"path" = "Caminho"
|
||||
"camouflage" = "Ofuscação"
|
||||
"status" = "Status"
|
||||
"enabled" = "Ativado"
|
||||
"disabled" = "Desativado"
|
||||
"depleted" = "Encerrado"
|
||||
"depletingSoon" = "Esgotando"
|
||||
"offline" = "Offline"
|
||||
"online" = "Online"
|
||||
"domainName" = "Nome de Domínio"
|
||||
"monitor" = "IP de Escuta"
|
||||
"certificate" = "Certificado Digital"
|
||||
"fail" = " Falhou"
|
||||
"success" = " Com Sucesso"
|
||||
"getVersion" = "Obter Versão"
|
||||
"install" = "Instalar"
|
||||
"clients" = "Clientes"
|
||||
"usage" = "Uso"
|
||||
"secretToken" = "Token Secreto"
|
||||
"remained" = "Restante"
|
||||
"security" = "Segurança"
|
||||
"secAlertTitle" = "Alerta de Segurança"
|
||||
"secAlertSsl" = "Esta conexão não é segura. Evite inserir informações confidenciais até que o TLS seja ativado para proteção de dados."
|
||||
"secAlertConf" = "Algumas configurações estão vulneráveis a ataques. Recomenda-se reforçar os protocolos de segurança para evitar possíveis violações."
|
||||
"secAlertSSL" = "O painel não possui uma conexão segura. Instale o certificado TLS para proteção de dados."
|
||||
"secAlertPanelPort" = "A porta padrão do painel é vulnerável. Configure uma porta aleatória ou específica."
|
||||
"secAlertPanelURI" = "O caminho URI padrão do painel não é seguro. Configure um caminho URI complexo."
|
||||
"secAlertSubURI" = "O caminho URI padrão de inscrição não é seguro. Configure um caminho URI complexo."
|
||||
"secAlertSubJsonURI" = "O caminho URI JSON de inscrição padrão não é seguro. Configure um caminho URI complexo."
|
||||
|
||||
[menu]
|
||||
"dashboard" = "Visão Geral"
|
||||
"inbounds" = "Inbounds"
|
||||
"settings" = "Panel Settings"
|
||||
"xray" = "Xray Configs"
|
||||
"logout" = "Sair"
|
||||
"link" = "Gerenciar"
|
||||
|
||||
[pages.login]
|
||||
"hello" = "Olá"
|
||||
"title" = "Bem-vindo"
|
||||
"loginAgain" = "Sua sessão expirou, faça login novamente"
|
||||
|
||||
[pages.login.toasts]
|
||||
"invalidFormData" = "O formato dos dados de entrada é inválido."
|
||||
"emptyUsername" = "Nome de usuário é obrigatório"
|
||||
"emptyPassword" = "Senha é obrigatória"
|
||||
"wrongUsernameOrPassword" = "Nome de usuário, senha ou segredo inválidos."
|
||||
"successLogin" = "Login realizado com sucesso"
|
||||
|
||||
[pages.index]
|
||||
"title" = "Visão Geral"
|
||||
"memory" = "Memória RAM"
|
||||
"hard" = "Disco"
|
||||
"xrayStatus" = "Xray"
|
||||
"stopXray" = "Parar"
|
||||
"restartXray" = "Reiniciar"
|
||||
"xraySwitch" = "Versão"
|
||||
"xraySwitchClick" = "Escolha a versão para a qual deseja alternar."
|
||||
"xraySwitchClickDesk" = "Escolha com cuidado, pois versões mais antigas podem não ser compatíveis com as configurações atuais."
|
||||
"operationHours" = "Tempo de Atividade"
|
||||
"systemLoad" = "Carga do Sistema"
|
||||
"systemLoadDesc" = "Média de carga do sistema nos últimos 1, 5 e 15 minutos"
|
||||
"connectionTcpCountDesc" = "Total de conexões TCP no sistema"
|
||||
"connectionUdpCountDesc" = "Total de conexões UDP no sistema"
|
||||
"connectionCount" = "Estatísticas de Conexão"
|
||||
"upSpeed" = "Velocidade total de upload no sistema"
|
||||
"downSpeed" = "Velocidade total de download no sistema"
|
||||
"totalSent" = "Dados totais enviados desde a inicialização do sistema"
|
||||
"totalReceive" = "Dados totais recebidos desde a inicialização do sistema"
|
||||
"xraySwitchVersionDialog" = "Alterar Versão do Xray"
|
||||
"xraySwitchVersionDialogDesc" = "Tem certeza de que deseja alterar a versão do Xray para"
|
||||
"dontRefresh" = "Instalação em andamento, por favor não atualize a página"
|
||||
"logs" = "Logs"
|
||||
"config" = "Configuração"
|
||||
"backup" = "Backup e Restauração"
|
||||
"backupTitle" = "Backup e Restauração do Banco de Dados"
|
||||
"backupDescription" = "É recomendado fazer um backup antes de restaurar o banco de dados."
|
||||
"exportDatabase" = "Fazer Backup"
|
||||
"importDatabase" = "Restaurar"
|
||||
|
||||
[pages.inbounds]
|
||||
"title" = "Inbounds"
|
||||
"totalDownUp" = "Total Enviado/Recebido"
|
||||
"totalUsage" = "Uso Total"
|
||||
"inboundCount" = "Total de Inbounds"
|
||||
"operate" = "Menu"
|
||||
"enable" = "Ativado"
|
||||
"remark" = "Observação"
|
||||
"protocol" = "Protocolo"
|
||||
"port" = "Porta"
|
||||
"traffic" = "Tráfego"
|
||||
"details" = "Detalhes"
|
||||
"transportConfig" = "Transporte"
|
||||
"expireDate" = "Duração"
|
||||
"resetTraffic" = "Redefinir Tráfego"
|
||||
"addInbound" = "Adicionar Inbound"
|
||||
"generalActions" = "Ações Gerais"
|
||||
"create" = "Criar"
|
||||
"update" = "Atualizar"
|
||||
"modifyInbound" = "Modificar Inbound"
|
||||
"deleteInbound" = "Excluir Inbound"
|
||||
"deleteInboundContent" = "Tem certeza de que deseja excluir o inbound?"
|
||||
"deleteClient" = "Excluir Cliente"
|
||||
"deleteClientContent" = "Tem certeza de que deseja excluir o cliente?"
|
||||
"resetTrafficContent" = "Tem certeza de que deseja redefinir o tráfego?"
|
||||
"copyLink" = "Copiar URL"
|
||||
"address" = "Endereço"
|
||||
"network" = "Rede"
|
||||
"destinationPort" = "Porta de Destino"
|
||||
"targetAddress" = "Endereço de Destino"
|
||||
"monitorDesc" = "Deixe em branco para ouvir todos os IPs"
|
||||
"meansNoLimit" = " = Ilimitado. (unidade: GB)"
|
||||
"totalFlow" = "Fluxo Total"
|
||||
"leaveBlankToNeverExpire" = "Deixe em branco para nunca expirar"
|
||||
"noRecommendKeepDefault" = "Recomenda-se manter o padrão"
|
||||
"certificatePath" = "Caminho"
|
||||
"certificateContent" = "Conteúdo"
|
||||
"publicKey" = "Chave Pública"
|
||||
"privatekey" = "Chave Privada"
|
||||
"clickOnQRcode" = "Clique no Código QR para Copiar"
|
||||
"client" = "Cliente"
|
||||
"export" = "Exportar Todos os URLs"
|
||||
"clone" = "Clonar"
|
||||
"cloneInbound" = "Clonar"
|
||||
"cloneInboundContent" = "Todas as configurações deste inbound, exceto Porta, IP de Escuta e Clientes, serão aplicadas ao clone."
|
||||
"cloneInboundOk" = "Clonar"
|
||||
"resetAllTraffic" = "Redefinir Tráfego de Todos os Inbounds"
|
||||
"resetAllTrafficTitle" = "Redefinir Tráfego de Todos os Inbounds"
|
||||
"resetAllTrafficContent" = "Tem certeza de que deseja redefinir o tráfego de todos os inbounds?"
|
||||
"resetInboundClientTraffics" = "Redefinir Tráfego dos Clientes"
|
||||
"resetInboundClientTrafficTitle" = "Redefinir Tráfego dos Clientes"
|
||||
"resetInboundClientTrafficContent" = "Tem certeza de que deseja redefinir o tráfego dos clientes deste inbound?"
|
||||
"resetAllClientTraffics" = "Redefinir Tráfego de Todos os Clientes"
|
||||
"resetAllClientTrafficTitle" = "Redefinir Tráfego de Todos os Clientes"
|
||||
"resetAllClientTrafficContent" = "Tem certeza de que deseja redefinir o tráfego de todos os clientes?"
|
||||
"delDepletedClients" = "Excluir Clientes Esgotados"
|
||||
"delDepletedClientsTitle" = "Excluir Clientes Esgotados"
|
||||
"delDepletedClientsContent" = "Tem certeza de que deseja excluir todos os clientes esgotados?"
|
||||
"email" = "Email"
|
||||
"emailDesc" = "Por favor, forneça um endereço de e-mail único."
|
||||
"IPLimit" = "Limite de IP"
|
||||
"IPLimitDesc" = "Desativa o inbound se o número ultrapassar o valor definido. (0 = desativar)"
|
||||
"IPLimitlog" = "Log de IP"
|
||||
"IPLimitlogDesc" = "O histórico de IPs. (para ativar o inbound após a desativação, limpe o log)"
|
||||
"IPLimitlogclear" = "Limpar o Log"
|
||||
"setDefaultCert" = "Definir Certificado pelo Painel"
|
||||
"xtlsDesc" = "O Xray deve ser v1.7.5"
|
||||
"realityDesc" = "O Xray deve ser v1.8.0+"
|
||||
"telegramDesc" = "Por favor, forneça o ID do Chat do Telegram. (use o comando '/id' no bot) ou (@userinfobot)"
|
||||
"subscriptionDesc" = "Para encontrar seu URL de assinatura, navegue até 'Detalhes'. Além disso, você pode usar o mesmo nome para vários clientes."
|
||||
"info" = "Informações"
|
||||
"same" = "Igual"
|
||||
"inboundData" = "Dados do Inbound"
|
||||
"exportInbound" = "Exportar Inbound"
|
||||
"import" = "Importar"
|
||||
"importInbound" = "Importar um Inbound"
|
||||
|
||||
[pages.client]
|
||||
"add" = "Adicionar Cliente"
|
||||
"edit" = "Editar Cliente"
|
||||
"submitAdd" = "Adicionar Cliente"
|
||||
"submitEdit" = "Salvar Alterações"
|
||||
"clientCount" = "Número de Clientes"
|
||||
"bulk" = "Adicionar Vários"
|
||||
"method" = "Método"
|
||||
"first" = "Primeiro"
|
||||
"last" = "Último"
|
||||
"prefix" = "Prefixo"
|
||||
"postfix" = "Sufixo"
|
||||
"delayedStart" = "Iniciar Após Primeiro Uso"
|
||||
"expireDays" = "Duração"
|
||||
"days" = "Dia(s)"
|
||||
"renew" = "Renovação Automática"
|
||||
"renewDesc" = "Renovação automática após expiração. (0 = desativado)(unidade: dia)"
|
||||
|
||||
[pages.inbounds.toasts]
|
||||
"obtain" = "Obter"
|
||||
|
||||
[pages.inbounds.stream.general]
|
||||
"request" = "Requisição"
|
||||
"response" = "Resposta"
|
||||
"name" = "Nome"
|
||||
"value" = "Valor"
|
||||
|
||||
[pages.inbounds.stream.tcp]
|
||||
"version" = "Versão"
|
||||
"method" = "Método"
|
||||
"path" = "Caminho"
|
||||
"status" = "Status"
|
||||
"statusDescription" = "Descrição do Status"
|
||||
"requestHeader" = "Cabeçalho da Requisição"
|
||||
"responseHeader" = "Cabeçalho da Resposta"
|
||||
|
||||
[pages.inbounds.stream.quic]
|
||||
"encryption" = "Criptografia"
|
||||
|
||||
[pages.settings]
|
||||
"title" = "Configurações do Painel"
|
||||
"save" = "Salvar"
|
||||
"infoDesc" = "Toda alteração feita aqui precisa ser salva. Reinicie o painel para aplicar as alterações."
|
||||
"restartPanel" = "Reiniciar Painel"
|
||||
"restartPanelDesc" = "Tem certeza de que deseja reiniciar o painel? Se não conseguir acessar o painel após reiniciar, consulte os logs do painel no servidor."
|
||||
"actions" = "Ações"
|
||||
"resetDefaultConfig" = "Redefinir para Padrão"
|
||||
"panelSettings" = "Geral"
|
||||
"securitySettings" = "Autenticação"
|
||||
"TGBotSettings" = "Bot do Telegram"
|
||||
"panelListeningIP" = "IP de Escuta"
|
||||
"panelListeningIPDesc" = "O endereço IP para o painel web. (deixe em branco para escutar em todos os IPs)"
|
||||
"panelListeningDomain" = "Domínio de Escuta"
|
||||
"panelListeningDomainDesc" = "O nome de domínio para o painel web. (deixe em branco para escutar em todos os domínios e IPs)"
|
||||
"panelPort" = "Porta de Escuta"
|
||||
"panelPortDesc" = "O número da porta para o painel web. (deve ser uma porta não usada)"
|
||||
"publicKeyPath" = "Caminho da Chave Pública"
|
||||
"publicKeyPathDesc" = "O caminho do arquivo de chave pública para o painel web. (começa com ‘/‘)"
|
||||
"privateKeyPath" = "Caminho da Chave Privada"
|
||||
"privateKeyPathDesc" = "O caminho do arquivo de chave privada para o painel web. (começa com ‘/‘)"
|
||||
"panelUrlPath" = "Caminho URI"
|
||||
"panelUrlPathDesc" = "O caminho URI para o painel web. (começa com ‘/‘ e termina com ‘/‘)"
|
||||
"pageSize" = "Tamanho da Paginação"
|
||||
"pageSizeDesc" = "Definir o tamanho da página para a tabela de entradas. (0 = desativado)"
|
||||
"remarkModel" = "Modelo de Observação & Caractere de Separação"
|
||||
"datepicker" = "Tipo de Calendário"
|
||||
"datepickerPlaceholder" = "Selecionar data"
|
||||
"datepickerDescription" = "Tarefas agendadas serão executadas com base neste calendário."
|
||||
"sampleRemark" = "Exemplo de Observação"
|
||||
"oldUsername" = "Nome de Usuário Atual"
|
||||
"currentPassword" = "Senha Atual"
|
||||
"newUsername" = "Novo Nome de Usuário"
|
||||
"newPassword" = "Nova Senha"
|
||||
"telegramBotEnable" = "Ativar Bot do Telegram"
|
||||
"telegramBotEnableDesc" = "Ativa o bot do Telegram."
|
||||
"telegramToken" = "Token do Telegram"
|
||||
"telegramTokenDesc" = "O token do bot do Telegram obtido de '@BotFather'."
|
||||
"telegramProxy" = "Proxy SOCKS"
|
||||
"telegramProxyDesc" = "Ativa o proxy SOCKS5 para conectar ao Telegram. (ajuste as configurações conforme o guia)"
|
||||
"telegramChatId" = "ID de Chat do Administrador"
|
||||
"telegramChatIdDesc" = "O(s) ID(s) de Chat do Administrador no Telegram. (separado por vírgulas)(obtenha aqui @userinfobot) ou (use o comando '/id' no bot)"
|
||||
"telegramNotifyTime" = "Hora da Notificação"
|
||||
"telegramNotifyTimeDesc" = "O horário de notificação do bot do Telegram configurado para relatórios periódicos. (use o formato de tempo do crontab)"
|
||||
"tgNotifyBackup" = "Backup do Banco de Dados"
|
||||
"tgNotifyBackupDesc" = "Enviar arquivo de backup do banco de dados junto com o relatório."
|
||||
"tgNotifyLogin" = "Notificação de Login"
|
||||
"tgNotifyLoginDesc" = "Receba notificações sobre o nome de usuário, endereço IP e horário sempre que alguém tentar fazer login no seu painel web."
|
||||
"sessionMaxAge" = "Duração da Sessão"
|
||||
"sessionMaxAgeDesc" = "A duração pela qual você pode permanecer logado. (unidade: minuto)"
|
||||
"expireTimeDiff" = "Notificação de Expiração"
|
||||
"expireTimeDiffDesc" = "Receba notificações sobre a data de expiração ao atingir esse limite. (unidade: dia)"
|
||||
"trafficDiff" = "Notificação de Limite de Tráfego"
|
||||
"trafficDiffDesc" = "Receba notificações sobre o limite de tráfego ao atingir esse limite. (unidade: GB)"
|
||||
"tgNotifyCpu" = "Notificação de Carga da CPU"
|
||||
"tgNotifyCpuDesc" = "Receba notificações se a carga da CPU ultrapassar esse limite. (unidade: %)"
|
||||
"timeZone" = "Fuso Horário"
|
||||
"timeZoneDesc" = "As tarefas agendadas serão executadas com base nesse fuso horário."
|
||||
"subSettings" = "Assinatura"
|
||||
"subEnable" = "Ativar Serviço de Assinatura"
|
||||
"subEnableDesc" = "Ativa o serviço de assinatura."
|
||||
"subListen" = "IP de Escuta"
|
||||
"subListenDesc" = "O endereço IP para o serviço de assinatura. (deixe em branco para escutar em todos os IPs)"
|
||||
"subPort" = "Porta de Escuta"
|
||||
"subPortDesc" = "O número da porta para o serviço de assinatura. (deve ser uma porta não usada)"
|
||||
"subCertPath" = "Caminho da Chave Pública"
|
||||
"subCertPathDesc" = "O caminho do arquivo de chave pública para o serviço de assinatura. (começa com ‘/‘)"
|
||||
"subKeyPath" = "Caminho da Chave Privada"
|
||||
"subKeyPathDesc" = "O caminho do arquivo de chave privada para o serviço de assinatura. (começa com ‘/‘)"
|
||||
"subPath" = "Caminho URI"
|
||||
"subPathDesc" = "O caminho URI para o serviço de assinatura. (começa com ‘/‘ e termina com ‘/‘)"
|
||||
"subDomain" = "Domínio de Escuta"
|
||||
"subDomainDesc" = "O nome de domínio para o serviço de assinatura. (deixe em branco para escutar em todos os domínios e IPs)"
|
||||
"subUpdates" = "Intervalos de Atualização"
|
||||
"subUpdatesDesc" = "Os intervalos de atualização da URL de assinatura nos aplicativos de cliente. (unidade: hora)"
|
||||
"subEncrypt" = "Codificar"
|
||||
"subEncryptDesc" = "O conteúdo retornado pelo serviço de assinatura será codificado em Base64."
|
||||
"subShowInfo" = "Mostrar Informações de Uso"
|
||||
"subShowInfoDesc" = "O tráfego restante e a data serão exibidos nos aplicativos de cliente."
|
||||
"subURI" = "URI de Proxy Reverso"
|
||||
"subURIDesc" = "O caminho URI da URL de assinatura para uso por trás de proxies."
|
||||
"fragment" = "Fragmentação"
|
||||
"fragmentDesc" = "Ativa a fragmentação para o pacote TLS hello."
|
||||
"fragmentSett" = "Configurações de Fragmentação"
|
||||
"noiseDesc" = "Ativar Noise."
|
||||
"noiseSett" = "Configurações de Noise"
|
||||
"mux" = "Mux"
|
||||
"muxDesc" = "Transmitir múltiplos fluxos de dados independentes dentro de um fluxo de dados estabelecido."
|
||||
"muxSett" = "Configurações de Mux"
|
||||
"direct" = "Conexão Direta"
|
||||
"directDesc" = "Estabelece conexões diretamente com domínios ou intervalos de IP de um país específico."
|
||||
"directSett" = "Opções de Conexão Direta"
|
||||
|
||||
[pages.xray]
|
||||
"title" = "Configurações Xray"
|
||||
"save" = "Salvar"
|
||||
"restart" = "Reiniciar Xray"
|
||||
"basicTemplate" = "Básico"
|
||||
"advancedTemplate" = "Avançado"
|
||||
"generalConfigs" = "Geral"
|
||||
"generalConfigsDesc" = "Essas opções determinam ajustes gerais."
|
||||
"logConfigs" = "Log"
|
||||
"logConfigsDesc" = "Os logs podem afetar a eficiência do servidor. É recomendável habilitá-los com sabedoria apenas se necessário."
|
||||
"blockConfigs" = "Escudo de Proteção"
|
||||
"blockConfigsDesc" = "Essas opções bloqueiam tráfego com base em protocolos e sites específicos solicitados."
|
||||
"blockCountryConfigs" = "Bloquear País"
|
||||
"blockCountryConfigsDesc" = "Essas opções bloqueiam tráfego com base no país solicitado."
|
||||
"directCountryConfigs" = "País Direto"
|
||||
"directCountryConfigsDesc" = "Uma conexão direta garante que o tráfego específico não seja roteado por outro servidor."
|
||||
"ipv4Configs" = "Roteamento IPv4"
|
||||
"ipv4ConfigsDesc" = "Essas opções roteam o tráfego para um destino específico via IPv4."
|
||||
"warpConfigs" = "Roteamento WARP"
|
||||
"warpConfigsDesc" = "Essas opções roteam o tráfego para um destino específico via WARP."
|
||||
"Template" = "Modelo de Configuração Avançada do Xray"
|
||||
"TemplateDesc" = "O arquivo final de configuração do Xray será gerado com base neste modelo."
|
||||
"FreedomStrategy" = "Estratégia do Protocolo Freedom"
|
||||
"FreedomStrategyDesc" = "Definir a estratégia de saída para a rede no Protocolo Freedom."
|
||||
"RoutingStrategy" = "Estratégia Geral de Roteamento"
|
||||
"RoutingStrategyDesc" = "Definir a estratégia geral de roteamento de tráfego para resolver todas as solicitações."
|
||||
"Torrent" = "Bloquear Protocolo BitTorrent"
|
||||
"TorrentDesc" = "Bloqueia o protocolo BitTorrent."
|
||||
"PrivateIp" = "Bloquear Conexão para IPs Privados"
|
||||
"PrivateIpDesc" = "Bloqueia a conexão com faixas de IP privadas."
|
||||
"Ads" = "Bloquear Anúncios"
|
||||
"AdsDesc" = "Bloqueia sites de publicidade."
|
||||
"Family" = "Proteção Familiar"
|
||||
"FamilyDesc" = "Bloqueia conteúdo adulto e sites maliciosos."
|
||||
"Security" = "Escudo de Segurança"
|
||||
"SecurityDesc" = "Bloqueia sites de malware, phishing e mineradores de criptomoedas."
|
||||
"Speedtest" = "Bloquear Speedtest"
|
||||
"SpeedtestDesc" = "Bloqueia a conexão com sites de teste de velocidade."
|
||||
"IRIp" = "Bloquear Conexão para IPs do Irã"
|
||||
"IRIpDesc" = "Bloqueia a conexão com faixas de IP do Irã."
|
||||
"IRDomain" = "Bloquear Conexão para Domínios do Irã"
|
||||
"IRDomainDesc" = "Bloqueia a conexão com domínios do Irã."
|
||||
"ChinaIp" = "Bloquear Conexão para IPs da China"
|
||||
"ChinaIpDesc" = "Bloqueia a conexão com faixas de IP da China."
|
||||
"ChinaDomain" = "Bloquear Conexão para Domínios da China"
|
||||
"ChinaDomainDesc" = "Bloqueia a conexão com domínios da China."
|
||||
"RussiaIp" = "Bloquear Conexão para IPs da Rússia"
|
||||
"RussiaIpDesc" = "Bloqueia a conexão com faixas de IP da Rússia."
|
||||
"RussiaDomain" = "Bloquear Conexão para Domínios da Rússia"
|
||||
"RussiaDomainDesc" = "Bloqueia a conexão com domínios da Rússia."
|
||||
"VNIp" = "Bloquear Conexão para IPs do Vietnã"
|
||||
"VNIpDesc" = "Bloqueia a conexão com faixas de IP do Vietnã."
|
||||
"VNDomain" = "Bloquear Conexão para Domínios do Vietnã"
|
||||
"VNDomainDesc" = "Bloqueia a conexão com domínios do Vietnã."
|
||||
"DirectIRIp" = "Conexão Direta para IPs do Irã"
|
||||
"DirectIRIpDesc" = "Estabelece conexão diretamente com faixas de IP do Irã."
|
||||
"DirectIRDomain" = "Conexão Direta para Domínios do Irã"
|
||||
"DirectIRDomainDesc" = "Estabelece conexão diretamente com domínios do Irã."
|
||||
"DirectChinaIp" = "Conexão Direta para IPs da China"
|
||||
"DirectChinaIpDesc" = "Estabelece conexão diretamente com faixas de IP da China."
|
||||
"DirectChinaDomain" = "Conexão Direta para Domínios da China"
|
||||
"DirectChinaDomainDesc" = "Estabelece conexão diretamente com domínios da China."
|
||||
"DirectRussiaIp" = "Conexão Direta para IPs da Rússia"
|
||||
"DirectRussiaIpDesc" = "Estabelece conexão diretamente com faixas de IP da Rússia."
|
||||
"DirectRussiaDomain" = "Conexão Direta para Domínios da Rússia"
|
||||
"DirectRussiaDomainDesc" = "Estabelece conexão diretamente com domínios da Rússia."
|
||||
"DirectVNIp" = "Conexão Direta para IPs do Vietnã"
|
||||
"DirectVNIpDesc" = "Estabelece conexão diretamente com faixas de IP do Vietnã."
|
||||
"DirectVNDomain" = "Conexão Direta para Domínios do Vietnã"
|
||||
"DirectVNDomainDesc" = "Estabelece conexão diretamente com domínios do Vietnã."
|
||||
"GoogleIPv4" = "Google"
|
||||
"GoogleIPv4Desc" = "Roteia tráfego para o Google via IPv4."
|
||||
"NetflixIPv4" = "Netflix"
|
||||
"NetflixIPv4Desc" = "Roteia tráfego para a Netflix via IPv4."
|
||||
"GoogleWARP" = "Google"
|
||||
"GoogleWARPDesc" = "Adiciona roteamento para o Google via WARP."
|
||||
"OpenAIWARP" = "ChatGPT"
|
||||
"OpenAIWARPDesc" = "Roteia tráfego para o ChatGPT via WARP."
|
||||
"NetflixWARP" = "Netflix"
|
||||
"NetflixWARPDesc" = "Roteia tráfego para a Netflix via WARP."
|
||||
"MetaWARP" = "Meta"
|
||||
"MetaWARPDesc" = "Roteia tráfego para Meta (Instagram, Facebook, WhatsApp, Threads,...) via WARP."
|
||||
"AppleWARP" = "Apple"
|
||||
"AppleWARPDesc" = "Roteia tráfego para a Apple via WARP."
|
||||
"RedditWARP" = "Reddit"
|
||||
"RedditWARPDesc" = "Roteia tráfego para o Reddit via WARP."
|
||||
"SpotifyWARP" = "Spotify"
|
||||
"SpotifyWARPDesc" = "Roteia tráfego para o Spotify via WARP."
|
||||
"IRWARP" = "Domínios do Irã"
|
||||
"IRWARPDesc" = "Roteia tráfego para domínios do Irã via WARP."
|
||||
"Inbounds" = "Inbounds"
|
||||
"InboundsDesc" = "Aceitar clientes específicos."
|
||||
"Outbounds" = "Outbounds"
|
||||
"Balancers" = "Balanceadores"
|
||||
"OutboundsDesc" = "Definir o caminho de saída do tráfego."
|
||||
"Routings" = "Regras de Roteamento"
|
||||
"RoutingsDesc" = "A prioridade de cada regra é importante!"
|
||||
"completeTemplate" = "Todos"
|
||||
"logLevel" = "Nível de Log"
|
||||
"logLevelDesc" = "O nível de log para erros, indicando a informação que precisa ser registrada."
|
||||
"accessLog" = "Log de Acesso"
|
||||
"accessLogDesc" = "O caminho do arquivo para o log de acesso. O valor especial 'none' desativa os logs de acesso."
|
||||
"errorLog" = "Log de Erros"
|
||||
"errorLogDesc" = "O caminho do arquivo para o log de erros. O valor especial 'none' desativa os logs de erro."
|
||||
|
||||
[pages.xray.rules]
|
||||
"first" = "Primeiro"
|
||||
"last" = "Último"
|
||||
"up" = "Cima"
|
||||
"down" = "Baixo"
|
||||
"source" = "Fonte"
|
||||
"dest" = "Destino"
|
||||
"inbound" = "Entrada"
|
||||
"outbound" = "Saída"
|
||||
"balancer" = "Balanceador"
|
||||
"info" = "Info"
|
||||
"add" = "Adicionar Regra"
|
||||
"edit" = "Editar Regra"
|
||||
"useComma" = "Itens separados por vírgula"
|
||||
|
||||
[pages.xray.outbound]
|
||||
"addOutbound" = "Adicionar Saída"
|
||||
"addReverse" = "Adicionar Reverso"
|
||||
"editOutbound" = "Editar Saída"
|
||||
"editReverse" = "Editar Reverso"
|
||||
"tag" = "Tag"
|
||||
"tagDesc" = "Tag Única"
|
||||
"address" = "Endereço"
|
||||
"reverse" = "Reverso"
|
||||
"domain" = "Domínio"
|
||||
"type" = "Tipo"
|
||||
"bridge" = "Ponte"
|
||||
"portal" = "Portal"
|
||||
"intercon" = "Interconexão"
|
||||
"settings" = "Configurações"
|
||||
"accountInfo" = "Informações da Conta"
|
||||
"outboundStatus" = "Status de Saída"
|
||||
"sendThrough" = "Enviar Através de"
|
||||
|
||||
[pages.xray.balancer]
|
||||
"addBalancer" = "Adicionar Balanceador"
|
||||
"editBalancer" = "Editar Balanceador"
|
||||
"balancerStrategy" = "Estratégia"
|
||||
"balancerSelectors" = "Seletores"
|
||||
"tag" = "Tag"
|
||||
"tagDesc" = "Tag Única"
|
||||
"balancerDesc" = "Não é possível usar balancerTag e outboundTag ao mesmo tempo. Se usados simultaneamente, apenas outboundTag funcionará."
|
||||
|
||||
[pages.xray.wireguard]
|
||||
"secretKey" = "Chave Secreta"
|
||||
"publicKey" = "Chave Pública"
|
||||
"allowedIPs" = "IPs Permitidos"
|
||||
"endpoint" = "Ponto Final"
|
||||
"psk" = "Chave Pré-Compartilhada"
|
||||
"domainStrategy" = "Estratégia de Domínio"
|
||||
|
||||
[pages.xray.dns]
|
||||
"enable" = "Ativar DNS"
|
||||
"enableDesc" = "Ativar o servidor DNS integrado"
|
||||
"tag" = "Tag de Entrada DNS"
|
||||
"tagDesc" = "Esta tag estará disponível como uma tag de Entrada nas regras de roteamento."
|
||||
"strategy" = "Estratégia de Consulta"
|
||||
"strategyDesc" = "Estratégia geral para resolver nomes de domínio"
|
||||
"add" = "Adicionar Servidor"
|
||||
"edit" = "Editar Servidor"
|
||||
"domains" = "Domínios"
|
||||
|
||||
[pages.xray.fakedns]
|
||||
"add" = "Adicionar Fake DNS"
|
||||
"edit" = "Editar Fake DNS"
|
||||
"ipPool" = "Sub-rede do Pool de IP"
|
||||
"poolSize" = "Tamanho do Pool"
|
||||
|
||||
[pages.settings.security]
|
||||
"admin" = "Admin"
|
||||
"secret" = "Token Secreto"
|
||||
"loginSecurity" = "Login Seguro"
|
||||
"loginSecurityDesc" = "Adiciona uma camada extra de autenticação para fornecer mais segurança."
|
||||
"secretToken" = "Token Secreto"
|
||||
"secretTokenDesc" = "Por favor, armazene este token em um local seguro. Este token é necessário para o login e não pode ser recuperado."
|
||||
|
||||
[pages.settings.toasts]
|
||||
"modifySettings" = "Modificar Configurações"
|
||||
"getSettings" = "Obter Configurações"
|
||||
"modifyUser" = "Modificar Admin"
|
||||
"originalUserPassIncorrect" = "O nome de usuário ou senha atual é inválido"
|
||||
"userPassMustBeNotEmpty" = "O novo nome de usuário e senha não podem estar vazios"
|
||||
|
||||
[tgbot]
|
||||
"keyboardClosed" = "❌ Teclado personalizado fechado!"
|
||||
"noResult" = "❗ Nenhum resultado!"
|
||||
"noQuery" = "❌ Consulta não encontrada! Por favor, use o comando novamente!"
|
||||
"wentWrong" = "❌ Algo deu errado!"
|
||||
"noIpRecord" = "❗ Nenhum registro de IP!"
|
||||
"noInbounds" = "❗ Nenhuma entrada encontrada!"
|
||||
"unlimited" = "♾ Ilimitado (Reiniciar)"
|
||||
"add" = "Adicionar"
|
||||
"month" = "Mês"
|
||||
"months" = "Meses"
|
||||
"day" = "Dia"
|
||||
"days" = "Dias"
|
||||
"hours" = "Horas"
|
||||
"unknown" = "Desconhecido"
|
||||
"inbounds" = "Entradas"
|
||||
"clients" = "Clientes"
|
||||
"offline" = "🔴 Offline"
|
||||
"online" = "🟢 Online"
|
||||
|
||||
[tgbot.commands]
|
||||
"unknown" = "❗ Comando desconhecido."
|
||||
"pleaseChoose" = "👇 Escolha:\r\n"
|
||||
"help" = "🤖 Bem-vindo a este bot! Ele foi projetado para oferecer dados específicos do painel da web e permite que você faça as modificações necessárias.\r\n\r\n"
|
||||
"start" = "👋 Olá <i>{{ .Firstname }}</i>.\r\n"
|
||||
"welcome" = "🤖 Bem-vindo ao bot de gerenciamento do <b>{{ .Hostname }}</b>.\r\n"
|
||||
"status" = "✅ Bot está OK!"
|
||||
"usage" = "❗ Por favor, forneça um texto para pesquisar!"
|
||||
"getID" = "🆔 Seu ID: <code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "Para pesquisar por um email de cliente:\r\n<code>/usage [Email]</code>\r\n\r\nPara pesquisar por inbounds (com estatísticas do cliente):\r\n<code>/inbound [Remark]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>"
|
||||
"helpClientCommands" = "Para pesquisar por estatísticas, use o seguinte comando:\r\n\r\n<code>/usage [Email]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>"
|
||||
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 A carga da CPU {{ .Percent }}% excede o limite de {{ .Threshold }}%"
|
||||
"selectUserFailed" = "❌ Erro na seleção do usuário!"
|
||||
"userSaved" = "✅ Usuário do Telegram salvo."
|
||||
"loginSuccess" = "✅ Conectado ao painel com sucesso.\r\n"
|
||||
"loginFailed" = "❗️Tentativa de login no painel falhou.\r\n"
|
||||
"report" = "🕰 Relatórios agendados: {{ .RunTime }}\r\n"
|
||||
"datetime" = "⏰ Data&Hora: {{ .DateTime }}\r\n"
|
||||
"hostname" = "💻 Host: {{ .Hostname }}\r\n"
|
||||
"version" = "🚀 Versão 3X-UI: {{ .Version }}\r\n"
|
||||
"xrayVersion" = "📡 Versão Xray: {{ .XrayVersion }}\r\n"
|
||||
"ipv6" = "🌐 IPv6: {{ .IPv6 }}\r\n"
|
||||
"ipv4" = "🌐 IPv4: {{ .IPv4 }}\r\n"
|
||||
"ip" = "🌐 IP: {{ .IP }}\r\n"
|
||||
"ips" = "🔢 IPs:\r\n{{ .IPs }}\r\n"
|
||||
"serverUpTime" = "⏳ Tempo de atividade: {{ .UpTime }} {{ .Unit }}\r\n"
|
||||
"serverLoad" = "📈 Carga do sistema: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n"
|
||||
"serverMemory" = "📋 RAM: {{ .Current }}/{{ .Total }}\r\n"
|
||||
"tcpCount" = "🔹 TCP: {{ .Count }}\r\n"
|
||||
"udpCount" = "🔸 UDP: {{ .Count }}\r\n"
|
||||
"traffic" = "🚦 Tráfego: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n"
|
||||
"xrayStatus" = "ℹ️ Status: {{ .State }}\r\n"
|
||||
"username" = "👤 Nome de usuário: {{ .Username }}\r\n"
|
||||
"password" = "👤 Senha: {{ .Password }}\r\n"
|
||||
"time" = "⏰ Hora: {{ .Time }}\r\n"
|
||||
"inbound" = "📍 Inbound: {{ .Remark }}\r\n"
|
||||
"port" = "🔌 Porta: {{ .Port }}\r\n"
|
||||
"expire" = "📅 Data de expiração: {{ .Time }}\r\n"
|
||||
"expireIn" = "📅 Expira em: {{ .Time }}\r\n"
|
||||
"active" = "💡 Ativo: {{ .Enable }}\r\n"
|
||||
"enabled" = "🚨 Ativado: {{ .Enable }}\r\n"
|
||||
"online" = "🌐 Status da conexão: {{ .Status }}\r\n"
|
||||
"email" = "📧 Email: {{ .Email }}\r\n"
|
||||
"upload" = "🔼 Upload: ↑{{ .Upload }}\r\n"
|
||||
"download" = "🔽 Download: ↓{{ .Download }}\r\n"
|
||||
"total" = "📊 Total: ↑↓{{ .UpDown }} / {{ .Total }}\r\n"
|
||||
"TGUser" = "👤 Usuário do Telegram: {{ .TelegramID }}\r\n"
|
||||
"exhaustedMsg" = "🚨 {{ .Type }} esgotado:\r\n"
|
||||
"exhaustedCount" = "🚨 Contagem de {{ .Type }} esgotado:\r\n"
|
||||
"onlinesCount" = "🌐 Clientes online: {{ .Count }}\r\n"
|
||||
"disabled" = "🛑 Desativado: {{ .Disabled }}\r\n"
|
||||
"depleteSoon" = "🔜 Esgotar em breve: {{ .Deplete }}\r\n\r\n"
|
||||
"backupTime" = "🗄 Hora do backup: {{ .Time }}\r\n"
|
||||
"refreshedOn" = "\r\n📋🔄 Atualizado em: {{ .Time }}\r\n\r\n"
|
||||
"yes" = "✅ Sim"
|
||||
"no" = "❌ Não"
|
||||
|
||||
[tgbot.buttons]
|
||||
"closeKeyboard" = "❌ Fechar teclado"
|
||||
"cancel" = "❌ Cancelar"
|
||||
"cancelReset" = "❌ Cancelar redefinição"
|
||||
"cancelIpLimit" = "❌ Cancelar limite de IP"
|
||||
"confirmResetTraffic" = "✅ Confirmar redefinição de tráfego?"
|
||||
"confirmClearIps" = "✅ Confirmar limpar IPs?"
|
||||
"confirmRemoveTGUser" = "✅ Confirmar remover usuário do Telegram?"
|
||||
"confirmToggle" = "✅ Confirmar ativar/desativar usuário?"
|
||||
"dbBackup" = "Obter backup do DB"
|
||||
"serverUsage" = "Uso do servidor"
|
||||
"getInbounds" = "Obter Inbounds"
|
||||
"depleteSoon" = "Esgotar em breve"
|
||||
"clientUsage" = "Obter uso"
|
||||
"onlines" = "Clientes online"
|
||||
"commands" = "Comandos"
|
||||
"refresh" = "🔄 Atualizar"
|
||||
"clearIPs" = "❌ Limpar IPs"
|
||||
"removeTGUser" = "❌ Remover usuário do Telegram"
|
||||
"selectTGUser" = "👤 Selecionar usuário do Telegram"
|
||||
"selectOneTGUser" = "👤 Selecione um usuário do Telegram:"
|
||||
"resetTraffic" = "📈 Redefinir tráfego"
|
||||
"resetExpire" = "📅 Alterar data de expiração"
|
||||
"ipLog" = "🔢 Log de IP"
|
||||
"ipLimit" = "🔢 Limite de IP"
|
||||
"setTGUser" = "👤 Definir usuário do Telegram"
|
||||
"toggle" = "🔘 Ativar / Desativar"
|
||||
"custom" = "🔢 Personalizado"
|
||||
"confirmNumber" = "✅ Confirmar: {{ .Num }}"
|
||||
"confirmNumberAdd" = "✅ Confirmar adicionar: {{ .Num }}"
|
||||
"limitTraffic" = "🚧 Limite de tráfego"
|
||||
"getBanLogs" = "Obter logs de banimento"
|
||||
"allClients" = "Todos os clientes"
|
||||
|
||||
[tgbot.answers]
|
||||
"successfulOperation" = "✅ Operação bem-sucedida!"
|
||||
"errorOperation" = "❗ Erro na operação."
|
||||
"getInboundsFailed" = "❌ Falha ao obter inbounds."
|
||||
"getClientsFailed" = "❌ Falha ao obter clientes."
|
||||
"canceled" = "❌ {{ .Email }}: Operação cancelada."
|
||||
"clientRefreshSuccess" = "✅ {{ .Email }}: Cliente atualizado com sucesso."
|
||||
"IpRefreshSuccess" = "✅ {{ .Email }}: IPs atualizados com sucesso."
|
||||
"TGIdRefreshSuccess" = "✅ {{ .Email }}: Usuário do Telegram do cliente atualizado com sucesso."
|
||||
"resetTrafficSuccess" = "✅ {{ .Email }}: Tráfego redefinido com sucesso."
|
||||
"setTrafficLimitSuccess" = "✅ {{ .Email }}: Limite de tráfego salvo com sucesso."
|
||||
"expireResetSuccess" = "✅ {{ .Email }}: Dias de expiração redefinidos com sucesso."
|
||||
"resetIpSuccess" = "✅ {{ .Email }}: Limite de IP {{ .Count }} salvo com sucesso."
|
||||
"clearIpSuccess" = "✅ {{ .Email }}: IPs limpos com sucesso."
|
||||
"getIpLog" = "✅ {{ .Email }}: Obter log de IP."
|
||||
"getUserInfo" = "✅ {{ .Email }}: Obter informações do usuário do Telegram."
|
||||
"removedTGUserSuccess" = "✅ {{ .Email }}: Usuário do Telegram removido com sucesso."
|
||||
"enableSuccess" = "✅ {{ .Email }}: Ativado com sucesso."
|
||||
"disableSuccess" = "✅ {{ .Email }}: Desativado com sucesso."
|
||||
"askToAddUserId" = "Sua configuração não foi encontrada!\r\nPeça ao seu administrador para usar seu Telegram ChatID em suas configurações.\r\n\r\nSeu ChatID: <code>{{ .TgUserID }}</code>"
|
||||
"chooseClient" = "Escolha um cliente para Inbound {{ .Inbound }}"
|
||||
"chooseInbound" = "Escolha um Inbound"
|
||||
Reference in New Issue
Block a user