package polygon
import (
"log"
"strconv"
"strings"
"time"
"wartank/app/lev0/alias"
"wartank/app/lev0/cons"
. "wartank/app/lev0/types"
"wartank/app/lev1/stat_param"
"wartank/app/lev2/arena"
"wartank/kernel"
. "wartank/kernel/kernel_types"
)
/*
Объект полигона на базе
*/
const (
времОжидПлат = "05:00" // Время ожидания платного ускорения
времОжидБесплат = "30:00" // Время ожидания бесплатного ускорения
стрПрочность = "прочность"
стрТочность = "точность"
стрБроня = "броня"
стрАтака = "атака"
)
// Полигон -- объект полигона на базе
type Полигон struct {
ИАрена
бот ИБот
танкСтат ИТанкСтат
продуктСейчас ИБезопСтрока
продуктКол ИБезопЦелое
уровень *stat_param.СтатПарам
лог ИЯдроЛог
}
// НовПолигон -- возвращает новый *Polygon
func НовПолигон(конт ИБотКонтекст, база ИАренаБаза) *Полигон {
лог := kernel.НовЛог("Полигон " + база.Бот().Имя())
лог.Инфо("НовПолигон(): бот=%s\n", база.Бот().Имя())
сам := &Полигон{
бот: база.Бот(),
танкСтат: база.Бот().Стата(),
продуктСейчас: kernel.НовБезопСтрока(),
продуктКол: kernel.НовБезопЦелое(),
уровень: stat_param.НовСтатПарам("уровень"), // FIXME: вынести на уровень арены
лог: лог,
}
аренаКонфиг := arena.АренаКонфиг{
Бот_: база.Бот(),
АренаИмя_: "Полигон",
СтрКонтроль_: `Полигон
`,
ФнПуск_: сам.пуск,
СтрУрл_: "https://wartank.ru/polygon",
}
сам.ИАрена = arena.НовАрена(конт, аренаКонфиг)
_ = ИАренаПолигон(сам)
return сам
}
// Уровень -- возвращает уровень полигона
func (сам *Полигон) Уровень() ИСтатПарам {
return сам.уровень
}
// ПродуктКолСейчас -- количество продукта, что именно сейчас производится на полигоне
func (сам *Полигон) ПродуктКолСейчас() int {
return сам.продуктКол.Получ()
}
// ПродуктИмяСейчас -- что именно сейчас производится на полигоне
func (сам *Полигон) ПродуктИмяСейчас() string {
return сам.продуктСейчас.Получ()
}
// ПродуктВремяСейчас -- сколько осталось времени до обновы полигона
func (сам *Полигон) ПродуктВремяСейчас() string {
return сам.ВремяОстат().String()
}
// Пуск -- запускает работу полигона в отдельном потоке
func (сам *Полигон) Пуск() {
go сам.пуск()
}
const (
стрАпгрейд = "апгрейд"
)
// выполняет опрос полигона базы.
func (сам *Полигон) пуск() {
ош := сам.ОбратВремяУст("02")
if ош != nil {
log.Printf("Полигон(): при установке времени обратного отсчета, ош=\n\t%v\n", ош)
сам.бот.Сервер().Отменить()
return
}
фнРабота := func() {
defer func() {
for сам.ВремяОстат().ПолучМилСек() > 0 {
select {
case <-сам.Контекст().Done():
return
default:
time.Sleep(time.Second * 5)
}
}
}()
if сам.построитьПровер() { // Можно ли посторить?
if сам.построить() {
return
}
}
сам.проверитьУскорение()
сам.усилениеДобавить()
сам.усилениеПровер()
сам.времяОбнов()
if сам.продуктСейчас.Получ() == стрАпгрейд {
ош := сам.ВремяОстат().Уст("00:10:00")
if ош != nil {
log.Printf("Полигон(): при установке времени обратного отсчета, ош=\n\t%v\n", ош)
сам.бот.Сервер().Отменить()
return
}
}
счёт := 5
for счёт > 0 {
if сам.уровеньПолучить() {
break
}
счёт--
}
log.Printf("Полигон.пуск(): бот=%q, цикл завершён\n", сам.бот.Имя())
}
for {
select {
case <-сам.Контекст().Done():
return
case <-сам.ВремяОстат().КаналСиг():
фнРабота()
default:
фнРабота()
}
}
}
// Построить
func (сам *Полигон) построить() bool {
списСтр := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/building-upgrade/Polygon")
ссылка0 := "" // ссылка на постройку
{ // Поиск ссылки на покупку
for _, стр := range списСтр {
if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
ссылка0 = стр
break
}
}
if ссылка0 == "" {
return false
}
//
ссылка0 = strings.TrimPrefix(ссылка0, ``)
// https://wartank.ru/building-upgrade/Polygon?40-1.ILinkListener-upgradeLink-link
ссылка0 = "http://wartank.ru/building-upgrade/" + ссылка0
списСтр = сам.Сеть().ВебВоркер().Получ(ссылка0)
}
ссылка1 := "" // ссылка на улучшение здания
{ // Выбор покупки
//
for _, стр := range списСтр {
if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
ссылка1 = стр
break
}
}
if ссылка1 == "" {
return false
}
ссылка1 = strings.TrimPrefix(ссылка1, ``)
// https://wartank.ru/building-upgrade/Polygon?48-1.ILinkListener-upgradeLink-link
ссылка1 = "http://wartank.ru/building-upgrade/" + ссылка1
списСтр = сам.Сеть().ВебВоркер().Получ(ссылка1)
}
ссылка2 := "" // подтверждение покупки
{ // Подтверждение покупки
// да, подтверждаю
for _, стр := range списСтр {
if strings.Contains(стр, `confirmLink`) {
ссылка2 = стр
break
}
}
if ссылка2 == "" {
return false
}
ссылка2 = strings.TrimPrefix(ссылка2, ``)
// https://wartank.ru/wicket/page?52-1.ILinkListener-confirmLink
ссылка2 = "http://wartank.ru/wicket/" + ссылка2
//ссылка2="https://wartank.ru/wicket/page?25-1.ILinkListener-confirmLink"
_ = сам.Сеть().ВебВоркер().Получ(ссылка2)
}
return true
}
// Проверяет уровень полигона
func (сам *Полигон) уровеньПолучить() bool {
var (
стрВых = ""
еслиНайдено bool
)
lstBase := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/buildings")
// Полигон - 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 (сам *Полигон) проверитьУскорение() bool {
var (
strOut = ""
еслиНайдено bool
)
lstBase := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/buildings")
// Проверка на платное ускорение апгрейда + время
{ // Платное ускорение
if strings.Contains(strOut, `Ускорить за`) {
if err := сам.ОбратВремяУст(времОжидПлат); err != nil {
log.Printf("WARN Base.checkArsenalForce(): при установке платного времени ускорения апгрейда арсенала(%v)\n\terr=%v\n", времОжидПлат, err)
}
сам.АренаСостояние().РаботаИмяУст("")
сам.АренаСостояние().СостояниеУст(cons.РежимАпгрейд)
сам.продуктСейчас.Уст(стрАпгрейд)
сам.продуктКол.Уст(0)
return true
}
}
{ // Проверка на бесплатное ускорение апгрейда
еслиНайдено = false
for _, strOut = range lstBase {
if strings.Contains(strOut, `Производит снаряды, ремкомплекты
`) {
// Убедиться что есть строка платного ускорения
еслиНайдено = true
break
}
}
if !еслиНайдено {
return false
}
if !strings.Contains(strOut, `>Ускорение<`) {
return false
}
сам.АренаСостояние().СостояниеУст(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 false
}
// sound.ArsenalForce()
if err := сам.СтрОбновить(lstBase); err != nil {
// log._rintf("ERRO NetBank.checkArsenalForce(): при обновлении lstBase, err=\n\t%v\n", err)
return false
}
сам.АренаСостояние().РаботаИмяУст("")
сам.АренаСостояние().СостояниеУст(cons.РежимАпгрейд)
сам.продуктКол.Уст(0)
if err := сам.ОбратВремяУст(времОжидБесплат); err != nil {
log.Printf("WARN Base.checkArsenalForce(): при установке бесплатного времени ускорения апгрейда арсенала(%v)\n\terr=%v\n", времОжидБесплат, err)
}
}
// Все проверки прошли -- это просто работа
сам.АренаСостояние().РаботаИмяУст("work")
return true
}
// Проверяет необходимость постройки полигона
func (сам *Полигон) построитьПровер() bool {
// https://wartank.ru/building-upgrade/Polygon
списПолигон := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/building-upgrade/Polygon")
стрСсылка := ""
еслиНайти := false
//
for _, стрСсылка = range списПолигон {
if strings.Contains(стрСсылка, `href="Polygon?`) {
еслиНайти = true
break
}
}
return еслиНайти
}
// Обновляет оставшееся время полигона
//
// Этот объект сам описывает своё время
func (сам *Полигон) времяОбнов() {
var (
strLastTime string
еслиНайдено bool
isSet bool
lstPolygon = сам.СписПолучить()
)
defer func() {
if !isSet {
ош := сам.ОбратВремяУст("05")
if ош != nil {
log.Printf("Полигон.времяОбнов(): при установке обратного времени ожидания полигона, ош=\n\t%v\n", ош)
сам.бот.Сервер().Отменить()
return
}
}
}()
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 (сам *Полигон) усилениеДобавить() {
сам.Сеть().Обновить()
// log._rintf("Polygon.checkPolygon(): при принудительном обновлении lstPolygon, mode=%s\terr=\n\t%v\n", сам.ModeCurrent().Get(), err)
if err := сам.ОбратВремяУст("05"); err != nil {
log.Printf("Polygon.checkPolygon(): при принудительном обновлении обратного времени, время=`05`\terr=\n\t%v\n", err)
сам.бот.Сервер().Отменить()
return
}
lstPolygon := сам.СписПолучить()
if len(lstPolygon) == 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 lstPolygon {
if strings.Contains(strOut, `>усиление атаки<`) {
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
ind += 8
strOut = lstPolygon[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 := lstPolygon[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 lstPolygon {
if strings.Contains(strOut, `>усиление брони<`) {
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
ind += 8
strOut = lstPolygon[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 := lstPolygon[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 lstPolygon {
if strings.Contains(strOut, `>улучшение точности<`) {
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
ind += 8
strOut = lstPolygon[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 := lstPolygon[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 lstPolygon {
if strings.Contains(strOut, `>увеличение прочности<`) {
еслиНайдено = true
break
}
}
if !еслиНайдено {
return
}
ind += 8
strOut = lstPolygon[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 := lstPolygon[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
}
}
|