浏览代码

d04 Массовая переделка Под новую архитектуру

SVI 2 年之前
父节点
当前提交
527c330881

+ 7 - 1
cmd/server/main.go

@@ -17,8 +17,14 @@ import (
 	"wartank/server"
 )
 
+func profile() {
+	for {
+		http.ListenAndServe("0.0.0.0:8080", nil)
+	}
+}
+
 func main() {
-	go http.ListenAndServe("0.0.0.0:8080", nil)
+	go profile()
 	serv, err := server.НовСервер()
 	if err != nil {
 		log.Printf("main(): in make IServer, err=\n\t%v\n", err)

+ 4 - 1
pakApp/pakGui/pakWinState/modWinState.py

@@ -4,6 +4,7 @@ from typing import Any
 from tkinter import Toplevel, LabelFrame, Label, Frame, Button
 
 from pakApp.pakGui.pakWinState.pakFrmShahta.modFrmShahta import FrmShahta
+from pakApp.pakGui.pakWinState.pakFrmPolygon.modFrmPolygon import FrmPolygon
 
 
 class WinState(Toplevel):
@@ -12,7 +13,7 @@ class WinState(Toplevel):
     def __init__(self, win_main: Any, name_bot: str) -> None:
         Toplevel.__init__(self, master=win_main)
         self.title("Статистика бота: "+name_bot)
-        self.geometry("800x600")
+        self.geometry("800x640")
         self.win_main = win_main
         self.name = name_bot
         if True:  # Кнопки команд
@@ -138,6 +139,7 @@ class WinState(Toplevel):
         self.frm_basa.pack(side="top", fill="x")
 
         self.frm_shahta = FrmShahta(self.frm_basa)
+        self.frm_poligon = FrmPolygon(self.frm_basa)
 
         self.auto_update()
 
@@ -160,6 +162,7 @@ class WinState(Toplevel):
         self.lbl_prochnost["text"] = "Прочность: " + res["прочность"]
         self.lbl_mosh["text"] = "Танковая мощь: " + res["мощь"]
         self.frm_shahta.upstat(res)
+        self.frm_poligon(res)
 
     def close(self):
         """Закрывает окно по требованию"""

+ 51 - 0
pakApp/pakGui/pakWinState/pakFrmPolygon/modFrmPolygon.py

@@ -0,0 +1,51 @@
+"""Фрейм для отображения состояния полигона"""
+
+from typing import Any
+from tkinter import LabelFrame, Label
+
+
+class FrmPolygon(LabelFrame):
+    """Фрейм для отображения состояния полигона на базе"""
+
+    def __init__(self, frm_basa: Any) -> None:
+        LabelFrame.__init__(self,
+                            master=frm_basa,
+                            text="Полигон",
+                            border=3,
+                            relief="sunken")
+        self.pack(side="left")
+
+        self.lbl_level = Label(self,
+                               text="Уровень: 0",
+                               border=3,
+                               relief="ridge",
+                               anchor="w")
+        self.lbl_level.pack(side="top", fill="x")
+
+        self.lbl_kol = Label(self,
+                             text="Режим: -",
+                             border=3,
+                             relief="ridge",
+                             anchor="w")
+        self.lbl_kol.pack(side="top", fill="x")
+
+        self.lbl_nazv = Label(self,
+                              text="Название: -",
+                              border=3,
+                              relief="ridge",
+                              anchor="w")
+        self.lbl_nazv.pack(side="top", fill="x")
+
+        self.lbl_vrema = Label(self,
+                               text="Время: -",
+                               border=3,
+                               relief="ridge",
+                               anchor="w")
+        self.lbl_vrema.pack(side="top", fill="x")
+
+    def upstat(self, src) -> None:
+        """Обновляет состояние шахты на базе"""
+        self.lbl_level["text"] = "Уровень: " + src["полигон_уровень"]
+        self.lbl_kol["text"] = "Режим: " + src["полигон_сделать_кол"]
+        self.lbl_nazv["text"] = "Название: " + src["полигон_сделать_назв"]
+        self.lbl_vrema["text"] = "Время: " + src["полигон_сделать_время"]

+ 1 - 1
pakApp/pakGui/pakWinState/pakFrmShahta/modFrmShahta.py

@@ -10,7 +10,7 @@ class FrmShahta(LabelFrame):
     def __init__(self, frm_basa: Any) -> None:
         LabelFrame.__init__(self,
                             master=frm_basa,
-                            text="шахта",
+                            text="Шахта",
                             border=3,
                             relief="sunken")
         self.pack(side="left")

+ 21 - 50
pkg/components/section/down_time/down_time.go

@@ -26,11 +26,10 @@ type ВремОбрат struct {
 
 	остатПарсер types.ИПарсерВремя // Парсер значения (мсек)
 
-	остатЗнач    *safe_int.БезопЦелое // Фактическое значение счётчика в мсек
-	порогЗнач    *safe_int.БезопЦелое // Целевое время срабатывания в мсек
+	текущ        *safe_int.БезопЦелое // Фактическое значение счётчика в мсек
+	лимит        *safe_int.БезопЦелое // Целевое время срабатывания в мсек
 	еслиРаботает *safe_bool.БезопБул  // Признак работы
 
-	канТик   chan int // Канал секундных интервалов сна (для отображения)
 	канВызов chan int // Канал для отправки сигналов (для верхнего уровня)
 
 	кнт      context.Context // Контекст для счётчика времени
@@ -47,19 +46,17 @@ func НовВремОбрат(сцена types.ИСцена, время alias.М
 	кнт, фнОтмена := context.WithCancel(сцена.Кнт())
 	сам := &ВремОбрат{
 		сцена:        сцена,
-		остатЗнач:    safe_int.НовБезопЦелое(),
-		канТик:       make(chan int, 5),
+		текущ:        safe_int.НовБезопЦелое(),
 		канВызов:     make(chan int, 2),
 		еслиРаботает: safe_bool.НовБезопБул(),
 		остатПарсер:  parser_time.НовПарсерВремя(),
-		порогЗнач:    safe_int.НовБезопЦелое(),
+		лимит:        safe_int.НовБезопЦелое(),
 		кнт:          кнт,
 		фнОтмена:     фнОтмена,
 	}
 	мСек := alias.МилСек(time.Now().UTC().UnixMilli()) + время
-	сам.порогЗнач.Уст(int(мСек))
+	сам.лимит.Уст(int(мСек))
 	сам.еслиРаботает.Уст()
-	go сам.сделатьТик()
 	go сам.пуск()
 	go сам.закрыть()
 	_ = types.ИВремяОстат(сам)
@@ -72,44 +69,32 @@ func (сам *ВремОбрат) ПолучМилСек() alias.МилСек {
 }
 
 // Запускает тикер для интервалов сна (через каждые 100 мСек)
-func (сам *ВремОбрат) сделатьТик() {
-	defer close(сам.канТик)
+func (сам *ВремОбрат) пуск() {
+	defer close(сам.канВызов)
+	фнЖдать := func() {
+		timeNow := time.Now().UTC().UnixMilli()
+		if сам.лимит.Получ() > int(timeNow) {
+			return
+		}
+		сам.канВызов <- 1
+		сам.лимит.Уст(int(timeNow) + int(сам.остатПарсер.ПолучМилСек()))
+	}
 	for {
 		select {
 		case <-сам.кнт.Done(): // Отмена контекста тикера (а может и сцены, может и бота)
 			return
 		default:
 			time.Sleep(спатьИнтервал)
-			if !сам.еслиРаботает.Получ() {
-				сам.фнОтмена()
-				return
-			}
-			timeNow := time.Now().UTC().Unix()
-			if сам.порогЗнач.Получ() < int(timeNow) {
-				continue
-			}
-			сам.канТик <- 1
-			сам.фнОтмена()
-			сам.еслиРаботает.Сброс()
-			return
+			фнЖдать()
 		}
 	}
 }
 
-// Главный цикл обратного отсчёта
-func (сам *ВремОбрат) пуск() {
-	for range сам.канТик {
-		close(сам.канВызов)
-		сам.фнОтмена()
-		return
-	}
-}
-
 // Сброс -- сбрасывает оставшееся время в ноль
 func (сам *ВремОбрат) Сброс() {
 	сам.остатПарсер.Сброс()
-	сам.остатЗнач.Сброс()
-	сам.порогЗнач.Сброс()
+	сам.текущ.Сброс()
+	сам.лимит.Сброс()
 }
 
 // Стоп -- останавливает работу cчётчика
@@ -125,20 +110,9 @@ func (сам *ВремОбрат) Уст(время alias.Время) error {
 		return fmt.Errorf("ВремОбрат(): ошибка при установке времени, ош=\n\t%w", ош)
 	}
 	_val := сам.остатПарсер.ПолучМилСек()
-	сам.остатЗнач.Уст(int(_val))
-	val := int(time.Now().UTC().UnixMilli()) + сам.остатЗнач.Получ()
-	сам.порогЗнач.Уст(val)
-	return nil
-}
-
-// устанавливает число оставшихся сек
-func (сам *ВремОбрат) set_val(val int) error {
-	сам.блок.Lock()
-	defer сам.блок.Unlock()
-	if val < 0 {
-		return fmt.Errorf("CountTime.set_val(): val(%v)<0", val)
-	}
-	сам.остатЗнач.Уст(val)
+	сам.текущ.Уст(int(_val))
+	val := int(time.Now().UTC().UnixMilli()) + сам.текущ.Получ()
+	сам.лимит.Уст(val)
 	return nil
 }
 
@@ -146,9 +120,6 @@ func (сам *ВремОбрат) set_val(val int) error {
 func (сам *ВремОбрат) String() string {
 	сам.блок.RLock()
 	defer сам.блок.RUnlock()
-	timeNow := time.Now().UTC().Unix()
-	val := сам.порогЗнач.Получ() - int(timeNow)
-	go сам.set_val(val)
 	return сам.остатПарсер.String()
 }
 

+ 5 - 20
pkg/components/section/down_time/down_time_test.go

@@ -51,10 +51,7 @@ func TestCountTime(t *testing.T) {
 // Оменяет работу таймера
 func (sf *tester) cancel() {
 	sf.t.Logf("=cancel=\n")
-	ct := НовВремОбрат(sf.zone, 0)
-	for len(ct.канТик) > 0 {
-		<-ct.канТик
-	}
+	_ = НовВремОбрат(sf.zone, 0)
 	sf.app.CancelApp()
 	time.Sleep(time.Millisecond * 150)
 }
@@ -65,15 +62,12 @@ func (sf *tester) checkTick() {
 	{ // Секундный тик
 		времОбрат.Уст("00:00:08")
 		time.Sleep(time.Second * 1)
-		времОбрат.канТик <- 1
-		time.Sleep(time.Millisecond * 20)
 		if val := времОбрат.String(); val != "00:00:08" {
 			sf.t.Errorf("checkTick(): счётчик(%v)!='00:00:08'", val)
 		}
 	}
 	{ // Проверка времени прямо сейчас
-		времОбрат.канТик <- 1
-		time.Sleep(time.Millisecond * 20)
+		time.Sleep(time.Millisecond * 100)
 		if val := времОбрат.String(); val != "00:00:08" {
 			sf.t.Errorf("checkTick(): счётчик(%v)!='00:00:08'", val)
 		}
@@ -84,14 +78,10 @@ func (sf *tester) checkTick() {
 		if val := времОбрат.String(); val != string(strTime) {
 			sf.t.Errorf("checkTick(): счётчик(%v)!=%s", val, strTime)
 		}
-		времОбрат.канТик <- 1
 		// Выход из функции -- и есть факт обратного вызова
 		sf.call()
 		{ // Проверка отсутствия обратного вызова прямо сейчас
 			времОбрат.Уст("00:00:00")
-			времОбрат.блок.Lock()
-			времОбрат.канТик <- 1
-			времОбрат.блок.Unlock()
 			// Выход из функции -- и есть факт обратного вызова
 			sf.call()
 			if val := времОбрат.ПолучМилСек(); val != 0 {
@@ -174,13 +164,8 @@ func (sf *tester) setInt() {
 	go sf.call()
 	sf.zone = mock_zone.НовМокСцена()
 	ct := НовВремОбрат(sf.zone, 0)
-	{ // Bad-1 Отрицательное число
-		if sf.err = ct.set_val(-1); sf.err == nil {
-			sf.t.Errorf("setInt(): BAD-1 err==nil")
-		}
-	}
 	{ // GOOD-1
-		if sf.err = ct.set_val(8); sf.err != nil {
+		if sf.err = ct.Уст("8"); sf.err != nil {
 			sf.t.Errorf("setInt(): GOOD-1 err=%v", sf.err)
 		}
 		if ct.остатПарсер.Час().Получ() != 0 {
@@ -197,7 +182,7 @@ func (sf *tester) setInt() {
 		}
 	}
 	{ // GOOD-2
-		if sf.err = ct.set_val(121); sf.err != nil {
+		if sf.err = ct.Уст("121"); sf.err != nil {
 			sf.t.Errorf("setInt(): GOOD-2 err=%v", sf.err)
 		}
 		if ct.остатПарсер.Час().Получ() != 0 {
@@ -214,7 +199,7 @@ func (sf *tester) setInt() {
 		}
 	}
 	{ // GOOD-3
-		if sf.err = ct.set_val(7203); sf.err != nil {
+		if sf.err = ct.Уст("7203"); sf.err != nil {
 			sf.t.Errorf("setInt(): GOOD-3 err=%v", sf.err)
 		}
 		if ct.остатПарсер.Час().Получ() != 2 {

+ 27 - 32
pkg/components/section/section.go

@@ -8,7 +8,6 @@ import (
 
 	"wartank/pkg/alias"
 	"wartank/pkg/components/lst_string"
-	"wartank/pkg/components/parser_time"
 	"wartank/pkg/components/section/down_time"
 	"wartank/pkg/components/section/section_mode"
 	"wartank/pkg/components/section/zone"
@@ -17,26 +16,26 @@ import (
 
 // Секция -- секция игры
 type Секция struct {
-	*zone.Zone
-	countDown types.ИВремяОстат     // Обратный отсчёт до окончания работы режима
-	mode      types.ИРежимРаботы    // Объект режима работы
-	lstString *lst_string.LstString // Список строк из сети для анализа секции
-	блок      sync.RWMutex
+	*zone.Зона
+	времяОстат types.ИВремяОстат     // Обратный отсчёт до окончания работы режима
+	режим      types.ИРежимРаботы    // Объект режима работы
+	списСтр    *lst_string.LstString // Список строк из сети для анализа секции
+	блок       sync.RWMutex
 }
 
 // НовСекция -- возвращает новую секцию игры
 func НовСекция(бот types.ИБот, зонаИмя, стрКонтроль string) (*Секция, error) {
 	log.Printf("НовСекция(): стрКонтроль=%q\n", стрКонтроль)
-	zone, err := zone.NewZone(бот, зонаИмя)
+	zone, err := zone.НовЗона(бот, зонаИмя)
 	if err != nil {
 		return nil, fmt.Errorf("НовСекция(): in create IZone, err=\n\t%w", err)
 	}
 	sf := &Секция{
-		Zone:      zone,
-		countDown: down_time.НовВремОбрат(zone, 5),
-		mode:      section_mode.NewSectionMode(),
+		Зона:       zone,
+		времяОстат: down_time.НовВремОбрат(zone, 5),
+		режим:      section_mode.NewSectionMode(),
 	}
-	sf.lstString, err = lst_string.NewLstString(стрКонтроль)
+	sf.списСтр, err = lst_string.NewLstString(стрКонтроль)
 	if err != nil {
 		return nil, fmt.Errorf("НовСекция(): in create *LstString, err=\n\t%w", err)
 	}
@@ -45,7 +44,7 @@ func НовСекция(бот types.ИБот, зонаИмя, стрКонтр
 
 // СтрОбновить -- обновляет список строк секции по требованию
 func (sf *Секция) СтрОбновить(lstString []string) error {
-	if err := sf.lstString.Set(lstString); err != nil {
+	if err := sf.списСтр.Set(lstString); err != nil {
 		return fmt.Errorf("Section.СтрОбновить(): при установке lstString, err=\n\t%w", err)
 	}
 	return nil
@@ -53,29 +52,25 @@ func (sf *Секция) СтрОбновить(lstString []string) error {
 
 // СписПолучить -- возвращает список строк секции
 func (sf *Секция) СписПолучить() []string {
-	return sf.lstString.Get()
+	return sf.списСтр.Get()
 }
 
-// ОбратВремяУст -- устанавливает новое значение обратного счётчика времени (int)
-func (сам *Секция) ОбратВремяУст(время alias.МилСек) error {
-	сам.блок.Lock()
-	defer сам.блок.Unlock()
-	сам.countDown = down_time.НовВремОбрат(сам, время)
-	// if err := sf.countDown.Set(sec); err != nil {
-	// 	return fmt.Errorf("Секция.ОбратВремяУст(): err=\n\t%w", err)
-	// }
+// ОбратВремяУст -- устанавливает новое значение обратного счётчика времени
+func (сам *Секция) ОбратВремяУст(время alias.Время) error {
+	ош := сам.времяОстат.Уст(время)
+	if ош != nil {
+		return fmt.Errorf("Секция.ОбратВремяУст(): ош=\n\t%w", ош)
+	}
 	return nil
 }
 
-// ParseCountDown -- устанавливает новое значение обратного счётчика времени (string)
-func (sf *Секция) ParseCountDown(времяСек alias.Время) error {
-	var pt types.ИПарсерВремя
-	pt = parser_time.НовПарсерВремя()
-	pt.Уст(времяСек)
-	милСек := pt.ПолучМилСек()
-	sf.countDown = down_time.НовВремОбрат(sf, милСек)
+// Уст -- устанавливает новое значение обратного счётчика времени
+func (сам *Секция) Уст(времяСек alias.Время) error {
+	if ош := сам.времяОстат.Уст(времяСек); ош != nil {
+		return fmt.Errorf("Секция.ParseCountDown(): err=\n\t%w", ош)
+	}
 	// if err := sf.countDown.Set(sec); err != nil {
-	// 	return fmt.Errorf("Section.SetCountDown(): err=\n\t%w", err)
+	//
 	// }
 	return nil
 }
@@ -84,10 +79,10 @@ func (sf *Секция) ParseCountDown(времяСек alias.Время) error
 func (сам *Секция) ВремяОпрос() types.ИВремяОстат {
 	сам.блок.RLock()
 	defer сам.блок.RUnlock()
-	return сам.countDown
+	return сам.времяОстат
 }
 
 // РежимТекущ -- текущий режим работы
-func (sf *Секция) РежимТекущ() types.ИРежимРаботы {
-	return sf.mode
+func (сам *Секция) РежимТекущ() types.ИРежимРаботы {
+	return сам.режим
 }

+ 27 - 27
pkg/components/section/zone/zone.go

@@ -8,52 +8,52 @@ import (
 	"wartank/pkg/types"
 )
 
-// Zone -- игровая зона (ангар, база, бан, битва и т.п.)
-type Zone struct {
-	bot      types.ИБот // Ссылка на бота зоны
-	ctx      context.Context
-	fnCancel func()
-	name     string // Имя игровой зоны
+// Зона -- игровая зона (ангар, база, бан, битва и т.п.)
+type Зона struct {
+	бот      types.ИБот // Ссылка на бота зоны
+	кнт      context.Context
+	фнОтмена func()
+	имя      string // Имя игровой зоны
 }
 
-// NewZone -- возвращает новую игровую зону
-func NewZone(bot types.ИБот, zoneName string) (*Zone, error) {
+// НовЗона -- возвращает новую игровую зону
+func НовЗона(бот types.ИБот, зонаИмя string) (*Зона, error) {
 	{ // Предусловия
-		if bot == nil {
-			return nil, fmt.Errorf("NewZone(): IBot==nil")
+		if бот == nil {
+			return nil, fmt.Errorf("НовЗона(): IBot==nil")
 		}
-		if zoneName == "" {
-			return nil, fmt.Errorf("NewZone(): zoneName is empty")
+		if зонаИмя == "" {
+			return nil, fmt.Errorf("НовЗона(): zoneName is empty")
 		}
 	}
-	log.Printf("NewZone(): name=%q\tzone=%q\n", bot.Имя(), zoneName)
-	ctx, fnCancel := context.WithCancel(bot.Кнт())
-	sf := &Zone{
-		bot:      bot,
-		name:     zoneName,
-		ctx:      ctx,
-		fnCancel: fnCancel,
+	log.Printf("НовЗона(): name=%q\tzone=%q\n", бот.Имя(), зонаИмя)
+	кнт, fnCancel := context.WithCancel(бот.Кнт())
+	sf := &Зона{
+		бот:      бот,
+		имя:      зонаИмя,
+		кнт:      кнт,
+		фнОтмена: fnCancel,
 	}
 	_ = types.ИСцена(sf)
 	return sf, nil
 }
 
 // Кнт -- возвращает контекст игровой зоны
-func (sf *Zone) Кнт() context.Context {
-	return sf.ctx
+func (sf *Зона) Кнт() context.Context {
+	return sf.кнт
 }
 
 // Закончить -- отменяет контекст игровой зоны
-func (sf *Zone) Закончить() {
-	sf.fnCancel()
+func (sf *Зона) Закончить() {
+	sf.фнОтмена()
 }
 
 // Бот -- возвращает бота игровой зоны
-func (sf *Zone) Бот() types.ИБот {
-	return sf.bot
+func (sf *Зона) Бот() types.ИБот {
+	return sf.бот
 }
 
 // Имя -- возвращает имя зоны
-func (sf *Zone) Имя() string {
-	return sf.name
+func (sf *Зона) Имя() string {
+	return sf.имя
 }

+ 2 - 2
pkg/types/ibase.go

@@ -12,9 +12,9 @@ type ИБаза interface {
 	// Банк -- возвращает объект банка
 	Банк() ИБанк
 	// Полигон -- возвращает объект полигона
-	Полигон() ИПолигон
+	Полигон() ИБазаПолигон
 	// Шахта -- возвращает объект шахты
-	Шахта() ИШахта
+	Шахта() ИБазаШахта
 	// Рынок -- возвращает рынок
 	Рынок() ИРынок
 }

+ 4 - 17
pkg/types/imine.go → pkg/types/ibase_basic.go

@@ -1,26 +1,13 @@
 package types
 
-/*
-	Интерфейс к объекту шахты
-*/
-
-// ИШахта -- интерфейс к объекту шахты
-type ИШахта interface {
-	ИСценаСтр
-	// Руда -- возвращает объект руды
-	Руда() ИСтатПарам
-	// Железо -- возвращает объект железа
-	Железо() ИСтатПарам
-	// Сталь -- возвращает объект стали
-	Сталь() ИСтатПарам
-	// Свинец -- возвращает объект свинца
-	Свинец() ИСтатПарам
+// ИБазаСтроение -- базовое строение для строения на базе
+type ИБазаСтроение interface {
+	// Уровень -- возвращает уровень шахты
+	Уровень() ИСтатПарам
 	// ПродуктКолСейчас -- количество производимого продукта
 	ПродуктКолСейчас() int
 	// ПродуктИмяСейчас -- количество производимого продукта сейчас
 	ПродуктИмяСейчас() string
 	// ПродуктВремяСейчас -- сколько времени до окончания продукта ждать
 	ПродуктВремяСейчас() string
-	// Уровень -- возвращает уровень шахты
-	Уровень() ИСтатПарам
 }

+ 19 - 0
pkg/types/ibase_mine.go

@@ -0,0 +1,19 @@
+package types
+
+/*
+	Интерфейс к объекту шахты
+*/
+
+// ИБазаШахта -- интерфейс к объекту шахты
+type ИБазаШахта interface {
+	ИСценаСтр
+	ИБазаСтроение
+	// Руда -- возвращает объект руды
+	Руда() ИСтатПарам
+	// Железо -- возвращает объект железа
+	Железо() ИСтатПарам
+	// Сталь -- возвращает объект стали
+	Сталь() ИСтатПарам
+	// Свинец -- возвращает объект свинца
+	Свинец() ИСтатПарам
+}

+ 11 - 0
pkg/types/ibase_polygon.go

@@ -0,0 +1,11 @@
+package types
+
+/*
+	Интерфейс к полигону.
+*/
+
+// ИБазаПолигон -- интерфейс к полигону
+type ИБазаПолигон interface {
+	ИСценаСтр
+	ИБазаСтроение
+}

+ 0 - 10
pkg/types/ipolygon.go

@@ -1,10 +0,0 @@
-package types
-
-/*
-	Интерфейс к полигону.
-*/
-
-// ИПолигон -- интерфейс к полигону
-type ИПолигон interface {
-	ИСценаСтр
-}

+ 2 - 2
server/serv_bots/warbot/angar/angar.go

@@ -188,7 +188,7 @@ func (sf *Ангар) Пуск() error {
 	фнЦикл := func() bool {
 		sf.Обновить()
 		// sf.конвойПроверить()
-		if err := sf.Секция.ОбратВремяУст(60); err != nil {
+		if err := sf.Секция.ОбратВремяУст("01:00"); err != nil {
 			sf.Закончить()
 			logrus.WithError(err).Errorln("Ангар.Run(): in update ICountTime")
 			return false
@@ -196,7 +196,7 @@ func (sf *Ангар) Пуск() error {
 		return true
 	}
 	go func() {
-		sf.Секция.ОбратВремяУст(1)
+		sf.Секция.ОбратВремяУст("01")
 		for {
 			select {
 			case <-sf.бот.Кнт().Done(): // Отмена контекста

+ 1 - 1
server/serv_bots/warbot/angar/base/bank/bank.go

@@ -235,7 +235,7 @@ func (sf *Банк) сделатьСеребро() (alias.МилСек, error) {
 		if err = sf.СтрОбновить(lstBank); err != nil {
 			return 0, fmt.Errorf("BankNet.makeProduct(): при обновлении lstBank, err=%w", err)
 		}
-		if err := sf.ParseCountDown(alias.Время(time1)); err != nil {
+		if err := sf.Уст(alias.Время(time1)); err != nil {
 			log.Printf("WARN Банк.makeProduct(): при установке времени производства банка(%v)\n\terr=%v\n", time1, err)
 		}
 	}

+ 17 - 17
server/serv_bots/warbot/angar/base/base.go

@@ -25,8 +25,8 @@ import (
 */
 
 const (
-	времОжидПлат    = 60 * 1_000   // Время ожидания платного ускорения
-	времОжидБесплат = 1810 * 1_000 // Время ожидания бесплатного ускорения
+	времОжидПлат    = "01:00" // Время ожидания платного ускорения
+	времОжидБесплат = "30:00" // Время ожидания бесплатного ускорения
 
 )
 
@@ -154,24 +154,24 @@ func (sf *База) runComponent() error {
 
 // Выбирает время обновления базы по компонентам
 func (sf *База) setCountDown() {
-	timeBase := sf.банк.ВремяОпрос().ПолучМилСек()
+	timeBase := sf.банк.ВремяОпрос().String()
 	timeCount := timeBase
-	timeArsenal := sf.арсенал.ВремяОпрос().ПолучМилСек()
-	timeMine := sf.шахта.ВремяОпрос().ПолучМилСек()
+	timeArsenal := sf.арсенал.ВремяОпрос().String()
+	timeMine := sf.шахта.ВремяОпрос().String()
 	if timeArsenal < timeCount {
 		timeCount = timeArsenal
 	}
 	if timeMine < timeCount {
 		timeCount = timeMine
 	}
-	if timeCount <= 1*1_000 {
+	if timeCount <= "05" {
 		sf.времОстат = 5
 		return
 	}
-	if timeCount > (600 * 1_000) {
+	if timeCount > "00:10:00" {
 		sf.времОстат = 600
 	}
-	sf.Секция.ОбратВремяУст(timeCount)
+	sf.Секция.ОбратВремяУст(alias.Время(timeCount))
 }
 
 // Арсенал -- возвращает объект арсенала
@@ -187,12 +187,12 @@ func (sf *База) Банк() types.ИБанк {
 }
 
 // Полигон -- возвращает объект полигона
-func (sf *База) Полигон() types.ИПолигон {
+func (sf *База) Полигон() types.ИБазаПолигон {
 	return sf.полигон
 }
 
 // Шахта -- возвращает объект шахты
-func (sf *База) Шахта() types.ИШахта {
+func (sf *База) Шахта() types.ИБазаШахта {
 	return sf.шахта
 }
 
@@ -241,7 +241,7 @@ func (sf *База) checkMineTime() {
 	strTime := lstTime[1]
 	lstTime = strings.Split(strTime, `</span></span></div></td>`)
 	strTime = lstTime[0]
-	if err := sf.шахта.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := sf.шахта.Уст(alias.Время(strTime)); err != nil {
 		log.Printf("ERRO Base.checkMineTime(): при установке обратного отсчёта(%v), err=\n\t%v\n", strTime, err)
 	}
 }
@@ -349,7 +349,7 @@ func (sf *База) шахтаСтатаОбновить() {
 			strTime := lstTime[1]
 			lstTime = strings.Split(strTime, `</span></span></div></td>`)
 			strTime = lstTime[0]
-			if err := sf.шахта.ParseCountDown(alias.Время(strTime)); err != nil {
+			if err := sf.шахта.Уст(alias.Время(strTime)); err != nil {
 				log.Printf("ERRO Base.checkMineStat(): при установке времени ожидания шахты(%v)\n\terr=%v\n", strTime, err)
 			}
 		}
@@ -434,7 +434,7 @@ func (sf *База) проверитьАрсеналВремя() {
 	strTime := lstTime[1]
 	lstTime = strings.Split(strTime, `</span></span></div></td>`)
 	strTime = lstTime[0]
-	if err := sf.арсенал.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := sf.арсенал.Уст(alias.Время(strTime)); err != nil {
 		log.Printf("ERRO Base.checkArsenalTime(): при установке времени ожидания арсенала(%v)\n\terr=%v\n", strTime, err)
 	}
 }
@@ -608,7 +608,7 @@ func (sf *База) checkBankTime() {
 	strTime := lstTime[1]
 	lstTime = strings.Split(strTime, `</span></span></div></td>`)
 	strTime = lstTime[0]
-	if err := sf.банк.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := sf.банк.Уст(alias.Время(strTime)); err != nil {
 		log.Printf("ERRO Base.checkBankTime(): при установке времени ожидания банка(%v)\n\terr=%v\n", strTime, err)
 	}
 }
@@ -636,7 +636,7 @@ func (sf *База) checkBankProduct() {
 		return
 	}
 	sf.банк.UpdateLst()
-	sf.банк.ОбратВремяУст(1_1000)
+	sf.банк.ОбратВремяУст("01:00")
 }
 
 // Проверка получения серебра из банка
@@ -683,13 +683,13 @@ func (sf *База) checkBankTake() {
 		if err := sf.банк.СтрОбновить(lstBank); err != nil {
 			log.Printf("ERRO Base.checkBankTake(): при установке lstBank, err=\n\t%v'n", err)
 		}
-		sf.банк.ОбратВремяУст(1_000)
+		sf.банк.ОбратВремяУст("01:00")
 		return
 	}
 	if err := sf.СтрОбновить(lstBank); err != nil {
 		log.Printf("ERRO Base.checkBankTake(): при установке lstBase, err=\n\t%v'n", err)
 	}
-	sf.банк.ОбратВремяУст(1_000)
+	sf.банк.ОбратВремяУст("01:00")
 }
 
 // Проверяет на ускорение апгрейда банка

+ 2 - 2
server/serv_bots/warbot/angar/base/market/market.go

@@ -59,7 +59,7 @@ func (сам *Рынок) пуск() {
 			log.Printf("Market.run(): timeCount=%v\n", сам.ВремяОпрос().ПолучМилСек())
 			_ = сам.купитьЗолото()
 			// Если золото не куплено -- обновить время ожидания
-			сам.Секция.ОбратВремяУст(120 * 1_000)
+			сам.Секция.ОбратВремяУст("02:00")
 		}
 		сам.проверОжидание()
 		for сам.купитьЗолото() {
@@ -120,7 +120,7 @@ func (сам *Рынок) проверОжидание() {
 		}
 		lstTime := strings.Split(strOut, `Минимальная цена через `)
 		strTime := lstTime[1]
-		if err := сам.ParseCountDown(alias.Время(strTime)); err != nil {
+		if err := сам.Уст(alias.Время(strTime)); err != nil {
 			// log._rintf("ERRO Market.checkTime(): при установке времени ожидания рынка(%v)\n\terr=%v\n", strTime, err)
 			return // Возможно минимальная цена
 		}

+ 15 - 6
server/serv_bots/warbot/angar/base/mine/mine.go

@@ -1,6 +1,7 @@
 package mine
 
 import (
+	"context"
 	"fmt"
 	"log"
 	"strconv"
@@ -32,6 +33,8 @@ type Шахта struct {
 	продуктИмя   string           // Что сейчас делается
 	продуктКол   types.ИСтатПарам // Сколько делается прямо сейчас
 	продуктВремя string           // Сколько осталось времени прямо сейчас
+	кнт          context.Context  // контекст шахты
+	фнОтмена     func()           // Функция отмены шахты
 }
 
 // НовШахта -- возвращает новый *Mine
@@ -64,6 +67,7 @@ func НовШахта(база types.ИБаза) (*Шахта, error) {
 	if ош != nil {
 		return nil, fmt.Errorf("НовШахта(): при создании статистики числа добычи, ош=\n\t%w", ош)
 	}
+	кнт, фнОтмена := context.WithCancel(база.Кнт())
 	сам := &Шахта{
 		Секция:     секция,
 		бот:        база.Бот(),
@@ -74,11 +78,15 @@ func НовШахта(база types.ИБаза) (*Шахта, error) {
 		свинец:     свинец,
 		продуктКол: добычаЧисло,
 		уровень:    уровень,
+		кнт:        кнт,
+		фнОтмена:   фнОтмена,
 	}
+
 	сам.сеть, ош = minenet.NewMineNet(сам)
 	if ош != nil {
 		return nil, fmt.Errorf("NewMine(): in create NetMine, err=\n\t%w", ош)
 	}
+	_ = types.ИБазаШахта(сам)
 	return сам, nil
 }
 
@@ -92,9 +100,10 @@ func (сам *Шахта) пуск() {
 	time.Sleep(time.Second * 3)
 	for {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.кнт.Done():
 			return
 		case <-сам.ВремяОпрос().КаналСиг():
+
 		default:
 			log.Printf("Шахта.пуск()\n")
 			сам.шахтаЗабрать()
@@ -160,7 +169,7 @@ func (сам *Шахта) количествоПолучить() {
 	strTime = strings.TrimPrefix(strTime, `<td><div class="value-block lh1"><span><span>`)
 	strTime = strings.TrimSuffix(strTime, `</span></span></div></td>`)
 	сам.продуктВремя = strTime
-	if err := сам.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := сам.Уст(alias.Время(strTime)); err != nil {
 		log.Printf("Шахта.количествоПолучить(): при установке времени производства(%v), err=\n\t%v\n", strTime, err)
 	}
 }
@@ -487,7 +496,7 @@ func (сам *Шахта) рудаСделать() {
 		// log._rintf("ERRO Шахта.сделатьРуду(): при обновлении lstMine, err=\n\t%v\n", err)
 		return
 	}
-	if err := сам.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := сам.Уст(alias.Время(strTime)); err != nil {
 		log.Printf("ERRO Шахта.сделатьРуду(): при установке времени ожидания добычи руды(%v)\n\terr=%v\n", strTime, err)
 	}
 	lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
@@ -547,7 +556,7 @@ func (сам *Шахта) железоСделать() {
 		// log._rintf("ERRO MineNet.makeFerrum(): при обновлении lstMine, err=\n\t%v\n", err)
 		return
 	}
-	if err := сам.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := сам.Уст(alias.Время(strTime)); err != nil {
 		log.Printf("ERRO Mine.makeFerrum(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
 	}
 	lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
@@ -607,7 +616,7 @@ func (сам *Шахта) стальСделать() {
 		// log._rintf("ERRO MineNet.makeSteel(): при обновлении lstMine, err=\n\t%v\n", err)
 		return
 	}
-	if err := сам.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := сам.Уст(alias.Время(strTime)); err != nil {
 		log.Printf("ERRO Mine.makeSteel(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
 	}
 	lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
@@ -667,7 +676,7 @@ func (сам *Шахта) свинецСделать() {
 		// log._rintf("ERRO Шахта.сделатьСвинец(): при обновлении lstMine, err=\n\t%v\n", err)
 		return
 	}
-	if err := сам.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := сам.Уст(alias.Время(strTime)); err != nil {
 		log.Printf("ERRO Шахта.сделатьСвинец(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
 	}
 	lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)

+ 1 - 1
server/serv_bots/warbot/angar/base/mine/minenet/minenet.go

@@ -16,7 +16,7 @@ type MineNet struct {
 }
 
 // NewMineNet -- возвращает новый *MineNet
-func NewMineNet(mine types.ИШахта) (*MineNet, error) {
+func NewMineNet(mine types.ИБазаШахта) (*MineNet, error) {
 	sectionNet, err := sectionnet.NewSectionNet(mine, "https://wartank.ru/production/Mine")
 	if err != nil {
 		return nil, fmt.Errorf("NewMineNet(): in create *SectionNet, err=\n\t%w", err)

+ 53 - 16
server/serv_bots/warbot/angar/base/polygon/polygon.go

@@ -8,9 +8,13 @@ import (
 	"time"
 
 	"wartank/pkg/alias"
+	"wartank/pkg/components/safe_int"
+	"wartank/pkg/components/safe_string"
 	"wartank/pkg/components/section"
+	"wartank/pkg/components/section/down_time"
 	"wartank/pkg/types"
 	"wartank/server/serv_bots/warbot/angar/base/polygon/polygonnet"
+	"wartank/server/serv_bots/warbot/tank/tankstat/static_param"
 )
 
 /*
@@ -18,37 +22,70 @@ import (
 */
 
 const (
-	времОжидПлат    = 60   // Время ожидания платного ускорения
-	времОжидБесплат = 1810 // Время ожидания бесплатного ускорения
+	времОжидПлат    = "05:00" // Время ожидания платного ускорения
+	времОжидБесплат = "30:00" // Время ожидания бесплатного ускорения
 
 )
 
 // Полигон -- объект полигона на базе
 type Полигон struct {
 	*section.Секция
-	бот      types.ИБот
-	танкСтат types.ИТанкСтат
-	сеть     *polygonnet.ПолигонСеть
+	бот           types.ИБот
+	танкСтат      types.ИТанкСтат
+	сеть          *polygonnet.ПолигонСеть
+	времяОстат    types.ИВремяОстат
+	продуктСейчас *safe_string.БезопСтрока
+	продуктКол    *safe_int.БезопЦелое
+	уровень       *static_param.СтатПарам
 }
 
 // НовПолигон -- возвращает новый *Polygon
-func НовПолигон(base types.ИБаза) (*Полигон, error) {
-	секция, ош := section.НовСекция(base.Бот(), "Полигон", `<title>Полигон</title>`)
+func НовПолигон(база types.ИБаза) (*Полигон, error) {
+	секция, ош := section.НовСекция(база.Бот(), "Полигон", `<title>Полигон</title>`)
 	if ош != nil {
-		return nil, fmt.Errorf("NewPolygon(): in create *Section, err=\n\t%w", ош)
+		return nil, fmt.Errorf("НовПолигон(): при создании ИСекция, ош=\n\t%w", ош)
+	}
+	уровень, ош := static_param.НовСтатПарам("уровень полигона")
+	if ош != nil {
+		return nil, fmt.Errorf("НовПолигон(): при создании уровня полигона, ош=\n\t%w", ош)
 	}
 	сам := &Полигон{
-		Секция:   секция,
-		бот:      base.Бот(),
-		танкСтат: base.Бот().Танк().ТанкСтат(),
+		Секция:        секция,
+		бот:           база.Бот(),
+		танкСтат:      база.Бот().Танк().ТанкСтат(),
+		времяОстат:    down_time.НовВремОбрат(секция, 5_000),
+		продуктСейчас: safe_string.НовБезопСтрока(),
+		продуктКол:    safe_int.НовБезопЦелое(),
+		уровень:       уровень,
 	}
 	сам.сеть, ош = polygonnet.НовПолигонСеть(сам)
 	if ош != nil {
 		return nil, fmt.Errorf("NewPolygon(): in create NetPolygon, err=\n\t%w", ош)
 	}
+	_ = types.ИБазаПолигон(сам)
 	return сам, nil
 }
 
+// Уровень -- возвращает уровень полигона
+func (сам *Полигон) Уровень() types.ИСтатПарам {
+	return сам.уровень
+}
+
+// ПродуктКолСейчас -- количество продукта, что именно сейчас производится на полигоне
+func (сам *Полигон) ПродуктКолСейчас() int {
+	return сам.продуктКол.Получ()
+}
+
+// ПродуктИмяСейчас -- что именно сейчас производится на полигоне
+func (сам *Полигон) ПродуктИмяСейчас() string {
+	return сам.продуктСейчас.Получ()
+}
+
+// ПродуктВремяСейчас -- сколько осталось времени до обновы полигона
+func (сам *Полигон) ПродуктВремяСейчас() string {
+	return сам.времяОстат.String()
+}
+
 // Пуск -- запускает работу полигона в отдельном потоке
 func (sf *Полигон) Пуск() error {
 	go sf.пуск()
@@ -57,10 +94,10 @@ func (sf *Полигон) Пуск() error {
 
 // выполняет опрос полигона базы.
 func (сам *Полигон) пуск() {
-	сам.ОбратВремяУст(2_000)
+	сам.ОбратВремяУст("02")
 	for {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.Кнт().Done():
 			return
 		case <-сам.ВремяОпрос().КаналСиг():
 		default:
@@ -228,7 +265,7 @@ func (сам *Полигон) времяОбнов() {
 	)
 	defer func() {
 		if !isSet {
-			сам.ОбратВремяУст(5_000)
+			сам.ОбратВремяУст("05")
 		}
 	}()
 	for _, lastTime := range lstPolygon {
@@ -245,7 +282,7 @@ func (сам *Полигон) времяОбнов() {
 	strLastTime = lstTime[1]
 	lstTime = strings.Split(strLastTime, `</span>`)
 	strLastTime = lstTime[0]
-	if err := сам.ParseCountDown(alias.Время(strLastTime)); err != nil {
+	if err := сам.Уст(alias.Время(strLastTime)); err != nil {
 		// log._rintf("ERRO Polygon.updateTime(): при установке времени ожидания полигона(%v)\n\terr=%v\n", strLastTime, err)
 		return
 	}
@@ -301,7 +338,7 @@ func (сам *Полигон) усилениеПровер() {
 func (сам *Полигон) усилениеДобавить() {
 	if err := сам.сеть.UpdateLst(); err != nil {
 		// log._rintf("Polygon.checkPolygon(): при принудительном обновлении lstPlygon, mode=%s\terr=\n\t%v\n", sf.ModeCurrent().Get(), err)
-		сам.ОбратВремяУст(5_000)
+		сам.ОбратВремяУст("05")
 		return
 	}
 	lstPoligon := сам.СписПолучить()

+ 1 - 1
server/serv_bots/warbot/angar/base/polygon/polygonnet/polygonnet.go

@@ -17,7 +17,7 @@ type ПолигонСеть struct {
 }
 
 // НовПолигонСеть -- возвращает новый *PolygonNet
-func НовПолигонСеть(polygon types.ИПолигон) (*ПолигонСеть, error) {
+func НовПолигонСеть(polygon types.ИБазаПолигон) (*ПолигонСеть, error) {
 	sectionNet, err := sectionnet.NewSectionNet(polygon, "https://wartank.ru/polygon")
 	if err != nil {
 		return nil, fmt.Errorf("NewPolygonNet(): in create *SectionNet, err=\n\t%w", err)

+ 1 - 1
server/serv_bots/warbot/angar/battle/battle_wait/battle_wait.go

@@ -106,7 +106,7 @@ func (сам *СражениеОжидание) ждать() string {
 	strTime := lstTime[1]
 	lstTime = strings.Split(strTime, ` (`)
 	strTime = lstTime[0]
-	if err := сам.Секция.ParseCountDown(alias.Время(strTime)); err != nil { // Возможно уже всё
+	if err := сам.Секция.Уст(alias.Время(strTime)); err != nil { // Возможно уже всё
 		// log._rintf("WARN BattleWait.Wait(): при установке времени ожидания сражения(%v)\n\terr=%v\n", strTime, err)
 		return ""
 	}

+ 6 - 6
server/serv_bots/warbot/angar/convoy/convoy.go

@@ -140,7 +140,7 @@ func (sf *Конвой) обновитьВремя() {
 	// Время подходит надо обновляться
 	if err := sf.net.UpdateLst(); err != nil {
 		logrus.WithError(err).Error("Конвой.обновитьВремя(): при выполнении GET-команды обновления")
-		sf.ОбратВремяУст(20_000)
+		sf.ОбратВремяУст("20")
 		return
 	}
 	// Найти строку с упоминанием оставшегося времени конвоя
@@ -178,17 +178,17 @@ func (sf *Конвой) обновитьВремя() {
 		// Ждём окончания ожидания конвоя
 		lstTime := strings.Split(strLastTime, `До следующего конвоя: `)
 		strLastTime = lstTime[1]
-		if err := sf.ParseCountDown(alias.Время(strLastTime)); err != nil {
+		if err := sf.Уст(alias.Время(strLastTime)); err != nil {
 			// log._rintf("WARN Конвой.обновитьВремя(): при установке времени ожидания конвоя(%v)\n\terr=%v\n", strLastTime, err)
-			sf.ОбратВремяУст(10_000)
+			sf.ОбратВремяУст("10")
 		}
 	case isMask: // Если маскировка между конвоями
 		// Ждём окончания ожидания конвоя
 		lstTime := strings.Split(strLastTime, `Полная маскировка через `)
 		strLastTime = lstTime[1]
-		if err := sf.ParseCountDown(alias.Время(strLastTime)); err != nil {
+		if err := sf.Уст(alias.Время(strLastTime)); err != nil {
 			// log._rintf("ERRO BКонвой.обновитьВремя(): при установке времени банка для 1го режима(%v)\n\terr=%v\n", strLastTime, err)
-			sf.ОбратВремяУст(10_000)
+			sf.ОбратВремяУст("10")
 		}
 	}
 }
@@ -289,7 +289,7 @@ func (сам *Конвой) атакаНачать() {
 		return
 	}
 	сам.начатьРазведку()
-	if err := сам.ОбратВремяУст(1_000); err != nil {
+	if err := сам.ОбратВремяУст("01"); err != nil {
 		panic(fmt.Errorf("Конвой.атакаНачать(): при установке CountDown, err=\n\t%w", err))
 	}
 }

+ 2 - 2
server/serv_bots/warbot/angar/division/divwar/divwar.go

@@ -151,7 +151,7 @@ func (sf *DivWar) findTimeCount() {
 	strTime := lstTime[1]
 	lstTime = strings.Split(strTime, `</span>`)
 	strTime = lstTime[0]
-	if err := sf.ParseCountDown(alias.Время(strTime)); err != nil {
+	if err := sf.Уст(alias.Время(strTime)); err != nil {
 		// log._rintf("WARN DivWar.findTimeCount(): при установке времени ожидания битвы дивизий(%v)\n\terr=%v\n", strTime, err)
 		return
 	}
@@ -198,7 +198,7 @@ func (sf *DivWar) DivWar() {
 	defer func() {
 		sf.divon = nil
 		sf.block.Unlock()
-		if err := sf.Секция.ОбратВремяУст(1_000); err != nil {
+		if err := sf.Секция.ОбратВремяУст("01"); err != nil {
 			panic(fmt.Errorf("DivWar.DivWar(): при установке CountDown, err=\n\t%w", err))
 		}
 		// log.Printf("INFO DivWar.DivWar(): сражение завершено\n")

+ 5 - 6
server/serv_bots/warbot/angar/masters/bat_masters.go

@@ -77,10 +77,9 @@ func (sf *БитваМастеров) goBatMas() bool {
 	if !sf.upBattle() {
 		return false
 	}
-	countTime := sf.ВремяОпрос().ПолучМилСек()
-	countTime -= 5_000
-	if countTime > 25_000 {
-		if err := sf.ОбратВремяУст(countTime); err != nil {
+	countTime := sf.ВремяОпрос().String()
+	if countTime > "00:25:00" {
+		if err := sf.ОбратВремяУст(alias.Время(countTime)); err != nil {
 			log.Printf("ERRO BatMas.goBatMas(): при установке времени ожидания битвы мастеров(%v)\n\terr=%v\n", countTime, err)
 		}
 		return false
@@ -93,7 +92,7 @@ func (sf *БитваМастеров) goBatMas() bool {
 		return true
 	}
 	// Время ожидания вышло, надо начать атаку
-	if err := sf.ОбратВремяУст(0); err != nil {
+	if err := sf.ОбратВремяУст("00"); err != nil {
 		log.Printf("ERRO BatMas.goBatMas(): при установке времени ожидания битвы мастеров(0)\n\terr=%v\n", err)
 	}
 	return false
@@ -119,7 +118,7 @@ func (sf *БитваМастеров) findTimeCount() {
 		lstTime = strings.Split(strTime, ` (`)
 		strTime = lstTime[0]
 
-		if err := sf.ParseCountDown(alias.Время(strTime)); err != nil {
+		if err := sf.Уст(alias.Время(strTime)); err != nil {
 			log.Printf("WARN BatMas.findTimeCount(): при установке времени ожидания битвы мастеров(%v)\n\terr=%v\n", strTime, err)
 		}
 	}

+ 7 - 0
server/serv_web/serv_web.go

@@ -174,11 +174,18 @@ func (сам *СервВеб) постБотСтат(кнт *fiber.Ctx) error {
 	диктБот["точность"] = 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(диктБот)
 }