|
@@ -263,7 +263,18 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
|
|
|
|
|
|
tag := oldInbound.Tag
|
|
|
|
|
|
- err = s.updateClientTraffics(oldInbound, inbound)
|
|
|
+ db := database.GetDB()
|
|
|
+ tx := db.Begin()
|
|
|
+
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ tx.Rollback()
|
|
|
+ } else {
|
|
|
+ tx.Commit()
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ err = s.updateClientTraffics(tx, oldInbound, inbound)
|
|
|
if err != nil {
|
|
|
return inbound, false, err
|
|
|
}
|
|
@@ -304,11 +315,10 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
|
|
|
}
|
|
|
s.xrayApi.Close()
|
|
|
|
|
|
- db := database.GetDB()
|
|
|
- return inbound, needRestart, db.Save(oldInbound).Error
|
|
|
+ return inbound, needRestart, tx.Save(oldInbound).Error
|
|
|
}
|
|
|
|
|
|
-func (s *InboundService) updateClientTraffics(oldInbound *model.Inbound, newInbound *model.Inbound) error {
|
|
|
+func (s *InboundService) updateClientTraffics(tx *gorm.DB, oldInbound *model.Inbound, newInbound *model.Inbound) error {
|
|
|
oldClients, err := s.GetClients(oldInbound)
|
|
|
if err != nil {
|
|
|
return err
|
|
@@ -318,17 +328,6 @@ func (s *InboundService) updateClientTraffics(oldInbound *model.Inbound, newInbo
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- db := database.GetDB()
|
|
|
- tx := db.Begin()
|
|
|
-
|
|
|
- defer func() {
|
|
|
- if err != nil {
|
|
|
- tx.Rollback()
|
|
|
- } else {
|
|
|
- tx.Commit()
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
var emailExists bool
|
|
|
|
|
|
for _, oldClient := range oldClients {
|
|
@@ -601,7 +600,7 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
|
|
|
|
|
|
if len(clients[0].Email) > 0 {
|
|
|
if len(oldEmail) > 0 {
|
|
|
- err = s.UpdateClientStat(oldEmail, &clients[0])
|
|
|
+ err = s.UpdateClientStat(tx, oldEmail, &clients[0])
|
|
|
if err != nil {
|
|
|
return false, err
|
|
|
}
|
|
@@ -676,6 +675,13 @@ func (s *InboundService) AddTraffic(inboundTraffics []*xray.Traffic, clientTraff
|
|
|
return err, false
|
|
|
}
|
|
|
|
|
|
+ needRestart0, count, err := s.autoRenewClients(tx)
|
|
|
+ if err != nil {
|
|
|
+ logger.Warning("Error in renew clients:", err)
|
|
|
+ } else if count > 0 {
|
|
|
+ logger.Debugf("%v clients renewed", count)
|
|
|
+ }
|
|
|
+
|
|
|
needRestart1, count, err := s.disableInvalidClients(tx)
|
|
|
if err != nil {
|
|
|
logger.Warning("Error in disabling invalid clients:", err)
|
|
@@ -689,7 +695,7 @@ func (s *InboundService) AddTraffic(inboundTraffics []*xray.Traffic, clientTraff
|
|
|
} else if count > 0 {
|
|
|
logger.Debugf("%v inbounds disabled", count)
|
|
|
}
|
|
|
- return nil, (needRestart1 || needRestart2)
|
|
|
+ return nil, (needRestart0 || needRestart1 || needRestart2)
|
|
|
}
|
|
|
|
|
|
func (s *InboundService) addInboundTraffic(tx *gorm.DB, traffics []*xray.Traffic) error {
|
|
@@ -823,6 +829,102 @@ func (s *InboundService) adjustTraffics(tx *gorm.DB, dbClientTraffics []*xray.Cl
|
|
|
return dbClientTraffics, nil
|
|
|
}
|
|
|
|
|
|
+func (s *InboundService) autoRenewClients(tx *gorm.DB) (bool, int64, error) {
|
|
|
+ // check for time expired
|
|
|
+ var traffics []*xray.ClientTraffic
|
|
|
+ now := time.Now().Unix() * 1000
|
|
|
+ var err, err1 error
|
|
|
+
|
|
|
+ err = tx.Model(xray.ClientTraffic{}).Where("reset > 0 and expiry_time > 0 and expiry_time <= ?", now).Find(&traffics).Error
|
|
|
+ if err != nil {
|
|
|
+ return false, 0, err
|
|
|
+ }
|
|
|
+ // return if there is no client to renew
|
|
|
+ if len(traffics) == 0 {
|
|
|
+ return false, 0, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ var inbound_ids []int
|
|
|
+ var inbounds []*model.Inbound
|
|
|
+ needRestart := false
|
|
|
+ var clientsToAdd []struct {
|
|
|
+ protocol string
|
|
|
+ tag string
|
|
|
+ client map[string]interface{}
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, traffic := range traffics {
|
|
|
+ inbound_ids = append(inbound_ids, traffic.InboundId)
|
|
|
+ }
|
|
|
+ err = tx.Model(model.Inbound{}).Where("id IN ?", inbound_ids).Find(&inbounds).Error
|
|
|
+ if err != nil {
|
|
|
+ return false, 0, err
|
|
|
+ }
|
|
|
+ for inbound_index := range inbounds {
|
|
|
+ settings := map[string]interface{}{}
|
|
|
+ json.Unmarshal([]byte(inbounds[inbound_index].Settings), &settings)
|
|
|
+ clients := settings["clients"].([]interface{})
|
|
|
+ for client_index := range clients {
|
|
|
+ c := clients[client_index].(map[string]interface{})
|
|
|
+ for traffic_index, traffic := range traffics {
|
|
|
+ if traffic.Email == c["email"].(string) {
|
|
|
+ newExpiryTime := traffic.ExpiryTime
|
|
|
+ for newExpiryTime < now {
|
|
|
+ newExpiryTime += (int64(traffic.Reset) * 86400000)
|
|
|
+ }
|
|
|
+ c["expiryTime"] = newExpiryTime
|
|
|
+ traffics[traffic_index].ExpiryTime = newExpiryTime
|
|
|
+ traffics[traffic_index].Down = 0
|
|
|
+ traffics[traffic_index].Up = 0
|
|
|
+ if !traffic.Enable {
|
|
|
+ traffics[traffic_index].Enable = true
|
|
|
+ clientsToAdd = append(clientsToAdd,
|
|
|
+ struct {
|
|
|
+ protocol string
|
|
|
+ tag string
|
|
|
+ client map[string]interface{}
|
|
|
+ }{
|
|
|
+ protocol: string(inbounds[inbound_index].Protocol),
|
|
|
+ tag: inbounds[inbound_index].Tag,
|
|
|
+ client: c,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ clients[client_index] = interface{}(c)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ settings["clients"] = clients
|
|
|
+ newSettings, err := json.MarshalIndent(settings, "", " ")
|
|
|
+ if err != nil {
|
|
|
+ return false, 0, err
|
|
|
+ }
|
|
|
+ inbounds[inbound_index].Settings = string(newSettings)
|
|
|
+ }
|
|
|
+ err = tx.Save(inbounds).Error
|
|
|
+ if err != nil {
|
|
|
+ return false, 0, err
|
|
|
+ }
|
|
|
+ err = tx.Save(traffics).Error
|
|
|
+ if err != nil {
|
|
|
+ return false, 0, err
|
|
|
+ }
|
|
|
+ if p != nil {
|
|
|
+ err1 = s.xrayApi.Init(p.GetAPIPort())
|
|
|
+ if err1 != nil {
|
|
|
+ return true, int64(len(traffics)), nil
|
|
|
+ }
|
|
|
+ for _, clientToAdd := range clientsToAdd {
|
|
|
+ err1 = s.xrayApi.AddUser(clientToAdd.protocol, clientToAdd.tag, clientToAdd.client)
|
|
|
+ if err1 != nil {
|
|
|
+ needRestart = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ s.xrayApi.Close()
|
|
|
+ }
|
|
|
+ return needRestart, int64(len(traffics)), nil
|
|
|
+}
|
|
|
+
|
|
|
func (s *InboundService) disableInvalidInbounds(tx *gorm.DB) (bool, int64, error) {
|
|
|
now := time.Now().Unix() * 1000
|
|
|
needRestart := false
|
|
@@ -916,6 +1018,7 @@ func (s *InboundService) AddClientStat(tx *gorm.DB, inboundId int, client *model
|
|
|
clientTraffic.Enable = true
|
|
|
clientTraffic.Up = 0
|
|
|
clientTraffic.Down = 0
|
|
|
+ clientTraffic.Reset = client.Reset
|
|
|
result := tx.Create(&clientTraffic)
|
|
|
err := result.Error
|
|
|
if err != nil {
|
|
@@ -924,16 +1027,15 @@ func (s *InboundService) AddClientStat(tx *gorm.DB, inboundId int, client *model
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *InboundService) UpdateClientStat(email string, client *model.Client) error {
|
|
|
- db := database.GetDB()
|
|
|
-
|
|
|
- result := db.Model(xray.ClientTraffic{}).
|
|
|
+func (s *InboundService) UpdateClientStat(tx *gorm.DB, email string, client *model.Client) error {
|
|
|
+ result := tx.Model(xray.ClientTraffic{}).
|
|
|
Where("email = ?", email).
|
|
|
Updates(map[string]interface{}{
|
|
|
"enable": true,
|
|
|
"email": client.Email,
|
|
|
"total": client.TotalGB,
|
|
|
- "expiry_time": client.ExpiryTime})
|
|
|
+ "expiry_time": client.ExpiryTime,
|
|
|
+ "reset": client.Reset})
|
|
|
err := result.Error
|
|
|
if err != nil {
|
|
|
return err
|
|
@@ -1429,7 +1531,7 @@ func (s *InboundService) DelDepletedClients(id int) (err error) {
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
- whereText := "inbound_id "
|
|
|
+ whereText := "reset = 0 and inbound_id "
|
|
|
if id < 0 {
|
|
|
whereText += "> ?"
|
|
|
} else {
|