market.go 17 KB

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