|
@@ -3,6 +3,7 @@ package service
|
|
|
import (
|
|
|
"encoding/json"
|
|
|
"errors"
|
|
|
+ "runtime"
|
|
|
"sync"
|
|
|
|
|
|
"x-ui/logger"
|
|
@@ -14,7 +15,8 @@ import (
|
|
|
var (
|
|
|
p *xray.Process
|
|
|
lock sync.Mutex
|
|
|
- isNeedXrayRestart atomic.Bool
|
|
|
+ isNeedXrayRestart atomic.Bool // Indicates that restart was requested for Xray
|
|
|
+ isManuallyStopped atomic.Bool // Indicates that Xray was stopped manually from the panel
|
|
|
result string
|
|
|
)
|
|
|
|
|
@@ -32,7 +34,16 @@ func (s *XrayService) GetXrayErr() error {
|
|
|
if p == nil {
|
|
|
return nil
|
|
|
}
|
|
|
- return p.GetErr()
|
|
|
+
|
|
|
+ err := p.GetErr()
|
|
|
+
|
|
|
+ if runtime.GOOS == "windows" && err.Error() == "exit status 1" {
|
|
|
+ // exit status 1 on Windows means that Xray process was killed
|
|
|
+ // as we kill process to stop in on Windows, this is not an error
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
func (s *XrayService) GetXrayResult() string {
|
|
@@ -45,7 +56,15 @@ func (s *XrayService) GetXrayResult() string {
|
|
|
if p == nil {
|
|
|
return ""
|
|
|
}
|
|
|
+
|
|
|
result = p.GetResult()
|
|
|
+
|
|
|
+ if runtime.GOOS == "windows" && result == "exit status 1" {
|
|
|
+ // exit status 1 on Windows means that Xray process was killed
|
|
|
+ // as we kill process to stop in on Windows, this is not an error
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+
|
|
|
return result
|
|
|
}
|
|
|
|
|
@@ -184,7 +203,8 @@ func (s *XrayService) GetXrayTraffic() ([]*xray.Traffic, []*xray.ClientTraffic,
|
|
|
func (s *XrayService) RestartXray(isForce bool) error {
|
|
|
lock.Lock()
|
|
|
defer lock.Unlock()
|
|
|
- logger.Debug("restart xray, force:", isForce)
|
|
|
+ logger.Debug("restart Xray, force:", isForce)
|
|
|
+ isManuallyStopped.Store(false)
|
|
|
|
|
|
xrayConfig, err := s.GetXrayConfig()
|
|
|
if err != nil {
|
|
@@ -192,8 +212,8 @@ func (s *XrayService) RestartXray(isForce bool) error {
|
|
|
}
|
|
|
|
|
|
if s.IsXrayRunning() {
|
|
|
- if !isForce && p.GetConfig().Equals(xrayConfig) {
|
|
|
- logger.Debug("It does not need to restart xray")
|
|
|
+ if !isForce && p.GetConfig().Equals(xrayConfig) && !isNeedXrayRestart.Load() {
|
|
|
+ logger.Debug("It does not need to restart Xray")
|
|
|
return nil
|
|
|
}
|
|
|
p.Stop()
|
|
@@ -205,12 +225,14 @@ func (s *XrayService) RestartXray(isForce bool) error {
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
+
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
func (s *XrayService) StopXray() error {
|
|
|
lock.Lock()
|
|
|
defer lock.Unlock()
|
|
|
+ isManuallyStopped.Store(true)
|
|
|
logger.Debug("Attempting to stop Xray...")
|
|
|
if s.IsXrayRunning() {
|
|
|
return p.Stop()
|
|
@@ -225,3 +247,8 @@ func (s *XrayService) SetToNeedRestart() {
|
|
|
func (s *XrayService) IsNeedRestartAndSetFalse() bool {
|
|
|
return isNeedXrayRestart.CompareAndSwap(true, false)
|
|
|
}
|
|
|
+
|
|
|
+// Check if Xray is not running and wasn't stopped manually, i.e. crashed
|
|
|
+func (s *XrayService) DidXrayCrash() bool {
|
|
|
+ return !s.IsXrayRunning() && !isManuallyStopped.Load()
|
|
|
+}
|