diff options
Diffstat (limited to 'web/service/xray.go')
| -rw-r--r-- | web/service/xray.go | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/web/service/xray.go b/web/service/xray.go new file mode 100644 index 00000000..37fd3b05 --- /dev/null +++ b/web/service/xray.go @@ -0,0 +1,163 @@ +package service + +import ( + "encoding/json" + "errors" + "sync" + "x-ui/logger" + "x-ui/xray" + "go.uber.org/atomic" +) + +var p *xray.Process +var lock sync.Mutex +var isNeedXrayRestart atomic.Bool +var result string + +type XrayService struct { + inboundService InboundService + settingService SettingService +} + +func (s *XrayService) IsXrayRunning() bool { + return p != nil && p.IsRunning() +} + +func (s *XrayService) GetXrayErr() error { + if p == nil { + return nil + } + return p.GetErr() +} + +func (s *XrayService) GetXrayResult() string { + if result != "" { + return result + } + if s.IsXrayRunning() { + return "" + } + if p == nil { + return "" + } + result = p.GetResult() + return result +} + +func (s *XrayService) GetXrayVersion() string { + if p == nil { + return "Unknown" + } + return p.GetVersion() +} +func RemoveIndex(s []interface{}, index int) []interface{} { + return append(s[:index], s[index+1:]...) +} + +func (s *XrayService) GetXrayConfig() (*xray.Config, error) { + templateConfig, err := s.settingService.GetXrayConfigTemplate() + if err != nil { + return nil, err + } + + xrayConfig := &xray.Config{} + err = json.Unmarshal([]byte(templateConfig), xrayConfig) + if err != nil { + return nil, err + } + + s.inboundService.DisableInvalidClients() + + inbounds, err := s.inboundService.GetAllInbounds() + if err != nil { + return nil, err + } + for _, inbound := range inbounds { + if !inbound.Enable { + continue + } + // get settings clients + settings := map[string]interface{}{} + json.Unmarshal([]byte(inbound.Settings), &settings) + clients, ok := settings["clients"].([]interface{}) + if ok { + // check users active or not + + clientStats := inbound.ClientStats + for _, clientTraffic := range clientStats { + + for index, client := range clients { + c := client.(map[string]interface{}) + if c["email"] == clientTraffic.Email { + if ! clientTraffic.Enable { + clients = RemoveIndex(clients,index) + logger.Info("Remove Inbound User",c["email"] ,"due the expire or traffic limit") + + } + + } + } + + + } + settings["clients"] = clients + modifiedSettings, err := json.Marshal(settings) + if err != nil { + return nil, err + } + + inbound.Settings = string(modifiedSettings) + } + inboundConfig := inbound.GenXrayInboundConfig() + xrayConfig.InboundConfigs = append(xrayConfig.InboundConfigs, *inboundConfig) + } + return xrayConfig, nil +} + +func (s *XrayService) GetXrayTraffic() ([]*xray.Traffic, []*xray.ClientTraffic, error) { + if !s.IsXrayRunning() { + return nil, nil, errors.New("xray is not running") + } + return p.GetTraffic(true) +} + +func (s *XrayService) RestartXray(isForce bool) error { + lock.Lock() + defer lock.Unlock() + logger.Debug("restart xray, force:", isForce) + + xrayConfig, err := s.GetXrayConfig() + if err != nil { + return err + } + + if p != nil && p.IsRunning() { + if !isForce && p.GetConfig().Equals(xrayConfig) { + logger.Debug("not need to restart xray") + return nil + } + p.Stop() + } + + p = xray.NewProcess(xrayConfig) + result = "" + return p.Start() +} + +func (s *XrayService) StopXray() error { + lock.Lock() + defer lock.Unlock() + logger.Debug("stop xray") + if s.IsXrayRunning() { + return p.Stop() + } + return errors.New("xray is not running") +} + +func (s *XrayService) SetToNeedRestart() { + isNeedXrayRestart.Store(true) +} + +func (s *XrayService) IsNeedRestartAndSetFalse() bool { + return isNeedXrayRestart.CAS(true, false) +} |
