mine.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. package mine
  2. import (
  3. "fmt"
  4. "log"
  5. "strconv"
  6. "strings"
  7. "wartank/pkg/components/section"
  8. "wartank/pkg/types"
  9. "wartank/server/serv_bots/warbot/angar/base/mine/minenet"
  10. "wartank/server/serv_bots/warbot/tank/tankstat/static_param"
  11. )
  12. /*
  13. Объект шахты на базе
  14. */
  15. // Шахта -- объект шахты на базе
  16. type Шахта struct {
  17. *section.Section
  18. net *minenet.MineNet
  19. бот types.ИБот
  20. база types.ИБаза
  21. руда types.ИСтатПарам
  22. железо types.ИСтатПарам
  23. сталь types.ИСтатПарам
  24. свинец types.ИСтатПарам
  25. numProduct types.ИСтатПарам
  26. }
  27. // НовШахта -- возвращает новый *Mine
  28. func НовШахта(база types.ИБаза) (*Шахта, error) {
  29. section, err := section.NewSection(база.Бот(), "Шахта", `<span class="green2">Руда</span><br/>`)
  30. if err != nil {
  31. return nil, fmt.Errorf("НовШахта(): in create *Section, err=\n\t%w", err)
  32. }
  33. руда, ош := static_param.НовСтатПарам("ruda")
  34. if ош != nil {
  35. return nil, fmt.Errorf("НовШахта(): при создании статистики руды, ош=\n\t%w", ош)
  36. }
  37. железо, ош := static_param.НовСтатПарам("ferrum")
  38. if ош != nil {
  39. return nil, fmt.Errorf("НовШахта(): при создании статистики железа, ош=\n\t%w", ош)
  40. }
  41. сталь, ош := static_param.НовСтатПарам("steel")
  42. if ош != nil {
  43. return nil, fmt.Errorf("НовШахта(): при создании статистики стали, ош=\n\t%w", ош)
  44. }
  45. свинец, ош := static_param.НовСтатПарам("plumbum")
  46. if ош != nil {
  47. return nil, fmt.Errorf("НовШахта(): при создании статистики свинца, ош=\n\t%w", ош)
  48. }
  49. добычаЧисло, ош := static_param.НовСтатПарам("plumbum")
  50. if ош != nil {
  51. return nil, fmt.Errorf("НовШахта(): при создании статистики числа добычи, ош=\n\t%w", ош)
  52. }
  53. sf := &Шахта{
  54. Section: section,
  55. бот: база.Бот(),
  56. база: база,
  57. руда: руда,
  58. железо: железо,
  59. сталь: сталь,
  60. свинец: свинец,
  61. numProduct: добычаЧисло,
  62. }
  63. sf.net, err = minenet.NewMineNet(sf)
  64. if err != nil {
  65. return nil, fmt.Errorf("NewMine(): in create NetMine, err=\n\t%w", err)
  66. }
  67. return sf, nil
  68. }
  69. func (sf *Шахта) Run() error {
  70. go sf.run()
  71. return nil
  72. }
  73. // run -- запускает обработку шахты
  74. func (sf *Шахта) run() {
  75. sf.SetCountDown(1)
  76. for {
  77. select {
  78. case <-sf.бот.Кнт().Done():
  79. sf.ВремяОпрос().Стоп()
  80. return
  81. case <-sf.ВремяОпрос().КаналСиг():
  82. log.Printf("Mine.run(): time sig")
  83. sf.Section.SetCountDown(120)
  84. work := sf.РежимТекущ().Режим()
  85. log.Printf("Mine.run(): work=%v\n", work)
  86. if work == "upgrade" {
  87. continue
  88. }
  89. if err := sf.net.UpdateLst(); err != nil {
  90. log.Printf("ERRO Mine.Run(): при обновлении lstMine, err=\n\t%v\n", err)
  91. continue
  92. }
  93. if err := sf.selectProduct(); err != nil {
  94. log.Printf("ERRO MineNet.Run(): при выборе продукции, err=\n\t%v\n", err)
  95. continue
  96. }
  97. switch work {
  98. case "руда":
  99. sf.makeRuda()
  100. case "железо":
  101. sf.makeFerrum()
  102. case "сталь":
  103. sf.makeSteel()
  104. default:
  105. // log._rintf("ERRO MineNet.Run(): неизвестный режим производства, режим=%q\n", work)
  106. }
  107. }
  108. // time.Sleep(time.Second * 30)
  109. }
  110. }
  111. // Свинец -- возвращает объект свинца
  112. func (sf *Шахта) Свинец() types.ИСтатПарам {
  113. return sf.свинец
  114. }
  115. // Сталь -- возвращает объект стали
  116. func (sf *Шахта) Сталь() types.ИСтатПарам {
  117. return sf.сталь
  118. }
  119. // Железо -- возвращает объект железа
  120. func (sf *Шахта) Железо() types.ИСтатПарам {
  121. return sf.железо
  122. }
  123. // Руда -- возвращает объект руды
  124. func (sf *Шахта) Руда() types.ИСтатПарам {
  125. return sf.руда
  126. }
  127. // КолвоСделатьСейчас -- возвращает количество прозводимого продукта
  128. func (sf *Шахта) КолвоСделатьСейчас() types.ИСтатПарам {
  129. return sf.numProduct
  130. }
  131. // Выбирает продукцию по возможности произвести и её количеству
  132. func (sf *Шахта) selectProduct() error {
  133. var (
  134. mapProduct = make(map[string]bool) // Словарь известной продукции
  135. lstMine = sf.СписПолучить()
  136. )
  137. fnProduct := func() { // вычисляет список допустимой продукции
  138. mapProduct["ruda"] = true // Руда есть всегда
  139. mapProduct["ferrum"] = false
  140. mapProduct["steel"] = false
  141. mapProduct["plumbum"] = false
  142. for _, strProd := range lstMine { // Проверить железо
  143. if strings.Contains(strProd, `<span class="green2">Железо</span><br/>`) {
  144. mapProduct["ferrum"] = true
  145. break
  146. }
  147. }
  148. for _, strProd := range lstMine { // Проверить сталь
  149. if strings.Contains(strProd, `<span class="green2">Сталь</span><br/>`) {
  150. mapProduct["steel"] = true
  151. break
  152. }
  153. }
  154. for _, strProd := range lstMine { // Проверить свинец
  155. if strings.Contains(strProd, `<span class="green2">Свинец</span><br/>`) {
  156. mapProduct["plumbum"] = true
  157. break
  158. }
  159. }
  160. }
  161. fnProduct()
  162. sf.РежимТекущ().РежимУст("руда")
  163. ruda := sf.Руда().Получ()
  164. ferrum := sf.Железо().Получ()
  165. if mapProduct["ferrum"] {
  166. if ruda >= ferrum*2 {
  167. sf.РежимТекущ().РежимУст("железо")
  168. }
  169. }
  170. steel := sf.Сталь().Получ()
  171. if mapProduct["steel"] {
  172. if ferrum >= steel*2 {
  173. sf.РежимТекущ().РежимУст("сталь")
  174. }
  175. }
  176. plumbum := sf.Свинец().Получ()
  177. if mapProduct["plumbum"] {
  178. if steel > plumbum*2 {
  179. sf.РежимТекущ().РежимУст("свинец")
  180. }
  181. }
  182. return nil
  183. }
  184. // Создаёт руду
  185. func (sf *Шахта) makeRuda() {
  186. var (
  187. lstMine = sf.СписПолучить()
  188. ind int
  189. strOut string
  190. strTime string
  191. strLink string
  192. strNum string
  193. isFind bool
  194. )
  195. for ind, strOut = range lstMine {
  196. if strings.Contains(strOut, `<span class="green2">Руда</span><br/>`) {
  197. strNum = lstMine[ind+1]
  198. strTime = lstMine[ind+3]
  199. strLink = lstMine[ind+10]
  200. isFind = true
  201. break
  202. }
  203. }
  204. if !isFind {
  205. return
  206. }
  207. if !strings.Contains(strLink, `>Начать производство<`) {
  208. return
  209. }
  210. lstLink := strings.Split(strLink, `<a class="simple-but border" href="`)
  211. strLink = lstLink[1]
  212. lstLink = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  213. strLink = "http://wartank.ru/production/" + lstLink[0]
  214. lstMine, err := sf.net.Get(strLink)
  215. if err != nil {
  216. // log._rintf("ERRO MineNet.makeRuda(): при GET-команде 'начать производство руды', err=\n\t%v\n", err)
  217. return
  218. }
  219. isFind = false
  220. for _, strOut = range lstMine {
  221. if strings.Contains(strOut, `<title>База</title>`) {
  222. // log._rintf("WARN MineNet.makeRuda(): при обновлении lstMine обнаружено lstBase\n")
  223. return
  224. }
  225. }
  226. if err = sf.СтрОбновить(lstMine); err != nil {
  227. // log._rintf("ERRO MineNet.makeRuda(): при обновлении lstMine, err=\n\t%v\n", err)
  228. return
  229. }
  230. if err := sf.ParseCountDown(strTime); err != nil {
  231. log.Printf("ERRO Mine.makeRuda(): при установке времени ожидания добычи руды(%v)\n\terr=%v\n", strTime, err)
  232. }
  233. lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
  234. strNum = lstNum[1]
  235. lstNum = strings.Split(strNum, `</span><br/>`)
  236. strNum = lstNum[0]
  237. iNum, err := strconv.Atoi(strNum)
  238. if err != nil {
  239. // log._rintf("ERRO MineNet.makeRuda(): кол-во(%v) не число, err=\n\t%v\n", strNum, err)
  240. return
  241. }
  242. sf.КолвоСделатьСейчас().Уст(iNum)
  243. }
  244. // Создаёт железо
  245. func (sf *Шахта) makeFerrum() {
  246. var (
  247. lstMine = sf.СписПолучить()
  248. ind int
  249. strOut string
  250. strTime string
  251. strLink string
  252. strNum string
  253. isFind bool
  254. )
  255. for ind, strOut = range lstMine {
  256. if strings.Contains(strOut, `<span class="green2">Железо</span><br/>`) {
  257. strNum = lstMine[ind+1]
  258. strTime = lstMine[ind+3]
  259. strLink = lstMine[ind+10]
  260. isFind = true
  261. break
  262. }
  263. }
  264. if !isFind {
  265. return
  266. }
  267. if !strings.Contains(strLink, `>Начать производство<`) {
  268. return
  269. }
  270. lstLink := strings.Split(strLink, `<a class="simple-but border" href="`)
  271. strLink = lstLink[1]
  272. lstLink = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  273. strLink = "http://wartank.ru/production/" + lstLink[0]
  274. lstMine, err := sf.net.Get(strLink)
  275. if err != nil {
  276. // log._rintf("ERRO MineNet.makeFerrum(): при GET-команде 'начать производство железа', err=\n\t%v\n", err)
  277. return
  278. }
  279. for _, strOut := range lstMine { // Проверка на базу
  280. if strings.Contains(strOut, `<title>База</title>`) {
  281. // log._rintf("ERRO MineNet.makeFerrum(): при обновлении lstMine найден lstBase")
  282. return
  283. }
  284. }
  285. if err = sf.СтрОбновить(lstMine); err != nil {
  286. // log._rintf("ERRO MineNet.makeFerrum(): при обновлении lstMine, err=\n\t%v\n", err)
  287. return
  288. }
  289. if err := sf.ParseCountDown(strTime); err != nil {
  290. log.Printf("ERRO Mine.makeFerrum(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
  291. }
  292. lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
  293. strNum = lstNum[1]
  294. lstNum = strings.Split(strNum, `</span><br/>`)
  295. strNum = lstNum[0]
  296. iNum, err := strconv.Atoi(strNum)
  297. if err != nil {
  298. // log._rintf("ERRO MineNet.makeFerrum(): кол-во(%v) не число, err=\n\t%v\n", strNum, err)
  299. return
  300. }
  301. sf.КолвоСделатьСейчас().Уст(iNum)
  302. }
  303. // Создаёт сталь
  304. func (sf *Шахта) makeSteel() {
  305. var (
  306. lstMine = sf.СписПолучить()
  307. ind int
  308. strOut string
  309. strTime string
  310. strLink string
  311. strNum string
  312. isFind bool
  313. )
  314. for ind, strOut = range lstMine {
  315. if strings.Contains(strOut, `<span class="green2">Сталь</span><br/>`) {
  316. strNum = lstMine[ind+1]
  317. strTime = lstMine[ind+3]
  318. strLink = lstMine[ind+10]
  319. isFind = true
  320. break
  321. }
  322. }
  323. if !isFind {
  324. return
  325. }
  326. if !strings.Contains(strLink, `>Начать производство<`) {
  327. return
  328. }
  329. lstLink := strings.Split(strLink, `<a class="simple-but border" href="`)
  330. strLink = lstLink[1]
  331. lstLink = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  332. strLink = "http://wartank.ru/production/" + lstLink[0]
  333. lstMine, err := sf.net.Get(strLink)
  334. if err != nil {
  335. // log._rintf("ERRO MineNet.makeSteel(): при GET-команде 'начать производство стали', err=\n\t%v\n", err)
  336. return
  337. }
  338. for _, strOut := range lstMine { // Проверка на базу
  339. if strings.Contains(strOut, `<title>База</title>`) {
  340. // log._rintf("ERRO MineNet.makeSteel(): при обновлении lstMine найден lstBase")
  341. return
  342. }
  343. }
  344. if err = sf.СтрОбновить(lstMine); err != nil {
  345. // log._rintf("ERRO MineNet.makeSteel(): при обновлении lstMine, err=\n\t%v\n", err)
  346. return
  347. }
  348. if err := sf.ParseCountDown(strTime); err != nil {
  349. log.Printf("ERRO Mine.makeSteel(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
  350. }
  351. lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
  352. strNum = lstNum[1]
  353. lstNum = strings.Split(strNum, `</span><br/>`)
  354. strNum = lstNum[0]
  355. iNum, err := strconv.Atoi(strNum)
  356. if err != nil {
  357. // log._rintf("ERRO MineNet.makeSteel(): кол-во(%v) не число, err=\n\t%v\n", strNum, err)
  358. return
  359. }
  360. sf.КолвоСделатьСейчас().Уст(iNum)
  361. }