package divwaron import ( "context" "fmt" "strings" "time" "wartank/pkg/components/safebool" "wartank/pkg/components/section" "wartank/pkg/components/sectionnet" "wartank/pkg/types" "wartank/server/serv_bots/warbot/angar/division/divwar/divwaron/health" "wartank/server/serv_bots/warbot/angar/division/divwar/divwaron/manevr" "wartank/server/serv_bots/warbot/angar/division/divwar/divwaron/shot" ) /* Предоставляет сетевой компонент при непосредственном сражении */ // DivWarOn -- непосредственно танкует в сражении type DivWarOn struct { *section.Section bot types.ИБот net *sectionnet.SectionNet ctxDivWar context.Context // Контекст сражения fnCancelDivWar func() // Функция отмены сражения shot *shot.Shot // Объект выстрела health *health.Health // Текущее здоровье танка manevr *manevr.Manevr // Возможность маневрирования login string isMasking *safebool.SafeBool // Признак необходимости маскирования (запрет стрельбы, когда слабое здоровье) chTick chan int // Ежесекудная проверка на окончание сражения isEnd *safebool.SafeBool } // NewDivWarOn -- возвращает новый *DivWarOn func NewDivWarOn(bot types.ИБот) (*DivWarOn, error) { if bot == nil { return nil, fmt.Errorf("NewDivWarOn(): IBot == nil") } ctxDivWar, fnCancelDivWar := context.WithTimeout(bot.Кнт(), time.Second*305) sf := &DivWarOn{ bot: bot, ctxDivWar: ctxDivWar, fnCancelDivWar: fnCancelDivWar, login: bot.Имя(), isMasking: safebool.NewSafeBool(), isEnd: safebool.NewSafeBool(), } var err error { // ISection (ожидание) sf.Section, err = section.NewSection(bot, "Ожидание битвы дивизий", `Сражения`) if err != nil { return nil, fmt.Errorf("NewDivWarOn(): in create *Section, err=\n\t%w", err) } } // sf.net = sectionnet.NewSectionNet(server, bot, "https://wartank.ru/pve") if sf.checkEnd() { return nil, fmt.Errorf("NewDivWarOn(): нет страницы для сражения") } go sf.makeTick() go sf.run() return sf, nil } // Ежесекудный тик func (sf *DivWarOn) makeTick() { defer func() { close(sf.chTick) sf.isEnd.Уст() }() for !sf.isEnd.Получ() { select { case <-sf.bot.Кнт().Done(): // Отмена контекста приложения return case <-sf.ctxDivWar.Done(): // Битва закончилась return default: if sf.isEnd.Получ() { return } sf.chTick <- 1 time.Sleep(time.Second * 1) } } } // запускает сражение func (sf *DivWarOn) run() { // defer log._rintf("DivWarOn.run(): сражение завершено\n") { // Подготовка к сражению var err error sf.shot, err = shot.NewShot(sf, sf.login) // Объект выстрела if err != nil { // log._rintf("ERRO DivWarOn.Run(): при создании выстрела танка, err=\n\t%v\n", err) return } sf.health, err = health.NewHealth(sf, sf.shot.IsEnd(), sf.login) if err != nil { // log._rintf("ERRO DivWarOn.Run(): при создании здоровья танка, err=\n\t%v\n", err) sf.shot.IsEnd().Сброс() return } sf.manevr, err = manevr.NewManevr(sf, sf.shot.IsEnd()) if err != nil { // log._rintf("ERRO DivWarOn.Run(): при создании маневра танка, err=\n\t%v\n", err) sf.shot.IsEnd().Сброс() return } } for { // Рабочий цикл сражения select { case <-sf.ctxDivWar.Done(): return case <-sf.ВремяОпрос().КаналСиг(): if sf.checkEnd() { return } } } } // Сеть -- возвращает сетевой компонент секции func (sf *DivWarOn) Сеть() types.ISectionNet { return sf.net } // Проверяет окончание сражения func (sf *DivWarOn) checkEnd() bool { defer func() { if sf.isEnd.Получ() { sf.fnCancelDivWar() // log._rintf("DivWarOn.checkEnd(): сражение завершено\n") } }() if err := sf.net.UpdateLst(); err != nil { // log._rintf("WARN DivWarOn.checkEnd(): при обновлении lstDivWarOn, err=\n\t%v\n", err) sf.isEnd.Уст() sf.fnCancelDivWar() return true } lstDivWarOn := sf.СписПолучить() for _, strOut := range lstDivWarOn { if strings.Contains(strOut, `" class="simple-but gray">ОБЫЧНЫЕ`) { sf.isEnd.Сброс() return false } } sf.isEnd.Уст() sf.fnCancelDivWar() return true } // ЕслиКонец -- возвращает признак окончания сражения (интерфейс) func (sf *DivWarOn) ЕслиКонец() *safebool.SafeBool { return sf.isEnd } func (sf *DivWarOn) Манёвр() { if sf.manevr == nil { return } if sf.manevr.IsReady() { sf.manevr.Manevr() } } // ВыстрелБлок -- признак запрета стрельбы при слабом здоровье func (sf *DivWarOn) ВыстрелБлок() *safebool.SafeBool { return sf.isMasking } // Ctx -- возвращает контекст отмены сражения func (sf *DivWarOn) Ctx() context.Context { return sf.ctxDivWar } // CancelBattle - -вызов функции отмены контекста сражения func (sf *DivWarOn) CancelBattle() { sf.fnCancelDivWar() }