market.go 5.1 KB

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