// package serv_web -- веб-сервер для графики package serv_web import ( "fmt" "log" "os" "time" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/compress" "github.com/gofiber/template/html/v2" "wartank/pkg/types" "wartank/server/serv_web/web_api" "wartank/server/serv_web/web_gui" ) type СервВеб struct { серв types.ИСервер файбер fiber.App порт string } // НовСервВеб -- возвращает новый веб-сервер func НовСервВеб(серв types.ИСервер) (*СервВеб, error) { if серв == nil { return nil, fmt.Errorf("НовСерВеб(): ИСервер==nil") } engine := html.New("./web/tmpl", ".tmpl.html") конф := fiber.Config{ // Prefork: false, ServerHeader: "WarTank", //StrictRouting: false, //CaseSensitive: false, //Immutable: false, //UnescapePath: false, //ETag: false, BodyLimit: 10_000_000, Concurrency: 50, Views: engine, //ViewsLayout: "", //PassLocalsToViews: false, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 15 * time.Second, ReadBufferSize: 4096, WriteBufferSize: 4096, //CompressedFileSuffix: "", //ProxyHeader: "", //GETOnly: false, //ErrorHandler: func(*fiber.Ctx, error) error { panic("not implemented") }, //DisableKeepalive: false, //DisableDefaultDate: false, //DisableDefaultContentType: false, //DisableHeaderNormalizing: false, //DisableStartupMessage: false, AppName: "WarTank.App", // StreamRequestBody: false, // DisablePreParseMultipartForm: false, // ReduceMemoryUsage: false, // JSONEncoder: func(interface{}) ([]byte, error) { panic("not implemented") }, // JSONDecoder: func([]byte, interface{}) error { panic("not implemented") }, // XMLEncoder: func(interface{}) ([]byte, error) { panic("not implemented") }, Network: "tcp4", // EnableTrustedProxyCheck: false, // TrustedProxies: []string{}, // EnableIPValidation: false, // EnablePrintRoutes: false, // ColorScheme: fiber.Colors{ // Black: "", // Red: "", // Green: "", // Yellow: "", // Blue: "", // Magenta: "", // Cyan: "", // White: "", // Reset: "", // }, // RequestMethods: []string{}, // EnableSplittingOnParsers: false, } сам := &СервВеб{ серв: серв, файбер: *fiber.New(конф), } compresConfig := compress.Config{ Level: compress.LevelBestCompression, } сам.файбер.Use(compress.New(compresConfig)) сам.файбер.Static("/static", "./web/static", fiber.Static{ Compress: true, ByteRange: true, Browse: true, Index: "index.html", CacheDuration: 30 * time.Second, MaxAge: 3600, }) сам.файбер.Get("/list_bot/get", сам.гетСписБот) сам.файбер.Post("/list_bot/add", сам.постБотНов) сам.файбер.Post("/bot/stat", сам.постБотСтат) _, ош := web_api.НовВебАпи(сам) if ош != nil { return nil, fmt.Errorf("НовСерВеб(): при создании веб-апи, ош=\n\t%w", ош) } _, ош = web_gui.НовВебГуи(сам) if ош != nil { return nil, fmt.Errorf("НовСерВеб(): при создании веб-гуи, ош=\n\t%w", ош) } return сам, nil } // Файбер -- возвращает файбер func (сам *СервВеб) Файбер() *fiber.App { return &сам.файбер } // Сервер -- возвращает сервер func (сам *СервВеб) Сервер() types.ИСервер { return сам.серв } // Пуск -- запускае веб-сервер в работу func (сам *СервВеб) Пуск() { фнПуск := func() { ош := сам.файбер.Listen(":" + сам.порт) if ош != nil { log.Printf("СервВеб.Пуск(): при работе веб-сервера, ош=\n\t%v\n", ош) сам.серв.CancelApp() } } stage := os.Getenv("STAGE") switch stage { case "local": сам.порт = "18061" case "prod": сам.порт = "18060" case "prod2": сам.порт = "18062" } go фнПуск() } type ПостБотСтат struct { Логин string `form:"name"` } // постБотСтат -- возвращает статистику бота func (сам *СервВеб) постБотСтат(кнт *fiber.Ctx) error { ботСт := &ПостБотСтат{} if err := кнт.BodyParser(ботСт); err != nil { return кнт.JSON(fiber.Map{ "error": "СервВеб.постБотСтат(): при парсинге тела запроса, ош=\n\t%" + err.Error(), }) } if ботСт.Логин == "" { return кнт.JSON(fiber.Map{ "error": "СервВеб.постБотСтат(): пустой логин", }) } имя := ботСт.Логин if имя == "" { return кнт.JSON(fiber.Map{ "error": "СервВеб.постБотСтат(): пустое имя бота", }) } ботоФерма := сам.серв.ServBots() бот := ботоФерма.Get(имя) if бот == nil { return кнт.JSON(fiber.Map{ "error": fmt.Sprintf("СервВеб.постБотСтат(): бот c имнем %q не существует", имя), }) } диктБот := map[string]string{} диктБот["isAuto"] = fmt.Sprint(бот.АвтоИграЕсли()) диктБот["isWork"] = fmt.Sprint(бот.ЕслиПуск()) топливо := бот.Ангар().Топливо().Получ() if топливо == 0 { бот.Ангар().Обновить() топливо = бот.Ангар().Топливо().Получ() } диктБот["топливо"] = fmt.Sprint(топливо) диктБот["золото"] = fmt.Sprint(бот.Ангар().Золото().Получ()) диктБот["серебро"] = fmt.Sprint(бот.Ангар().СереброВсего().Получ()) слава := бот.Ангар().Конвой().Слава().Получ() if слава == 0 { бот.Ангар().Обновить() слава = бот.Ангар().Конвой().Слава().Получ() } диктБот["слава"] = fmt.Sprint(слава) диктБот["прогресс"] = fmt.Sprintf("%v%%", бот.Ангар().Прогресс().Получ()) диктБот["уровень"] = fmt.Sprintf("%v", бот.Ангар().Уровень().Получ()) диктБот["атака"] = fmt.Sprintf("%v", бот.Танк().ТанкСтат().Атака().Получ()) диктБот["броня"] = fmt.Sprintf("%v", бот.Танк().ТанкСтат().Броня().Получ()) диктБот["точность"] = fmt.Sprintf("%v", бот.Танк().ТанкСтат().Точность().Получ()) диктБот["прочность"] = fmt.Sprintf("%v", бот.Танк().ТанкСтат().Прочность().Получ()) диктБот["мощь"] = fmt.Sprintf("%v", бот.Танк().ТанкСтат().Мощь().Получ()) диктБот["шахта_уровень"] = fmt.Sprintf("%v", бот.Ангар().База().Шахта().Уровень().Получ()) диктБот["шахта_режим"] = fmt.Sprintf("%v", бот.Ангар().База().Шахта().СценаРежим().Режим()) диктБот["шахта_сделать_кол"] = fmt.Sprintf("%v", бот.Ангар().База().Шахта().ПродуктКолСейчас()) диктБот["шахта_сделать_назв"] = бот.Ангар().База().Шахта().ПродуктИмяСейчас() диктБот["шахта_сделать_время"] = бот.Ангар().База().Шахта().ПродуктВремяСейчас() диктБот["полигон_уровень"] = fmt.Sprintf("%v", бот.Ангар().База().Полигон().Уровень().Получ()) диктБот["полигон_режим"] = fmt.Sprintf("%v", бот.Ангар().База().Полигон().СценаРежим().Режим()) диктБот["полигон_сделать_кол"] = fmt.Sprintf("%v", бот.Ангар().База().Полигон().ПродуктКолСейчас()) диктБот["полигон_сделать_назв"] = бот.Ангар().База().Полигон().ПродуктИмяСейчас() диктБот["полигон_сделать_время"] = бот.Ангар().База().Полигон().ПродуктВремяСейчас() return кнт.JSON(диктБот) } type ПостБотНов struct { Логин string `form:"login"` Пароль string `form:"pass"` ЕслиАвто string `form:"is_auto"` } // постБотНов -- добавляет бота на бото-ферму func (сам *СервВеб) постБотНов(кнт *fiber.Ctx) error { бот := &ПостБотНов{} if err := кнт.BodyParser(бот); err != nil { return кнт.JSON(fiber.Map{ "error": "СервВеб.постБотНов(): при парсинге тела запроса, ош=\n\t%" + err.Error(), }) } if бот.Логин == "" { return кнт.JSON(fiber.Map{ "error": "СервВеб.постБотНов(): пустой логин", }) } if бот.Пароль == "" { return кнт.JSON(fiber.Map{ "error": "СервВеб.постБотНов(): пустой пароль", }) } if бот.ЕслиАвто == "" { return кнт.JSON(fiber.Map{ "error": "СервВеб.постБотНов(): пустой еслиАвто", }) } var еслиАвто bool if бот.ЕслиАвто == "true" { еслиАвто = true } ботоФерма := сам.серв.ServBots() ош := ботоФерма.НовБот(бот.Логин, бот.Пароль, еслиАвто) if ош != nil { return кнт.JSON(fiber.Map{ "error": "СервВеб.постБотНов(): при создании бота %q, ош=\n\t%" + ош.Error(), }) } return nil } // гетСписБот -- возвращает список ботов func (сам *СервВеб) гетСписБот(кнт *fiber.Ctx) error { списБот := сам.серв.ServBots().ListBot() рез := make([]map[string]string, 0) for _, бот := range списБот { _бот := map[string]string{} _бот["name"] = бот.Имя() _бот["isAuto"] = fmt.Sprint(бот.АвтоИграЕсли()) _бот["isWork"] = fmt.Sprint(бот.ЕслиПуск()) _бот["gold"] = fmt.Sprint(бот.Ангар().Золото().Получ()) _бот["fuel"] = fmt.Sprint(бот.Ангар().Топливо().Получ()) рез = append(рез, _бот) } return кнт.JSON(рез) }