Jelajahi Sumber

d04 Массовые переделки и доделки

SVI 2 tahun lalu
induk
melakukan
0826a49799

+ 15 - 14
pakApp/pakGui/pakWinMain/modWinMain.py

@@ -1,9 +1,10 @@
 """Главное окно приложения"""
 
-from typing import Any
-from tkinter import Tk,LabelFrame,Frame,Label
+from typing import Any,Dict
+from tkinter import Tk,LabelFrame
 
 from pakApp.pakGui.pakWinMain.pakFrmCmd.modFrmCmd import FrmCmd
+from pakApp.pakGui.pakWinMain.pakFrmBot.modFrmBot import FrmBot
 
 class WinMain(Tk):
     def __init__(self, gui:Any)->None:
@@ -12,7 +13,8 @@ class WinMain(Tk):
         self.gui:Any=gui
         self.title("БотоФерма WarTank")
         self.geometry("800x640")
-        self.dict_bot:list[str]=[]
+        self.list_bot:list[str]=[]
+        self.listFrmBot:dict[str, FrmBot]={}
 
     def run(self)->None:
         self.frmCmd=FrmCmd(self)
@@ -24,16 +26,15 @@ class WinMain(Tk):
     def update_list_bot(self)->None:
         """Обновляет список ботоов с сервера"""
         print("WinMain.update_list_bot()")
-        list_bot:Any=self.app.logic.get_list_bot()
+        list_bot:list[Dict[str,str]]=self.app.logic.get_list_bot()
         print(f"WinMain.update_list_bot(): list_bot={list_bot}")
-        self.frmListBot.destroy()
-        self.dict_bot=[]
-        self.frmListBot=LabelFrame(self,text="Список ботов")
-        self.frmListBot.pack(fill="both",expand=1)
-        for bot_name in list_bot:
-            frmBot=Frame(self.frmListBot, border=3,relief="sunken")
-            frmBot.pack(fill="x", side="top")
-            lblName=Label(frmBot, text="["+bot_name+"]")
-            lblName.pack(side="left")
-            self.dict_bot.append(bot_name)
+        for dict_bot in list_bot:
+            name=dict_bot["name"]
+            if name not in self.list_bot:
+                statBot=FrmBot(self.app, self.frmListBot, name)
+                self.listFrmBot[name]=statBot
+                self.list_bot.append(name)
+            statBot=self.listFrmBot[name]
+            statBot.update_state(dict_bot)
+        self.after(5000,self.update_list_bot)
 

+ 32 - 0
pakApp/pakGui/pakWinMain/pakFrmBot/modFrmBot.py

@@ -0,0 +1,32 @@
+"""Фрейм для обновления статистики бота"""
+
+from typing import Dict, Any
+from tkinter import LabelFrame,Frame, Label, Button
+
+from pakApp.pakGui.pakWinState.modWinState import WinState
+
+class FrmBot(Frame):
+    def __init__(self, app:Any, frmListBot:LabelFrame, name:str)->None:
+        Frame.__init__(self, frmListBot, border=3,relief="sunken")
+        self.pack(fill="x", side="top")
+        self.app=app
+        self.lblState=Label(self)
+        self.lblState.pack(side="left")
+        self.name=name
+        self.btnStat=Button(self, text="Статистика",command=self.show_stat)
+        self.btnStat.pack(side="right")
+
+    def show_stat(self):
+        print(f"FrmBot.show_Stat: name={self.name}")
+        WinState(self.app.gui.winMain, self.name)
+
+    def update_state(self, dictBot:Dict[str,str])->None:
+        strAuto:str=dictBot["isAuto"]
+        strIsWork:str=dictBot["isWork"]
+        gold:str=dictBot["gold"]
+        fuel:str=dictBot["fuel"]
+        self.lblState["text"]="["+self.name+"] "+\
+            "[АвтоИгра="+strAuto+"] "+\
+            "[Работа="+strIsWork+"] "+\
+            "[Золото="+gold+"] "+\
+            "[Топливо="+fuel+"] "

+ 92 - 0
pakApp/pakGui/pakWinState/modWinState.py

@@ -0,0 +1,92 @@
+"""Окно показывает статистику бота"""
+
+from typing import Any
+from tkinter import Toplevel, LabelFrame, Label, Frame, Button
+
+class WinState(Toplevel):
+    def __init__(self, winMain:Any, nameBot:str)->None:
+        Toplevel.__init__(self, master=winMain)
+        self.title("Стаистика бта: "+nameBot)
+        self.geometry("800x600")
+        self.winMain=winMain
+        self.name=nameBot
+
+        self.frmCmd=Frame(self, border=3, relief="sunken")
+        self.frmCmd.pack(side="bottom", fill="x")
+        self.btnClose=Button(self.frmCmd, text="Закрыть", command=self.close)
+        self.btnClose.pack(side="right")
+
+        self.frmResource=LabelFrame(self,text="Ресурсы",border=3, relief="sunken")
+        self.frmResource.pack(side="top",fill="x")
+
+        self.lblAuto=Label(self.frmResource, text="Автоигра: false", border=3, relief="ridge", anchor="w")
+        self.lblAuto.pack(side="top", fill="x")
+
+        self.lblIsWork=Label(self.frmResource, text="В работе: false", border=3, relief="ridge", anchor="w")
+        self.lblIsWork.pack(side="top", fill="x")
+
+        self.lblFuel=Label(self.frmResource, text="Топливо: 0", border=3, relief="ridge", anchor="w")
+        self.lblFuel.pack(side="top", fill="x")
+
+        self.lblSlava=Label(self.frmResource, text="Слава: 0", border=3, relief="ridge", anchor="w")
+        self.lblSlava.pack(side="top", fill="x")
+
+        self.lblSerebro=Label(self.frmResource, text="Серебро: 0", border=3, relief="ridge", anchor="w")
+        self.lblSerebro.pack(side="top", fill="x")
+
+        self.lblZoloto=Label(self.frmResource, text="Золото: 0", border=3, relief="ridge", anchor="w")
+        self.lblZoloto.pack(side="top", fill="x")
+
+        self.lblLevel=Label(self.frmResource, text="Уровень: 0", border=3, relief="ridge", anchor="w")
+        self.lblLevel.pack(side="top", fill="x")
+
+        self.lblProgress=Label(self.frmResource, text="Прогресс: 0", border=3, relief="ridge", anchor="w")
+        self.lblProgress.pack(side="top", fill="x")
+
+        self.frmTank=LabelFrame(self, text="Танк", border=3, relief="sunken")
+        self.frmTank.pack(side="top",fill="x")
+
+        self.lblAtaka=Label(self.frmTank, text="Атака: 0", border=3, relief="ridge", anchor="w")
+        self.lblAtaka.pack(side="top", fill="x")
+
+        self.lblBrona=Label(self.frmTank, text="Броня: 0", border=3, relief="ridge", anchor="w")
+        self.lblBrona.pack(side="top", fill="x")
+
+        self.лблТочность=Label(self.frmTank, text="Точность: 0", border=3, relief="ridge", anchor="w")
+        self.лблТочность.pack(side="top", fill="x")
+
+        self.лблПрочность=Label(self.frmTank, text="Прочность: 0", border=3, relief="ridge", anchor="w")
+        self.лблПрочность.pack(side="top", fill="x")
+
+        self.лблМощь=Label(self.frmTank, text="Танковая мощь: 0", border=3, relief="ridge", anchor="w")
+        self.лблМощь.pack(side="top", fill="x")
+
+        self.фрмБаза=LabelFrame(self, text="База", border=3, relief="sunken")
+        self.фрмБаза.pack(side="top",fill="x")
+
+        self.лблШахта=Label(self.фрмБаза, text="Шахта: 0", border=3, relief="ridge", anchor="w")
+        self.лблШахта.pack(side="top", fill="x")
+
+        self.auto_update()
+
+    def auto_update(self):
+        self.after(5000, self.auto_update)
+        app=self.winMain.app
+        res=app.logic.get_stat_bot(self.name)
+        self.lblAuto["text"]="АвтоИгра: "+ res["isAuto"]
+        self.lblIsWork["text"]="В работе: "+ res["isWork"]
+        self.lblFuel["text"]="Топливо: "+ res["топливо"]
+        self.lblSlava["text"]="Слава: "+ res["слава"]
+        self.lblSerebro["text"]="Серебро: "+ res["серебро"]
+        self.lblZoloto["text"]="Золото: "+ res["золото"]
+        self.lblLevel["text"]="Уровень: "+ res["уровень"]
+        self.lblProgress["text"]="Прогресс: "+ res["прогресс"]
+        self.lblAtaka["text"]="Атака: "+ res["атака"]
+        self.lblBrona["text"]="Броня: "+ res["броня"]
+        self.лблТочность["text"]="Точность: "+ res["точность"]
+        self.лблПрочность["text"]="Прочность: "+ res["прочность"]
+        self.лблМощь["text"]="Танковая мощь: "+ res["мощь"]
+        self.лблШахта["text"]="Шахта: уровень="+ res["шахта_уровень"]
+
+    def close(self):
+        self.destroy()

+ 9 - 0
pakApp/pakLogic/modLogic.py

@@ -30,3 +30,12 @@ class Logic():
         content=json.loads(res.content)
         return content
 
+    def get_stat_bot(self, name:str):
+        """Возвращает статистику бота"""
+        data={
+            "name":name,
+        }
+        res=requests.post("http://localhost:"+self.port+"/bot/stat", data=data)
+        print(f"Logic.get_stat_bot(): result={res.text}")
+        content=json.loads(res.content)
+        return content

+ 1 - 1
pkg/components/section/down_time/down_time.go

@@ -67,6 +67,7 @@ func НовВремОбрат(сцена types.ИСцена, знач int) *Вр
 // Запускает тикер для секундных интервалов
 func (сам *ВремОбрат) сделатьТик() {
 	спатьСчёт := 0 // Счётчик сна (10 периодов -- 1 секунда)
+	defer close(сам.канТик)
 	for {
 		select {
 		case <-сам.кнт.Done(): // Отмена контекста бота
@@ -183,5 +184,4 @@ func (сам *ВремОбрат) закрыть() {
 		return
 	}
 	сам.еслиРаботает.Сброс()
-	close(сам.канТик)
 }

+ 9 - 4
pkg/components/sectionnet/sectionnet.go

@@ -18,7 +18,7 @@ import (
 
 // SectionNet -- базовый тип для сетевых секций
 type SectionNet struct {
-	client  types.INetClient
+	клиент  types.ИСетьКлиент
 	section types.ИСценаСтр
 	strUrl  string
 	block   sync.Mutex
@@ -38,7 +38,7 @@ func NewSectionNet(section types.ИСценаСтр, strUrl string) (*SectionNet
 	sf := &SectionNet{
 		section: section,
 		strUrl:  strUrl,
-		client:  section.Бот().Сеть().КлиентСеть(),
+		клиент:  section.Бот().Сеть().КлиентСеть(),
 	}
 	return sf, nil
 }
@@ -53,7 +53,7 @@ func (sf *SectionNet) UpdateLst() (err error) {
 	// FIXME: попытка разобраться, что за фигня творится
 	// time.Sleep(time.Millisecond * 500)
 	log.Printf("SectionNet.UpdateLst(): bot=%s\tsection=%v\n", sf.section.Бот().Имя(), sf.section.Имя())
-	lstString, err := sf.client.Get(sf.strUrl)
+	lstString, err := sf.клиент.Get(sf.strUrl)
 	if err != nil {
 		return fmt.Errorf("SectionNet.UpdateLst(): in make request, err=\n\t%w", err)
 	}
@@ -71,9 +71,14 @@ func (sf *SectionNet) Get(strLink string) (lstString []string, err error) {
 	if !strings.Contains(strLink, sf.strUrl) {
 		return nil, fmt.Errorf("SectionNet.Get(): strLink(%v) не содержит strUrl(%v)", strLink, sf.strUrl)
 	}
-	lstString, err = sf.client.Get(strLink)
+	lstString, err = sf.клиент.Get(strLink)
 	if err != nil {
 		return nil, fmt.Errorf("SectionNet.Get(): err=\n\t%v", err)
 	}
 	return lstString, nil
 }
+
+// Клиент -- возвращает хранимого клиента
+func (сам *SectionNet) Клиент() types.ИСетьКлиент {
+	return сам.клиент
+}

+ 1 - 1
pkg/cons/cons.go

@@ -12,7 +12,7 @@ const (
 	Delay100   = 100 // Задержка в миллисекундах для битвы, сражения, войны
 	Delay500   = 500 // Задержка в миллисекундах для сражения (100 мсек -- слишком часто)
 	SelfName   = "WarTank"
-	ТопливоМин = 315 // Минимальное количество топлива
+	ТопливоМин = 299 // Минимальное количество топлива
 )
 
 const (

+ 2 - 0
pkg/types/iangar.go

@@ -35,4 +35,6 @@ type ИАнгар interface {
 	Миссии() ИМиссии
 	// РесурсыОбновить -- принудитеьно обновляет ресурсы бота
 	РесурсыОбновить()
+	// Обновить -- требует обновления ангара
+	Обновить()
 }

+ 1 - 1
pkg/types/ibot_net.go

@@ -20,7 +20,7 @@ type ИБотСеть interface {
 	// Куки -- возвращает объект кукисов
 	Куки() ИБотКуки
 	// КлиентСеть -- возвращает сетевой клиент бота
-	КлиентСеть() INetClient
+	КлиентСеть() ИСетьКлиент
 	// Кнт -- контекст сетевого клиента
 	Кнт() context.Context
 	// Отмена -- вызывает отмену котекста сетевого клиента бота

+ 2 - 0
pkg/types/imine.go

@@ -17,4 +17,6 @@ type ИШахта interface {
 	Свинец() ИСтатПарам
 	// КолвоРаботаСейчас -- количество производимого продукта
 	КолвоРаботаСейчас() ИСтатПарам
+	// Уровень -- возвращает уровень шахты
+	Уровень() ИСтатПарам
 }

+ 2 - 2
pkg/types/inet_client.go

@@ -1,7 +1,7 @@
 package types
 
-// INetClient -- интерфейс к GET-запросу
-type INetClient interface {
+// ИСетьКлиент -- интерфейс к GET-запросу
+type ИСетьКлиент interface {
 	// Get -- теневая функция на блокировку
 	Get(strLink string) (lstString []string, err error)
 }

+ 12 - 5
server/serv_bots/warbot/angar/angar.go

@@ -50,8 +50,8 @@ type Ангар struct {
 	сереброВсего types.ИСтатПарам
 	silverOnline types.ИСтатПарам
 
-	сетьСтат *netstat.NetStat
-	блок     sync.Mutex
+	сетьТанкСтат *netstat.NetStat
+	блок         sync.Mutex
 }
 
 // НовАнгар -- возвращает новый *Angar
@@ -109,7 +109,7 @@ func НовАнгар(bot types.ИБот) (*Ангар, error) {
 		}
 	}
 	{ // Статистика
-		сам.сетьСтат, err = netstat.NewNetStat(сам.бот)
+		сам.сетьТанкСтат, err = netstat.NewNetStat(сам.бот)
 		if err != nil {
 			return nil, fmt.Errorf("НовАнгар(): in create NetResource, err=\n\t%w", err)
 		}
@@ -154,6 +154,14 @@ func НовАнгар(bot types.ИБот) (*Ангар, error) {
 	return сам, nil
 }
 
+// Обновить -- обновить ангар принудиельно
+func (сам *Ангар) Обновить() {
+	сам.РесурсыОбновить()
+	сам.сетьТанкСтат.Update()
+	сам.конвой.Обновить()
+	сам.топливо.Обновить()
+}
+
 // запускает обработку ангара
 func (sf *Ангар) Пуск() error {
 	{ // Запуск компонентов
@@ -178,8 +186,7 @@ func (sf *Ангар) Пуск() error {
 		go sf.топливо.Run()
 	}
 	фнЦикл := func() bool {
-		sf.РесурсыОбновить()
-		sf.сетьСтат.Update()
+		sf.Обновить()
 		// sf.конвойПроверить()
 		if err := sf.Секция.SetCountDown(60); err != nil {
 			sf.Закончить()

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

@@ -28,6 +28,7 @@ type Шахта struct {
 	сталь      types.ИСтатПарам
 	свинец     types.ИСтатПарам
 	numProduct types.ИСтатПарам
+	уровень    types.ИСтатПарам
 }
 
 // НовШахта -- возвращает новый *Mine
@@ -56,6 +57,10 @@ func НовШахта(база types.ИБаза) (*Шахта, error) {
 	if ош != nil {
 		return nil, fmt.Errorf("НовШахта(): при создании статистики числа добычи, ош=\n\t%w", ош)
 	}
+	уровень, ош := static_param.НовСтатПарам("уровень")
+	if ош != nil {
+		return nil, fmt.Errorf("НовШахта(): при создании статистики числа добычи, ош=\n\t%w", ош)
+	}
 	сам := &Шахта{
 		Секция:     секция,
 		бот:        база.Бот(),
@@ -65,6 +70,7 @@ func НовШахта(база types.ИБаза) (*Шахта, error) {
 		сталь:      сталь,
 		свинец:     свинец,
 		numProduct: добычаЧисло,
+		уровень:    уровень,
 	}
 	сам.сеть, ош = minenet.NewMineNet(сам)
 	if ош != nil {
@@ -80,7 +86,7 @@ func (сам *Шахта) Пуск() error {
 
 // пуск -- запускает обработку шахты
 func (сам *Шахта) пуск() {
-	сам.SetCountDown(1)
+	time.Sleep(time.Second * 3)
 	for {
 		select {
 		case <-сам.бот.Кнт().Done():
@@ -89,17 +95,135 @@ func (сам *Шахта) пуск() {
 		case <-сам.ВремяОпрос().КаналСиг():
 		default:
 			log.Printf("Шахта.пуск()\n")
-			руда := сам.Руда().Получ()
-			if руда == 0 {
-				time.Sleep(time.Second * 5)
-				сам.бот.Ангар().РесурсыОбновить()
+			if сам.уровеньОбновить() {
+				сам.ускорениеПровер()
+				руда := сам.Руда().Получ()
+				if руда == 0 {
+					time.Sleep(time.Second * 5)
+					сам.бот.Ангар().РесурсыОбновить()
+				}
+				сам.Сделать()
 			}
-			сам.Сделать()
 			time.Sleep(time.Minute * 5)
 		}
 	}
 }
 
+// Проверяет ускорение строительства
+func (сам *Шахта) ускорениеПровер() {
+	списСтр, ош := сам.сеть.Клиент().Get("http://wartank.ru/buildings")
+	if ош != nil {
+		log.Printf("Шахта.ускорениеПровер(): in make request, err=\n\t%v\n", ош)
+		return
+	}
+	// <span class="green2">Шахта - 0</span><br/>
+	var (
+		еслиНайти = false
+		стр       = ""
+	)
+	for _, стр = range списСтр {
+		if strings.Contains(стр, `<span class="green2">Шахта - `) {
+			еслиНайти = true
+			break
+		}
+	}
+	if !еслиНайти {
+		return
+	}
+}
+
+// Уровень -- возвращает уровень шахты
+func (сам *Шахта) Уровень() types.ИСтатПарам {
+	return сам.уровень
+}
+
+// Обновляет текущий уровень шахты (может быть не построена)
+func (сам *Шахта) уровеньОбновить() bool {
+	списСтр := сам.СписПолучить()
+	if len(списСтр) == 0 {
+		var ош error
+		списСтр, ош = сам.сеть.Клиент().Get("http://wartank.ru/buildings")
+		if ош != nil {
+			log.Printf("Шахта.уровеньОбновить(): in make request, err=\n\t%v\n", ош)
+			return false
+		}
+	}
+	// <span class="green2">Шахта - 0</span><br/>
+	var (
+		еслиНайти = false
+		стр       = ""
+	)
+	for _, стр = range списСтр {
+		if strings.Contains(стр, `<span class="green2">Шахта - `) {
+			еслиНайти = true
+			break
+		}
+	}
+	if !еслиНайти {
+		return false
+	}
+	_стр := strings.TrimPrefix(стр, `<span class="green2">Шахта - `)
+	_стр = strings.TrimSuffix(_стр, `</span><br/>`)
+	иУровень, ош := strconv.Atoi(_стр)
+	if ош != nil {
+		log.Printf("Шахта.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
+		return false
+	}
+	сам.уровень.Уст(иУровень)
+	if иУровень == 0 { // шахту надо построить
+		сам.построить(списСтр)
+		return false
+	}
+	return true
+}
+
+// Строит шахту принулевом уровне
+func (сам *Шахта) построить(списСтр []string) {
+	// <td style="width:50%;padding-left:1px;"><a class="simple-but border mb5" href="building-upgrade/Mine"><span><span>Построить</span></span></a></td>
+	var (
+		еслиНайти = false
+		стр       = ""
+	)
+	for _, стр = range списСтр {
+		if strings.Contains(стр, `href="building-upgrade/Mine"><span><span>Построить</span></span>`) {
+			еслиНайти = true
+			break
+		}
+	}
+	if !еслиНайти {
+		return
+	}
+	// Пробуем построить шахту
+	_стр := strings.TrimPrefix(стр, `<td style="width:50%;padding-left:1px;"><a class="simple-but border mb5" href="`)
+	_стр = strings.TrimSuffix(_стр, `"><span><span>Построить</span></span></a></td>`)
+	ссылка := "https://wartank.ru/" + _стр
+	списСтр, ош := сам.сеть.Клиент().Get(ссылка)
+	if ош != nil {
+		log.Printf("ERRO Шахта.построить(): при GET-команде 'построить шахту', err=\n\t%v\n", ош)
+		return
+	}
+	еслиНайти = false
+	// "<a class=\"simple-but border mb5\" href=\"Mine?14-1.ILinkListener-upgradeLink-link\">"
+	for _, стр = range списСтр {
+		if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
+			еслиНайти = true
+			break
+		}
+	}
+	if !еслиНайти {
+		return
+	}
+	_стр = strings.TrimPrefix(стр, "<a class=\"simple-but border mb5\" href=\"")
+	_стр = strings.TrimSuffix(_стр, "\">")
+	// http://wartank.ru/building-upgrade/Mine?16-1.ILinkListener-upgradeLink-link
+	ссылка = "https://wartank.ru/building-upgrade/" + _стр
+	_, ош = сам.сеть.Клиент().Get(ссылка)
+	if ош != nil {
+		log.Printf("ERRO Шахта.построить(): при GET-команде 'купить постройку шахты', err=\n\t%v\n", ош)
+		return
+	}
+}
+
 // Сделать -- вызывается с базы, если она обнаружила, что пора сделать продукцию
 func (сам *Шахта) Сделать() {
 	работа := сам.РежимТекущ().Режим()
@@ -111,6 +235,9 @@ func (сам *Шахта) Сделать() {
 		log.Printf("ERRO Шахта.Сделать(): при обновлении lstMine, err=\n\t%v\n", err)
 		return
 	}
+	if !сам.уровеньОбновить() {
+		return
+	}
 	if err := сам.выбратьМеталл(); err != nil {
 		log.Printf("ERRO Шахта.Сделать(): при выборе продукции, err=\n\t%v\n", err)
 		return

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

@@ -93,12 +93,12 @@ func (сам *Конвой) атаковать() {
 		сам.проверитьМиссияКонвой()
 		сам.проверитьМиссияМастерДозора()
 		сам.проверитьМиссия6фрагов()
-		сам.славаОбновить()
+		сам.Обновить()
 	}
 }
 
 // Обновляет славу по требованию
-func (sf *Конвой) славаОбновить() {
+func (sf *Конвой) Обновить() {
 	// Найти строку с упоминанием оставшегося времени конвоя
 	lstConvoy := sf.СписПолучить()
 	var (

+ 5 - 5
server/serv_bots/warbot/angar/fuel/fuel.go

@@ -40,7 +40,7 @@ func (sf *Топливо) Run() {
 	for {
 		time.Sleep(time.Second * 15)
 		if sf.топливо.Получ() < 314 {
-			sf.топливоНайти()
+			sf.Обновить()
 			count = 0
 			continue
 		}
@@ -52,8 +52,8 @@ func (sf *Топливо) Run() {
 	}
 }
 
-// Ищет в теле текста ангара топливо
-func (sf *Топливо) топливоНайти() {
+// Обновить -- ищет в теле текста ангара топливо
+func (sf *Топливо) Обновить() {
 	// _mt.Println("\tAngarNet.findFuel()")
 	lstAngar := sf.ангар.СписПолучить()
 	var strOut string
@@ -67,11 +67,11 @@ func (sf *Топливо) топливоНайти() {
 	lstFuel := strings.Split(strOut, `<img title="Топливо" alt="Топливо" src="/images/icons/fuel.png?2"/> `)
 	// Здесь бывает ошибка (когда возвращена пустая строка)
 	if len(lstFuel) != 2 {
-		log.Printf("ERRO Топливо.топливоНайти(): при поиске строки тплива, стр=\n\t%v\n", strOut)
+		log.Printf("ERRO Топливо.Обновить(): при поиске строки тплива, стр=\n\t%v\n", strOut)
 		return
 	}
 	if lstFuel[1] == "" {
-		log.Printf("ERRO Топливо.топливоНайти(): пустое значение в строке тплива, стр=\n\t%v\n", strOut)
+		log.Printf("ERRO Топливо.Обновить(): пустое значение в строке тплива, стр=\n\t%v\n", strOut)
 		return
 	}
 	strFuel := lstFuel[1]

+ 1 - 1
server/serv_bots/warbot/warbot_net/warbot_net.go

@@ -76,7 +76,7 @@ func (сам *ВарБотСеть) ЕслиОнлайн() *safebool.SafeBool {
 }
 
 // КлиентСеть -- возвращает исполнитель запросов
-func (sf *ВарБотСеть) КлиентСеть() types.INetClient {
+func (sf *ВарБотСеть) КлиентСеть() types.ИСетьКлиент {
 	return sf.сеть
 }
 

+ 68 - 2
server/serv_web/serv_web.go

@@ -103,6 +103,7 @@ func НовСервВеб(серв types.ИСервер) (*СервВеб, error
 	// })
 	сам.роутер.Get("/list_bot/get", сам.гетСписБот)
 	сам.роутер.Post("/list_bot/add", сам.постБотНов)
+	сам.роутер.Post("bot/stat", сам.постБотСтат)
 	return сам, nil
 }
 
@@ -118,6 +119,65 @@ func (сам *СервВеб) Пуск() {
 	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", бот.Ангар().База().Шахта().Уровень().Получ())
+	return кнт.JSON(диктБот)
+}
+
 type ПостБотНов struct {
 	Логин    string `form:"login"`
 	Пароль   string `form:"pass"`
@@ -165,9 +225,15 @@ func (сам *СервВеб) постБотНов(кнт *fiber.Ctx) error {
 // гетСписБот -- возвращает список ботов
 func (сам *СервВеб) гетСписБот(кнт *fiber.Ctx) error {
 	списБот := сам.серв.ServBots().ListBot()
-	рез := []string{}
+	рез := make([]map[string]string, 0)
 	for _, бот := range списБот {
-		рез = append(рез, бот.Имя())
+		_бот := map[string]string{}
+		_бот["name"] = бот.Имя()
+		_бот["isAuto"] = fmt.Sprint(бот.АвтоИграЕсли())
+		_бот["isWork"] = fmt.Sprint(бот.ЕслиПуск())
+		_бот["gold"] = fmt.Sprint(бот.Ангар().Золото().Получ())
+		_бот["fuel"] = fmt.Sprint(бот.Ангар().Топливо().Получ())
+		рез = append(рез, _бот)
 	}
 	return кнт.JSON(рез)
 }