arena_arsenal.go 14 KB

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