package divwar import ( "fmt" // "log" "net/http" "strings" "sync" "time" "wartank/pkg/components/section" "wartank/pkg/types" "wartank/server/serv_bots/warbot/angar/division/divwar/divwarnet" "wartank/server/serv_bots/warbot/angar/division/divwar/divwaron" "wartank/server/serv_bots/warbot/angar/division/divwar/divwaron/divwarsound" "wartank/server/serv_bots/warbot/tank/tankstat/static_param" ) /* Объект ожидания битвы дивизий */ // DivWar -- объект ожидания битвы дивизий type DivWar struct { *section.Section bot types.IBot alarm types.IStatParam net *divwarnet.DivWarNet conn *http.Client // Непосредственная битва divon *divwaron.DivWarOn login string // Для несоредственной битвы дивизий block sync.Mutex chDivWar chan int // Сигнал начала битвы дивизий sound *divwarsound.DivWarSound // Однопоточное проигрывание звука } // NewDivWar -- возвращает новый *DivWar func NewDivWar(bot types.IBot) (*DivWar, error) { if bot == nil { return nil, fmt.Errorf("NewDivWar(): IBot == nil") } sf := &DivWar{ bot: bot, alarm: static_param.NewStaticParam("alarm"), chDivWar: make(chan int, 1), sound: divwarsound.NewDivWarSound(), conn: bot.BotNet().Conn(), login: "prospero tank", } // sf.shotTimeFull.Set(8000) // 8000 msec var err error { // ISection sf.Section, err = section.NewSection(bot, "Битва дивизий", `до начала `) if err != nil { return nil, fmt.Errorf("NewDivWar(): in create *Section, err=\n\t%w", err) } } { // Net sf.net, err = divwarnet.NewDivWarNet(bot) if err != nil { return nil, fmt.Errorf("NewDivWar(): при создании DivWarNet, err=\n\t%w", err) } } go sf.run() go sf.reservTick() return sf, nil } func (sf *DivWar) reservTick() { defer sf.CountDown().Stop() for { select { case <-sf.bot.Ctx().Done(): return default: ct0 := sf.CountDown().Get() time.Sleep(time.Second * 7) ct1 := sf.CountDown().Get() if ct1 != ct0 { continue } if sf.divon != nil { continue } sf.chDivWar <- 1 } } } // запускает в работу битву дивизий func (sf *DivWar) run() { sf.chDivWar <- 1 for { select { case <-sf.bot.Ctx().Done(): sf.CountDown().Stop() return case <-sf.CountDown().ChanSig(): // Время обновить данные по сражению sf.findTimeCount() sf.upDivWar() case <-sf.chDivWar: // Сигнал к началу сражения sf.block.Lock() if sf.divon != nil { continue } sf.alarm.SetVal(1) sf.sound.Play() go sf.DivWar() // Запустить цикл непосредственного сражения time.Sleep(time.Second * 10) // Задержка для звука на странице sf.alarm.SetVal(0) } } } // Ищет время до начала битвы дивизий func (sf *DivWar) findTimeCount() { if err := sf.net.UpdateLst(); err != nil { // Здесь может уже обратный отсчёт перед сражением sf.chDivWar <- 1 return } var ( strOut string lstDivWar = sf.GetLst() isFind bool ind int ) for ind, strOut = range lstDivWar { if strings.Contains(strOut, `до начала: `) { ind++ strOut = lstDivWar[ind] isFind = true break } if strings.Contains(strOut, `>ОБЫЧНЫЕ<`) { // Это уже битва sf.chDivWar <- 1 return } } if !isFind { // Битва дивизий уже идёт sf.chDivWar <- 1 return } lstTime := strings.Split(strOut, ``) strTime := lstTime[1] lstTime = strings.Split(strTime, ``) strTime = lstTime[0] if err := sf.ParseCountDown(strTime); err != nil { // log._rintf("WARN DivWar.findTimeCount(): при установке времени ожидания битвы дивизий(%v)\n\terr=%v\n", strTime, err) return } } // При необходимости поднимает взвод в атаку, вызывается только если обнаружено приглашение (+) func (sf *DivWar) upDivWar() { var ( strOut string lstDivWar = sf.GetLst() isFind bool ) for _, strOut = range lstDivWar { if strings.Contains(strOut, `>Взвод, подъем! В атаку!<`) { isFind = true break } if strings.Contains(strOut, `
Вы в рядах участников
`) { // log._rintf("INFO DivWar.upDivWar(): уже зарегистрирован\n") return } } if !isFind { return } // Найдено приглашение на участие lstUp := strings.Split(strOut, `Взвод, подъем! В атаку!`) linkUp = "http://wartank.ru/" + lstUp[0] lstDivWar, err := sf.net.Get(linkUp) if err != nil { // log._rintf("ERRO DivWar.upDivWar(): при выполнении GET-команды на подъём в атаку, err=\n\t%v\n", err) return } if err = sf.Update(lstDivWar); err != nil { // log._rintf("ERRO DivWar.upDivWar(): при обновлении lstDivWar, err=\n\t%v\n", err) } // log._rintf("INFO DivWar.upDivWar(): регистрация прошла успешно\n") } // Ведёт сражение func (sf *DivWar) DivWar() { defer func() { sf.divon = nil sf.block.Unlock() if err := sf.SetCountDown(1); err != nil { panic(fmt.Errorf("DivWar.DivWar(): при установке CountDown, err=\n\t%w", err)) } // log.Printf("INFO DivWar.DivWar(): сражение завершено\n") }() var err error sf.divon, err = divwaron.NewDivWarOn(sf.bot) // IDivWarOn (онлайн) if err != nil { // log._rintf("ERRO DivWar.DivWarOn(): при создании IDivWarOn, err=\n\t%v\n", err) time.Sleep(time.Millisecond * 250) return } // Цикл ожидания окончания сражения for !sf.divon.IsEnd().Get() { time.Sleep(time.Second * 1) } } // Alarm -- возвращает признак начала сражения (для браузера) func (sf *DivWar) Alarm() types.IStatParam { return sf.alarm }