package convoy
import (
"fmt"
"log"
"strconv"
"strings"
"time"
"github.com/sirupsen/logrus"
"wartank/pkg/components/section"
"wartank/pkg/types"
"wartank/server/serv_bots/warbot/angar/convoy/convoynet"
"wartank/server/serv_bots/warbot/tank/tankstat/static_param"
)
/*
Объект конвоя в ангаре
*/
// Convoy -- объект конвоя в ангаре
type Convoy struct {
*section.Section
net *convoynet.ConvoyNet
bot types.IBot
glory types.IStatParam // Количество славы
chAttack chan int // Канал проведения атаки
}
// NewConvoy -- возвращает новый *Convoy
func NewConvoy(bot types.IBot) (*Convoy, error) {
section, err := section.NewSection(bot, `
Конвой`)
if err != nil {
return nil, fmt.Errorf("NewConvoy(): in create ISection, err=\n\t%w", err)
}
sf := &Convoy{
Section: section,
bot: bot,
glory: static_param.NewStaticParam("glory"),
chAttack: make(chan int, 5),
}
sf.net, err = convoynet.NewConvoyNet(sf)
if err != nil {
return nil, fmt.Errorf("NewConvoy(): in create *SectionNet, err=\n\t%w", err)
}
return sf, nil
}
// Run -- запускает конвой в работу
func (sf *Convoy) Run() error {
go sf.reservTick()
go sf.run()
return nil
}
// UpdateLst -- принудительно обновляет состояние конвоя
func (sf *Convoy) UpdateLst() {
if err := sf.net.UpdateLst("Конвой"); err != nil {
log.Printf("Convoy.UpdateLst(): err=\n\t%v\n", err)
}
}
// Glory --возвращает счётчик славы конвоя
func (sf *Convoy) Glory() types.IStatParam {
return sf.glory
}
// Если время конвоя замерло -- посылает контрольный сигнал на атаку
func (sf *Convoy) reservTick() {
defer func() {
close(sf.chAttack)
}()
for {
select {
case <-sf.bot.Ctx().Done():
return
default:
ct0 := sf.CountDown().Get()
time.Sleep(time.Second * 60)
ct1 := sf.CountDown().Get()
if ct1 != ct0 {
continue
}
sf.chAttack <- 1
}
}
}
// обрабатывает конвой
func (sf *Convoy) run() {
sf.chAttack <- 1
for {
select {
case <-sf.bot.Ctx().Done():
sf.CountDown().Stop()
return
case <-sf.CountDown().ChanSig(): // Время истекло
sf.updateTime()
sf.updateGlory()
case <-sf.chAttack: // Сигнал к атаке
sf.attackConvoy() // в этом месте только атаковать
sf.checkWarForce()
sf.checkMaster()
sf.check6frage()
}
}
}
// Обновляет славу потребованию
func (sf *Convoy) updateGlory() {
// Найти строку с упоминанием оставшегося времени конвоя
lstConvoy := sf.GetLst()
var (
strGlory string
isFind bool
)
for _, lastTime := range lstConvoy {
if strings.Contains(lastTime, `alt="Слава" title="Слава"> `) {
strGlory = lastTime
isFind = true
break
}
}
if !isFind { // Не найдена строка со славой -- это атака
return
}
// Ищем количество славы
lstGlory := strings.Split(strGlory, `alt="Слава" title="Слава"> `)
strGlory = lstGlory[1]
iGlory, err := strconv.Atoi(strGlory)
if err != nil {
// log._rintf("ERRO ConvoyNet.updateGlory(): слава(%v) не число, err=\n\t%v\n", strGlory, err)
return
}
sf.glory.SetVal(iGlory)
}
// Обновляет оставшееся время конвоя
func (sf *Convoy) updateTime() {
// Время подходит надо обновляться
if err := sf.net.UpdateLst("Конвой"); err != nil {
logrus.WithError(err).Error("ConvoyNet.updateTime(): при выполнении GET-команды обновления")
sf.CountDown().Set(20)
return
}
// Найти строку с упоминанием оставшегося времени конвоя
lstConvoy := sf.GetLst()
var (
strLastTime string
isFind bool
isMask bool
)
for _, lastTime := range lstConvoy {
if strings.Contains(lastTime, `До следующего конвоя: `) {
strLastTime = lastTime
isFind = true
break
}
if strings.Contains(lastTime, `Полная маскировка через `) {
strLastTime = lastTime
isMask = true
break
}
//
if strings.Contains(lastTime, `ILinkListener-root-startFight`) {
sf.chAttack <- 1
return
}
if strings.Contains(lastTime, `ILinkListener-root-findEnemy`) {
sf.chAttack <- 1
return
}
//
if strings.Contains(lastTime, `ILinkListener-root-startMasking`) {
sf.chAttack <- 1
return
}
}
switch {
case isFind: // Большая пауза между конвоями
// Ждём окончания ожидания конвоя
lstTime := strings.Split(strLastTime, `До следующего конвоя: `)
strLastTime = lstTime[1]
if err := sf.CountDown().Parse(strLastTime); err != nil {
// log._rintf("WARN Convoy.updateTime(): при установке времени ожидания конвоя(%v)\n\terr=%v\n", strLastTime, err)
sf.CountDown().Set(10)
}
case isMask: // Если маскировка между конвоями
// Ждём окончания ожидания конвоя
lstTime := strings.Split(strLastTime, `Полная маскировка через `)
strLastTime = lstTime[1]
if err := sf.CountDown().Parse(strLastTime); err != nil {
// log._rintf("ERRO Bank.getAllMode(): при установке времени банка для 1го режима(%v)\n\terr=%v\n", strLastTime, err)
sf.CountDown().Set(10)
}
}
}
// Проводит атаку на конвой
func (sf *Convoy) attackConvoy() {
// Найти контрольную строку
var (
strOut = ""
lstConvoy = sf.GetLst()
isFind bool
)
for _, strLink := range lstConvoy {
if strings.Contains(strLink, `>Начать разведку<`) {
strOut = strLink
lstLink := strings.Split(strOut, ``)
strOut = "http://wartank.ru/" + lstLink[0]
isFind = true
break
}
if strings.Contains(strLink, `В БОЙ!`) {
strOut = strLink
lstLink := strings.Split(strOut, ``)
strOut = "http://wartank.ru/" + lstLink[0]
isFind = true
break
}
if strings.Contains(strLink, `>ОБЫЧНЫЕ<`) {
strOut = strLink
lstLink := strings.Split(strOut, `ОБЫЧНЫЕ`)
strOut = "http://wartank.ru/" + lstLink[0]
isFind = true
break
}
}
if !isFind { // Время ожидания
if err := sf.CountDown().Set(1); err != nil {
panic(fmt.Errorf("ConvoyNet.attackConvoy(): пр установке CountDown, err=\n\t%w", err))
}
return
}
strLink := strOut
// Можно начать разведку
lstConvoy, err := sf.net.Get(strLink)
if err != nil {
// log._rintf("ERRO ConvoyNet.attackConvoy(): при выполнении GET-команды 'В атаку!', err=\n\t%v\n", err)
return
}
if err = sf.Update(lstConvoy); err != nil {
for _, strOut = range lstConvoy {
if strings.Contains(strOut, `Ошибка на сервере. Сообщение админу уже отправлено.`) {
// log._rintf("ERRO ConvoyNet.attackConvoy(): при обновлении lstConvoy, strOut=\n\t%v\n", strOut)
return
}
}
for _, strOut = range lstConvoy {
if strings.Contains(strOut, `База`) {
// log._rintf("ERRO ConvoyNet.attackConvoy(): при обновлении lstConvoy (найдено lstBase), strOut=\n\t%v\n", strOut)
return
}
}
// log._rintf("ERRO ConvoyNet.attackConvoy(): при обновлении lstConvoy, err=\n\t%v\n", err)
return
}
for sf.attack() {
}
if err := sf.CountDown().Set(1); err != nil {
panic(fmt.Errorf("ConvoyNet.attackConvoy(): при установке CountDown, err=\n\t%w", err))
}
}
// Выполняет атаку на конвой
func (sf *Convoy) attack() (isNext bool) {
// Вырезать ссылку на атаку
strOut := ""
lstConvoy := sf.GetLst()
// ОБЫЧНЫЕ
for _, strAttack := range lstConvoy {
if strings.Contains(strAttack, `>ОБЫЧНЫЕ<`) {
strOut = strAttack
break
}
// Полная маскировка через 39:53
if strings.Contains(strAttack, `Полная маскировка через `) {
return false
}
}
if strOut == "" { // Нечего атаковать
return false
}
// Атакуем конвой
lstLink := strings.Split(strOut, `ОБЫЧНЫЕ`)
strLink = "http://wartank.ru/" + lstLink[0]
{ // Выполнить атаку
var err error
lstConvoy, err = sf.net.Get(strLink)
if err != nil {
logrus.WithError(err).Error("ConvoyNet.attack(): in get page find attack")
return false
}
if err = sf.Update(lstConvoy); err != nil {
logrus.WithError(err).Error("Convoy.attack(): при обновлении lstConvoy")
return false
}
}
return true
}
// Забирает награду в конвое "Активируй боевую силу"
func (sf *Convoy) checkWarForce() {
var (
strOut string
isFind bool
lstConvoy = sf.GetLst()
ind int
)
if len(lstConvoy) == 0 {
if err := sf.net.UpdateLst("Конвой"); err != nil {
// log._rintf("Convoy.check6frage(): при обновлении пустого lstConvoy, err=\n\t%v\n", err)
return
}
lstConvoy = sf.GetLst()
}
for ind, strOut = range lstConvoy {
if strings.Contains(strOut, `Активируй усиление "Боевая сила"
`) {
isFind = true
ind += 23
strOut = lstConvoy[ind]
break
}
}
if !isFind {
return
}
// Получить награду
if !strings.Contains(strOut, `ILinkListener-missions-cc-0-c-awardLink`) {
return
}
lstLink := strings.Split(strOut, `Получить награду`)
// http://wartank.ru/convoy?80-1.ILinkListener-missions-cc-0-c-awardLink
strLink = "http://wartank.ru/" + lstLink[0]
lstConvoy, err := sf.net.Get(strLink)
if err != nil {
// log._rintf("ERRO Convoy.checkWarForce(): при выполнени команды GET, err=\n\t%v\n", err)
return
}
if err := sf.Update(lstConvoy); err != nil {
// log._rintf("ERRO Convoy.checkWarForce(): пр обновлении lstConvoy, err=\n\t%v\n", err)
return
}
// log._rintf("INFO Convoy.checkWarForce(): награда получена\n")
}
// Забирает награду в конвое "Мастер дозора"
func (sf *Convoy) checkMaster() {
var (
strOut string
isFind bool
lstConvoy = sf.GetLst()
ind int
)
if len(lstConvoy) == 0 {
if err := sf.net.UpdateLst("Конвой"); err != nil {
// log._rintf("Convoy.check6frage(): при обновлении пустого lstConvoy, err=\n\t%v\n", err)
return
}
lstConvoy = sf.GetLst()
}
for ind, strOut = range lstConvoy {
if strings.Contains(strOut, `Проведи разведку в конвое
`) {
isFind = true
ind += 23
strOut = lstConvoy[ind]
break
}
}
if !isFind {
return
}
// Получить награду
if !strings.Contains(strOut, `ILinkListener-missions-cc-0-c-awardLink`) {
return
}
lstLink := strings.Split(strOut, `Получить награду`)
// http://wartank.ru/convoy?61-1.ILinkListener-missions-cc-0-c-awardLink
strLink = "http://wartank.ru/" + lstLink[0]
lstConvoy, err := sf.net.Get(strLink)
if err != nil {
// log._rintf("ERRO Convoy.checkMaster(): при выполнени команды GET, err=\n\t%v\n", err)
return
}
if err := sf.Update(lstConvoy); err != nil {
// log._rintf("ERRO Convoy.checkMaster(): пр обновлении lstConvoy, err=\n\t%v\n", err)
return
}
// log._rintf("INFO Convoy.checkMaster(): награда получена\n")
}
// Забирает награду в конвое "Уничтожь 6 врагов в конвое"
func (sf *Convoy) check6frage() {
var (
strOut string
isFind bool
lstConvoy = sf.GetLst()
ind int
)
if len(lstConvoy) == 0 {
if err := sf.net.UpdateLst("Конвой"); err != nil {
// log._rintf("Convoy.check6frage(): при обновлении пустого lstConvoy, err=\n\t%v\n", err)
return
}
lstConvoy = sf.GetLst()
}
for ind, strOut = range lstConvoy {
if strings.Contains(strOut, `Уничтожь 6 врагов в конвое
`) {
isFind = true
ind += 23
strOut = lstConvoy[ind]
break
}
}
if !isFind {
return
}
// Получить награду
if !strings.Contains(strOut, `ILinkListener-missions-cc-0-c-awardLink`) {
return
}
lstLink := strings.Split(strOut, `Получить награду`)
// http://wartank.ru/convoy?61-1.ILinkListener-missions-cc-0-c-awardLink
strLink = "http://wartank.ru/" + lstLink[0]
lstConvoy, err := sf.net.Get(strLink)
if err != nil {
// log._rintf("ERRO Convoy.check6frage(): при выполнени команды GET, err=\n\t%v\n", err)
return
}
if err := sf.Update(lstConvoy); err != nil {
// log._rintf("ERRO Convoy.check6frage(): пр обновлении lstConvoy, err=\n\t%v\n", err)
return
}
// log._rintf("INFO Convoy.check6frage(): награда получена\n")
}