market.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. // package market -- объект рынка
  2. package market
  3. import (
  4. "fmt"
  5. "log"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "wartank/pkg/alias"
  10. "wartank/pkg/arena"
  11. "wartank/pkg/components/arena_net"
  12. "wartank/pkg/types"
  13. "wartank/server/serv_bots/warbot/tank_stat/static_param"
  14. )
  15. // Рынок -- объект рынка
  16. type Рынок struct {
  17. types.ИАрена
  18. бот types.ИБот
  19. сеть types.ИАренаСеть
  20. уровень types.ИСтатПарам
  21. }
  22. // НовРынок -- возвращает новый рынок
  23. func НовРынок(база types.ИБаза) (*Рынок, error) {
  24. арена := arena.НовАрена(база.Бот(), "Рынок", `<title>Рынок</title>`)
  25. уровень, ош := static_param.НовСтатПарам("уровень")
  26. if ош != nil {
  27. return nil, fmt.Errorf("НовРынок(): при создании статистики уровня, ош=\n\t%w", ош)
  28. }
  29. сам := &Рынок{
  30. ИАрена: арена,
  31. бот: база.Бот(),
  32. уровень: уровень,
  33. }
  34. сам.сеть = arena_net.НовАренаСеть(сам, "https://wartank.ru/market")
  35. return сам, nil
  36. }
  37. // Пуск -- запускает всю работу рынка в отдельном потоке
  38. func (сам *Рынок) Пуск() error {
  39. go сам.пуск()
  40. return nil
  41. }
  42. // выполняет опрос рынка базы, должен работать как горутина
  43. func (сам *Рынок) пуск() {
  44. time.Sleep(time.Second * 7)
  45. фнРабота := func() {
  46. defer time.Sleep(time.Minute * 30)
  47. for !сам.уровеньОбновить() {
  48. }
  49. сам.ускорениеПровер()
  50. сам.проверОжидание()
  51. for сам.купитьЗолото() {
  52. }
  53. }
  54. for {
  55. select {
  56. case <-сам.бот.Контекст().Done():
  57. return
  58. default:
  59. фнРабота()
  60. }
  61. }
  62. }
  63. // Проверяет ускорение строительства
  64. func (сам *Рынок) ускорениеПровер() {
  65. списСтр, ош := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
  66. if ош != nil {
  67. log.Printf("Рынок.ускорениеПровер(): in make request, err=\n\t%v\n", ош)
  68. return
  69. }
  70. // <span class="green2">Склад топлива -
  71. var (
  72. еслиНайти = false
  73. стр string
  74. )
  75. for _, стр = range списСтр {
  76. if strings.Contains(стр, `<span class="green2">Склад топлива - `) {
  77. еслиНайти = true
  78. break
  79. }
  80. }
  81. if !еслиНайти {
  82. return
  83. }
  84. }
  85. // Обновляет текущий уровень рынка (может быть не построен)
  86. func (сам *Рынок) уровеньОбновить() bool {
  87. списСтр, ош := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
  88. if ош != nil {
  89. log.Printf("Рынок.уровеньОбновить(): in make request, err=\n\t%v\n", ош)
  90. return false
  91. }
  92. // <span class="green2">Рынок -
  93. var (
  94. еслиНайти = false
  95. стр = ""
  96. )
  97. for _, стр = range списСтр {
  98. if strings.Contains(стр, `<span class="green2">Рынок -`) {
  99. еслиНайти = true
  100. break
  101. }
  102. }
  103. if !еслиНайти {
  104. return false
  105. }
  106. // <span class="green2">Рынок - 0</span><br/>
  107. _стр := strings.TrimPrefix(стр, `<span class="green2">Рынок - `)
  108. _стр = strings.TrimSuffix(_стр, `</span><br/>`)
  109. иУровень, ош := strconv.Atoi(_стр)
  110. if ош != nil {
  111. log.Printf("Рынок.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
  112. return false
  113. }
  114. сам.уровень.Уст(иУровень)
  115. switch иУровень {
  116. case 0: // рынок надо построить
  117. for !сам.построить() {
  118. }
  119. default: // Может можно проапгрейдить
  120. счёт := 5
  121. for !сам.проапгрейдить() {
  122. счёт--
  123. if счёт >= 0 {
  124. break
  125. }
  126. }
  127. }
  128. return true
  129. }
  130. // Строит шахту при нулевом уровне
  131. func (сам *Рынок) построить() bool {
  132. time.Sleep(time.Millisecond * 1000)
  133. // <td style="width:50%;padding-left:1px;"><a class="simple-but border mb5" href="building-upgrade/Market"><span><span>Построить</span></span></a></td>
  134. var (
  135. еслиНайти = false
  136. списСтр []string
  137. стр = ""
  138. ош error
  139. )
  140. фнКупить := func() bool {
  141. defer time.Sleep(time.Millisecond * 1000)
  142. списСтр, ош = сам.сеть.ВебВоркер().Получ("https://wartank.ru/building-upgrade/Market")
  143. if ош != nil {
  144. log.Printf("Рынок.построить().фнКупить(): при GET-команде 'купить постройку склада топлива', err=\n\t%v\n", ош)
  145. return false
  146. }
  147. for _, стр = range списСтр {
  148. // <a class="simple-but border mb5" href="Market?19-1.ILinkListener-upgradeLink-link">
  149. if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
  150. еслиНайти = true
  151. break
  152. }
  153. }
  154. if !еслиНайти {
  155. return true
  156. }
  157. // Пробуем построить шахту
  158. _стр := strings.TrimPrefix(стр, "<a class=\"simple-but border mb5\" href=\"")
  159. _стр = strings.TrimSuffix(_стр, "\">")
  160. // https://wartank.ru/building-upgrade/Market?18-1.ILinkListener-upgradeLink-link
  161. // <a class="simple-but border mb5" href="Market?19-1.ILinkListener-upgradeLink-link">
  162. ссылка := "https://wartank.ru/building-upgrade/" + _стр
  163. списСтр, ош = сам.сеть.ВебВоркер().Получ(ссылка)
  164. if ош != nil {
  165. log.Printf("Рынок.построить().фнКупить(): при GET-команде 'купить постройку склада топлива', err=\n\t%v\n", ош)
  166. return false
  167. }
  168. // Проверить, что постройка состоялась
  169. for _, стр := range списСтр {
  170. if strings.Contains(стр, "ILinkListener-upgradeLink-link") {
  171. log.Printf("Рынок.построить().фнКупить(): покупка склада топлива не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
  172. return false // Покупка не оплачена
  173. }
  174. }
  175. log.Printf("+++++Рынок.построить().фнКупить(): покупка склада топлива прошла\n")
  176. return true
  177. }
  178. фнПодтверждение := func() bool {
  179. for _, стр = range списСтр {
  180. // <a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="../wicket/page?21-1.ILinkListener-confirmLink"><span><span>да, подтверждаю</span></span></a>
  181. if strings.Contains(стр, `ILinkListener-confirmLink`) {
  182. еслиНайти = true
  183. break
  184. }
  185. }
  186. if !еслиНайти {
  187. return true
  188. }
  189. // Пробуем построить шахту
  190. _стр := strings.TrimPrefix(стр, `<a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="..`)
  191. _стр = strings.TrimSuffix(_стр, `"><span><span>да, подтверждаю</span></span></a>`)
  192. // https://wartank.ru/wicket/page?20-1.ILinkListener-confirmLink
  193. ссылка := "https://wartank.ru" + _стр
  194. списСтр, ош = сам.сеть.ВебВоркер().Получ(ссылка)
  195. if ош != nil {
  196. log.Printf("Рынок.построить().фнПодтверждение(): при GET-команде 'подтвердить постройку склада топлива', err=\n\t%v\n", ош)
  197. return false
  198. }
  199. // Проверить, что постройка состоялась
  200. for _, стр := range списСтр {
  201. if strings.Contains(стр, "<title>Вы сделали слишком большую паузу</title>") {
  202. log.Printf("Рынок.построить().фнПодтверждение(): подтверждение покупка склада топлива не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
  203. return false // Покупка не оплачена
  204. }
  205. }
  206. log.Printf("+++++Рынок.построить().фнПодтверждение(): подтверждение покупка склада топлива прошла\n")
  207. return true
  208. }
  209. фнКомплекс := func() {
  210. for {
  211. if фнКупить() {
  212. if фнПодтверждение() {
  213. break
  214. }
  215. }
  216. }
  217. }
  218. фнКомплекс()
  219. return true
  220. }
  221. // Пытается проапгрейдить топливный склад
  222. func (сам *Рынок) проапгрейдить() bool {
  223. time.Sleep(time.Millisecond * 1000)
  224. var (
  225. еслиНайти = false
  226. списСтр []string
  227. стр = ""
  228. ош error
  229. )
  230. фнКупить := func() bool {
  231. defer time.Sleep(time.Millisecond * 1000)
  232. списСтр, ош = сам.сеть.ВебВоркер().Получ("https://wartank.ru/building-upgrade/Market")
  233. if ош != nil {
  234. log.Printf("Рынок.проапгрейдить().фнКупить(): при GET-команде 'купить постройку рынка', err=\n\t%v\n", ош)
  235. return false
  236. }
  237. for _, стр = range списСтр {
  238. // <a class="simple-but border mb5" href="Market?5-1.ILinkListener-upgradeLink-link">
  239. if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
  240. еслиНайти = true
  241. break
  242. }
  243. }
  244. if !еслиНайти {
  245. return true
  246. }
  247. // Пробуем улучшить шахту
  248. _стр := strings.TrimPrefix(стр, "<a class=\"simple-but border mb5\" href=\"")
  249. _стр = strings.TrimSuffix(_стр, "\">")
  250. // https://wartank.ru/building-upgrade/Market?4-1.ILinkListener-upgradeLink-link
  251. // <a class="simple-but border mb5" href="Market?50-1.ILinkListener-upgradeLink-link">
  252. ссылка := "https://wartank.ru/building-upgrade/" + _стр
  253. списСтр, ош = сам.сеть.ВебВоркер().Получ(ссылка)
  254. if ош != nil {
  255. log.Printf("Рынок.проапгрейдить().фнКупить(): при GET-команде 'купить постройку рынка', err=\n\t%v\n", ош)
  256. return false
  257. }
  258. // Проверить, что постройка состоялась
  259. for _, стр := range списСтр {
  260. if strings.Contains(стр, "ILinkListener-upgradeLink-link") {
  261. log.Printf("Рынок.проапгрейдить().фнКупить(): покупка рынка не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
  262. return false // Покупка не оплачена
  263. }
  264. }
  265. log.Printf("+++++Рынок.проапгрейдить().фнКупить(): покупка рынка прошла\n")
  266. return true
  267. }
  268. фнПодтверждение := func() bool {
  269. for _, стр = range списСтр {
  270. // <a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="../wicket/page?7-1.ILinkListener-confirmLink"><span><span>да, подтверждаю</span></span></a>
  271. if strings.Contains(стр, `ILinkListener-confirmLink`) {
  272. еслиНайти = true
  273. break
  274. }
  275. }
  276. if !еслиНайти {
  277. return true
  278. }
  279. // Пробуем построить шахту
  280. _стр := strings.TrimPrefix(стр, `<a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="..`)
  281. _стр = strings.TrimSuffix(_стр, `"><span><span>да, подтверждаю</span></span></a>`)
  282. // https://wartank.ru/wicket/page?6-1.ILinkListener-confirmLink
  283. ссылка := "https://wartank.ru" + _стр
  284. списСтр, ош = сам.сеть.ВебВоркер().Получ(ссылка)
  285. if ош != nil {
  286. log.Printf("Рынок.проапгрейдить().фнПодтверждение(): при GET-команде 'подтвердить постройку рынка', err=\n\t%v\n", ош)
  287. return false
  288. }
  289. // Проверить, что постройка состоялась
  290. for _, стр := range списСтр {
  291. if strings.Contains(стр, "<title>Вы сделали слишком большую паузу</title>") {
  292. log.Printf("Рынок.проапгрейдить().фнПодтверждение(): подтверждение покупка рынка не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
  293. return false // Покупка не оплачена
  294. }
  295. }
  296. log.Printf("+++++Рынок.проапгрейдить().фнПодтверждение(): подтверждение покупка склада топлива прошла\n")
  297. return true
  298. }
  299. фнКомплекс := func() {
  300. count := 5
  301. for count > 0 {
  302. if фнКупить() {
  303. if фнПодтверждение() {
  304. break
  305. }
  306. }
  307. count--
  308. }
  309. }
  310. фнКомплекс()
  311. return true
  312. }
  313. // Проверяет время ожидания рынка
  314. func (сам *Рынок) проверОжидание() {
  315. var (
  316. strOut string
  317. еслиНайдено bool
  318. )
  319. // countDown := сам.CountDown().Get()
  320. фнЕслиСеребро := func() bool { // Найти счётчик цены серебра
  321. сам.сеть.Обновить()
  322. еслиНайдено := false
  323. lstMarket := сам.СписПолучить()
  324. for _, strOut = range lstMarket {
  325. if strings.Contains(strOut, `alt="Серебро" title="Серебро"> `) {
  326. еслиНайдено = true
  327. break
  328. }
  329. }
  330. if еслиНайдено {
  331. lstSilver := strings.Split(strOut, `<img class="ico vm" src="/images/icons/silver.png?2" alt="Серебро" title="Серебро"> `)
  332. strSilver := lstSilver[1]
  333. switch strSilver {
  334. case "10", "50", "100", "500":
  335. return true
  336. default:
  337. серебро := сам.бот.Ангар().СереброВсего()
  338. if серебро.Получ() > 1_000_000 {
  339. return true
  340. }
  341. return false
  342. }
  343. }
  344. return false
  345. }
  346. fnGetCountDown := func() { // Искать счётчик времени
  347. lstMarket := сам.СписПолучить()
  348. // Найти счётчик времени
  349. for _, strOut = range lstMarket {
  350. if strings.Contains(strOut, `Минимальная цена через `) {
  351. еслиНайдено = true
  352. break
  353. }
  354. }
  355. if !еслиНайдено {
  356. return // Минимальная цена
  357. }
  358. lstTime := strings.Split(strOut, `Минимальная цена через `)
  359. strTime := lstTime[1]
  360. if err := сам.ОбратВремяУст(alias.Время(strTime)); err != nil {
  361. // log._rintf("ERRO Market.checkTime(): при установке времени ожидания рынка(%v)\n\terr=%v\n", strTime, err)
  362. return // Возможно минимальная цена
  363. }
  364. }
  365. if фнЕслиСеребро() {
  366. return
  367. }
  368. fnGetCountDown()
  369. }
  370. // Проверяет рынок на режим покупки
  371. func (сам *Рынок) купитьЗолото() bool {
  372. var (
  373. ind int
  374. еслиНайдено bool
  375. strOut string
  376. lstMarket = сам.СписПолучить()
  377. strSilver string
  378. )
  379. for ind, strOut = range lstMarket {
  380. if strings.Contains(strOut, `alt="Серебро" title="Серебро"> `) {
  381. еслиНайдено = true
  382. break
  383. }
  384. }
  385. if !еслиНайдено { // Не найдена продажа золота за серебро
  386. return false
  387. }
  388. lstSilver := strings.Split(strOut, `<img class="ico vm" src="/images/icons/silver.png?2" alt="Серебро" title="Серебро"> `)
  389. strSilver = lstSilver[1]
  390. серебро := сам.бот.Ангар().СереброВсего().Получ()
  391. еслиКупить := false
  392. switch strSilver {
  393. case "10", "50", "100", "500": // Допустимые суммы трат
  394. еслиКупить = true
  395. case "1000": // Если стоит тысяча серебра
  396. if серебро > 500_000 { // Если серебра больше полумиллона -- покупаем
  397. еслиКупить = true
  398. }
  399. case "5000", "10000": // Если большая сумма -- можно купить и больше
  400. if серебро > 1_000_000 {
  401. еслиКупить = true
  402. }
  403. }
  404. if !еслиКупить {
  405. return false
  406. }
  407. ind -= 15
  408. strOut = lstMarket[ind]
  409. lstLink := strings.Split(strOut, `<a class="simple-but border mb5" href="`)
  410. if len(lstLink) < 2 {
  411. return false
  412. }
  413. strLink := lstLink[1]
  414. lstLink = strings.Split(strLink, `"><span><span>Получить `)
  415. strLink = "https://wartank.ru/" + lstLink[0]
  416. lstMarket, err := сам.сеть.Get(strLink)
  417. if err != nil {
  418. // log._rintf("ERRO Market.buyGold(): при выполнении GET-команды на покупку золота, err=\n\t%v\n", err)
  419. return true
  420. }
  421. for _, strOut = range lstMarket {
  422. if strings.Contains(strOut, `Ошибка на сервере. Сообщение админу уже отправлено.`) {
  423. // log._rintf("ERRO Market.buyGold(): при получении lstMarket, strHTML=%v, err=\nt%v\n", strOut, err)
  424. return false
  425. }
  426. }
  427. if err = сам.СтрОбновить(lstMarket); err != nil {
  428. // log._rintf("Market.buyGold(): при обновлении lstMarket, err=\n\t%v\n", err)
  429. return true
  430. }
  431. return true
  432. }