package polygon
import (
"fmt"
"log"
"strconv"
"strings"
"time"
"wartank/pkg/alias"
"wartank/pkg/components/safe_int"
"wartank/pkg/components/safe_string"
"wartank/pkg/cons"
"wartank/pkg/section"
"wartank/pkg/types"
"wartank/server/serv_bots/warbot/angar/base/polygon/polygonnet"
"wartank/server/serv_bots/warbot/tank/tankstat/static_param"
)
/*
Объект полигона на базе
*/
const (
времОжидПлат = "05:00" // Время ожидания платного ускорения
времОжидБесплат = "30:00" // Время ожидания бесплатного ускорения
стрПрочность = "прочность"
стрТочность = "точность"
стрБроня = "броня"
стрАтака = "атака"
)
// Полигон -- объект полигона на базе
type Полигон struct {
*section.Секция
бот types.ИБот
танкСтат types.ИТанкСтат
сеть *polygonnet.ПолигонСеть
продуктСейчас *safe_string.БезопСтрока
продуктКол *safe_int.БезопЦелое
уровень *static_param.СтатПарам
}
// НовПолигон -- возвращает новый *Polygon
func НовПолигон(база types.ИБаза) (*Полигон, error) {
секция, ош := section.НовСекция(база.Бот(), "Полигон", `
Полигон`)
if ош != nil {
return nil, fmt.Errorf("НовПолигон(): при создании ИСекция, ош=\n\t%w", ош)
}
уровень, ош := static_param.НовСтатПарам("уровень полигона")
if ош != nil {
return nil, fmt.Errorf("НовПолигон(): при создании уровня полигона, ош=\n\t%w", ош)
}
сам := &Полигон{
Секция: секция,
бот: база.Бот(),
танкСтат: база.Бот().Танк().ТанкСтат(),
продуктСейчас: 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 (сам *Полигон) Пуск() error {
go сам.пуск()
return nil
}
const (
стрАпгрейд = "апгрейд"
)
// выполняет опрос полигона базы.
func (сам *Полигон) пуск() {
сам.ОбратВремяУст("02")
фнРабота := func() {
defer time.Sleep(time.Minute * 20)
сам.усилениеДобавить()
сам.усилениеПровер()
сам.времяОбнов()
сам.построитьПровер()
сам.проверитьУскорение()
if сам.продуктСейчас.Получ() == стрАпгрейд {
сам.ВремяОстат().Уст("00:10:00")
}
счёт := 5
for счёт > 0 {
if сам.уровеньПолучить() {
break
}
счёт--
}
}
for {
select {
case <-сам.Кнт().Done():
return
case <-сам.ВремяОстат().КаналСиг():
фнРабота()
default:
фнРабота()
}
}
}
// Проверяет уровень полигона
func (сам *Полигон) уровеньПолучить() bool {
var (
стрВых = ""
еслиНидено bool
)
lstBase, err := сам.сеть.Клиент().Get("https://wartank.ru/buildings")
if err != nil {
log.Printf("Полигон.уровеньПолучить(): при обновлении строк базы, err=\n\t%v\n", err)
return false
}
// Полигон - 5
for _, стрВых = range lstBase {
if strings.Contains(стрВых, `Полигон - `) {
еслиНидено = true
break
}
}
if !еслиНидено {
return false
}
стрУровень := strings.TrimPrefix(стрВых, `Полигон - `)
стрУровень = strings.TrimSuffix(стрУровень, `
`)
цУров, ош := strconv.Atoi(стрУровень)
if ош != nil {
return false
}
сам.уровень.Уст(цУров)
return true
}
// Проверяет на ускорение апгрейда полигона
func (сам *Полигон) проверитьУскорение() {
var (
strOut = ""
еслиНайдено bool
)
lstBase, err := сам.сеть.Клиент().Get("https://wartank.ru/buildings")
if err != nil {
log.Printf("Полигон.проверитьУскорение(): при обновлении строк базы, err=\n\t%v\n", err)
return
}
// Проверка на платное ускорение апгрейда + время
{ // Платное ускорение
if strings.Contains(strOut, `Ускорить за`) {
if err := сам.ОбратВремяУст(времОжидПлат); err != nil {
log.Printf("WARN Base.checkArsenalForce(): при установке платного времени ускорения апгрейда арсенала(%v)\n\terr=%v\n", времОжидПлат, err)
}
сам.СценаРежим().РаботаУст(стрАпгрейд)
сам.СценаРежим().РежимУст(cons.РежимАпгрейд)
сам.продуктСейчас.Уст(стрАпгрейд)
сам.продуктКол.Уст(0)
return
}
}
{ // Проверка на бесплатное ускорение апгрейда
еслиНайдено = false
for _, strOut = range lstBase {
if strings.Contains(strOut, `Производит снаряды, ремкомплекты
`) {
// Убедиться что есть строка платного ускорения
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
if !strings.Contains(strOut, `>Ускорение<`) {
return
}
сам.СценаРежим().РежимУст(cons.РежимАпгрейд)
сам.продуктСейчас.Уст(стрАпгрейд)
сам.продуктКол.Уст(0)
lstLink := strings.Split(strOut, `Ускорение`)
strLink = "https://wartank.ru/" + lstLink[0]
lstBase, err := сам.сеть.Get(strLink)
if err != nil {
// log._rintf("ERRO NetBank.checkArsenalForce(): при GET-запросе на бесплатном ускорении апгрейда арсенала, err=\n\t%v\n", err)
return
}
// sound.ArsenalForce()
if err := сам.СтрОбновить(lstBase); err != nil {
// log._rintf("ERRO NetBank.checkArsenalForce(): при обновлении lstBase, err=\n\t%v\n", err)
return
}
сам.СценаРежим().РаботаУст(стрАпгрейд)
сам.СценаРежим().РежимУст(cons.РежимАпгрейд)
сам.продуктКол.Уст(0)
if err := сам.ОбратВремяУст(времОжидБесплат); err != nil {
log.Printf("WARN Base.checkArsenalForce(): при установке бесплатного времени ускорения апгрейда арсенала(%v)\n\terr=%v\n", времОжидБесплат, err)
}
}
// Все проверки прошли -- это просто работа
сам.СценаРежим().РаботаУст("work")
}
// Проверяет необходимость постройки полигона
func (сам *Полигон) построитьПровер() {
фнПостроить := func() bool { // Поиск кнопки строительства
// https://wartank.ru/building-upgrade/Polygon
списПолигон, ош := сам.сеть.Клиент().Get("https://wartank.ru/building-upgrade/Polygon")
if ош != nil {
log.Printf("Полигон.построитьПровер(): при чтении страницы строительства полигона, ош=\n\t%v\n", ош)
return false
}
стрСсылка := ""
еслиНайти := false
//
for _, стрСсылка = range списПолигон {
if strings.Contains(стрСсылка, `href="Polygon?`) {
еслиНайти = true
break
}
}
if !еслиНайти { // Время полигона вышло
return false
}
_ссылка := strings.TrimPrefix(стрСсылка, ``)
ссылка := "https://wartank.ru/building-upgrade/" + _ссылка
// https://wartank.ru/building-upgrade/Polygon?83-1.ILinkListener-upgradeLink-link
списПолигон, ош = сам.сеть.Клиент().Get(ссылка)
if ош != nil {
log.Printf("Полигон.построитьПровер(): при выполнении запроса на строительство, ош=\n\t%v\n", ош)
return false
}
for _, стр := range списПолигон {
if strings.Contains(стр, `href="Polygon?`) {
return false
}
}
{ // подтверждение постройки
// "да, подтверждаю"
стрСсылка := ""
еслиНайти := false
for _, стрСсылка = range списПолигон {
if strings.Contains(стрСсылка, `.ILinkListener-confirmLink`) {
еслиНайти = true
break
}
}
if !еслиНайти { // Время полигона вышло
return false
}
_ссылка := strings.TrimPrefix(стрСсылка, "да, подтверждаю")
ссылка := "https://wartank.ru/" + _ссылка
// https://wartank.ru/wicket/page?135-1.ILinkListener-confirmLink
_, ош = сам.сеть.Клиент().Get(ссылка)
if ош != nil {
log.Printf("Полигон.построитьПровер(): при выполнении запроса на строительство, ош=\n\t%v\n", ош)
return false
}
}
return true
}
фнПостроить()
log.Printf("Полигон.построитьПровер(): построен упешно\n")
}
// Обновляет оставшееся время полигона
//
// Этот объект сам описывает своё время
func (сам *Полигон) времяОбнов() {
var (
strLastTime string
еслиНайдено bool
isSet bool
lstPolygon = сам.СписПолучить()
)
defer func() {
if !isSet {
сам.ОбратВремяУст("05")
}
}()
for _, lastTime := range lstPolygon {
if strings.Contains(lastTime, `>Осталось: `) {
strLastTime = lastTime
еслиНайдено = true
break
}
}
if !еслиНайдено { // Время полигона вышло
return
}
lstTime := strings.Split(strLastTime, `>Осталось: `)
strLastTime = lstTime[1]
lstTime = strings.Split(strLastTime, ``)
strLastTime = lstTime[0]
if err := сам.Уст(alias.Время(strLastTime)); err != nil {
// log._rintf("ERRO Polygon.updateTime(): при установке времени ожидания полигона(%v)\n\terr=%v\n", strLastTime, err)
return
}
isSet = true
}
// Проверяет что именно активировано
func (сам *Полигон) усилениеПровер() {
var (
еслиНайдено bool
lstPolygon = сам.СписПолучить()
ind = 0
strOut string
)
for ind, strOut = range lstPolygon {
if strings.Contains(strOut, `Активно`) {
ind -= 9
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
strOut = lstPolygon[ind]
форсажИмя := ""
switch { // Вычисляем контрольную строку
case strings.Contains(strOut, `>улучшение точности<`):
форсажИмя = стрТочность
case strings.Contains(strOut, `>увеличение прочности<`):
форсажИмя = стрПрочность
case strings.Contains(strOut, `>усиление брони<`):
форсажИмя = стрБроня
case strings.Contains(strOut, `>усиление атаки<`):
форсажИмя = стрАтака
}
// Вычислим на сколько
strOut = lstPolygon[ind+1]
lstOut := strings.Split(strOut, `+`)
strOut = lstOut[1]
lstOut = strings.Split(strOut, ` на `)
strOut = lstOut[0]
iForce, err := strconv.Atoi(strOut)
if err != nil {
// log._rintf("NetPolygon.checkTime(): force(%v) not number, err=\n\t%v\n", strOut, err)
return
}
сам.танкСтат.ФорсажОбнов(форсажИмя, iForce)
сам.продуктСейчас.Уст("усиление-" + форсажИмя)
сам.продуктКол.Уст(iForce)
}
// Выбирает самый слабый параметр и усиливает его
func (сам *Полигон) усилениеДобавить() {
if ош := сам.сеть.Обновить(); ош != nil {
// log._rintf("Polygon.checkPolygon(): при принудительном обновлении lstPlygon, mode=%s\terr=\n\t%v\n", сам.ModeCurrent().Get(), err)
сам.ОбратВремяУст("05")
return
}
lstPoligon := сам.СписПолучить()
if len(lstPoligon) == 0 {
return
}
stat := сам.танкСтат
iAttack := stat.Атака().Получ()
iArmor := stat.Броня().Получ()
iFyne := stat.Точность().Получ()
iHard := stat.Прочность().Получ()
strParam := стрАтака
iParam := iHard
{
/*
Вычислить самый слабый параметр.
Политика вычислений:
1) hard -- прочность, самый низкоприоритетный параметр
2) armor -- броня, чуть лучше power
3) fyne -- точность, чуть лучше armor
4) attack -- атака, самый важный
*/
if iArmor <= iParam {
iParam = iArmor
strParam = стрБроня
}
if iFyne <= iParam {
iParam = iFyne
strParam = стрТочность
}
if iAttack < iParam {
strParam = стрАтака
}
}
// Найти нужную строку активации
var (
ind int
strOut string
еслиНайдено bool
)
switch strParam {
case стрАтака: // Усиливаем атаку
for ind, strOut = range lstPoligon {
if strings.Contains(strOut, `>усиление атаки<`) {
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
ind += 8
strOut = lstPoligon[ind]
if strOut == "" {
return
}
lstLink := strings.Split(strOut, `Получить бесплатно`)
strLink := "https://wartank.ru/" + lstLink[0]
if _, err := сам.сеть.Get(strLink); err != nil {
// log._rintf("ERRO NetPolygon.addForce(): in make request force attack, err=\n\t%v\n", err)
return
}
{ // Узнать на сколько форсирована атака
strForce := lstPoligon[ind-7]
lstForce := strings.Split(strForce, `+`)
strForce = lstForce[1]
lstForce = strings.Split(strForce, ` на `)
strForce = lstForce[0]
iForce, err := strconv.Atoi(strForce)
if err != nil {
// log._rintf("ERRO NetPolygon.addForce(): strForceAttack(%v) not int, err=\n\t%v\n", strForce, err)
return
}
сам.танкСтат.ФорсажОбнов("attack", iForce)
сам.СценаРежим().РаботаУст(стрАтака)
}
case стрБроня: // Усиливаем броню
еслиНайдено = false
for ind, strOut = range lstPoligon {
if strings.Contains(strOut, `>усиление брони<`) {
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
ind += 8
strOut = lstPoligon[ind]
if strOut == "" {
return
}
lstLink := strings.Split(strOut, `Получить бесплатно`)
strLink := "https://wartank.ru/" + lstLink[0]
if _, err := сам.сеть.Get(strLink); err != nil {
// log._rintf("NetPolygon.addForce(): in make request force armor, err=\n\t%v\n", err)
return
}
{ // Узнать на сколько форсирована броня
strForce := lstPoligon[ind-7]
lstForce := strings.Split(strForce, `+`)
strForce = lstForce[1]
lstForce = strings.Split(strForce, ` на `)
strForce = lstForce[0]
iForce, err := strconv.Atoi(strForce)
if err != nil {
// log._rintf("ERRO NetPolygon.addForce(): strForceArmor(%v) not int, err=\n\t%v\n", strForce, err)
return
}
сам.танкСтат.ФорсажОбнов(стрБроня, iForce)
сам.СценаРежим().РаботаУст(стрБроня)
}
case стрТочность: // Усиливаем точность
еслиНайдено = false
for ind, strOut = range lstPoligon {
if strings.Contains(strOut, `>улучшение точности<`) {
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
ind += 8
strOut = lstPoligon[ind]
if strOut == "" {
return
}
lstLink := strings.Split(strOut, `Получить бесплатно`)
strLink := "https://wartank.ru/" + lstLink[0]
if _, err := сам.сеть.Get(strLink); err != nil {
// log._rintf("ERRO NetPolygon.addForce(): in make request force fyne, err=\n\t%v\n", err)
return
}
{ // Узнать на сколько форсирована точность
strForce := lstPoligon[ind-7]
lstForce := strings.Split(strForce, `+`)
strForce = lstForce[1]
lstForce = strings.Split(strForce, ` на `)
strForce = lstForce[0]
iForce, err := strconv.Atoi(strForce)
if err != nil {
// log._rintf("ERRO NetPolygon.addForce(): strForceFyne(%v) not int, err=\n\t%v\n", strForce, err)
return
}
сам.танкСтат.ФорсажОбнов(стрТочность, iForce)
сам.СценаРежим().РаботаУст(стрТочность)
}
case стрПрочность: // Усиливаем мощность
еслиНайдено = false
for ind, strOut = range lstPoligon {
if strings.Contains(strOut, `>увеличение прочности<`) {
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
ind += 8
strOut = lstPoligon[ind]
lstLink := strings.Split(strOut, `Получить бесплатно`)
strLink := "https://wartank.ru/" + lstLink[0]
if _, err := сам.сеть.Get(strLink); err != nil {
// log._rintf("NetPolygon.addForce(): in make request force hard, err=\n\t%v\n", err)
return
}
{ // Узнать на сколько форсирована прочность
strForce := lstPoligon[ind-7]
lstForce := strings.Split(strForce, `+`)
strForce = lstForce[1]
lstForce = strings.Split(strForce, ` на `)
strForce = lstForce[0]
iForce, err := strconv.Atoi(strForce)
if err != nil {
// log._rintf("ERRO NetPolygon.addForce(): strForceHard(%v) not int, err=\n\t%v\n", strForce, err)
return
}
сам.танкСтат.ФорсажОбнов(стрПрочность, iForce)
сам.СценаРежим().РаботаУст(стрПрочность)
}
default: // Неизвестно что
сам.СценаРежим().РаботаУст("неизвестно")
// log._rintf("ERRO NetPolygon.addForce(): неизвестно что это, strParam=%q", strParam)
return
}
}
|