convoy.go 17 KB

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