123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- // package web_api -- реализация API запросов в веб-сервер
- package web_api
- import (
- "encoding/json"
- "fmt"
- "log"
- "sync"
- "time"
- "github.com/gofiber/fiber/v2"
- "github.com/gofiber/websocket/v2"
- "wartank/pkg/types"
- )
- // WebApi -- рализация веб-запросов
- type WebApi struct {
- server types.IServer
- store types.IStore
- }
- // NewWebApi -- возвращает новый WebApi
- func NewWebApi(server types.IServer) (*WebApi, error) {
- if server == nil {
- return nil, fmt.Errorf("NewWebApi(): IServer is nil")
- }
- sf := &WebApi{
- server: server,
- store: server.Store(),
- }
- server.ServWeb().Router().Use("/api/ws", sf.fnWs)
- server.ServWeb().Router().Get("/api/ws", websocket.New(sf.fnWsRun))
- return sf, nil
- }
- // Run -- заглушка к вызову
- func (sf *WebApi) Run() {}
- // fnWs -- апгрейдит веб-сокет
- func (sf *WebApi) fnWs(c *fiber.Ctx) error {
- if websocket.IsWebSocketUpgrade(c) {
- c.Locals("allowed", true)
- return c.Next()
- }
- return fiber.ErrUpgradeRequired
- }
- // fnWsRun -- запускает веб-сокет в работу
- func (sf *WebApi) fnWsRun(c *websocket.Conn) {
- // c.Locals is added to the *websocket.Conn
- log.Println(c.Locals("allowed")) // true
- log.Println(c.Params("id")) // 123
- log.Println(c.Query("v")) // 1.0
- log.Println(c.Cookies("session")) // ""
- // websocket.Conn bindings https://pkg.go.dev/github.com/fasthttp/websocket?tab=doc#pkg-index
- var (
- mt int
- dictReq = make(map[string]string)
- dictResp = make(map[string]string)
- binReq []byte
- err error
- block sync.Mutex
- )
- fnWrite := func() (isOk bool) {
- defer block.Unlock()
- binResp, err := json.Marshal(dictResp)
- if err != nil {
- log.Println("WebApi.fnWsRun(): in marshall response, err=", err)
- return false
- }
- if err = c.WriteMessage(mt, binResp); err != nil {
- log.Println("WebApi.fnWsRun(): in write, err=", err)
- return false
- }
- return true
- }
- for {
- block.Lock()
- if mt, binReq, err = c.ReadMessage(); err != nil {
- log.Println("WebApi.fnWsRun(): in read, err=", err)
- return
- }
- dictResp = make(map[string]string)
- dictResp["err"] = ""
- err = json.Unmarshal(binReq, &dictReq)
- if err != nil {
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in unmarshall request, err=\n\t%v", err)
- if !fnWrite() {
- return
- }
- continue
- }
- topic, isOk := dictReq["topic"]
- if !isOk {
- dictResp["err"] = "WebApi.fnWsRun(): dictReq not have key `topic`"
- if !fnWrite() {
- return
- }
- continue
- }
- switch topic {
- case "/server/time": // Запрос времени сервера
- dictResp["/server/time"] = time.Now().UTC().Format("2006-01-02 15:04:05.000")
- case "/root/password/is_exists":
- _, err := sf.store.Get("/root/password/val")
- if err != nil {
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in get root password, err=\n\t%v", err)
- } else {
- dictResp["/root/password/is_exists"] = "true"
- }
- case "/root/password/set":
- strPass := dictReq["pass"]
- err := sf.store.Put("/root/password/val", strPass)
- if err != nil {
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in save root password, err=\n\t%v", err)
- }
- case "/root/password/check": // Проверка пароля рута
- binPass, err_ := sf.store.Get("/root/password/val")
- if err_ != nil {
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in get root password, err=\n\t%v", err_)
- } else {
- strPassRoot := string(binPass)
- strPassUser := dictReq["pass"]
- if strPassRoot != strPassUser {
- dictResp["err"] = "WebApi.fnWsRun(): bad root password"
- }
- }
- case "/bot/list/load": // Запрос списка ботов
- binBots, err := sf.store.Get("/bot/list")
- if err != nil {
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in get list bot from store, err=\n\t%v\n", err)
- } else {
- dictResp["/bot/list"] = string(binBots)
- }
- case "/bot/list/save": // Сохранение списка ботов
- strBotList := dictReq["binData"]
- err := sf.store.Put("/bot/list", strBotList)
- if err != nil {
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in save list bot to store, err=\n\t%v\n", err)
- }
- case "/store/put": // Поместить запись в хранилище
- key := dictReq["key"]
- val := dictReq["val"]
- err := sf.store.Put(key, val)
- if err != nil {
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): in put key(%q) to store, err=\n\t%v\n", key, err)
- }
- case "/bot/status": // Получить статус бота
- name := dictReq["name"]
- bot := sf.server.ServBots().Get(name)
- if bot == nil {
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): unknown bit name (%q)", name)
- } else {
- dictResp["/bot/pass"] = bot.Pass()
- dictResp["/bot/name"] = bot.Name()
- dictResp["/bot/online"] = fmt.Sprint(bot.BotNet().IsOnline().Get())
- dictResp["/bot/fuel"] = fmt.Sprint(bot.Angar().Fuel().Get())
- dictResp["/bot/gold"] = fmt.Sprint(bot.Angar().Gold().Get())
- angar := bot.Angar()
- base := angar.Base()
- bank := base.Bank()
- silverBot := bank.SilverBot()
- dictResp["/bot/silver"] = fmt.Sprint(silverBot.Get())
- dictResp["/bank/silver-time"] = bot.Angar().Base().Bank().CountDown().String()
- dictResp["/bank/silver-mode"] = bot.Angar().Base().Bank().ModeCurrent().Work()
- dictResp["/angar/silver-all"] = fmt.Sprint(bot.Angar().SilverAll().Get())
- dictResp["/bot/mine-time"] = bot.Angar().Base().Mine().CountDown().String()
- dictResp["/bot/mine-mode"] = bot.Angar().Base().Mine().ModeCurrent().Work()
- dictResp["/mine/ruda"] = fmt.Sprint(bot.Angar().Base().Mine().Ruda().Get())
- }
- default:
- dictReq = make(map[string]string)
- dictResp["err"] = fmt.Sprintf("WebApi.fnWsRun(): unknown topic (%q)", topic)
- }
- if !fnWrite() {
- return
- }
- }
- }
|