web_api.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // package web_api -- реализация API запросов в веб-сервер
  2. package web_api
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. "sync"
  8. "time"
  9. "github.com/gofiber/fiber/v2"
  10. "github.com/gofiber/websocket/v2"
  11. "wartank/pkg/types"
  12. )
  13. // WebApi -- рализация веб-запросов
  14. type WebApi struct {
  15. server types.IServer
  16. store types.IStore
  17. }
  18. // NewWebApi -- возвращает новый WebApi
  19. func NewWebApi(server types.IServer) (*WebApi, error) {
  20. if server == nil {
  21. return nil, fmt.Errorf("NewWebApi(): IServer is nil")
  22. }
  23. sf := &WebApi{
  24. server: server,
  25. store: server.Store(),
  26. }
  27. server.ServWeb().Router().Use("/api/ws", sf.fnWs)
  28. server.ServWeb().Router().Get("/api/ws", websocket.New(sf.fnWsRun))
  29. return sf, nil
  30. }
  31. // Run -- заглушка к вызову
  32. func (sf *WebApi) Run() {}
  33. // fnWs -- апгрейдит веб-сокет
  34. func (sf *WebApi) fnWs(c *fiber.Ctx) error {
  35. if websocket.IsWebSocketUpgrade(c) {
  36. c.Locals("allowed", true)
  37. return c.Next()
  38. }
  39. return fiber.ErrUpgradeRequired
  40. }
  41. // fnWsRun -- запускает веб-сокет в работу
  42. func (sf *WebApi) fnWsRun(c *websocket.Conn) {
  43. // c.Locals is added to the *websocket.Conn
  44. log.Println(c.Locals("allowed")) // true
  45. log.Println(c.Params("id")) // 123
  46. log.Println(c.Query("v")) // 1.0
  47. log.Println(c.Cookies("session")) // ""
  48. // websocket.Conn bindings https://pkg.go.dev/github.com/fasthttp/websocket?tab=doc#pkg-index
  49. var (
  50. mt int
  51. dictReq = make(map[string]string)
  52. dictResp = make(map[string]string)
  53. binReq []byte
  54. err error
  55. block sync.Mutex
  56. )
  57. fnWrite := func() (isOk bool) {
  58. defer block.Unlock()
  59. binResp, err := json.Marshal(dictResp)
  60. if err != nil {
  61. log.Println("WebApi.fnWsRun(): in marshall response, err=", err)
  62. return false
  63. }
  64. if err = c.WriteMessage(mt, binResp); err != nil {
  65. log.Println("WebApi.fnWsRun(): in write, err=", err)
  66. return false
  67. }
  68. return true
  69. }
  70. for {
  71. block.Lock()
  72. if mt, binReq, err = c.ReadMessage(); err != nil {
  73. log.Println("WebApi.fnWsRun(): in read, err=", err)
  74. return
  75. }
  76. dictResp = make(map[string]string)
  77. dictResp["err"] = ""
  78. err = json.Unmarshal(binReq, &dictReq)
  79. if err != nil {
  80. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in unmarshall request, err=\n\t%v", err)
  81. if !fnWrite() {
  82. return
  83. }
  84. continue
  85. }
  86. topic, isOk := dictReq["topic"]
  87. if !isOk {
  88. dictResp["err"] = "WebApi.fnWsRun(): dictReq not have key `topic`"
  89. if !fnWrite() {
  90. return
  91. }
  92. continue
  93. }
  94. switch topic {
  95. case "/server/time": // Запрос времени сервера
  96. dictResp["/server/time"] = time.Now().UTC().Format("2006-01-02 15:04:05.000")
  97. case "/root/password/is_exists":
  98. _, err := sf.store.Get("/root/password/val")
  99. if err != nil {
  100. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in get root password, err=\n\t%v", err)
  101. } else {
  102. dictResp["/root/password/is_exists"] = "true"
  103. }
  104. case "/root/password/set":
  105. strPass := dictReq["pass"]
  106. err := sf.store.Put("/root/password/val", strPass)
  107. if err != nil {
  108. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in save root password, err=\n\t%v", err)
  109. }
  110. case "/root/password/check": // Проверка пароля рута
  111. binPass, err_ := sf.store.Get("/root/password/val")
  112. if err_ != nil {
  113. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in get root password, err=\n\t%v", err_)
  114. } else {
  115. strPassRoot := string(binPass)
  116. strPassUser := dictReq["pass"]
  117. if strPassRoot != strPassUser {
  118. dictResp["err"] = "WebApi.fnWsRun(): bad root password"
  119. }
  120. }
  121. case "/bot/list/load": // Запрос списка ботов
  122. binBots, err := sf.store.Get("/bot/list")
  123. if err != nil {
  124. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in get list bot from store, err=\n\t%v\n", err)
  125. } else {
  126. dictResp["/bot/list"] = string(binBots)
  127. }
  128. case "/bot/list/save": // Сохранение списка ботов
  129. strBotList := dictReq["binData"]
  130. err := sf.store.Put("/bot/list", strBotList)
  131. if err != nil {
  132. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in save list bot to store, err=\n\t%v\n", err)
  133. }
  134. case "/store/put": // Поместить запись в хранилище
  135. key := dictReq["key"]
  136. val := dictReq["val"]
  137. err := sf.store.Put(key, val)
  138. if err != nil {
  139. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in put key(%q) to store, err=\n\t%v\n", key, err)
  140. }
  141. case "/bot/status": // Получить статус бота
  142. name := dictReq["name"]
  143. bot := sf.server.ServBots().Get(name)
  144. if bot == nil {
  145. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): unknown bit name (%q)", name)
  146. } else {
  147. dictResp["/bot/pass"] = bot.Pass()
  148. dictResp["/bot/name"] = bot.Name()
  149. dictResp["/bot/online"] = fmt.Sprint(bot.BotNet().IsOnline().Get())
  150. dictResp["/bot/fuel"] = fmt.Sprint(bot.Angar().Fuel().Get())
  151. dictResp["/bot/gold"] = fmt.Sprint(bot.Angar().Gold().Get())
  152. angar := bot.Angar()
  153. base := angar.Base()
  154. bank := base.Bank()
  155. silverBot := bank.SilverBot()
  156. dictResp["/bot/silver"] = fmt.Sprint(silverBot.Get())
  157. dictResp["/bank/silver-time"] = bot.Angar().Base().Bank().CountDown().String()
  158. dictResp["/bank/silver-mode"] = bot.Angar().Base().Bank().ModeCurrent().Work()
  159. dictResp["/angar/silver-all"] = fmt.Sprint(bot.Angar().SilverAll().Get())
  160. dictResp["/bot/mine-time"] = bot.Angar().Base().Mine().CountDown().String()
  161. dictResp["/bot/mine-mode"] = bot.Angar().Base().Mine().ModeCurrent().Work()
  162. dictResp["/mine/ruda"] = fmt.Sprint(bot.Angar().Base().Mine().Ruda().Get())
  163. }
  164. default:
  165. dictReq = make(map[string]string)
  166. dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): unknown topic (%q)", topic)
  167. }
  168. if !fnWrite() {
  169. return
  170. }
  171. }
  172. }