// package arena_mine -- объект шахты на базе package arena_mine import ( "fmt" "strconv" "strings" "time" . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes" // . "wartank/app/lev0/alias" "wartank/app/lev0/cons" . "wartank/app/lev0/types" "wartank/app/lev1" "wartank/app/lev2/arena" "wartank/app/lev2/arena/arena_build" "wartank/app/lev2/arena/arena_mine/bf_mine_accelerate" "wartank/app/lev2/arena/arena_mine/bf_mine_build" "wartank/app/lev2/arena/arena_mine/bf_mine_time_work" ) // АренаШахта -- объект шахты на базе type АренаШахта struct { ИАренаСтроение лог ИВебЛог база ИАренаБаза руда ИСтатПарам железо ИСтатПарам сталь ИСтатПарам свинец ИСтатПарам конт ILocalCtx } // НовШахта -- возвращает новый *Mine func НовШахта(конт ILocalCtx) *АренаШахта { сам := &АренаШахта{ конт: конт, база: конт.Get("база").Val().(ИАренаБаза), руда: lev1.НовСтатПарам("руда"), железо: lev1.НовСтатПарам("железо"), сталь: lev1.НовСтатПарам("сталь"), свинец: lev1.НовСтатПарам("свинец"), } аренаКонфиг := arena.АренаКонфиг{ Конт_: сам.конт, АренаИмя_: "Шахта", СтрКонтроль_: `Руда
`, ФнПуск_: сам.пуск, СтрУрл_: "https://wartank.ru/production/Mine", } сам.ИАренаСтроение = arena_build.НовАренаСтроение(конт, аренаКонфиг) сам.лог = сам.ВебЛог() go сам.пуск() сам.лог.ОтклВывод() сам.лог.Добавить("Шахта.НовШахта(): бот=%q\n", конт.Get("бот").Val().(ИБот).Имя()) конт.Set("шахта", сам, "Шахта бота") _ = ИАренаШахта(сам) return сам } func (сам *АренаШахта) Пуск() { фнОбновить := func() { // Когда арена не построена -- ничего не вернёт defer func() { _ = recover() }() сам.Обновить() } фнОбновить() bf_mine_build.ШахтаПостроить(сам.конт) bf_mine_accelerate.ШахтаУскорить(сам.конт) bf_mine_time_work.ШахтаРаботаВремя(сам.конт) } // пуск -- запускает обработку шахты func (сам *АренаШахта) пуск() { фнРабота := func() { defer func() { for сам.ВремяОстат().ПолучМилСек() > 0 { time.Sleep(time.Second * 5) } }() сам.лог.Добавить("Шахта.пуск().фнРабота()") { // Построить счёт := 5 for счёт > 0 { break // еcлиНет := сам.построить() // if еcлиНет { // break // } // счёт-- } } { // Забрать из шахты счёт := 5 for счёт > 0 { // Забрать из шахты if сам.шахтаЗабрать() { break } счёт-- } } сам.уровеньОбновить() { // Получить продукцию счёт := 5 for счёт > 0 { счёт-- еслиПолуч, ош := сам.количествоПолучить() if ош != nil { continue } if еслиПолуч { break } } } сам.Сделать() } for { select { case <-сам.конт.Ctx().Done(): return case <-сам.ВремяОстат().КаналСиг(): фнРабота() default: фнРабота() } } } // Проверяет количество продукта в шахте func (сам *АренаШахта) количествоПолучить() (bool, error) { сам.лог.Добавить("Шахта.количествоПолучить()\n") var ( strOut string еслиНайдено bool режим string ) lstMine := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/buildings") /* Режим (руда-1):
ore 1
Время (+8 строк):
ore 1
*/ for _, strOut = range lstMine { // Руда текущее if strings.Contains(strOut, `src="/images/icons/ore.png?2" alt="ore"`) { //
ore 1
еслиНайдено = true режим = "руда" break } // Железо текущее if strings.Contains(strOut, `src="/images/icons/iron.png?2" alt="iron"`) { //
iron 2
еслиНайдено = true режим = "железо" break } // Сталь текущее if strings.Contains(strOut, `src="/images/icons/steel.png?2" alt="steel"`) { //
iron 2
еслиНайдено = true режим = "сталь" break } // Свинец текущее if strings.Contains(strOut, `src="/images/icons/plumbum.png?2" alt="plumbum"`) { //
iron 2
еслиНайдено = true режим = "свинец" break } } if !еслиНайдено { сам.лог.Добавить("Шахта.количествоПолучить(): не надо\n") return true, nil } switch режим { case "руда": _число := strings.TrimPrefix(strOut, `
ore `) _число = strings.TrimSuffix(_число, `
`) iNum, err := strconv.Atoi(_число) if err != nil { сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): кол-во руды (%v) не число, err=\n\t%v\n", _число, err) return false, fmt.Errorf("") } сам.ПродуктСейчас().Уст(iNum) сам.ПродуктСейчас().ИмяУст("руда") сам.лог.Добавить("Шахта.количествоПолучить(): кол-во руды = %v\n", iNum) case "железо": _число := strings.TrimPrefix(strOut, `
iron `) _число = strings.TrimSuffix(_число, `
`) iNum, err := strconv.Atoi(_число) if err != nil { сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): кол-во железа (%v) не число, err=\n\t%v\n", _число, err) return false, fmt.Errorf("") } сам.ПродуктСейчас().Уст(iNum) сам.ПродуктСейчас().ИмяУст("железо") сам.лог.Добавить("Шахта.количествоПолучить(): кол-во железа = %v\n", iNum) case "сталь": _число := strings.TrimPrefix(strOut, `
steel `) _число = strings.TrimSuffix(_число, `
`) iNum, err := strconv.Atoi(_число) if err != nil { сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): кол-во стали (%v) не число, err=\n\t%v\n", _число, err) return false, fmt.Errorf("") } сам.ПродуктСейчас().Уст(iNum) сам.ПродуктСейчас().ИмяУст("сталь") сам.лог.Добавить("Шахта.количествоПолучить(): кол-во стали = %v\n", iNum) case "свинец": _число := strings.TrimPrefix(strOut, `
plumbum `) _число = strings.TrimSuffix(_число, `
`) iNum, err := strconv.Atoi(_число) if err != nil { сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): кол-во свинца (%v) не число, err=\n\t%v\n", _число, err) return false, fmt.Errorf("") } сам.ПродуктСейчас().Уст(iNum) сам.ПродуктСейчас().ИмяУст("свинец") сам.лог.Добавить("Шахта.количествоПолучить(): кол-во свинца = %v\n", iNum) default: сам.лог.Добавить("Шахта.количествоПолучить(): неизвестный режим (%v)\n", режим) return false, fmt.Errorf("") } return true, nil } // Проверяет на забор из шахты func (сам *АренаШахта) шахтаЗабрать() bool { сам.лог.Добавить("Шахта.шахтаЗабрать()\n") var ( strOut string еслиНайдено bool ) списШахта := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/buildings") // Забрать for _, strOut = range списШахта { if strings.Contains(strOut, `.ILinkListener-buildings-0-building-rootBlock-actionPanel-takeProductionLink`) { еслиНайдено = true break } } if !еслиНайдено { сам.лог.Добавить("Шахта.шахтаЗабрать(): не надо\n") return true } _ссылка := strings.TrimPrefix(strOut, `Забрать`) ссылка := "https://wartank.ru/" + _ссылка // http://wartank.ru/buildings?5-1.ILinkListener-buildings-0-building-rootBlock-actionPanel-takeProductionLink lstBase1 := сам.Сеть().ВебВоркер().Получ(ссылка) сам.СтрОбновить(lstBase1) сам.лог.Добавить("Шахта.шахтаЗабрать(): ОК\n") сост := сам.Состояние().Получ() if сост == cons.РежимНеСуществует { сам.Состояние().Уст(cons.РежимПостроено) } if сам.Состояние().Получ() == cons.РежимРабота { сам.Состояние().Уст(cons.РежимЗабрать) } сам.Состояние().Уст(cons.РежимОжидание) return true } // // Проверяет ускорение строительства FIXME: не работает // func (сам *АренаШахта) ускорениеПровер() { // сам.лог.Добавить("") // списСтр := сам.Сеть().ВебВоркер().Получ("http://wartank.ru/buildings") // // Шахта - 0
// var ( // еслиНайти bool // стр string // ) // for _, стр = range списСтр { // if strings.Contains(стр, `Шахта - `) { // еслиНайти = true // break // } // } // if !еслиНайти { // сам.лог.Добавить("Шахта.ускорениеПровер(): не надо\n") // return // } // сам.лог.Добавить("Шахта.ускорениеПровер(): надо\n") // } // Обновляет текущий уровень шахты (может быть не построена) 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 { сам.лог.Добавить("ОШИБКА Шахта.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош) return false } сам.Уровень().Уст(иУровень) сам.лог.Добавить("Шахта.уровеньОбновить(): уровень=%v\n", иУровень) return true } // Сделать -- вызывается с базы, если она обнаружила, что пора сделать продукцию func (сам *АренаШахта) Сделать() { еслиПостроено := сам.Состояние().Получ() == cons.РежимПостроено еслиОжидание := сам.Состояние().Получ() == cons.РежимОжидание if !(еслиПостроено || еслиОжидание) { return } сам.Сеть().Обновить() if err := сам.выбратьМеталл(); err != nil { сам.лог.Добавить("ERRO Шахта.Сделать(): при выборе продукции, err=\n\t%v\n", err) return } продукт := сам.ПродуктСейчас().Имя() switch продукт { case "руда": for !сам.рудаСделать() { } case "железо": for !сам.железоСделать() { } case "сталь": for !сам.стальСделать() { } case "свинец": for !сам.свинецСделать() { } default: сам.лог.Добавить("ERRO Шахта.Сделать(): неизвестный режим производства, режим=%q\n", продукт) } сам.Состояние().Уст(cons.РежимРабота) } // Свинец -- возвращает объект свинца func (сам *АренаШахта) Свинец() ИСтатПарам { return сам.свинец } // Сталь -- возвращает объект стали func (сам *АренаШахта) Сталь() ИСтатПарам { return сам.сталь } // Железо -- возвращает объект железа func (сам *АренаШахта) Железо() ИСтатПарам { return сам.железо } // Руда -- возвращает объект руды func (сам *АренаШахта) Руда() ИСтатПарам { return сам.руда } // Выбирает продукцию по возможности произвести и её количеству func (сам *АренаШахта) выбратьМеталл() error { var ( диктПродукция = make(map[string]bool) // Словарь известной продукции lstMine = сам.СписПолучить() ) фнВыбратьПродукт := func() { // вычисляет список допустимой продукции диктПродукция["руда"] = true // Руда есть всегда диктПродукция["железо"] = false диктПродукция["сталь"] = false диктПродукция["свинец"] = false for _, strProd := range lstMine { // Проверить руду if strings.Contains(strProd, `Руда
`) { диктПродукция["руда"] = true break } } for _, strProd := range lstMine { // Проверить руду if strings.Contains(strProd, `Железо
`) { диктПродукция["железо"] = true break } } for _, strProd := range lstMine { // Проверить сталь if strings.Contains(strProd, `Сталь
`) { диктПродукция["сталь"] = true break } } for _, strProd := range lstMine { // Проверить свинец if strings.Contains(strProd, `Свинец
`) { диктПродукция["свинец"] = true break } } } фнВыбратьПродукт() сам.ПродуктСейчас().ИмяУст("руда") руда := сам.Руда().Получ() железо := сам.Железо().Получ() if диктПродукция["железо"] { if руда > железо*2 { сам.ПродуктСейчас().ИмяУст("железо") } } сталь := сам.Сталь().Получ() if диктПродукция["сталь"] { if железо > сталь*2 { сам.ПродуктСейчас().ИмяУст("сталь") } } свинец := сам.Свинец().Получ() if диктПродукция["свинец"] { if сталь > свинец*2 { сам.ПродуктСейчас().ИмяУст("свинец") } } return nil } // Создаёт руду func (сам *АренаШахта) рудаСделать() bool { time.Sleep(time.Millisecond * 55) lstMine, err := сам.Сеть().Get("https://wartank.ru/production/Mine") if err != nil { // log._rintf("ERRO Шахта.сделатьРуду(): при GET-команде 'начать производство руды', err=\n\t%v\n", err) return false } var ( инд int стрВых string // strTime string strLink string strNum string еслиНайдено bool ) for инд, стрВых = range lstMine { if strings.Contains(стрВых, `Руда
`) { // Руда
strNum = lstMine[инд+1] // strTime = lstMine[инд+3] strLink = lstMine[инд+10] еслиНайдено = true break } } if !еслиНайдено { return false } if !strings.Contains(strLink, `>Начать производство<`) { return true } // "Mine?16-1.ILinkListener-productions-0-production-startProduceLink\">Начать производство" // "Начать производство" _link := strings.TrimPrefix(strLink, `Начать производство") strLink = "https://wartank.ru/production/" + _link // https://wartank.ru/production/Mine?19-1.ILinkListener-productions-0-production-startProduceLink time.Sleep(time.Millisecond * 55) lstMine, err = сам.Сеть().Get(strLink) if err != nil { // log._rintf("ERRO Шахта.сделатьРуду(): при GET-команде 'начать производство руды', err=\n\t%v\n", err) return false } for _, стрВых = range lstMine { if strings.Contains(стрВых, `>Начать производство`) { return false } } // сам.СтрОбновить(lstMine) //сам.ОбратВремяУст(АВремя(strTime)) lstNum := strings.Split(strNum, `Кол-во: `) strNum = lstNum[1] lstNum = strings.Split(strNum, `
`) strNum = lstNum[0] iNum, err := strconv.Atoi(strNum) if err != nil { // log._rintf("ERRO Шахта.сделатьРуду(): кол-во(%v) не число, err=\n\t%v\n", strNum, err) return false } сам.ПродуктСейчас().Уст(iNum) сам.ПродуктСейчас().ИмяУст("руда") return true } // Создаёт железо func (сам *АренаШахта) железоСделать() bool { var ( lstMine = сам.СписПолучить() ind int strOut string // strTime string strLink string strNum string еслиНайдено bool ) for ind, strOut = range lstMine { if strings.Contains(strOut, `Железо
`) { // Железо
strNum = lstMine[ind+1] // Кол-во: 1
// strTime = lstMine[ind+3] // Начать производство strLink = lstMine[ind+10] еслиНайдено = true break } } if !еслиНайдено { return true } lstLink := strings.Split(strLink, `Начать производство`) strLink = "https://wartank.ru/production/" + lstLink[0] // https://wartank.ru/production/Mine?4-1.ILinkListener-productions-1-production-startProduceLink lstMine, err := сам.Сеть().Get(strLink) if err != nil { // log._rintf("ERRO MineNet.makeFerrum(): при GET-команде 'начать производство железа', err=\n\t%v\n", err) return false } for _, strOut := range lstMine { // Проверка на базу if strings.Contains(strOut, `База`) { // log._rintf("ERRO MineNet.makeFerrum(): при обновлении lstMine найден lstBase") return false } } сам.СтрОбновить(lstMine) // сам.ОбратВремяУст(АВремя(strTime)) lstNum := strings.Split(strNum, `Кол-во: `) strNum = lstNum[1] lstNum = strings.Split(strNum, `
`) strNum = lstNum[0] iNum, err := strconv.Atoi(strNum) if err != nil { // log._rintf("ERRO MineNet.makeFerrum(): кол-во(%v) не число, err=\n\t%v\n", strNum, err) return false } сам.ПродуктСейчас().Уст(iNum) сам.ПродуктСейчас().ИмяУст("железо") return true } // Создаёт сталь func (сам *АренаШахта) стальСделать() bool { var ( lstMine = сам.СписПолучить() ind int strOut string // strTime string strLink string strNum string еслиНайдено bool ) for ind, strOut = range lstMine { if strings.Contains(strOut, `Сталь
`) { strNum = lstMine[ind+1] // strTime = lstMine[ind+3] strLink = lstMine[ind+10] еслиНайдено = true break } } if !еслиНайдено { return true } lstLink := strings.Split(strLink, `Начать производство`) strLink = "https://wartank.ru/production/" + lstLink[0] time.Sleep(time.Millisecond * 55) lstMine, err := сам.Сеть().Get(strLink) if err != nil { // log._rintf("ERRO MineNet.makeSteel(): при GET-команде 'начать производство стали', err=\n\t%v\n", err) return false } for _, strOut := range lstMine { // Проверка на базу if strings.Contains(strOut, `База`) { // log._rintf("ERRO MineNet.makeSteel(): при обновлении lstMine найден lstBase") return false } } сам.СтрОбновить(lstMine) // сам.ОбратВремяУст(АВремя(strTime)) lstNum := strings.Split(strNum, `Кол-во: `) strNum = lstNum[1] lstNum = strings.Split(strNum, `
`) strNum = lstNum[0] iNum, err := strconv.Atoi(strNum) if err != nil { // log._rintf("ERRO MineNet.makeSteel(): кол-во(%v) не число, err=\n\t%v\n", strNum, err) return false } сам.ПродуктСейчас().Уст(iNum) сам.ПродуктСейчас().ИмяУст("сталь") return true } // Создаёт свинец func (сам *АренаШахта) свинецСделать() bool { var ( lstMine = сам.СписПолучить() ind int strOut string // strTime string strLink string strNum string еслиНайдено bool ) for ind, strOut = range lstMine { if strings.Contains(strOut, `Свинец
`) { strNum = lstMine[ind+1] // strTime = lstMine[ind+3] strLink = lstMine[ind+10] еслиНайдено = true break } } if !еслиНайдено { return true } lstLink := strings.Split(strLink, `Начать производство`) strLink = "https://wartank.ru/production/" + lstLink[0] time.Sleep(time.Millisecond * 55) lstMine, err := сам.Сеть().Get(strLink) if err != nil { // log._rintf("ERRO Шахта.сделатьСвинец(): при GET-команде 'начать производство стали', err=\n\t%v\n", err) return false } for _, strOut := range lstMine { // Проверка на базу if strings.Contains(strOut, `База`) { // log._rintf("ERRO Шахта.сделатьСвинец(): при обновлении lstMine найден lstBase") return false } } сам.СтрОбновить(lstMine) // сам.ОбратВремяУст(АВремя(strTime)) lstNum := strings.Split(strNum, `Кол-во: `) strNum = lstNum[1] lstNum = strings.Split(strNum, `
`) strNum = lstNum[0] iNum, err := strconv.Atoi(strNum) if err != nil { // log._rintf("ERRO Шахта.сделатьСвинец(): кол-во(%v) не число, err=\n\t%v\n", strNum, err) return false } сам.ПродуктСейчас().Уст(iNum) сам.ПродуктСейчас().ИмяУст("свинец") return true }