main.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "log"
  6. "os"
  7. "os/signal"
  8. "syscall"
  9. _ "unsafe"
  10. "x-ui/config"
  11. "x-ui/database"
  12. "x-ui/logger"
  13. "x-ui/sub"
  14. "x-ui/web"
  15. "x-ui/web/global"
  16. "x-ui/web/service"
  17. "github.com/op/go-logging"
  18. )
  19. func runWebServer() {
  20. log.Printf("%v %v", config.GetName(), config.GetVersion())
  21. switch config.GetLogLevel() {
  22. case config.Debug:
  23. logger.InitLogger(logging.DEBUG)
  24. case config.Info:
  25. logger.InitLogger(logging.INFO)
  26. case config.Notice:
  27. logger.InitLogger(logging.NOTICE)
  28. case config.Warn:
  29. logger.InitLogger(logging.WARNING)
  30. case config.Error:
  31. logger.InitLogger(logging.ERROR)
  32. default:
  33. log.Fatal("unknown log level:", config.GetLogLevel())
  34. }
  35. err := database.InitDB(config.GetDBPath())
  36. if err != nil {
  37. log.Fatal(err)
  38. }
  39. var server *web.Server
  40. server = web.NewServer()
  41. global.SetWebServer(server)
  42. err = server.Start()
  43. if err != nil {
  44. log.Println(err)
  45. return
  46. }
  47. var subServer *sub.Server
  48. subServer = sub.NewServer()
  49. global.SetSubServer(subServer)
  50. err = subServer.Start()
  51. if err != nil {
  52. log.Println(err)
  53. return
  54. }
  55. sigCh := make(chan os.Signal, 1)
  56. // Trap shutdown signals
  57. signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM)
  58. for {
  59. sig := <-sigCh
  60. switch sig {
  61. case syscall.SIGHUP:
  62. err := server.Stop()
  63. if err != nil {
  64. logger.Warning("stop server err:", err)
  65. }
  66. err = subServer.Stop()
  67. if err != nil {
  68. logger.Warning("stop server err:", err)
  69. }
  70. server = web.NewServer()
  71. global.SetWebServer(server)
  72. err = server.Start()
  73. if err != nil {
  74. log.Println(err)
  75. return
  76. }
  77. subServer = sub.NewServer()
  78. global.SetSubServer(subServer)
  79. err = subServer.Start()
  80. if err != nil {
  81. log.Println(err)
  82. return
  83. }
  84. default:
  85. server.Stop()
  86. subServer.Stop()
  87. return
  88. }
  89. }
  90. }
  91. func resetSetting() {
  92. err := database.InitDB(config.GetDBPath())
  93. if err != nil {
  94. fmt.Println(err)
  95. return
  96. }
  97. settingService := service.SettingService{}
  98. err = settingService.ResetSettings()
  99. if err != nil {
  100. fmt.Println("reset setting failed:", err)
  101. } else {
  102. fmt.Println("reset setting success")
  103. }
  104. }
  105. func showSetting(show bool) {
  106. if show {
  107. settingService := service.SettingService{}
  108. port, err := settingService.GetPort()
  109. if err != nil {
  110. fmt.Println("get current port failed, error info:", err)
  111. }
  112. webBasePath, err := settingService.GetBasePath()
  113. if err != nil {
  114. fmt.Println("get webBasePath failed, error info:", err)
  115. }
  116. userService := service.UserService{}
  117. userModel, err := userService.GetFirstUser()
  118. if err != nil {
  119. fmt.Println("get current user info failed, error info:", err)
  120. }
  121. username := userModel.Username
  122. userpasswd := userModel.Password
  123. if username == "" || userpasswd == "" {
  124. fmt.Println("current username or password is empty")
  125. }
  126. fmt.Println("current panel settings as follows:")
  127. fmt.Println("username:", username)
  128. fmt.Println("password:", userpasswd)
  129. fmt.Println("port:", port)
  130. if webBasePath != "" {
  131. fmt.Println("webBasePath:", webBasePath)
  132. } else {
  133. fmt.Println("webBasePath is not set")
  134. }
  135. }
  136. }
  137. func updateTgbotEnableSts(status bool) {
  138. settingService := service.SettingService{}
  139. currentTgSts, err := settingService.GetTgbotEnabled()
  140. if err != nil {
  141. fmt.Println(err)
  142. return
  143. }
  144. logger.Infof("current enabletgbot status[%v],need update to status[%v]", currentTgSts, status)
  145. if currentTgSts != status {
  146. err := settingService.SetTgbotEnabled(status)
  147. if err != nil {
  148. fmt.Println(err)
  149. return
  150. } else {
  151. logger.Infof("SetTgbotEnabled[%v] success", status)
  152. }
  153. }
  154. }
  155. func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime string) {
  156. err := database.InitDB(config.GetDBPath())
  157. if err != nil {
  158. fmt.Println(err)
  159. return
  160. }
  161. settingService := service.SettingService{}
  162. if tgBotToken != "" {
  163. err := settingService.SetTgBotToken(tgBotToken)
  164. if err != nil {
  165. fmt.Println(err)
  166. return
  167. } else {
  168. logger.Info("updateTgbotSetting tgBotToken success")
  169. }
  170. }
  171. if tgBotRuntime != "" {
  172. err := settingService.SetTgbotRuntime(tgBotRuntime)
  173. if err != nil {
  174. fmt.Println(err)
  175. return
  176. } else {
  177. logger.Infof("updateTgbotSetting tgBotRuntime[%s] success", tgBotRuntime)
  178. }
  179. }
  180. if tgBotChatid != "" {
  181. err := settingService.SetTgBotChatId(tgBotChatid)
  182. if err != nil {
  183. fmt.Println(err)
  184. return
  185. } else {
  186. logger.Info("updateTgbotSetting tgBotChatid success")
  187. }
  188. }
  189. }
  190. func updateSetting(port int, username string, password string, webBasePath string) {
  191. err := database.InitDB(config.GetDBPath())
  192. if err != nil {
  193. fmt.Println(err)
  194. return
  195. }
  196. settingService := service.SettingService{}
  197. if port > 0 {
  198. err := settingService.SetPort(port)
  199. if err != nil {
  200. fmt.Println("set port failed:", err)
  201. } else {
  202. fmt.Printf("set port %v success", port)
  203. }
  204. }
  205. if username != "" || password != "" {
  206. userService := service.UserService{}
  207. err := userService.UpdateFirstUser(username, password)
  208. if err != nil {
  209. fmt.Println("set username and password failed:", err)
  210. } else {
  211. fmt.Println("set username and password success")
  212. }
  213. }
  214. if webBasePath != "" {
  215. err := settingService.SetBasePath(webBasePath)
  216. if err != nil {
  217. fmt.Println("set base URI path failed:", err)
  218. } else {
  219. fmt.Println("set base URI path success")
  220. }
  221. }
  222. }
  223. func updateCert(publicKey string, privateKey string) {
  224. err := database.InitDB(config.GetDBPath())
  225. if err != nil {
  226. fmt.Println(err)
  227. return
  228. }
  229. if (privateKey != "" && publicKey != "") || (privateKey == "" && publicKey == "") {
  230. settingService := service.SettingService{}
  231. err = settingService.SetCertFile(publicKey)
  232. if err != nil {
  233. fmt.Println("set certificate public key failed:", err)
  234. } else {
  235. fmt.Println("set certificate public key success")
  236. }
  237. err = settingService.SetKeyFile(privateKey)
  238. if err != nil {
  239. fmt.Println("set certificate private key failed:", err)
  240. } else {
  241. fmt.Println("set certificate private key success")
  242. }
  243. } else {
  244. fmt.Println("both public and private key should be entered.")
  245. }
  246. }
  247. func migrateDb() {
  248. inboundService := service.InboundService{}
  249. err := database.InitDB(config.GetDBPath())
  250. if err != nil {
  251. log.Fatal(err)
  252. }
  253. fmt.Println("Start migrating database...")
  254. inboundService.MigrateDB()
  255. fmt.Println("Migration done!")
  256. }
  257. func removeSecret() {
  258. userService := service.UserService{}
  259. secretExists, err := userService.CheckSecretExistence()
  260. if err != nil {
  261. fmt.Println("Error checking secret existence:", err)
  262. return
  263. }
  264. if !secretExists {
  265. fmt.Println("No secret exists to remove.")
  266. return
  267. }
  268. err = userService.RemoveUserSecret()
  269. if err != nil {
  270. fmt.Println("Error removing secret:", err)
  271. return
  272. }
  273. settingService := service.SettingService{}
  274. err = settingService.SetSecretStatus(false)
  275. if err != nil {
  276. fmt.Println("Error updating secret status:", err)
  277. return
  278. }
  279. fmt.Println("Secret removed successfully.")
  280. }
  281. func main() {
  282. if len(os.Args) < 2 {
  283. runWebServer()
  284. return
  285. }
  286. var showVersion bool
  287. flag.BoolVar(&showVersion, "v", false, "show version")
  288. runCmd := flag.NewFlagSet("run", flag.ExitOnError)
  289. settingCmd := flag.NewFlagSet("setting", flag.ExitOnError)
  290. var port int
  291. var username string
  292. var password string
  293. var webBasePath string
  294. var webCertFile string
  295. var webKeyFile string
  296. var tgbottoken string
  297. var tgbotchatid string
  298. var enabletgbot bool
  299. var tgbotRuntime string
  300. var reset bool
  301. var show bool
  302. var remove_secret bool
  303. settingCmd.BoolVar(&reset, "reset", false, "reset all settings")
  304. settingCmd.BoolVar(&show, "show", false, "show current settings")
  305. settingCmd.BoolVar(&remove_secret, "remove_secret", false, "remove secret")
  306. settingCmd.IntVar(&port, "port", 0, "set panel port")
  307. settingCmd.StringVar(&username, "username", "", "set login username")
  308. settingCmd.StringVar(&password, "password", "", "set login password")
  309. settingCmd.StringVar(&webBasePath, "webBasePath", "", "set web base path")
  310. settingCmd.StringVar(&webCertFile, "webCert", "", "set web public key path")
  311. settingCmd.StringVar(&webKeyFile, "webCertKey", "", "set web private key path")
  312. settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "set telegram bot token")
  313. settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "set telegram bot cron time")
  314. settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "set telegram bot chat id")
  315. settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "enable telegram bot notify")
  316. oldUsage := flag.Usage
  317. flag.Usage = func() {
  318. oldUsage()
  319. fmt.Println()
  320. fmt.Println("Commands:")
  321. fmt.Println(" run run web panel")
  322. fmt.Println(" migrate migrate form other/old x-ui")
  323. fmt.Println(" setting set settings")
  324. }
  325. flag.Parse()
  326. if showVersion {
  327. fmt.Println(config.GetVersion())
  328. return
  329. }
  330. switch os.Args[1] {
  331. case "run":
  332. err := runCmd.Parse(os.Args[2:])
  333. if err != nil {
  334. fmt.Println(err)
  335. return
  336. }
  337. runWebServer()
  338. case "migrate":
  339. migrateDb()
  340. case "setting":
  341. err := settingCmd.Parse(os.Args[2:])
  342. if err != nil {
  343. fmt.Println(err)
  344. return
  345. }
  346. if reset {
  347. resetSetting()
  348. } else {
  349. updateSetting(port, username, password, webBasePath)
  350. }
  351. if show {
  352. showSetting(show)
  353. }
  354. if (tgbottoken != "") || (tgbotchatid != "") || (tgbotRuntime != "") {
  355. updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime)
  356. }
  357. if remove_secret {
  358. removeSecret()
  359. }
  360. if enabletgbot {
  361. updateTgbotEnableSts(enabletgbot)
  362. }
  363. case "cert":
  364. err := settingCmd.Parse(os.Args[2:])
  365. if err != nil {
  366. fmt.Println(err)
  367. return
  368. }
  369. if reset {
  370. updateCert("", "")
  371. } else {
  372. updateCert(webCertFile, webKeyFile)
  373. }
  374. default:
  375. fmt.Println("Invalid subcommands")
  376. fmt.Println()
  377. runCmd.Usage()
  378. fmt.Println()
  379. settingCmd.Usage()
  380. }
  381. }