// package arena_arsenal -- объект оружейной на базе package arena_arsenal import ( "fmt" "log" "strconv" "strings" "time" . "wartank/app/lev0/types" "wartank/app/lev1" "wartank/app/lev1/web_log" "wartank/app/lev2/arena" . "gitp78su.ipnodns.ru/svi/kern" . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes" ) const ( стрКумулятивы = "кумулятивы" стрБронебойки = "бронебойки" стрФугасы = "фугасы" стрРемки = "ремки" ) // Арсенал -- объект оружейной на базе type АренаАрсенал struct { ИАрена вЛог ИВебЛог лог ILogBuf бот ИБот база ИАренаБаза фугас ИСтатПарам бронебойка ИСтатПарам кумулятив ИСтатПарам ремка ИСтатПарам продуктИмя string // Что сейчас делается продуктКол ИСтатПарам // Сколько делается прямо сейчас продуктВремя string // Сколько осталось времени прямо сейчас конт ILocalCtx } // НовАрсенал -- возвращает новый *Arsenal func НовАрсенал(конт ILocalCtx) ИАренаАрсенал { лог := NewLogBuf() лог.Info("НовАрсенал()\n") сам := &АренаАрсенал{ бот: конт.Get("бот").Val().(ИБот), база: конт.Get("база").Val().(ИАренаБаза), фугас: lev1.НовСтатПарам(стрФугасы), бронебойка: lev1.НовСтатПарам(стрБронебойки), кумулятив: lev1.НовСтатПарам(стрКумулятивы), ремка: lev1.НовСтатПарам(стрРемки), продуктКол: lev1.НовСтатПарам("свинец"), конт: конт, лог: лог, } аренаКонфиг := arena.АренаКонфиг{ Бот_: сам.бот, АренаИмя_: "Арсенал", СтрКонтроль_: `Ремкомплект
`, ФнПуск_: сам.пуск, СтрУрл_: "https://wartank.ru/production/Armory", } сам.ИАрена = arena.НовАрена(конт, аренаКонфиг) сам.вЛог = web_log.НовВебЛог(true) // go сам.пуск() сам.вЛог.Добавить("НовАрсенал(): Арсенал создан") конт.Set("арсенал", сам, "Арсенал бота") return сам } // ПродуктКолСейчас -- возвращает количество производимого продукта func (сам *АренаАрсенал) ПродуктКолСейчас() int { return сам.продуктКол.Получ() } // ПродуктИмяСейчас -- возвращает имя производимого продукта func (сам *АренаАрсенал) ПродуктИмяСейчас() string { return сам.продуктИмя } // ПродуктВремяСейчас -- сколько осталось времени до производства продукта func (сам *АренаАрсенал) ПродуктВремяСейчас() string { return сам.продуктВремя // return сам.Секция.ВремяОпрос().Стр() } // запускает обработку арсенала func (сам *АренаАрсенал) пуск() { еслиПостроить := true фнРабота := func() { defer func() { for сам.ВремяОстат().ПолучМилСек() > 0 { select { case <-сам.конт.Ctx().Done(): return default: time.Sleep(time.Second * 5) } } }() сам.вЛог.Добавить("Арсенал.пуск().фнРабота()\n") еслиПостроить = сам.проверитьПостроить() if еслиПостроить { еслиПостроено, ош := сам.построить() if ош != nil { return } if еслиПостроено { сам.вЛог.Добавить("построено") return } } { // апгрейд счёт := 5 for счёт > 0 { if сам.проапгрейдить() { break } счёт-- } } _ = сам.уровеньОбновить() ош := сам.СтатаОбновить() if ош != nil { сам.лог.Err("пуск(): при обновлении статы, ош=\n\t%v\n", ош) сам.вЛог.Добавить("пуск(): при обновлении статы, ош=\n\t%w", ош) } сам.забрать() сам.сделать() сам.лог.Info("пуск(): бот=%q, цикл завершён\n", сам.бот.Имя()) } for { фнРабота() } } // Проверяет необходимость постройки func (сам *АренаАрсенал) проверитьПостроить() bool { сам.вЛог.Добавить("Арсенал.проверитьПостроить()\n") _ = сам.Сеть().ВебВоркер().Получ("https://wartank.ru/building-upgrade/Armory") return true } // Обновляет текущий уровень арсенала (может быть не построена) func (сам *АренаАрсенал) уровеньОбновить() bool { сам.вЛог.Добавить("Арсенал.уровеньОбновить()\n") списСтр := сам.Сеть().ВебВоркер().Получ("http://wartank.ru/buildings") // Оружейная - 0
var ( еслиНайти = false стр = "" ) for _, стр = range списСтр { if strings.Contains(стр, `Оружейная -`) { еслиНайти = true break } } if !еслиНайти { сам.вЛог.Добавить("Арсенал.уровеньОбновить(): не надо\n") return false } _стр := strings.TrimPrefix(стр, `Оружейная - `) _стр = strings.TrimSuffix(_стр, `
`) иУровень, ош := strconv.Atoi(_стр) if ош != nil { сам.лог.Err("уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош) сам.вЛог.Добавить("ОШИБКА Арсенал.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош) return false } сам.Уровень().Уст(иУровень) сам.лог.Info("уровеньОбновить(): уровень=%d\n", иУровень) сам.вЛог.Добавить("Арсенал.уровеньОбновить(): уровень=%d\n", иУровень) return true } // Строит арсенал при нулевом уровне func (сам *АренаАрсенал) построить() (bool, error) { сам.вЛог.Добавить("Арсенал.построить()\n") списСтр := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/building-upgrade/Armory") // Арсенал - 0
var ( еслиНайти = false стр = "" ) for _, стр = range списСтр { if strings.Contains(стр, `ILinkListener-upgradeLink-link`) { еслиНайти = true break } } if !еслиНайти { сам.вЛог.Добавить("Арсенал.построить(): не надо\n") return true, nil } // // Пробуем построить арсенал _стр := strings.TrimPrefix(стр, ``) ссылка := "https://wartank.ru/building-upgrade/" + _стр // https://wartank.ru/building-upgrade/Armory?35-1.ILinkListener-upgradeLink-link списСтр = сам.Сеть().ВебВоркер().Получ(ссылка) еслиНайти = false // "" for _, стр = range списСтр { if strings.Contains(стр, `ILinkListener-upgradeLink-link`) { еслиНайти = true break } } if !еслиНайти { сам.вЛог.Добавить("Арсенал.построить(): не надо\n") return true, nil } сам.лог.Info("построить(): ок\n") сам.вЛог.Добавить("Арсенал.построить(): ок\n") return true, nil } // Пытается проапгрейдить арсенал func (сам *АренаАрсенал) проапгрейдить() bool { сам.вЛог.Добавить("Арсенал.проапгрейдить()\n") var ( еслиНайти = false списСтр []string стр = "" ) фнКупить := func() bool { defer time.Sleep(time.Millisecond * 1000) списСтр = сам.Сеть().ВебВоркер().Получ("https://wartank.ru/building-upgrade/Armory") for _, стр = range списСтр { // if strings.Contains(стр, `ILinkListener-upgradeLink-link`) { еслиНайти = true break } } if !еслиНайти { сам.вЛог.Добавить("Арсенал.проапгрейдить(): не надо\n") return true } // Пробуем улучшить шахту _стр := strings.TrimPrefix(стр, "") // https://wartank.ru/building-upgrade/Armory?4-1.ILinkListener-upgradeLink-link // ссылка := "https://wartank.ru/building-upgrade/" + _стр списСтр = сам.Сеть().ВебВоркер().Получ(ссылка) // Проверить, что постройка состоялась for _, стр := range списСтр { if strings.Contains(стр, "ILinkListener-upgradeLink-link") { log.Printf("Арсенал.проапгрейдить().фнКупить(): покупка арсенала не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр) return false // Покупка не оплачена } } сам.вЛог.Добавить("Арсенал.проапгрейдить().фнКупить(): ок\n") return true } фнПодтверждение := func() bool { for _, стр = range списСтр { // да, подтверждаю if strings.Contains(стр, `ILinkListener-confirmLink`) { еслиНайти = true break } } if !еслиНайти { сам.вЛог.Добавить("Арсенал.проапгрейдить().фнПодтверждение(): не надо\n") return true } // Пробуем построить шахту _стр := strings.TrimPrefix(стр, `да, подтверждаю`) // https://wartank.ru/wicket/page?6-1.ILinkListener-confirmLink ссылка := "https://wartank.ru" + _стр списСтр = сам.Сеть().ВебВоркер().Получ(ссылка) // Проверить, что постройка состоялась for _, стр := range списСтр { if strings.Contains(стр, "Вы сделали слишком большую паузу") { сам.вЛог.Добавить("ОШИБКА Арсенал.проапгрейдить().фнПодтверждение(): подтверждение покупка склада топлива не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр) return false // Покупка не оплачена } } сам.вЛог.Добавить("Арсенал.проапгрейдить().фнПодтверждение(): ок\n") return true } фнКомплекс := func() { count := 5 for count > 0 { if фнКупить() { if фнПодтверждение() { break } } count-- } } фнКомплекс() return true } // Проверяет на забрать оружейную func (сам *АренаАрсенал) забрать() bool { var ( strOut string ind int еслиНайдено bool lstBase = сам.СписПолучить() ) for ind, strOut = range lstBase { if strings.Contains(strOut, `Моя амуниция`) { еслиНайдено = true ind += 17 strOut = lstBase[ind] break } } if !еслиНайдено { return false } if !strings.Contains(strOut, `">Забрать`) { return false } lstLink := strings.Split(strOut, `Забрать`) // https://wartank.ru/buildings?80-1.ILinkListener-buildings-0-building-rootBlock-actionPanel-takeProductionLink strLink = "https://wartank.ru/" + lstLink[0] var ( лстАрсенал []string ош error ) time.Sleep(time.Millisecond * 100) лстАрсенал, ош = сам.Сеть().Get(strLink) if ош != nil { log.Printf("Арсенал.забрать(): при выполнении Get-запроса? err=\n\t%v\n", ош) return false } if len(лстАрсенал) == 0 { log.Printf("Арсенал.забрать(): len lstBase(%v)==0", len(lstBase)) return false } for _, strOut = range лстАрсенал { if strings.Contains(strOut, `Производство`) { return false } } if ош = сам.СтрОбновить(лстАрсенал); ош != nil { log.Printf("Арсенал.checkArsenalGet(): при обновлении lstBase, err=\n\t%v\n", ош) } if ош = сам.СтрОбновить(лстАрсенал); ош != nil { log.Printf("Арсенал.checkArsenalGet(): при обновлении lstArsenal, err=\n\t%v\n", ош) } return true } // Фугасы -- возвращает объект числа фугасов func (сам *АренаАрсенал) Фугасы() ИСтатПарам { return сам.фугас } // Бронебойки -- возвращает объект бронебойных снарядов func (сам *АренаАрсенал) Бронебойки() ИСтатПарам { return сам.бронебойка } // Кумулятивы -- возвращает объект бронебойных снарядов func (сам *АренаАрсенал) Кумулятивы() ИСтатПарам { return сам.кумулятив } // Ремки -- возвращает объект ремкомплектов func (сам *АренаАрсенал) Ремки() ИСтатПарам { return сам.ремка } // Обновляет состояние арсенала по требованию func (сам *АренаАрсенал) СтатаОбновить() (err error) { сам.вЛог.Добавить("Арсенал.СтатаОбновить()\n") сам.Сеть().Обновить() var ( strOut string lstArsenal = сам.СписПолучить() ) { // Найти маркер фугасного снаряда for _, стрФугас := range lstArsenal { if strings.Contains(стрФугас, `Фугасный снаряд `) { strOut = стрФугас break } } списФугас := strings.Split(strOut, `Фугасный снаряд `) стрФугас := списФугас[1] списФугас = strings.Split(стрФугас, `   `) стрФугас = списФугас[0] целФугас, err := strconv.Atoi(стрФугас) if err != nil { ош := fmt.Errorf("ОШИБКА Арсенал.СтатаОбновить(): фугас(%v) not number, err=\n\t%w", стрФугас, err) сам.вЛог.Добавить("%v\n", ош) return ош } сам.Фугасы().Уст(целФугас) } { // Найти маркер бронебойного снаряда for _, strArmor := range lstArsenal { if strings.Contains(strArmor, `alt="Бронебойный снаряд"`) { strOut = strArmor break } } lstArmor := strings.Split(strOut, `Бронебойный снаряд `) strArmor := lstArmor[1] lstArmor = strings.Split(strArmor, `   `) strArmor = lstArmor[0] iArmor, err := strconv.Atoi(strArmor) if err != nil { ош := fmt.Errorf("Арсенал.СтатаОбновить(): armor(%v) not number, err=\n\t%w", strArmor, err) сам.вЛог.Добавить("%v\n", ош) return ош } сам.Бронебойки().Уст(iArmor) сам.вЛог.Добавить("Арсенал.СтатаОбновить(): бронебойки=%v\n", iArmor) } { // Найти маркер кумулятивного снаряда for _, стрКумул := range lstArsenal { if strings.Contains(стрКумул, `Кумулятивный снаряд `) { strOut = стрКумул break } } списКумул := strings.Split(strOut, `Кумулятивный снаряд `) стрКумул := списКумул[1] списКумул = strings.Split(стрКумул, `   `) стрКумул = списКумул[0] целКумул, err := strconv.Atoi(стрКумул) if err != nil { return fmt.Errorf("Арсенал.СтатаОбновить(): кумул(%v) not number, err=\n\t%w", стрКумул, err) } сам.Кумулятивы().Уст(целКумул) } { // Найти маркер ремкомплекта for ind, стрРемка := range lstArsenal { if strings.Contains(стрРемка, ` `) { strOut = lstArsenal[ind] break } } списРемка := strings.Split(strOut, ` `) стрРемка := списРемка[1] списРемка = strings.Split(стрРемка, ``) стрРемка = списРемка[0] целРемка, err := strconv.Atoi(стрРемка) if err != nil { return fmt.Errorf("Арсенал.СтатаОбновить(): ремка(%v) not number, err=\n\t%w", стрРемка, err) } сам.Ремки().Уст(целРемка) } return nil } // Выбирает что надо делать, запускает процесс изготовления func (сам *АренаАрсенал) сделать() bool { сам.Обновить() // _mt.Println("\tArsenalNet.сделать()") var ( ремкаКол = сам.Ремки().Получ() фугасКол = сам.Фугасы().Получ() кумульКол = сам.Кумулятивы().Получ() ббКол = сам.Бронебойки().Получ() снарядТип string ) if ремкаКол < 70 { // Контроль ремки по времени суток и минимальному количеству ремок for !сам.сделатьРемку() { } сам.продуктИмя = стрРемки return true } { // Контроль по числу снарядов. В равных долях без приоритетов // снарядТип = стрФугасы снарядТип = стрБронебойки if ббКол > фугасКол { снарядТип = стрФугасы } if фугасКол > кумульКол { снарядТип = стрКумулятивы } switch снарядТип { case стрФугасы: // Мало фугасов for !сам.сделатьФугасы() { } case стрКумулятивы: // Мало кумулятивов for !сам.сделатьКумули() { } case стрБронебойки: // Мало бронебойных for !сам.сделатьБронебойки() { } default: // log._rintf("ERRO Арсенал.сделать(): неизвестный тип арсенала(%v)", typeArmor) } сам.продуктИмя = снарядТип } return true } // Создать бронебойные func (сам *АренаАрсенал) сделатьБронебойки() bool { var ( стрВых string lstArsenal = сам.СписПолучить() еслиНайдено bool инд int ) for инд, стрВых = range lstArsenal { if strings.Contains(стрВых, `Бронебойный снаряд
`) { еслиНайдено = true break } } if !еслиНайдено { return false } стрВых = lstArsenal[инд+10] // Получить ссылку на бронебойные lstArmor := strings.Split(стрВых, `Начать производство`) strLink = "https://wartank.ru/production/" + lstArmor[0] time.Sleep(time.Millisecond * 50) if _, err := сам.Сеть().Get(strLink); err != nil { // log._rintf("ERRO ArsenalNet.makeArmor(): in update lstArsenal, err=\n\t%v\n", err) return false } сам.АренаСостояние().СостояниеУст(стрБронебойки) return true } // Создать кумулятивные func (сам *АренаАрсенал) сделатьКумули() bool { var ( стрВых string lstArsenal = сам.СписПолучить() еслиНайдено bool инд int ) for инд, стрВых = range lstArsenal { if strings.Contains(стрВых, `Кумулятивный снаряд
`) { еслиНайдено = true break } } if !еслиНайдено { return false } стрВых = lstArsenal[инд+10] if !strings.Contains(стрВых, `>Начать производство<`) { return false } // Получить ссылку на кумулятив списКумул := strings.Split(стрВых, `Начать производство`) strLink = "https://wartank.ru/production/" + списКумул[0] time.Sleep(time.Millisecond * 50) if _, err := сам.Сеть().Get(strLink); err != nil { // log._rintf("ERRO ArsenalNet.makeКумуль(): in make product arsenal кумуль , err=\n\t%v\n", err) return false } сам.АренаСостояние().СостояниеУст(стрКумулятивы) return true } // Создать фугасы func (сам *АренаАрсенал) сделатьФугасы() bool { var ( lstArsenal = сам.СписПолучить() стрВых string еслиНайдено bool инд int ) for инд, стрВых = range lstArsenal { if strings.Contains(стрВых, `Фугасный снаряд
`) { еслиНайдено = true break } } if !еслиНайдено { return false } стрВых = lstArsenal[инд+10] if !strings.Contains(стрВых, `">Начать производство`) { return false } // Получить ссылку на ремку списКумул := strings.Split(стрВых, `Начать производство`) strLink = "https://wartank.ru/production/" + списКумул[0] time.Sleep(time.Millisecond * 50) if _, err := сам.Сеть().Get(strLink); err != nil { // log._rintf("ERRO ArsenalNet.makeФугас(): in make request arsenal product, err=\n\t%v\n", err) return false } сам.АренаСостояние().СостояниеУст(стрФугасы) // log._rintf("INFO Арсенал.makeФугас()\n") return true } // Создать ремку. Выполняется если подходят условия func (сам *АренаАрсенал) сделатьРемку() bool { // _mt.Println("\tArsenalNet.makeРемка()") var ( стрВых string еслиНайдено bool инд int ) lstArsenal := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/production/Armory") // Ремкомплект
for инд, стрВых = range lstArsenal { if strings.Contains(стрВых, `Ремкомплект
`) { еслиНайдено = true break } } if !еслиНайдено { return false } стрВых = lstArsenal[инд+10] // Если кривая строка, то надо вернуться if strings.Contains(стрВых, ``) { return true } // Получить ссылку на ремку _ссылка := strings.TrimPrefix(стрВых, `Начать производство`) // https://wartank.ru/production/Armory?37-1.ILinkListener-productions-3-production-startProduceLink ссылка := "https://wartank.ru/production/" + _ссылка time.Sleep(time.Millisecond * 50) _ = сам.Сеть().ВебВоркер().Получ(ссылка) сам.АренаСостояние().СостояниеУст(стрРемки) return true }