mine.go 11 KB

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