convoy.go 15 KB

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