market.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package market
  2. import (
  3. "fmt"
  4. "log"
  5. "strings"
  6. "wartank/pkg/components/section"
  7. "wartank/pkg/types"
  8. "wartank/server/serv_bots/warbot/angar/base/market/marketnet"
  9. )
  10. /*
  11. Объект рынка
  12. */
  13. // Market -- объект рынка
  14. type Market struct {
  15. *section.Section
  16. bot types.IBot
  17. net *marketnet.MarketNet
  18. }
  19. // NewMarket -- возвращает новый рынок
  20. func NewMarket(base types.IBase) (*Market, error) {
  21. section, err := section.NewSection(base.Bot(), "Рынок", `<title>Рынок</title>`)
  22. if err != nil {
  23. return nil, fmt.Errorf("NewMarket(): in create *Section, err=\n\t%w", err)
  24. }
  25. sf := &Market{
  26. Section: section,
  27. bot: base.Bot(),
  28. }
  29. { // Маркет
  30. sf.net, err = marketnet.NewMarketNet(sf)
  31. if err != nil {
  32. return nil, fmt.Errorf("NewMarket(): in create NetMarket, err=\n\t%w", err)
  33. }
  34. }
  35. return sf, nil
  36. }
  37. // Run -- запускает всю работу рынка в отдельном потоке
  38. func (sf *Market) Run() error {
  39. go sf.run()
  40. return nil
  41. }
  42. // выполняет опрос рынка базы, должен работать как горутина
  43. func (sf *Market) run() {
  44. sf.SetCountDown(25)
  45. for {
  46. select {
  47. case <-sf.bot.Ctx().Done():
  48. sf.CountDown().Stop()
  49. return
  50. case <-sf.CountDown().ChanSig():
  51. log.Printf("Market.run(): timeCount=%v\n", sf.CountDown().Get())
  52. _ = sf.buyGold()
  53. // Если золото не куплено -- обновить время ожидания
  54. sf.checkTime()
  55. sf.SetCountDown(120)
  56. }
  57. }
  58. }
  59. // Проверяет время ожидания рынка
  60. func (sf *Market) checkTime() {
  61. var (
  62. strOut string
  63. isFind bool
  64. )
  65. // countDown := sf.CountDown().Get()
  66. fnIsSilver := func() bool { // Найти счётчик цены серебра
  67. if err := sf.net.UpdateLst(); err != nil { // Принудительное ПЕРВОЕ обновление рынка
  68. log.Printf("Market.checkTime(): при обновлении lstMarket, err=\n\t%v\n", err)
  69. return false
  70. }
  71. isFind := false
  72. lstMarket := sf.GetLst()
  73. for _, strOut = range lstMarket {
  74. if strings.Contains(strOut, `alt="Серебро" title="Серебро"> `) {
  75. isFind = true
  76. break
  77. }
  78. }
  79. if isFind {
  80. lstSilver := strings.Split(strOut, `<img class="ico vm" src="/images/icons/silver.png?2" alt="Серебро" title="Серебро"> `)
  81. strSilver := lstSilver[1]
  82. switch strSilver {
  83. case "10", "50", "100", "500":
  84. return true
  85. default:
  86. return false
  87. }
  88. }
  89. return false
  90. }
  91. fnGetCountDown := func() { // Искать счётчик времени
  92. lstMarket := sf.GetLst()
  93. // Найти счётчик времени
  94. for _, strOut = range lstMarket {
  95. if strings.Contains(strOut, `Минимальная цена через `) {
  96. isFind = true
  97. break
  98. }
  99. }
  100. if !isFind {
  101. return // Минимальная цена
  102. }
  103. lstTime := strings.Split(strOut, `Минимальная цена через `)
  104. strTime := lstTime[1]
  105. if err := sf.ParseCountDown(strTime); err != nil {
  106. // log._rintf("ERRO Market.checkTime(): при установке времени ожидания рынка(%v)\n\terr=%v\n", strTime, err)
  107. return // Возможно минимальная цена
  108. }
  109. }
  110. if fnIsSilver() {
  111. return
  112. }
  113. fnGetCountDown()
  114. }
  115. // Проверяет рынок на режим покупки
  116. func (sf *Market) buyGold() bool {
  117. var (
  118. ind int
  119. isFind bool
  120. strOut string
  121. lstMarket = sf.GetLst()
  122. strSilver string
  123. )
  124. for ind, strOut = range lstMarket {
  125. if strings.Contains(strOut, `alt="Серебро" title="Серебро"> `) {
  126. isFind = true
  127. break
  128. }
  129. }
  130. if isFind { // Найдена продажа золота за серебро
  131. lstSilver := strings.Split(strOut, `<img class="ico vm" src="/images/icons/silver.png?2" alt="Серебро" title="Серебро"> `)
  132. strSilver = lstSilver[1]
  133. switch strSilver {
  134. case "10", "50", "100", "500": // Допустимые суммы трат
  135. ind -= 15
  136. strOut = lstMarket[ind]
  137. lstLink := strings.Split(strOut, `<a class="simple-but border mb5" href="`)
  138. if len(lstLink) < 2 {
  139. return false
  140. }
  141. strLink := lstLink[1]
  142. lstLink = strings.Split(strLink, `"><span><span>Получить `)
  143. strLink = "http://wartank.ru/" + lstLink[0]
  144. lstMarket, err := sf.net.Get(strLink)
  145. if err != nil {
  146. // log._rintf("ERRO Market.buyGold(): при выполнении GET-команды на покупку золота, err=\n\t%v\n", err)
  147. return true
  148. }
  149. for _, strOut = range lstMarket {
  150. if strings.Contains(strOut, `Ошибка на сервере. Сообщение админу уже отправлено.`) {
  151. // log._rintf("ERRO Market.buyGold(): при получении lstMarket, strHTML=%v, err=\nt%v\n", strOut, err)
  152. return false
  153. }
  154. }
  155. if err = sf.Update(lstMarket); err != nil {
  156. // log._rintf("Market.buyGold(): при обновлении lstMarket, err=\n\t%v\n", err)
  157. return true
  158. }
  159. default: // Недопустимая сумма, либо больше чем надо
  160. return false
  161. }
  162. }
  163. return true
  164. }