convoy.go 15 KB

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