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