mine.go 10 KB

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