mine.go 11 KB

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