diff --git a/.gitignore b/.gitignore index c59b097f..e0212345 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .cache .sync* *.tar.gz +*.log access.log error.log tmp diff --git a/database/db.go b/database/db.go index 596b0022..e18dcb4d 100644 --- a/database/db.go +++ b/database/db.go @@ -6,6 +6,7 @@ import ( "io/fs" "os" "path" + "x-ui/config" "x-ui/database/model" "x-ui/xray" diff --git a/database/model/model.go b/database/model/model.go index f7cdf322..c999462b 100644 --- a/database/model/model.go +++ b/database/model/model.go @@ -2,6 +2,7 @@ package model import ( "fmt" + "x-ui/util/json_util" "x-ui/xray" ) diff --git a/logger/logger.go b/logger/logger.go index a1386b05..983d4ae4 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -8,12 +8,14 @@ import ( "github.com/op/go-logging" ) -var logger *logging.Logger -var logBuffer []struct { - time string - level logging.Level - log string -} +var ( + logger *logging.Logger + logBuffer []struct { + time string + level logging.Level + log string + } +) func init() { InitLogger(logging.INFO) diff --git a/main.go b/main.go index b1327486..39a5a1bd 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "os/signal" "syscall" _ "unsafe" + "x-ui/config" "x-ui/database" "x-ui/logger" diff --git a/sub/sub.go b/sub/sub.go index b5eb4bf3..26dbcd2c 100644 --- a/sub/sub.go +++ b/sub/sub.go @@ -7,6 +7,7 @@ import ( "net" "net/http" "strconv" + "x-ui/config" "x-ui/logger" "x-ui/util/common" @@ -99,7 +100,7 @@ func (s *Server) initRouter() (*gin.Engine, error) { } func (s *Server) Start() (err error) { - //This is an anonymous function, no function name + // This is an anonymous function, no function name defer func() { if err != nil { s.Stop() diff --git a/sub/subController.go b/sub/subController.go index ea4cbc05..9d814965 100644 --- a/sub/subController.go +++ b/sub/subController.go @@ -25,8 +25,8 @@ func NewSUBController( showInfo bool, rModel string, update string, - jsonFragment string) *SUBController { - + jsonFragment string, +) *SUBController { a := &SUBController{ subPath: subPath, subJsonPath: jsonPath, diff --git a/sub/subJsonService.go b/sub/subJsonService.go index 8bc98dea..9320306e 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "strings" + "x-ui/database/model" "x-ui/logger" "x-ui/util/json_util" diff --git a/sub/subService.go b/sub/subService.go index ccf27b04..e873c15f 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -6,6 +6,7 @@ import ( "net/url" "strings" "time" + "x-ui/database" "x-ui/database/model" "x-ui/logger" diff --git a/util/common/err.go b/util/common/err.go index f6078c33..494e5c82 100644 --- a/util/common/err.go +++ b/util/common/err.go @@ -3,6 +3,7 @@ package common import ( "errors" "fmt" + "x-ui/logger" ) diff --git a/util/random/random.go b/util/random/random.go index c0894ec3..2de615b2 100644 --- a/util/random/random.go +++ b/util/random/random.go @@ -5,12 +5,14 @@ import ( "time" ) -var numSeq [10]rune -var lowerSeq [26]rune -var upperSeq [26]rune -var numLowerSeq [36]rune -var numUpperSeq [36]rune -var allSeq [62]rune +var ( + numSeq [10]rune + lowerSeq [26]rune + upperSeq [26]rune + numLowerSeq [36]rune + numUpperSeq [36]rune + allSeq [62]rune +) func init() { rand.Seed(time.Now().UnixNano()) diff --git a/web/assets/js/axios-init.js b/web/assets/js/axios-init.js index b864b714..f0b0f4be 100644 --- a/web/assets/js/axios-init.js +++ b/web/assets/js/axios-init.js @@ -14,3 +14,17 @@ axios.interceptors.request.use( }, (error) => Promise.reject(error), ); + +axios.interceptors.response.use( + (response) => response, + (error) => { + if (error.response) { + const statusCode = error.response.status; + // Check the status code + if (statusCode === 401) { // Unauthorized + return window.location.reload(); + } + } + return Promise.reject(error); + } +); diff --git a/web/controller/api.go b/web/controller/api.go index 127c3736..7802dea5 100644 --- a/web/controller/api.go +++ b/web/controller/api.go @@ -22,81 +22,35 @@ func (a *APIController) initRouter(g *gin.RouterGroup) { g = g.Group("/xui/API/inbounds") g.Use(a.checkLogin) - g.GET("/", a.inbounds) - g.GET("/get/:id", a.inbound) - g.GET("/getClientTraffics/:email", a.getClientTraffics) - g.POST("/add", a.addInbound) - g.POST("/del/:id", a.delInbound) - g.POST("/update/:id", a.updateInbound) - g.POST("/addClient", a.addInboundClient) - g.POST("/:id/delClient/:clientId", a.delInboundClient) - g.POST("/updateClient/:clientId", a.updateInboundClient) - g.POST("/:id/resetClientTraffic/:email", a.resetClientTraffic) - g.POST("/resetAllTraffics", a.resetAllTraffics) - g.POST("/resetAllClientTraffics/:id", a.resetAllClientTraffics) - g.POST("/delDepletedClients/:id", a.delDepletedClients) - g.GET("/createbackup", a.createBackup) - g.POST("/onlines", a.onlines) - a.inboundController = NewInboundController(g) -} -func (a *APIController) inbounds(c *gin.Context) { - a.inboundController.getInbounds(c) -} + inboundRoutes := []struct { + Method string + Path string + Handler gin.HandlerFunc + }{ + {"GET", "/createbackup", a.createBackup}, + {"GET", "/", a.inboundController.getInbounds}, + {"GET", "/get/:id", a.inboundController.getInbound}, + {"GET", "/getClientTraffics/:email", a.inboundController.getClientTraffics}, + {"POST", "/add", a.inboundController.addInbound}, + {"POST", "/del/:id", a.inboundController.delInbound}, + {"POST", "/update/:id", a.inboundController.updateInbound}, + {"POST", "/addClient", a.inboundController.addInboundClient}, + {"POST", "/:id/delClient/:clientId", a.inboundController.delInboundClient}, + {"POST", "/updateClient/:clientId", a.inboundController.updateInboundClient}, + {"POST", "/:id/resetClientTraffic/:email", a.inboundController.resetClientTraffic}, + {"POST", "/resetAllTraffics", a.inboundController.resetAllTraffics}, + {"POST", "/resetAllClientTraffics/:id", a.inboundController.resetAllClientTraffics}, + {"POST", "/delDepletedClients/:id", a.inboundController.delDepletedClients}, + {"POST", "/onlines", a.inboundController.onlines}, + } -func (a *APIController) inbound(c *gin.Context) { - a.inboundController.getInbound(c) -} - -func (a *APIController) getClientTraffics(c *gin.Context) { - a.inboundController.getClientTraffics(c) -} - -func (a *APIController) addInbound(c *gin.Context) { - a.inboundController.addInbound(c) -} - -func (a *APIController) delInbound(c *gin.Context) { - a.inboundController.delInbound(c) -} - -func (a *APIController) updateInbound(c *gin.Context) { - a.inboundController.updateInbound(c) -} - -func (a *APIController) addInboundClient(c *gin.Context) { - a.inboundController.addInboundClient(c) -} - -func (a *APIController) delInboundClient(c *gin.Context) { - a.inboundController.delInboundClient(c) -} - -func (a *APIController) updateInboundClient(c *gin.Context) { - a.inboundController.updateInboundClient(c) -} - -func (a *APIController) resetClientTraffic(c *gin.Context) { - a.inboundController.resetClientTraffic(c) -} - -func (a *APIController) resetAllTraffics(c *gin.Context) { - a.inboundController.resetAllTraffics(c) -} - -func (a *APIController) resetAllClientTraffics(c *gin.Context) { - a.inboundController.resetAllClientTraffics(c) -} - -func (a *APIController) delDepletedClients(c *gin.Context) { - a.inboundController.delDepletedClients(c) + for _, route := range inboundRoutes { + g.Handle(route.Method, route.Path, route.Handler) + } } func (a *APIController) createBackup(c *gin.Context) { a.Tgbot.SendBackupToAdmins() } - -func (a *APIController) onlines(c *gin.Context) { - a.inboundController.onlines(c) -} diff --git a/web/controller/base.go b/web/controller/base.go index 674a195d..492fc2dc 100644 --- a/web/controller/base.go +++ b/web/controller/base.go @@ -2,6 +2,7 @@ package controller import ( "net/http" + "x-ui/logger" "x-ui/web/locale" "x-ui/web/session" @@ -9,13 +10,12 @@ import ( "github.com/gin-gonic/gin" ) -type BaseController struct { -} +type BaseController struct{} func (a *BaseController) checkLogin(c *gin.Context) { if !session.IsLogin(c) { if isAjax(c) { - pureJsonMsg(c, false, I18nWeb(c, "pages.login.loginAgain")) + pureJsonMsg(c, http.StatusUnauthorized, false, I18nWeb(c, "pages.login.loginAgain")) } else { c.Redirect(http.StatusTemporaryRedirect, c.GetString("base_path")) } diff --git a/web/controller/inbound.go b/web/controller/inbound.go index eeb8e120..8db9d486 100644 --- a/web/controller/inbound.go +++ b/web/controller/inbound.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "strconv" + "x-ui/database/model" "x-ui/web/service" "x-ui/web/session" @@ -63,6 +64,7 @@ func (a *InboundController) getInbound(c *gin.Context) { } jsonObj(c, inbound, nil) } + func (a *InboundController) getClientTraffics(c *gin.Context) { email := c.Param("email") clientTraffics, err := a.inboundService.GetClientTrafficByEmail(email) diff --git a/web/controller/index.go b/web/controller/index.go index e6d7dc92..919a2648 100644 --- a/web/controller/index.go +++ b/web/controller/index.go @@ -3,6 +3,7 @@ package controller import ( "net/http" "time" + "x-ui/logger" "x-ui/web/service" "x-ui/web/session" @@ -47,15 +48,15 @@ func (a *IndexController) login(c *gin.Context) { var form LoginForm err := c.ShouldBind(&form) if err != nil { - pureJsonMsg(c, false, I18nWeb(c, "pages.login.toasts.invalidFormData")) + pureJsonMsg(c, http.StatusOK, false, I18nWeb(c, "pages.login.toasts.invalidFormData")) return } if form.Username == "" { - pureJsonMsg(c, false, I18nWeb(c, "pages.login.toasts.emptyUsername")) + pureJsonMsg(c, http.StatusOK, false, I18nWeb(c, "pages.login.toasts.emptyUsername")) return } if form.Password == "" { - pureJsonMsg(c, false, I18nWeb(c, "pages.login.toasts.emptyPassword")) + pureJsonMsg(c, http.StatusOK, false, I18nWeb(c, "pages.login.toasts.emptyPassword")) return } @@ -64,7 +65,7 @@ func (a *IndexController) login(c *gin.Context) { if user == nil { logger.Infof("wrong username or password: \"%s\" \"%s\"", form.Username, form.Password) a.tgbot.UserLoginNotify(form.Username, getRemoteIp(c), timeStr, 0) - pureJsonMsg(c, false, I18nWeb(c, "pages.login.toasts.wrongUsernameOrPassword")) + pureJsonMsg(c, http.StatusOK, false, I18nWeb(c, "pages.login.toasts.wrongUsernameOrPassword")) return } else { logger.Infof("%s login success ,Ip Address: %s\n", form.Username, getRemoteIp(c)) diff --git a/web/controller/server.go b/web/controller/server.go index b7ed4771..8ce0b6bb 100644 --- a/web/controller/server.go +++ b/web/controller/server.go @@ -5,6 +5,7 @@ import ( "net/http" "regexp" "time" + "x-ui/web/global" "x-ui/web/service" diff --git a/web/controller/setting.go b/web/controller/setting.go index 020c8dc5..bb17c4b3 100644 --- a/web/controller/setting.go +++ b/web/controller/setting.go @@ -3,6 +3,7 @@ package controller import ( "errors" "time" + "x-ui/web/entity" "x-ui/web/service" "x-ui/web/session" diff --git a/web/controller/util.go b/web/controller/util.go index da77189b..a32c9270 100644 --- a/web/controller/util.go +++ b/web/controller/util.go @@ -4,6 +4,7 @@ import ( "net" "net/http" "strings" + "x-ui/config" "x-ui/logger" "x-ui/web/entity" @@ -48,18 +49,11 @@ func jsonMsgObj(c *gin.Context, msg string, obj interface{}, err error) { c.JSON(http.StatusOK, m) } -func pureJsonMsg(c *gin.Context, success bool, msg string) { - if success { - c.JSON(http.StatusOK, entity.Msg{ - Success: true, - Msg: msg, - }) - } else { - c.JSON(http.StatusOK, entity.Msg{ - Success: false, - Msg: msg, - }) - } +func pureJsonMsg(c *gin.Context, statusCode int, success bool, msg string) { + c.JSON(statusCode, entity.Msg{ + Success: success, + Msg: msg, + }) } func html(c *gin.Context, name string, title string, data gin.H) { diff --git a/web/entity/entity.go b/web/entity/entity.go index 0bcbeb58..7b50341e 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -5,6 +5,7 @@ import ( "net" "strings" "time" + "x-ui/util/common" ) diff --git a/web/global/global.go b/web/global/global.go index 7d0b4e1f..e92c375b 100644 --- a/web/global/global.go +++ b/web/global/global.go @@ -7,8 +7,10 @@ import ( "github.com/robfig/cron/v3" ) -var webServer WebServer -var subServer SubServer +var ( + webServer WebServer + subServer SubServer +) type WebServer interface { GetCron() *cron.Cron diff --git a/web/html/xui/xray.html b/web/html/xui/xray.html index 40e23334..af273f12 100644 --- a/web/html/xui/xray.html +++ b/web/html/xui/xray.html @@ -1285,7 +1285,7 @@ newLogSettings = this.logSettings; newLogSettings.loglevel = newValue; this.logSettings = newLogSettings; - }, + }, }, logAccess: { get: function () { return this.logSettings?.access?? ''; }, @@ -1293,7 +1293,7 @@ newLogSettings = this.logSettings; newValue == "" ? delete newLogSettings.access : newLogSettings.access = newValue; this.logSettings = newLogSettings; - }, + }, }, logError: { get: function () { return this.logSettings?.error?? ''; }, @@ -1301,7 +1301,7 @@ newLogSettings = this.logSettings; newValue == "" ? delete newLogSettings.error : newLogSettings.error = newValue; this.logSettings = newLogSettings; - }, + }, }, inboundSettings: { get: function () { return this.templateSettings ? JSON.stringify(this.templateSettings.inbounds, null, 2) : null; }, diff --git a/web/job/check_cpu_usage.go b/web/job/check_cpu_usage.go index 74f6a544..b84ad054 100644 --- a/web/job/check_cpu_usage.go +++ b/web/job/check_cpu_usage.go @@ -3,6 +3,7 @@ package job import ( "strconv" "time" + "x-ui/web/service" "github.com/shirou/gopsutil/v3/cpu" diff --git a/web/job/xray_traffic_job.go b/web/job/xray_traffic_job.go index 158930a4..7c4726a1 100644 --- a/web/job/xray_traffic_job.go +++ b/web/job/xray_traffic_job.go @@ -31,5 +31,4 @@ func (j *XrayTrafficJob) Run() { if needRestart { j.xrayService.SetToNeedRestart() } - } diff --git a/web/locale/locale.go b/web/locale/locale.go index 4a5f5c6e..adc90ec5 100644 --- a/web/locale/locale.go +++ b/web/locale/locale.go @@ -4,6 +4,7 @@ import ( "embed" "io/fs" "strings" + "x-ui/logger" "github.com/gin-gonic/gin" @@ -12,9 +13,11 @@ import ( "golang.org/x/text/language" ) -var i18nBundle *i18n.Bundle -var LocalizerWeb *i18n.Localizer -var LocalizerBot *i18n.Localizer +var ( + i18nBundle *i18n.Bundle + LocalizerWeb *i18n.Localizer + LocalizerBot *i18n.Localizer +) type I18nType string @@ -79,7 +82,6 @@ func I18n(i18nType I18nType, key string, params ...string) string { MessageID: key, TemplateData: templateData, }) - if err != nil { logger.Errorf("Failed to localize message: %v", err) return "" @@ -135,7 +137,6 @@ func parseTranslationFiles(i18nFS embed.FS, i18nBundle *i18n.Bundle) error { _, err = i18nBundle.ParseMessageFileBytes(data, path) return err }) - if err != nil { return err } diff --git a/web/service/inbound.go b/web/service/inbound.go index 2e55609f..89f58a12 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" "time" + "x-ui/database" "x-ui/database/model" "x-ui/logger" @@ -90,7 +91,6 @@ func (s *InboundService) getAllEmails() ([]string, error) { FROM inbounds, JSON_EACH(JSON_EXTRACT(inbounds.settings, '$.clients')) AS client `).Scan(&emails).Error - if err != nil { return nil, err } @@ -1044,13 +1044,15 @@ func (s *InboundService) UpdateClientStat(tx *gorm.DB, email string, client *mod "email": client.Email, "total": client.TotalGB, "expiry_time": client.ExpiryTime, - "reset": client.Reset}) + "reset": client.Reset, + }) err := result.Error if err != nil { return err } return nil } + func (s *InboundService) DelClientStat(tx *gorm.DB, email string) error { return tx.Where("email = ?", email).Delete(xray.ClientTraffic{}).Error } @@ -1131,7 +1133,6 @@ func (s *InboundService) ResetAllClientTraffics(id int) error { Updates(map[string]interface{}{"enable": true, "up": 0, "down": 0}) err := result.Error - if err != nil { return err } @@ -1146,7 +1147,6 @@ func (s *InboundService) ResetAllTraffics() error { Updates(map[string]interface{}{"up": 0, "down": 0}) err := result.Error - if err != nil { return err } diff --git a/web/service/panel.go b/web/service/panel.go index f90d3e66..71782a8f 100644 --- a/web/service/panel.go +++ b/web/service/panel.go @@ -4,11 +4,11 @@ import ( "os" "syscall" "time" + "x-ui/logger" ) -type PanelService struct { -} +type PanelService struct{} func (s *PanelService) RestartPanel(delay time.Duration) error { p, err := os.FindProcess(syscall.Getpid()) diff --git a/web/service/server.go b/web/service/server.go index 1f46b8af..bfe37869 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -15,6 +15,7 @@ import ( "strconv" "strings" "time" + "x-ui/config" "x-ui/database" "x-ui/logger" @@ -250,7 +251,6 @@ func (s *ServerService) GetXrayVersions() ([]string, error) { } func (s *ServerService) StopXrayService() (string error) { - err := s.xrayService.StopXray() if err != nil { logger.Error("stop xray failed:", err) @@ -261,7 +261,6 @@ func (s *ServerService) StopXrayService() (string error) { } func (s *ServerService) RestartXrayService() (string error) { - s.xrayService.StopXray() defer func() { err := s.xrayService.RestartXray(true) @@ -365,7 +364,6 @@ func (s *ServerService) UpdateXray(version string) error { } return nil - } func (s *ServerService) GetLogs(count string, level string, syslog string) []string { diff --git a/web/service/setting.go b/web/service/setting.go index 9f68217b..b7738194 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" "time" + "x-ui/database" "x-ui/database/model" "x-ui/logger" @@ -61,8 +62,7 @@ var defaultValueMap = map[string]string{ "warp": "", } -type SettingService struct { -} +type SettingService struct{} func (s *SettingService) GetAllSetting() (*entity.AllSetting, error) { db := database.GetDB() @@ -406,6 +406,7 @@ func (s *SettingService) GetSubJsonFragment() (string, error) { func (s *SettingService) GetWarp() (string, error) { return s.getString("warp") } + func (s *SettingService) SetWarp(data string) error { return s.setString("warp", data) } diff --git a/web/service/tgbot.go b/web/service/tgbot.go index 573cf876..6ed8476e 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" "time" + "x-ui/config" "x-ui/database" "x-ui/database/model" @@ -19,10 +20,12 @@ import ( tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) -var bot *tgbotapi.BotAPI -var adminIds []int64 -var isRunning bool -var hostname string +var ( + bot *tgbotapi.BotAPI + adminIds []int64 + isRunning bool + hostname string +) type LoginStatus byte diff --git a/web/service/user.go b/web/service/user.go index 6da8bd1e..2b44733c 100644 --- a/web/service/user.go +++ b/web/service/user.go @@ -2,6 +2,7 @@ package service import ( "errors" + "x-ui/database" "x-ui/database/model" "x-ui/logger" @@ -9,8 +10,7 @@ import ( "gorm.io/gorm" ) -type UserService struct { -} +type UserService struct{} func (s *UserService) GetFirstUser() (*model.User, error) { db := database.GetDB() diff --git a/web/service/xray.go b/web/service/xray.go index 3827ba6d..849d3c2b 100644 --- a/web/service/xray.go +++ b/web/service/xray.go @@ -4,16 +4,19 @@ 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 +var ( + p *xray.Process + lock sync.Mutex + isNeedXrayRestart atomic.Bool + result string +) type XrayService struct { inboundService InboundService @@ -87,7 +90,6 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) { // check users active or not clientStats := inbound.ClientStats for _, clientTraffic := range clientStats { - indexDecrease := 0 for index, client := range clients { c := client.(map[string]interface{}) @@ -96,10 +98,8 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) { clients = RemoveIndex(clients, index-indexDecrease) indexDecrease++ } - } } - } // clear client config for additional parameters diff --git a/web/service/xray_setting.go b/web/service/xray_setting.go index 86bb1d7b..a203e649 100644 --- a/web/service/xray_setting.go +++ b/web/service/xray_setting.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "time" + "x-ui/util/common" "x-ui/xray" ) diff --git a/web/session/session.go b/web/session/session.go index 9b9a3589..90c9c217 100644 --- a/web/session/session.go +++ b/web/session/session.go @@ -2,6 +2,7 @@ package session import ( "encoding/gob" + "x-ui/database/model" sessions "github.com/Calidity/gin-sessions" diff --git a/web/web.go b/web/web.go index bcf1db18..258cca30 100644 --- a/web/web.go +++ b/web/web.go @@ -13,6 +13,7 @@ import ( "strconv" "strings" "time" + "x-ui/config" "x-ui/logger" "x-ui/util/common" @@ -283,7 +284,7 @@ func (s *Server) startTask() { } func (s *Server) Start() (err error) { - //This is an anonymous function, no function name + // This is an anonymous function, no function name defer func() { if err != nil { s.Stop() diff --git a/xray/api.go b/xray/api.go index 83fdb893..9bd0c31d 100644 --- a/xray/api.go +++ b/xray/api.go @@ -6,6 +6,7 @@ import ( "fmt" "regexp" "time" + "x-ui/logger" "x-ui/util/common" @@ -159,8 +160,8 @@ func (x *XrayAPI) GetTraffic(reset bool) ([]*Traffic, []*ClientTraffic, error) { if x.grpcClient == nil { return nil, nil, common.NewError("xray api is not initialized") } - var trafficRegex = regexp.MustCompile("(inbound|outbound)>>>([^>]+)>>>traffic>>>(downlink|uplink)") - var ClientTrafficRegex = regexp.MustCompile("(user)>>>([^>]+)>>>traffic>>>(downlink|uplink)") + trafficRegex := regexp.MustCompile("(inbound|outbound)>>>([^>]+)>>>traffic>>>(downlink|uplink)") + ClientTrafficRegex := regexp.MustCompile("(user)>>>([^>]+)>>>traffic>>>(downlink|uplink)") client := *x.StatsServiceClient ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) diff --git a/xray/config.go b/xray/config.go index ed2a2804..67ff7d95 100644 --- a/xray/config.go +++ b/xray/config.go @@ -2,6 +2,7 @@ package xray import ( "bytes" + "x-ui/util/json_util" ) diff --git a/xray/inbound.go b/xray/inbound.go index b3f07c7e..ea11449d 100644 --- a/xray/inbound.go +++ b/xray/inbound.go @@ -2,6 +2,7 @@ package xray import ( "bytes" + "x-ui/util/json_util" ) diff --git a/xray/log_writer.go b/xray/log_writer.go index b2d1c7fb..1f5794a1 100644 --- a/xray/log_writer.go +++ b/xray/log_writer.go @@ -3,6 +3,7 @@ package xray import ( "regexp" "strings" + "x-ui/logger" ) diff --git a/xray/process.go b/xray/process.go index bb784522..dbcd266a 100644 --- a/xray/process.go +++ b/xray/process.go @@ -11,6 +11,7 @@ import ( "runtime" "syscall" "time" + "x-ui/config" "x-ui/util/common" )