npc.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package main
  2. import (
  3. "ehang.io/nps/client"
  4. "ehang.io/nps/lib/common"
  5. "ehang.io/nps/lib/daemon"
  6. "ehang.io/nps/lib/version"
  7. "fmt"
  8. "fyne.io/fyne"
  9. "fyne.io/fyne/app"
  10. "fyne.io/fyne/container"
  11. "fyne.io/fyne/layout"
  12. "fyne.io/fyne/widget"
  13. "github.com/astaxie/beego/logs"
  14. "io/ioutil"
  15. "os"
  16. "path"
  17. "runtime"
  18. "strings"
  19. "time"
  20. )
  21. func main() {
  22. daemon.InitDaemon("npc", common.GetRunPath(), common.GetTmpPath())
  23. logs.SetLogger("store")
  24. application := app.New()
  25. window := application.NewWindow("Npc " + version.VERSION)
  26. window.SetContent(WidgetScreen())
  27. window.Resize(fyne.NewSize(910, 350))
  28. window.ShowAndRun()
  29. }
  30. var (
  31. start bool
  32. status = "Start!"
  33. connType = "tcp"
  34. cl = new(client.TRPClient)
  35. refreshCh = make(chan struct{})
  36. )
  37. func WidgetScreen() fyne.CanvasObject {
  38. return fyne.NewContainerWithLayout(layout.NewBorderLayout(nil, nil, nil, nil),
  39. makeMainTab(),
  40. )
  41. }
  42. func makeMainTab() *fyne.Container {
  43. serverPort := widget.NewEntry()
  44. serverPort.SetPlaceHolder("Server:Port")
  45. vKey := widget.NewEntry()
  46. vKey.SetPlaceHolder("Vkey")
  47. radio := widget.NewRadioGroup([]string{"tcp", "kcp"}, func(s string) { connType = s })
  48. radio.Horizontal = true
  49. button := widget.NewButton(status, func() {
  50. onclick(serverPort.Text, vKey.Text, connType)
  51. })
  52. go func() {
  53. for {
  54. <-refreshCh
  55. button.SetText(status)
  56. }
  57. }()
  58. lo := widget.NewMultiLineEntry()
  59. lo.Disable()
  60. lo.Resize(fyne.NewSize(910, 250))
  61. slo := container.NewScroll(lo)
  62. slo.Resize(fyne.NewSize(910, 250))
  63. go func() {
  64. for {
  65. time.Sleep(time.Second)
  66. lo.SetText(common.GetLogMsg())
  67. slo.Resize(fyne.NewSize(910, 250))
  68. }
  69. }()
  70. sp, vk, ct := loadConfig()
  71. if sp != "" && vk != "" && ct != "" {
  72. serverPort.SetText(sp)
  73. vKey.SetText(vk)
  74. connType = ct
  75. radio.SetSelected(ct)
  76. onclick(sp, vk, ct)
  77. }
  78. return container.NewVBox(
  79. widget.NewLabel("Npc "+version.VERSION),
  80. serverPort,
  81. vKey,
  82. radio,
  83. button,
  84. slo,
  85. )
  86. }
  87. func onclick(s, v, c string) {
  88. start = !start
  89. if start {
  90. status = "Stop!"
  91. // init the npc
  92. fmt.Println("submit", s, v, c)
  93. sp, vk, ct := loadConfig()
  94. if sp != s || vk != v || ct != c {
  95. saveConfig(s, v, c)
  96. }
  97. go func() {
  98. for {
  99. cl = client.NewRPClient(s, v, c, "", nil, 60)
  100. cl.Start()
  101. logs.Info("client disconnected, reconnecting in 5 seconds...")
  102. time.Sleep(time.Second * 5)
  103. }
  104. }()
  105. } else {
  106. // close the npc
  107. status = "Start!"
  108. if cl != nil {
  109. go cl.Close()
  110. cl = nil
  111. }
  112. }
  113. refreshCh <- struct{}{}
  114. }
  115. func getDir() (dir string, err error) {
  116. if runtime.GOOS != "android" {
  117. dir, err = os.UserConfigDir()
  118. if err != nil {
  119. return
  120. }
  121. } else {
  122. dir = "/data/data/org.nps.client/files"
  123. }
  124. return
  125. }
  126. func saveConfig(host, vkey, connType string) {
  127. data := strings.Join([]string{host, vkey, connType}, "\n")
  128. ph, err := getDir()
  129. if err != nil {
  130. logs.Warn("not found config dir")
  131. return
  132. }
  133. _ = os.Remove(path.Join(ph, "npc.conf"))
  134. f, err := os.OpenFile(path.Join(ph, "npc.conf"), os.O_CREATE|os.O_WRONLY, 0644)
  135. defer f.Close()
  136. if err != nil {
  137. logs.Error(err)
  138. return
  139. }
  140. if _, err := f.Write([]byte(data)); err != nil {
  141. _ = f.Close() // ignore error; Write error takes precedence
  142. logs.Error(err)
  143. return
  144. }
  145. }
  146. func loadConfig() (host, vkey, connType string) {
  147. ph, err := getDir()
  148. if err != nil {
  149. logs.Warn("not found config dir")
  150. return
  151. }
  152. f, err := os.OpenFile(path.Join(ph, "npc.conf"), os.O_RDONLY, 0644)
  153. defer f.Close()
  154. if err != nil {
  155. logs.Error(err)
  156. return
  157. }
  158. data, err := ioutil.ReadAll(f)
  159. if err != nil {
  160. logs.Error(err)
  161. return
  162. }
  163. li := strings.Split(string(data), "\n")
  164. host = li[0]
  165. vkey = li[1]
  166. connType = li[2]
  167. return
  168. }