// 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):
 1 |
Время (+8 строк):
 1 |
*/
for _, strOut = range lstMine {
// Руда текущее
if strings.Contains(strOut, `src="/images/icons/ore.png?2" alt="ore"`) {
//  1 |
еслиНайдено = true
режим = "руда"
break
}
// Железо текущее
if strings.Contains(strOut, `src="/images/icons/iron.png?2" alt="iron"`) {
//  2 |
еслиНайдено = true
режим = "железо"
break
}
// Сталь текущее
if strings.Contains(strOut, `src="/images/icons/steel.png?2" alt="steel"`) {
//  2 |
еслиНайдено = true
режим = "сталь"
break
}
// Свинец текущее
if strings.Contains(strOut, `src="/images/icons/plumbum.png?2" alt="plumbum"`) {
//  2 |
еслиНайдено = true
режим = "свинец"
break
}
}
if !еслиНайдено {
сам.лог.Добавить("Шахта.количествоПолучить(): не надо\n")
return true, nil
}
switch режим {
case "руда":
_число := strings.TrimPrefix(strOut, ` `)
_число = 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, ` `)
_число = 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, ` `)
_число = 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, ` `)
_число = 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
}