diff --git a/web/service/inbound.go b/web/service/inbound.go index 59dc9e65..5153b700 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -498,17 +498,23 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, logger.Debug("Old inbound deleted by api:", tag) } if inbound.Enable { - inboundJson, err2 := json.MarshalIndent(oldInbound.GenXrayInboundConfig(), "", " ") + runtimeInbound, err2 := s.buildRuntimeInboundForAPI(tx, oldInbound) if err2 != nil { - logger.Debug("Unable to marshal updated inbound config:", err2) + logger.Debug("Unable to prepare runtime inbound config:", err2) needRestart = true } else { - err2 = s.xrayApi.AddInbound(inboundJson) - if err2 == nil { - logger.Debug("Updated inbound added by api:", oldInbound.Tag) - } else { - logger.Debug("Unable to update inbound by api:", err2) + inboundJson, err2 := json.MarshalIndent(runtimeInbound.GenXrayInboundConfig(), "", " ") + if err2 != nil { + logger.Debug("Unable to marshal updated inbound config:", err2) needRestart = true + } else { + err2 = s.xrayApi.AddInbound(inboundJson) + if err2 == nil { + logger.Debug("Updated inbound added by api:", oldInbound.Tag) + } else { + logger.Debug("Unable to update inbound by api:", err2) + needRestart = true + } } } } @@ -517,6 +523,65 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, return inbound, needRestart, tx.Save(oldInbound).Error } +func (s *InboundService) buildRuntimeInboundForAPI(tx *gorm.DB, inbound *model.Inbound) (*model.Inbound, error) { + if inbound == nil { + return nil, fmt.Errorf("inbound is nil") + } + + runtimeInbound := *inbound + settings := map[string]any{} + if err := json.Unmarshal([]byte(inbound.Settings), &settings); err != nil { + return nil, err + } + + clients, ok := settings["clients"].([]any) + if !ok { + return &runtimeInbound, nil + } + + var clientStats []xray.ClientTraffic + err := tx.Model(xray.ClientTraffic{}). + Where("inbound_id = ?", inbound.Id). + Select("email", "enable"). + Find(&clientStats).Error + if err != nil { + return nil, err + } + + enableMap := make(map[string]bool, len(clientStats)) + for _, clientTraffic := range clientStats { + enableMap[clientTraffic.Email] = clientTraffic.Enable + } + + finalClients := make([]any, 0, len(clients)) + for _, client := range clients { + c, ok := client.(map[string]any) + if !ok { + continue + } + + email, _ := c["email"].(string) + if enable, exists := enableMap[email]; exists && !enable { + continue + } + + if manualEnable, ok := c["enable"].(bool); ok && !manualEnable { + continue + } + + finalClients = append(finalClients, c) + } + + settings["clients"] = finalClients + modifiedSettings, err := json.MarshalIndent(settings, "", " ") + if err != nil { + return nil, err + } + runtimeInbound.Settings = string(modifiedSettings) + + return &runtimeInbound, nil +} + func (s *InboundService) updateClientTraffics(tx *gorm.DB, oldInbound *model.Inbound, newInbound *model.Inbound) error { oldClients, err := s.GetClients(oldInbound) if err != nil {