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