mine.go 10 KB

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