arsenal.go 18 KB

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