package mine
import (
"fmt"
"log"
"strconv"
"strings"
"time"
"wartank/pkg/components/section"
"wartank/pkg/types"
"wartank/server/serv_bots/warbot/angar/base/mine/minenet"
"wartank/server/serv_bots/warbot/tank/tankstat/static_param"
)
/*
Объект шахты на базе
*/
// Шахта -- объект шахты на базе
type Шахта struct {
*section.Секция
сеть *minenet.MineNet
бот types.ИБот
база types.ИБаза
руда types.ИСтатПарам
железо types.ИСтатПарам
сталь types.ИСтатПарам
свинец types.ИСтатПарам
numProduct types.ИСтатПарам
уровень types.ИСтатПарам
}
// НовШахта -- возвращает новый *Mine
func НовШахта(база types.ИБаза) (*Шахта, error) {
секция, ош := section.NewSection(база.Бот(), "Шахта", `Руда
`)
if ош != nil {
return nil, fmt.Errorf("НовШахта(): in create *Section, err=\n\t%w", ош)
}
руда, ош := static_param.НовСтатПарам("ruda")
if ош != nil {
return nil, fmt.Errorf("НовШахта(): при создании статистики руды, ош=\n\t%w", ош)
}
железо, ош := static_param.НовСтатПарам("ferrum")
if ош != nil {
return nil, fmt.Errorf("НовШахта(): при создании статистики железа, ош=\n\t%w", ош)
}
сталь, ош := static_param.НовСтатПарам("steel")
if ош != nil {
return nil, fmt.Errorf("НовШахта(): при создании статистики стали, ош=\n\t%w", ош)
}
свинец, ош := static_param.НовСтатПарам("plumbum")
if ош != nil {
return nil, fmt.Errorf("НовШахта(): при создании статистики свинца, ош=\n\t%w", ош)
}
добычаЧисло, ош := static_param.НовСтатПарам("plumbum")
if ош != nil {
return nil, fmt.Errorf("НовШахта(): при создании статистики числа добычи, ош=\n\t%w", ош)
}
уровень, ош := static_param.НовСтатПарам("уровень")
if ош != nil {
return nil, fmt.Errorf("НовШахта(): при создании статистики числа добычи, ош=\n\t%w", ош)
}
сам := &Шахта{
Секция: секция,
бот: база.Бот(),
база: база,
руда: руда,
железо: железо,
сталь: сталь,
свинец: свинец,
numProduct: добычаЧисло,
уровень: уровень,
}
сам.сеть, ош = minenet.NewMineNet(сам)
if ош != nil {
return nil, fmt.Errorf("NewMine(): in create NetMine, err=\n\t%w", ош)
}
return сам, nil
}
func (сам *Шахта) Пуск() error {
go сам.пуск()
return nil
}
// пуск -- запускает обработку шахты
func (сам *Шахта) пуск() {
time.Sleep(time.Second * 3)
for {
select {
case <-сам.бот.Кнт().Done():
сам.ВремяОпрос().Стоп()
return
case <-сам.ВремяОпрос().КаналСиг():
default:
log.Printf("Шахта.пуск()\n")
if сам.уровеньОбновить() {
сам.ускорениеПровер()
руда := сам.Руда().Получ()
if руда == 0 {
time.Sleep(time.Second * 5)
сам.бот.Ангар().РесурсыОбновить()
}
сам.Сделать()
}
time.Sleep(time.Minute * 5)
}
}
}
// Проверяет ускорение строительства
func (сам *Шахта) ускорениеПровер() {
списСтр, ош := сам.сеть.Клиент().Get("http://wartank.ru/buildings")
if ош != nil {
log.Printf("Шахта.ускорениеПровер(): in make request, err=\n\t%v\n", ош)
return
}
// Шахта - 0
var (
еслиНайти = false
стр = ""
)
for _, стр = range списСтр {
if strings.Contains(стр, `Шахта - `) {
еслиНайти = true
break
}
}
if !еслиНайти {
return
}
}
// Уровень -- возвращает уровень шахты
func (сам *Шахта) Уровень() types.ИСтатПарам {
return сам.уровень
}
// Обновляет текущий уровень шахты (может быть не построена)
func (сам *Шахта) уровеньОбновить() bool {
списСтр, ош := сам.сеть.Клиент().Get("http://wartank.ru/buildings")
if ош != nil {
log.Printf("Шахта.уровеньОбновить(): in make request, err=\n\t%v\n", ош)
return false
}
// Шахта - 0
var (
еслиНайти = false
стр = ""
)
for _, стр = range списСтр {
if strings.Contains(стр, `Шахта - `) {
еслиНайти = true
break
}
}
if !еслиНайти {
return false
}
_стр := strings.TrimPrefix(стр, `Шахта - `)
_стр = strings.TrimSuffix(_стр, `
`)
иУровень, ош := strconv.Atoi(_стр)
if ош != nil {
log.Printf("Шахта.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
return false
}
сам.уровень.Уст(иУровень)
if иУровень == 0 { // шахту надо построить
сам.построить(списСтр)
return false
}
return true
}
// Строит шахту принулевом уровне
func (сам *Шахта) построить(списСтр []string) {
//
Построить |
var (
еслиНайти = false
стр = ""
)
for _, стр = range списСтр {
if strings.Contains(стр, `href="building-upgrade/Mine">Построить`) {
еслиНайти = true
break
}
}
if !еслиНайти {
return
}
// Пробуем построить шахту
_стр := strings.TrimPrefix(стр, `Построить | `)
ссылка := "https://wartank.ru/" + _стр
списСтр, ош := сам.сеть.Клиент().Get(ссылка)
if ош != nil {
log.Printf("ERRO Шахта.построить(): при GET-команде 'построить шахту', err=\n\t%v\n", ош)
return
}
еслиНайти = false
// ""
for _, стр = range списСтр {
if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
еслиНайти = true
break
}
}
if !еслиНайти {
return
}
_стр = strings.TrimPrefix(стр, "")
// http://wartank.ru/building-upgrade/Mine?16-1.ILinkListener-upgradeLink-link
ссылка = "https://wartank.ru/building-upgrade/" + _стр
_, ош = сам.сеть.Клиент().Get(ссылка)
if ош != nil {
log.Printf("ERRO Шахта.построить(): при GET-команде 'купить постройку шахты', err=\n\t%v\n", ош)
return
}
}
// Сделать -- вызывается с базы, если она обнаружила, что пора сделать продукцию
func (сам *Шахта) Сделать() {
работа := сам.РежимТекущ().Режим()
log.Printf("Шахта.Сделать(): work=%v\n", работа)
if работа == "upgrade" {
return
}
if err := сам.сеть.UpdateLst(); err != nil {
log.Printf("ERRO Шахта.Сделать(): при обновлении lstMine, err=\n\t%v\n", err)
return
}
if !сам.уровеньОбновить() {
return
}
if err := сам.выбратьМеталл(); err != nil {
log.Printf("ERRO Шахта.Сделать(): при выборе продукции, err=\n\t%v\n", err)
return
}
работа = сам.РежимТекущ().Режим()
switch работа {
case "руда":
сам.рудаСделать()
case "железо":
сам.железоСделать()
case "сталь":
сам.стальСделать()
case "свинец":
сам.свинецСделать()
default:
log.Printf("ERRO Шахта.Сделать(): неизвестный режим производства, режим=%q\n", работа)
}
}
// Свинец -- возвращает объект свинца
func (sf *Шахта) Свинец() types.ИСтатПарам {
return sf.свинец
}
// Сталь -- возвращает объект стали
func (сам *Шахта) Сталь() types.ИСтатПарам {
return сам.сталь
}
// Железо -- возвращает объект железа
func (сам *Шахта) Железо() types.ИСтатПарам {
return сам.железо
}
// Руда -- возвращает объект руды
func (сам *Шахта) Руда() types.ИСтатПарам {
return сам.руда
}
// КолвоРаботаСейчас -- возвращает количество прозводимого продукта
func (сам *Шахта) КолвоРаботаСейчас() types.ИСтатПарам {
return сам.numProduct
}
// Выбирает продукцию по возможности произвести и её количеству
func (сам *Шахта) выбратьМеталл() error {
var (
mapProduct = make(map[string]bool) // Словарь известной продукции
lstMine = сам.СписПолучить()
)
фнВыбратьПродукт := func() { // вычисляет список допустимой продукции
mapProduct["ruda"] = true // Руда есть всегда
mapProduct["ferrum"] = false
mapProduct["steel"] = false
mapProduct["plumbum"] = false
for _, strProd := range lstMine { // Проверить руду
if strings.Contains(strProd, `Руда
`) {
mapProduct["ruda"] = true
break
}
}
for _, strProd := range lstMine { // Проверить руду
if strings.Contains(strProd, `Железо
`) {
mapProduct["ferrum"] = true
break
}
}
for _, strProd := range lstMine { // Проверить сталь
if strings.Contains(strProd, `Сталь
`) {
mapProduct["steel"] = true
break
}
}
for _, strProd := range lstMine { // Проверить свинец
if strings.Contains(strProd, `Свинец
`) {
mapProduct["plumbum"] = true
break
}
}
}
фнВыбратьПродукт()
сам.РежимТекущ().РежимУст("руда")
руда := сам.Руда().Получ()
железо := сам.Железо().Получ()
if mapProduct["ferrum"] {
if руда > железо*2 {
сам.РежимТекущ().РежимУст("железо")
}
}
сталь := сам.Сталь().Получ()
if mapProduct["steel"] {
if железо > сталь*2 {
сам.РежимТекущ().РежимУст("сталь")
}
}
свинец := сам.Свинец().Получ()
if mapProduct["plumbum"] {
if сталь > свинец*2 {
сам.РежимТекущ().РежимУст("свинец")
}
}
return nil
}
// Создаёт руду
func (сам *Шахта) рудаСделать() {
var (
lstMine = сам.СписПолучить()
ind int
strOut string
strTime string
strLink string
strNum string
isFind bool
)
for ind, strOut = range lstMine {
if strings.Contains(strOut, `Руда
`) {
strNum = lstMine[ind+1]
strTime = lstMine[ind+3]
strLink = lstMine[ind+10]
isFind = true
break
}
}
if !isFind {
return
}
if !strings.Contains(strLink, `>Начать производство<`) {
return
}
// "Mine?16-1.ILinkListener-productions-0-production-startProduceLink\">Начать производство"
// "Начать производство"
_link := strings.TrimPrefix(strLink, `Начать производство")
strLink = "https://wartank.ru/production/" + _link
lstMine, err := сам.сеть.Get(strLink)
if err != nil {
// log._rintf("ERRO Шахта.сделатьРуду(): при GET-команде 'начать производство руды', err=\n\t%v\n", err)
return
}
isFind = false
for _, strOut = range lstMine {
if strings.Contains(strOut, `База`) {
// log._rintf("WARN Шахта.сделатьРуду(): при обновлении lstMine обнаружено lstBase\n")
return
}
}
if err = сам.СтрОбновить(lstMine); err != nil {
// log._rintf("ERRO Шахта.сделатьРуду(): при обновлении lstMine, err=\n\t%v\n", err)
return
}
if err := сам.ParseCountDown(strTime); err != nil {
log.Printf("ERRO Шахта.сделатьРуду(): при установке времени ожидания добычи руды(%v)\n\terr=%v\n", strTime, err)
}
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
}
сам.КолвоРаботаСейчас().Уст(iNum)
}
// Создаёт железо
func (сам *Шахта) железоСделать() {
var (
lstMine = сам.СписПолучить()
ind int
strOut string
strTime string
strLink string
strNum string
isFind bool
)
for ind, strOut = range lstMine {
if strings.Contains(strOut, `Железо
`) {
strNum = lstMine[ind+1]
strTime = lstMine[ind+3]
strLink = lstMine[ind+10]
isFind = true
break
}
}
if !isFind {
return
}
if !strings.Contains(strLink, `>Начать производство<`) {
return
}
lstLink := strings.Split(strLink, `Начать производство`)
strLink = "https://wartank.ru/production/" + lstLink[0]
lstMine, err := сам.сеть.Get(strLink)
if err != nil {
// log._rintf("ERRO MineNet.makeFerrum(): при GET-команде 'начать производство железа', err=\n\t%v\n", err)
return
}
for _, strOut := range lstMine { // Проверка на базу
if strings.Contains(strOut, `База`) {
// log._rintf("ERRO MineNet.makeFerrum(): при обновлении lstMine найден lstBase")
return
}
}
if err = сам.СтрОбновить(lstMine); err != nil {
// log._rintf("ERRO MineNet.makeFerrum(): при обновлении lstMine, err=\n\t%v\n", err)
return
}
if err := сам.ParseCountDown(strTime); err != nil {
log.Printf("ERRO Mine.makeFerrum(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
}
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
}
сам.КолвоРаботаСейчас().Уст(iNum)
}
// Создаёт сталь
func (сам *Шахта) стальСделать() {
var (
lstMine = сам.СписПолучить()
ind int
strOut string
strTime string
strLink string
strNum string
isFind bool
)
for ind, strOut = range lstMine {
if strings.Contains(strOut, `Сталь
`) {
strNum = lstMine[ind+1]
strTime = lstMine[ind+3]
strLink = lstMine[ind+10]
isFind = true
break
}
}
if !isFind {
return
}
if !strings.Contains(strLink, `>Начать производство<`) {
return
}
lstLink := strings.Split(strLink, `Начать производство`)
strLink = "https://wartank.ru/production/" + lstLink[0]
lstMine, err := сам.сеть.Get(strLink)
if err != nil {
// log._rintf("ERRO MineNet.makeSteel(): при GET-команде 'начать производство стали', err=\n\t%v\n", err)
return
}
for _, strOut := range lstMine { // Проверка на базу
if strings.Contains(strOut, `База`) {
// log._rintf("ERRO MineNet.makeSteel(): при обновлении lstMine найден lstBase")
return
}
}
if err = сам.СтрОбновить(lstMine); err != nil {
// log._rintf("ERRO MineNet.makeSteel(): при обновлении lstMine, err=\n\t%v\n", err)
return
}
if err := сам.ParseCountDown(strTime); err != nil {
log.Printf("ERRO Mine.makeSteel(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
}
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
}
сам.КолвоРаботаСейчас().Уст(iNum)
}
// Создаёт свинец
func (сам *Шахта) свинецСделать() {
var (
lstMine = сам.СписПолучить()
ind int
strOut string
strTime string
strLink string
strNum string
isFind bool
)
for ind, strOut = range lstMine {
if strings.Contains(strOut, `Свинец
`) {
strNum = lstMine[ind+1]
strTime = lstMine[ind+3]
strLink = lstMine[ind+10]
isFind = true
break
}
}
if !isFind {
return
}
if !strings.Contains(strLink, `>Начать производство<`) {
return
}
lstLink := strings.Split(strLink, `Начать производство`)
strLink = "https://wartank.ru/production/" + lstLink[0]
lstMine, err := сам.сеть.Get(strLink)
if err != nil {
// log._rintf("ERRO Шахта.сделатьСвинец(): при GET-команде 'начать производство стали', err=\n\t%v\n", err)
return
}
for _, strOut := range lstMine { // Проверка на базу
if strings.Contains(strOut, `База`) {
// log._rintf("ERRO Шахта.сделатьСвинец(): при обновлении lstMine найден lstBase")
return
}
}
if err = сам.СтрОбновить(lstMine); err != nil {
// log._rintf("ERRO Шахта.сделатьСвинец(): при обновлении lstMine, err=\n\t%v\n", err)
return
}
if err := сам.ParseCountDown(strTime); err != nil {
log.Printf("ERRO Шахта.сделатьСвинец(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
}
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
}
сам.КолвоРаботаСейчас().Уст(iNum)
}