mine.go 10 KB

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