mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-03-01 01:20:49 +03:00
Show client info in the remark (#765)
This commit is contained in:
parent
6beb19b945
commit
64d17bee70
1
go.mod
1
go.mod
@ -14,6 +14,7 @@ require (
|
|||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/shirou/gopsutil/v3 v3.23.6
|
github.com/shirou/gopsutil/v3 v3.23.6
|
||||||
github.com/xtls/xray-core v1.8.3
|
github.com/xtls/xray-core v1.8.3
|
||||||
|
github.com/yaa110/go-persian-calendar v1.1.5
|
||||||
go.uber.org/atomic v1.11.0
|
go.uber.org/atomic v1.11.0
|
||||||
golang.org/x/text v0.11.0
|
golang.org/x/text v0.11.0
|
||||||
google.golang.org/grpc v1.56.2
|
google.golang.org/grpc v1.56.2
|
||||||
|
2
go.sum
2
go.sum
@ -160,6 +160,8 @@ github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983 h1:AMyzgjkh54WocjQSlC
|
|||||||
github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983/go.mod h1:rkuAY1S9F8eI8gDiPDYvACE8e2uwkyg8qoOTuwWov7Y=
|
github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983/go.mod h1:rkuAY1S9F8eI8gDiPDYvACE8e2uwkyg8qoOTuwWov7Y=
|
||||||
github.com/xtls/xray-core v1.8.3 h1:lxaVklPjLKqUU4ua4qH8SBaRcAaNHlH+LmXOx0U/Ejg=
|
github.com/xtls/xray-core v1.8.3 h1:lxaVklPjLKqUU4ua4qH8SBaRcAaNHlH+LmXOx0U/Ejg=
|
||||||
github.com/xtls/xray-core v1.8.3/go.mod h1:i7t4JFnq828P2+XK0XjGQ8W9x78iu+EJ7jI4l3sonIw=
|
github.com/xtls/xray-core v1.8.3/go.mod h1:i7t4JFnq828P2+XK0XjGQ8W9x78iu+EJ7jI4l3sonIw=
|
||||||
|
github.com/yaa110/go-persian-calendar v1.1.5 h1:EUipRRhzE6bR2NZaSyZ5BEOP46LGbUjzQgdC+Ivrbe4=
|
||||||
|
github.com/yaa110/go-persian-calendar v1.1.5/go.mod h1:qtnmHCS9u1EiwzzSCSttGoxD5NfV9ZMzymxFCBYmqfg=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||||
|
@ -3,6 +3,8 @@ package sub
|
|||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
ptime "github.com/yaa110/go-persian-calendar"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"x-ui/database"
|
"x-ui/database"
|
||||||
@ -10,7 +12,7 @@ import (
|
|||||||
"x-ui/logger"
|
"x-ui/logger"
|
||||||
"x-ui/web/service"
|
"x-ui/web/service"
|
||||||
"x-ui/xray"
|
"x-ui/xray"
|
||||||
|
"x-ui/util/common"
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -55,7 +57,7 @@ func (s *SubService) GetSubs(subId string, host string) ([]string, []string, err
|
|||||||
}
|
}
|
||||||
for _, client := range clients {
|
for _, client := range clients {
|
||||||
if client.Enable && client.SubID == subId {
|
if client.Enable && client.SubID == subId {
|
||||||
link := s.getLink(inbound, client.Email)
|
link := s.getLink(inbound, client.Email,client.ExpiryTime)
|
||||||
result = append(result, link)
|
result = append(result, link)
|
||||||
clientTraffics = append(clientTraffics, s.getClientTraffics(inbound.ClientStats, client.Email))
|
clientTraffics = append(clientTraffics, s.getClientTraffics(inbound.ClientStats, client.Email))
|
||||||
}
|
}
|
||||||
@ -121,25 +123,29 @@ func (s *SubService) getFallbackMaster(dest string) (*model.Inbound, error) {
|
|||||||
return inbound, nil
|
return inbound, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SubService) getLink(inbound *model.Inbound, email string) string {
|
func (s *SubService) getLink(inbound *model.Inbound, email string, expiryTime int64) string {
|
||||||
switch inbound.Protocol {
|
switch inbound.Protocol {
|
||||||
case "vmess":
|
case "vmess":
|
||||||
return s.genVmessLink(inbound, email)
|
return s.genVmessLink(inbound, email, expiryTime)
|
||||||
case "vless":
|
case "vless":
|
||||||
return s.genVlessLink(inbound, email)
|
return s.genVlessLink(inbound, email, expiryTime)
|
||||||
case "trojan":
|
case "trojan":
|
||||||
return s.genTrojanLink(inbound, email)
|
return s.genTrojanLink(inbound, email, expiryTime)
|
||||||
case "shadowsocks":
|
case "shadowsocks":
|
||||||
return s.genShadowsocksLink(inbound, email)
|
return s.genShadowsocksLink(inbound, email, expiryTime)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
|
func (s *SubService) genVmessLink(inbound *model.Inbound, email string, expiryTime int64) string {
|
||||||
if inbound.Protocol != model.VMess {
|
if inbound.Protocol != model.VMess {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
remark := fmt.Sprintf("%s-%s", inbound.Remark, email)
|
|
||||||
|
remainedTraffic := s.getRemainedTraffic(email)
|
||||||
|
expiryTimeString := getExpiryTime(expiryTime)
|
||||||
|
|
||||||
|
remark := fmt.Sprintf("%s: %s- %s", email, remainedTraffic, expiryTimeString)
|
||||||
obj := map[string]interface{}{
|
obj := map[string]interface{}{
|
||||||
"v": "2",
|
"v": "2",
|
||||||
"ps": remark,
|
"ps": remark,
|
||||||
@ -256,7 +262,7 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
|
|||||||
return "vmess://" + base64.StdEncoding.EncodeToString(jsonStr)
|
return "vmess://" + base64.StdEncoding.EncodeToString(jsonStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
|
func (s *SubService) genVlessLink(inbound *model.Inbound, email string, expiryTime int64) string {
|
||||||
address := s.address
|
address := s.address
|
||||||
if inbound.Protocol != model.VLESS {
|
if inbound.Protocol != model.VLESS {
|
||||||
return ""
|
return ""
|
||||||
@ -449,7 +455,10 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
|
|||||||
// Set the new query values on the URL
|
// Set the new query values on the URL
|
||||||
url.RawQuery = q.Encode()
|
url.RawQuery = q.Encode()
|
||||||
|
|
||||||
remark := fmt.Sprintf("%s-%s", inbound.Remark, email)
|
remainedTraffic := s.getRemainedTraffic(email)
|
||||||
|
expiryTimeString := getExpiryTime(expiryTime)
|
||||||
|
|
||||||
|
remark := fmt.Sprintf("%s: %s- %s", email, remainedTraffic, expiryTimeString)
|
||||||
|
|
||||||
if len(domains) > 0 {
|
if len(domains) > 0 {
|
||||||
links := ""
|
links := ""
|
||||||
@ -468,7 +477,7 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
|
|||||||
return url.String()
|
return url.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string {
|
func (s *SubService) genTrojanLink(inbound *model.Inbound, email string, expiryTime int64) string {
|
||||||
address := s.address
|
address := s.address
|
||||||
if inbound.Protocol != model.Trojan {
|
if inbound.Protocol != model.Trojan {
|
||||||
return ""
|
return ""
|
||||||
@ -658,7 +667,10 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
|
|||||||
// Set the new query values on the URL
|
// Set the new query values on the URL
|
||||||
url.RawQuery = q.Encode()
|
url.RawQuery = q.Encode()
|
||||||
|
|
||||||
remark := fmt.Sprintf("%s-%s", inbound.Remark, email)
|
remainedTraffic := s.getRemainedTraffic(email)
|
||||||
|
expiryTimeString := getExpiryTime(expiryTime)
|
||||||
|
|
||||||
|
remark := fmt.Sprintf("%s: %s- %s", email, remainedTraffic, expiryTimeString)
|
||||||
|
|
||||||
if len(domains) > 0 {
|
if len(domains) > 0 {
|
||||||
links := ""
|
links := ""
|
||||||
@ -678,7 +690,7 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
|
|||||||
return url.String()
|
return url.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) string {
|
func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string, expiryTime int64) string {
|
||||||
address := s.address
|
address := s.address
|
||||||
if inbound.Protocol != model.Shadowsocks {
|
if inbound.Protocol != model.Shadowsocks {
|
||||||
return ""
|
return ""
|
||||||
@ -697,7 +709,11 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
encPart := fmt.Sprintf("%s:%s:%s", method, inboundPassword, clients[clientIndex].Password)
|
encPart := fmt.Sprintf("%s:%s:%s", method, inboundPassword, clients[clientIndex].Password)
|
||||||
remark := fmt.Sprintf("%s-%s", inbound.Remark, clients[clientIndex].Email)
|
|
||||||
|
remainedTraffic := s.getRemainedTraffic(clients[clientIndex].Email)
|
||||||
|
expiryTimeString := getExpiryTime(expiryTime)
|
||||||
|
|
||||||
|
remark := fmt.Sprintf("%s: %s- %s", clients[clientIndex].Email, remainedTraffic ,expiryTimeString)
|
||||||
return fmt.Sprintf("ss://%s@%s:%d#%s", base64.StdEncoding.EncodeToString([]byte(encPart)), address, inbound.Port, remark)
|
return fmt.Sprintf("ss://%s@%s:%d#%s", base64.StdEncoding.EncodeToString([]byte(encPart)), address, inbound.Port, remark)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,3 +758,38 @@ func searchHost(headers interface{}) string {
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getExpiryTime(expiryTime int64) string{
|
||||||
|
now := time.Now().Unix()
|
||||||
|
expiryString := ""
|
||||||
|
|
||||||
|
timeDifference := expiryTime/1000 - now
|
||||||
|
|
||||||
|
if expiryTime == 0 {
|
||||||
|
expiryString = "♾ ⏳"
|
||||||
|
} else if timeDifference > 172800 {
|
||||||
|
expiryString = fmt.Sprintf("%s ⏳", ptime.Unix((expiryTime / 1000), 0).Format("yy-MM-dd hh:mm"))
|
||||||
|
} else if expiryTime < 0 {
|
||||||
|
expiryString = fmt.Sprintf("%d ⏳", expiryTime/-86400000)
|
||||||
|
} else {
|
||||||
|
expiryString = fmt.Sprintf("%s %d ⏳", "ساعت", timeDifference/3600)
|
||||||
|
}
|
||||||
|
|
||||||
|
return expiryString
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SubService) getRemainedTraffic( email string) string{
|
||||||
|
traffic, err := s.inboundService.GetClientTrafficByEmail(email)
|
||||||
|
if err != nil {
|
||||||
|
logger.Warning(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
remainedTraffic := ""
|
||||||
|
if traffic.Total == 0 {
|
||||||
|
remainedTraffic = "♾ 📊"
|
||||||
|
} else {
|
||||||
|
remainedTraffic = fmt.Sprintf("%s%s" ,common.FormatTraffic(traffic.Total-(traffic.Up+traffic.Down)), "📊")
|
||||||
|
}
|
||||||
|
|
||||||
|
return remainedTraffic
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user