arena_market.go 15 KB

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