convoy.go 16 KB

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