arena_polygon.go 15 KB

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