market.go 15 KB

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