// package arsenal -- объект оружейной на базе
package arsenal
import (
"context"
"fmt"
"log"
"strconv"
"strings"
"time"
"wartank/pkg/section"
"wartank/pkg/types"
"wartank/server/serv_bots/warbot/angar/base/arsenal/arsenalnet"
"wartank/server/serv_bots/warbot/tank/tankstat/static_param"
)
const (
стрКумулятивы = "кумулятивы"
стрБронебойки = "бронебойки"
стрФугасы = "фугасы"
стрРемки = "ремки"
)
// Арсенал -- объект оружейной на базе
type Арсенал struct {
*section.Секция
слог types.ИСлог
бот types.ИБот
база types.ИБаза
сеть *arsenalnet.ArsenalNet
фугас types.ИСтатПарам
бронебойка types.ИСтатПарам
кумулятив types.ИСтатПарам
ремка types.ИСтатПарам
уровень types.ИСтатПарам
продуктИмя string // Что сейчас делается
продуктКол types.ИСтатПарам // Сколько делается прямо сейчас
продуктВремя string // Сколько осталось времени прямо сейчас
кнт context.Context // контекст шахты
фнОтмена func() // Функция отмены шахты
}
// НовАрсенал -- возвращает новый *Arsenal
func НовАрсенал(база types.ИБаза) (*Арсенал, error) {
section, err := section.НовСекция(база.Бот(), "Арсенал", `Ремкомплект
`)
if err != nil {
return nil, fmt.Errorf("НовАрсенал(): in create ISection, err=\n\t%w", err)
}
фугас, ош := static_param.НовСтатПарам(стрФугасы)
if ош != nil {
return nil, fmt.Errorf("НовАрсенал(): при создании статистики фугасов, ош=\n\t%w", ош)
}
бронейбойки, ош := static_param.НовСтатПарам(стрБронебойки)
if ош != nil {
return nil, fmt.Errorf("НовАрсенал(): при создании статистики бронебоек, ош=\n\t%w", ош)
}
кумулятив, ош := static_param.НовСтатПарам(стрКумулятивы)
if ош != nil {
return nil, fmt.Errorf("НовАрсенал(): при создании статистики кумулятивов, ош=\n\t%w", ош)
}
ремка, ош := static_param.НовСтатПарам(стрРемки)
if ош != nil {
return nil, fmt.Errorf("НовАрсенал(): при создании статистики ремок, ош=\n\t%w", ош)
}
уровень, ош := static_param.НовСтатПарам("уровень")
if ош != nil {
return nil, fmt.Errorf("НовАрсенал(): при создании статистики числа добычи, ош=\n\t%w", ош)
}
продуктКол, ош := static_param.НовСтатПарам("свинец")
if ош != nil {
return nil, fmt.Errorf("НовШахта(): при создании статистики числа добычи, ош=\n\t%w", ош)
}
кнт, фнОтмена := context.WithCancel(база.Контекст())
сам := &Арсенал{
Секция: section,
бот: база.Бот(),
слог: база.Бот().Сервер().Слог(),
база: база,
фугас: фугас,
бронебойка: бронейбойки,
кумулятив: кумулятив,
ремка: ремка,
уровень: уровень,
продуктКол: продуктКол,
кнт: кнт,
фнОтмена: фнОтмена,
}
{ // ArsenalNet
сам.сеть, err = arsenalnet.НовАрсеналСеть(сам)
if err != nil {
return nil, fmt.Errorf("НовАрсенал(): in create NetArsenal, err=\n\t%w", err)
}
}
_ = types.ИАрсенал(сам)
return сам, nil
}
// Уровень -- возвращает уровень шахты
func (сам *Арсенал) Уровень() types.ИСтатПарам {
return сам.уровень
}
// ПродуктКолСейчас -- возвращает количество прозводимого продукта
func (сам *Арсенал) ПродуктКолСейчас() int {
return сам.продуктКол.Получ()
}
// ПродуктИмяСейчас -- возвращает имя прозводимого продукта
func (сам *Арсенал) ПродуктИмяСейчас() string {
return сам.продуктИмя
}
// ПродуктВремяСейчас -- сколько осталось времени до производства продукта
func (сам *Арсенал) ПродуктВремяСейчас() string {
return сам.продуктВремя
// return сам.Секция.ВремяОпрос().Стр()
}
func (сам *Арсенал) Пуск() error {
go сам.пуск()
return nil
}
// запускает обработку арсенала
func (сам *Арсенал) пуск() {
// сам.getTime()
time.Sleep(time.Second * 3)
фнРабота := func() {
defer func() {
for сам.ВремяОстат().ПолучМилСек() > 0 {
time.Sleep(time.Second * 5)
}
}()
{ // стройка
счёт := 5
for счёт > 0 {
if сам.построить() {
break
}
счёт--
}
}
{ // апгрейд
счёт := 5
for счёт > 0 {
if сам.проапгрейдить() {
break
}
счёт--
}
}
_ = сам.уровеньОбновить()
ош := сам.СтатаОбновить()
if ош != nil {
сам.слог.Ошибка("ArsenalNet.Run(): in update stat, err=\n\t%w", ош)
}
сам.забрать()
сам.сделать()
log.Printf("Арсенал.пуск(): бот=%q, цикл завершён\n", сам.бот.Имя())
}
for {
select {
case <-сам.кнт.Done():
return
// case <-сам.ВремяОпрос().КаналСиг():
// if сам.РежимТекущ().Получ() == "upgrade" {
// continue
// }
// if err := сам.updateArsenal(); err != nil {
// return fmt.Errorf("ArsenalNet.Run(): in update arsenal, err=\n\t%w", err)
// }
default:
фнРабота()
}
}
}
// Обновляет текущий уровень оружейки (может быть не построена)
func (сам *Арсенал) уровеньОбновить() bool {
списСтр, ош := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
if ош != nil {
log.Printf("Арсенал.уровеньОбновить(): in make request, err=\n\t%v\n", ош)
return false
}
// Арсенал - 0
var (
еслиНайти = false
стр = ""
)
for _, стр = range списСтр {
if strings.Contains(стр, `Арсенал - `) {
еслиНайти = true
break
}
}
if !еслиНайти {
return false
}
_стр := strings.TrimPrefix(стр, `Арсенал - `)
_стр = strings.TrimSuffix(_стр, `
`)
иУровень, ош := strconv.Atoi(_стр)
if ош != nil {
log.Printf("Арсенал.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
return false
}
сам.уровень.Уст(иУровень)
return true
}
// Строит оружейку при нулевом уровне
func (сам *Арсенал) построить() bool {
списСтр, ош := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
if ош != nil {
log.Printf("Арсенал.уровеньОбновить(): in make request, err=\n\t%v\n", ош)
return false
}
// Арсенал - 0
var (
еслиНайти = false
стр = ""
)
for _, стр = range списСтр {
if strings.Contains(стр, `Арсенал - `) {
еслиНайти = true
break
}
}
if !еслиНайти {
return false
}
_стр := strings.TrimPrefix(стр, `Арсенал - `)
_стр = strings.TrimSuffix(_стр, `
`)
иУровень, ош := strconv.Atoi(_стр)
if ош != nil {
log.Printf("Арсенал.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
return false
}
сам.уровень.Уст(иУровень)
//
`) {
strOut = strFugas
break
}
}
lstFugas := strings.Split(strOut, `
`)
strFugas := lstFugas[1]
lstFugas = strings.Split(strFugas, ` `)
strFugas = lstFugas[0]
iFugas, err := strconv.Atoi(strFugas)
if err != nil {
return fmt.Errorf("Арсенал.СтатаОбновить(): fugas(%v) not number, err=\n\t%w", strFugas, err)
}
сам.Фугасы().Уст(iFugas)
}
{ // Найти маркер бронебойного снаряда
for _, strArmor := range lstArsenal {
if strings.Contains(strArmor, `alt="Бронебойный снаряд"`) {
strOut = strArmor
break
}
}
lstArmor := strings.Split(strOut, `
`)
strArmor := lstArmor[1]
lstArmor = strings.Split(strArmor, ` `)
strArmor = lstArmor[0]
iArmor, err := strconv.Atoi(strArmor)
if err != nil {
return fmt.Errorf("Арсенал.СтатаОбновить(): armor(%v) not number, err=\n\t%w", strArmor, err)
}
сам.Бронебойки().Уст(iArmor)
}
{ // Найти маркер кумулятивного снаряда
for _, strKumul := range lstArsenal {
if strings.Contains(strKumul, `
`) {
strOut = strKumul
break
}
}
lstKumul := strings.Split(strOut, `
`)
strKumul := lstKumul[1]
lstKumul = strings.Split(strKumul, ` `)
strKumul = lstKumul[0]
iKumul, err := strconv.Atoi(strKumul)
if err != nil {
return fmt.Errorf("Арсенал.СтатаОбновить(): kumul(%v) not number, err=\n\t%w", strKumul, err)
}
сам.Кумулятивы().Уст(iKumul)
}
{ // Найти маркер ремкомплекта
for ind, strRemka := range lstArsenal {
if strings.Contains(strRemka, `
`) {
strOut = lstArsenal[ind]
break
}
}
lstRemka := strings.Split(strOut, `
`)
strRemka := lstRemka[1]
lstRemka = strings.Split(strRemka, ``)
strRemka = lstRemka[0]
iRemka, err := strconv.Atoi(strRemka)
if err != nil {
return fmt.Errorf("Арсенал.СтатаОбновить(): remka(%v) not number, err=\n\t%w", strRemka, err)
}
сам.Ремки().Уст(iRemka)
}
return nil
}
// Выбирает что надо делать, запускает процесс изготовления
func (сам *Арсенал) сделать() bool {
ош := сам.сеть.Обновить()
if ош != nil {
// log._rintf("ERRO Арсенал.сделать(): при обновлении lstArsenal, err=\n\t%v\n", err)
return false
}
// _mt.Println("\tArsenalNet.сделать()")
var (
ремкаКол = сам.Ремки().Получ()
фугасКол = сам.Фугасы().Получ()
кумульКол = сам.Кумулятивы().Получ()
ббКол = сам.Бронебойки().Получ()
снарядТип string
)
if ремкаКол < 70 { // Контроль ремки по времени суток и минимальному количеству ремок
for !сам.сделатьРемку() {
}
сам.продуктИмя = стрРемки
return true
}
{ // Контроль по числу снарядов. В равных долях без приоритетов
// снарядТип = стрФугасы
снарядТип = стрБронебойки
if ббКол > фугасКол {
снарядТип = стрФугасы
}
if фугасКол > кумульКол {
снарядТип = стрКумулятивы
}
switch снарядТип {
case стрФугасы: // Мало фугасов
for !сам.сделатьФугасы() {
}
case стрКумулятивы: // Мало кумулятивов
for !сам.сделатьКумули() {
}
case стрБронебойки: // Мало бронебойных
for !сам.сделатьБронебойки() {
}
default:
// log._rintf("ERRO Арсенал.сделать(): неизвестный тип арсенала(%v)", typeArmor)
}
сам.продуктИмя = снарядТип
}
return true
}
// Создать бронебойные
func (сам *Арсенал) сделатьБронебойки() bool {
var (
стрВых string
lstArsenal = сам.СписПолучить()
еслиНайдено bool
инд int
)
for инд, стрВых = range lstArsenal {
if strings.Contains(стрВых, `Бронебойный снаряд