convoy.go 18 KB

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