mine.go 11 KB

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